Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 67e25ff

Browse filesBrowse files
committed
[fix] Fix case where abortHandshake() does not close the connection
On Node.js >= 14.3.0 `request.abort()` does not destroy the socket if called after the request completed. Fixes #1869
1 parent 23ba6b2 commit 67e25ff
Copy full SHA for 67e25ff

File tree

Expand file treeCollapse file tree

2 files changed

+60
-2
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+60
-2
lines changed

‎lib/websocket.js

Copy file name to clipboardExpand all lines: lib/websocket.js
+10Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,16 @@ function abortHandshake(websocket, stream, message) {
718718

719719
if (stream.setHeader) {
720720
stream.abort();
721+
722+
if (stream.socket && !stream.socket.destroyed) {
723+
//
724+
// On Node.js >= 14.3.0 `request.abort()` does not destroy the socket if
725+
// called after the request completed. See
726+
// https://github.com/websockets/ws/issues/1869.
727+
//
728+
stream.socket.destroy();
729+
}
730+
721731
stream.once('abort', websocket.emitClose.bind(websocket));
722732
websocket.emit('error', err);
723733
} else {

‎test/websocket.test.js

Copy file name to clipboardExpand all lines: test/websocket.test.js
+50-2Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1444,7 +1444,7 @@ describe('WebSocket', () => {
14441444
});
14451445

14461446
describe('#close', () => {
1447-
it('closes the connection if called while connecting (1/2)', (done) => {
1447+
it('closes the connection if called while connecting (1/3)', (done) => {
14481448
const wss = new WebSocket.Server({ port: 0 }, () => {
14491449
const ws = new WebSocket(`ws://localhost:${wss.address().port}`);
14501450

@@ -1461,7 +1461,7 @@ describe('WebSocket', () => {
14611461
});
14621462
});
14631463

1464-
it('closes the connection if called while connecting (2/2)', (done) => {
1464+
it('closes the connection if called while connecting (2/3)', (done) => {
14651465
const wss = new WebSocket.Server(
14661466
{
14671467
verifyClient: (info, cb) => setTimeout(cb, 300, true),
@@ -1484,6 +1484,54 @@ describe('WebSocket', () => {
14841484
);
14851485
});
14861486

1487+
it('closes the connection if called while connecting (3/3)', (done) => {
1488+
const server = http.createServer();
1489+
1490+
server.listen(0, function () {
1491+
const ws = new WebSocket(`ws://localhost:${server.address().port}`);
1492+
1493+
ws.on('open', () => done(new Error("Unexpected 'open' event")));
1494+
ws.on('error', (err) => {
1495+
assert.ok(err instanceof Error);
1496+
assert.strictEqual(
1497+
err.message,
1498+
'WebSocket was closed before the connection was established'
1499+
);
1500+
ws.on('close', () => {
1501+
server.close(done);
1502+
});
1503+
});
1504+
1505+
ws.on('unexpected-response', (req, res) => {
1506+
assert.strictEqual(res.statusCode, 502);
1507+
1508+
const chunks = [];
1509+
1510+
res.on('data', (chunk) => {
1511+
chunks.push(chunk);
1512+
});
1513+
1514+
res.on('end', () => {
1515+
assert.strictEqual(Buffer.concat(chunks).toString(), 'foo');
1516+
ws.close();
1517+
});
1518+
});
1519+
});
1520+
1521+
server.on('upgrade', (req, socket) => {
1522+
socket.on('end', socket.end);
1523+
1524+
socket.write(
1525+
`HTTP/1.1 502 ${http.STATUS_CODES[502]}\r\n` +
1526+
'Connection: keep-alive\r\n' +
1527+
'Content-type: text/html\r\n' +
1528+
'Content-Length: 3\r\n' +
1529+
'\r\n' +
1530+
'foo'
1531+
);
1532+
});
1533+
});
1534+
14871535
it('can be called from an error listener while connecting', (done) => {
14881536
const ws = new WebSocket('ws://localhost:1337');
14891537

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.