Skip to content

Commit

Permalink
[fix] Do not swallow errors emitted while destroying (#1672)
Browse files Browse the repository at this point in the history
  • Loading branch information
lpinca authored Feb 29, 2020
1 parent a39756a commit 3e7f69c
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 1 deletion.
11 changes: 10 additions & 1 deletion lib/stream.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ function createWebSocketStream(ws, options) {
});

ws.once('error', function error(err) {
if (duplex.destroyed) return;

duplex.destroy(err);
});

Expand All @@ -94,8 +96,15 @@ function createWebSocketStream(ws, options) {
return;
}

ws.once('close', function close() {
let called = false;

ws.once('error', function error(err) {
called = true;
callback(err);
});

ws.once('close', function close() {
if (!called) callback(err);
process.nextTick(emitClose, duplex);
});
ws.terminate();
Expand Down
46 changes: 46 additions & 0 deletions test/create-websocket-stream.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,52 @@ describe('createWebSocketStream', () => {
});
});

it('does not swallow errors that may occur while destroying', (done) => {
const frame = Buffer.concat(
Sender.frame(Buffer.from([0x22, 0xfa, 0xec, 0x78]), {
fin: true,
rsv1: true,
opcode: 0x02,
mask: false,
readOnly: false
})
);

const wss = new WebSocket.Server(
{
perMessageDeflate: true,
port: 0
},
() => {
const ws = new WebSocket(`ws://localhost:${wss.address().port}`);
const duplex = createWebSocketStream(ws);

duplex.on('error', (err) => {
assert.ok(err instanceof Error);
assert.strictEqual(err.code, 'Z_DATA_ERROR');
assert.strictEqual(err.errno, -3);

duplex.on('close', () => {
wss.close(done);
});
});

let bytesRead = 0;

ws.on('open', () => {
ws._socket.on('data', (chunk) => {
bytesRead += chunk.length;
if (bytesRead === frame.length) duplex.destroy();
});
});
}
);

wss.on('connection', (ws) => {
ws._socket.write(frame);
});
});

it("does not suppress the throwing behavior of 'error' events", (done) => {
const wss = new WebSocket.Server({ port: 0 }, () => {
const ws = new WebSocket(`ws://localhost:${wss.address().port}`);
Expand Down
1 change: 1 addition & 0 deletions test/permessage-deflate.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -589,6 +589,7 @@ describe('PerMessageDeflate', () => {
perMessageDeflate.accept([{}]);
perMessageDeflate.decompress(data, true, (err) => {
assert.ok(err instanceof Error);
assert.strictEqual(err.code, 'Z_DATA_ERROR');
assert.strictEqual(err.errno, -3);
done();
});
Expand Down

0 comments on commit 3e7f69c

Please sign in to comment.