diff --git a/lib/WebSocket.js b/lib/WebSocket.js index b835cdfe1..41868d832 100644 --- a/lib/WebSocket.js +++ b/lib/WebSocket.js @@ -653,10 +653,16 @@ function initAsClient (address, protocols, options) { }); this._req.on('upgrade', (res, socket, head) => { - this._req = null; - this.emit('headers', res.headers, res); + // + // The user may have closed the connection from a listener of the `headers` + // event. + // + if (this.readyState !== WebSocket.CONNECTING) return; + + this._req = null; + const digest = crypto.createHash('sha1') .update(key + constants.GUID, 'binary') .digest('base64'); diff --git a/test/WebSocket.test.js b/test/WebSocket.test.js index 348e112d7..78d5ebaa3 100644 --- a/test/WebSocket.test.js +++ b/test/WebSocket.test.js @@ -999,6 +999,20 @@ describe('WebSocket', function () { }); }); + it('can be called from a listener of the headers event', function (done) { + const wss = new WebSocketServer({ port: ++port }, () => { + const ws = new WebSocket(`ws://localhost:${port}`); + + ws.on('open', () => assert.fail(null, null, 'connect shouldnt be raised here')); + ws.on('error', (err) => { + assert.ok(err instanceof Error); + assert.strictEqual(err.message, 'closed before the connection is established'); + ws.on('close', () => wss.close(done)); + }); + ws.on('headers', () => ws.close()); + }); + }); + it('throws an error if the first argument is invalid (1/2)', function (done) { const wss = new WebSocketServer({ port: ++port }, () => { const ws = new WebSocket(`ws://localhost:${port}`); @@ -1209,6 +1223,20 @@ describe('WebSocket', function () { }); }); + it('can be called from a listener of the headers event', function (done) { + const wss = new WebSocketServer({ port: ++port }, () => { + const ws = new WebSocket(`ws://localhost:${port}`); + + ws.on('open', () => assert.fail(null, null, 'connect shouldnt be raised here')); + ws.on('error', (err) => { + assert.ok(err instanceof Error); + assert.strictEqual(err.message, 'closed before the connection is established'); + ws.on('close', () => wss.close(done)); + }); + ws.on('headers', () => ws.terminate()); + }); + }); + it('does nothing if the connection is already CLOSED', function (done) { const wss = new WebSocketServer({ port: ++port }, () => { const ws = new WebSocket(`ws://localhost:${port}`);