Skip to content

Commit 8806aa9

Browse files
committedJun 9, 2021
[fix] Close the connection cleanly when an error occurs
Instead of destroying the socket, try to close the connection cleanly if an error (such as a data framing error) occurs after the opening handshake has completed. Also, to comply with the specification, use the 1006 status code if no close frame is received, even if the connection is closed due to an error. Fixes #1898
1 parent 05b8ccd commit 8806aa9

File tree

2 files changed

+21
-7
lines changed

2 files changed

+21
-7
lines changed
 

‎lib/websocket.js

+2-3
Original file line numberDiff line numberDiff line change
@@ -808,11 +808,10 @@ function receiverOnError(err) {
808808
const websocket = this[kWebSocket];
809809

810810
websocket._socket.removeListener('data', socketOnData);
811+
websocket._socket.resume();
811812

812-
websocket._readyState = WebSocket.CLOSING;
813-
websocket._closeCode = err[kStatusCode];
813+
websocket.close(err[kStatusCode]);
814814
websocket.emit('error', err);
815-
websocket._socket.destroy();
816815
}
817816

818817
/**

‎test/websocket.test.js

+19-4
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,7 @@ describe('WebSocket', () => {
429429

430430
describe('Events', () => {
431431
it("emits an 'error' event if an error occurs", (done) => {
432+
let clientCloseEventEmitted = false;
432433
const wss = new WebSocket.Server({ port: 0 }, () => {
433434
const ws = new WebSocket(`ws://localhost:${wss.address().port}`);
434435

@@ -440,14 +441,21 @@ describe('WebSocket', () => {
440441
);
441442

442443
ws.on('close', (code, reason) => {
443-
assert.strictEqual(code, 1002);
444+
clientCloseEventEmitted = true;
445+
assert.strictEqual(code, 1006);
444446
assert.strictEqual(reason, '');
445-
wss.close(done);
446447
});
447448
});
448449
});
449450

450451
wss.on('connection', (ws) => {
452+
ws.on('close', (code, reason) => {
453+
assert.ok(clientCloseEventEmitted);
454+
assert.strictEqual(code, 1002);
455+
assert.strictEqual(reason, '');
456+
wss.close(done);
457+
});
458+
451459
ws._socket.write(Buffer.from([0x85, 0x00]));
452460
});
453461
});
@@ -1410,10 +1418,17 @@ describe('WebSocket', () => {
14101418
});
14111419

14121420
it('honors the `mask` option', (done) => {
1421+
let serverClientCloseEventEmitted = false;
14131422
const wss = new WebSocket.Server({ port: 0 }, () => {
14141423
const ws = new WebSocket(`ws://localhost:${wss.address().port}`);
14151424

14161425
ws.on('open', () => ws.send('hi', { mask: false }));
1426+
ws.on('close', (code, reason) => {
1427+
assert.ok(serverClientCloseEventEmitted);
1428+
assert.strictEqual(code, 1002);
1429+
assert.strictEqual(reason, '');
1430+
wss.close(done);
1431+
});
14171432
});
14181433

14191434
wss.on('connection', (ws) => {
@@ -1434,9 +1449,9 @@ describe('WebSocket', () => {
14341449
);
14351450

14361451
ws.on('close', (code, reason) => {
1437-
assert.strictEqual(code, 1002);
1452+
serverClientCloseEventEmitted = true;
1453+
assert.strictEqual(code, 1006);
14381454
assert.strictEqual(reason, '');
1439-
wss.close(done);
14401455
});
14411456
});
14421457
});

0 commit comments

Comments
 (0)
Please sign in to comment.