Skip to content

Commit

Permalink
[minor] Throw an error on invalid method usage
Browse files Browse the repository at this point in the history
Throw an error if `WebSocketServer.prototype.completeUpgrade()` is
called more than once with the same socket argument.
  • Loading branch information
lpinca committed Apr 22, 2020
1 parent 79dfbcf commit 62f71d1
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 1 deletion.
10 changes: 9 additions & 1 deletion lib/websocket-server.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const { createServer, STATUS_CODES } = require('http');
const PerMessageDeflate = require('./permessage-deflate');
const WebSocket = require('./websocket');
const { format, parse } = require('./extension');
const { GUID } = require('./constants');
const { GUID, kWebSocket } = require('./constants');

const keyRegex = /^[+/0-9A-Za-z]{22}==$/;

Expand Down Expand Up @@ -254,6 +254,7 @@ class WebSocketServer extends EventEmitter {
* @param {net.Socket} socket The network socket between the server and client
* @param {Buffer} head The first packet of the upgraded stream
* @param {Function} cb Callback
* @throws {Error} If called more than once with the same socket
* @private
*/
completeUpgrade(key, extensions, req, socket, head, cb) {
Expand All @@ -262,6 +263,13 @@ class WebSocketServer extends EventEmitter {
//
if (!socket.readable || !socket.writable) return socket.destroy();

if (socket[kWebSocket]) {
throw new Error(
'server.handleUpgrade() was called more than once with the same ' +
'socket, possibly due to a misconfiguration'
);
}

const digest = createHash('sha1')
.update(key + GUID)
.digest('base64');
Expand Down
37 changes: 37 additions & 0 deletions test/websocket-server.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const fs = require('fs');

const Sender = require('../lib/sender');
const WebSocket = require('..');
const { NOOP } = require('../lib/constants');

describe('WebSocketServer', () => {
describe('#ctor', () => {
Expand Down Expand Up @@ -383,6 +384,42 @@ describe('WebSocketServer', () => {
});
});

describe('#completeUpgrade', () => {
it('throws an error if called twice with the same socket', (done) => {
const server = http.createServer();

server.listen(0, () => {
const wss = new WebSocket.Server({ noServer: true });

server.on('upgrade', (req, socket, head) => {
wss.handleUpgrade(req, socket, head, (ws) => {
ws.close();
});
assert.throws(
() => wss.handleUpgrade(req, socket, head, NOOP),
(err) => {
assert.ok(err instanceof Error);
assert.strictEqual(
err.message,
'server.handleUpgrade() was called more than once with the ' +
'same socket, possibly due to a misconfiguration'
);
return true;
}
);
});

const ws = new WebSocket(`ws://localhost:${server.address().port}`);

ws.on('open', () => {
ws.on('close', () => {
server.close(done);
});
});
});
});
});

describe('Connection establishing', () => {
it('fails if the Sec-WebSocket-Key header is invalid (1/2)', (done) => {
const wss = new WebSocket.Server({ port: 0 }, () => {
Expand Down

0 comments on commit 62f71d1

Please sign in to comment.