Skip to content

Commit 71d6c8d

Browse files
committed
Emit error on Connection when received invalid handshake response
1 parent 5ad93b8 commit 71d6c8d

File tree

2 files changed

+15
-3
lines changed

2 files changed

+15
-3
lines changed

Connection.js

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,12 @@ Connection.prototype.readHandshake = function () {
302302
// Do the handshake and try to connect
303303
if (this.buffer.length > Connection.maxBufferLength) {
304304
// Too big for a handshake
305-
this.socket.end(this.server ? 'HTTP/1.1 400 Bad Request\r\n\r\n' : undefined)
305+
if (this.server) {
306+
this.socket.end('HTTP/1.1 400 Bad Request\r\n\r\n')
307+
} else {
308+
this.socket.end()
309+
this.emit('error', new Error('Handshake is too big'))
310+
}
306311
return false
307312
}
308313

@@ -359,9 +364,11 @@ Connection.prototype.checkHandshake = function (lines) {
359364

360365
// First line
361366
if (lines.length < 4) {
367+
this.emit('error', new Error('Invalid handshake: too short'))
362368
return false
363369
}
364370
if (!lines[0].match(/^HTTP\/\d\.\d 101( .*)?$/i)) {
371+
this.emit('error', new Error('Invalid handshake: invalid first line format'))
365372
return false
366373
}
367374

@@ -372,10 +379,12 @@ Connection.prototype.checkHandshake = function (lines) {
372379
if (!('upgrade' in this.headers) ||
373380
!('sec-websocket-accept' in this.headers) ||
374381
!('connection' in this.headers)) {
382+
this.emit('error', new Error('Invalid handshake: missing required headers'))
375383
return false
376384
}
377385
if (this.headers.upgrade.toLowerCase() !== 'websocket' ||
378386
this.headers.connection.toLowerCase().split(', ').indexOf('upgrade') === -1) {
387+
this.emit('error', new Error('Invalid handshake: invalid Upgrade or Connection header'))
379388
return false
380389
}
381390
key = this.headers['sec-websocket-accept']
@@ -385,11 +394,13 @@ Connection.prototype.checkHandshake = function (lines) {
385394
if (this.protocols && this.protocols.length) {
386395
// The server must choose one from our list
387396
if (!protocol || this.protocols.indexOf(protocol) === -1) {
397+
this.emit('error', new Error('Invalid handshake: no protocol was negotiated'))
388398
return false
389399
}
390400
} else {
391401
// The server must not choose a protocol
392402
if (protocol) {
403+
this.emit('error', new Error('Invalid handshake: no protocol negotiation was expected'))
393404
return false
394405
}
395406
}
@@ -399,6 +410,7 @@ Connection.prototype.checkHandshake = function (lines) {
399410
sha1 = crypto.createHash('sha1')
400411
sha1.end(this.key + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')
401412
if (key !== sha1.read().toString('base64')) {
413+
this.emit('error', new Error('Invalid handshake: hash mismatch'))
402414
return false
403415
}
404416
return true
@@ -457,7 +469,6 @@ Connection.prototype.answerHandshake = function (lines) {
457469
}
458470

459471
// Build and send the response
460-
461472
sha1 = crypto.createHash('sha1')
462473
sha1.end(this.key + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')
463474
key = sha1.read().toString('base64')

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,8 @@ The protocol agreed for this connection, if any. It will be an element of `conne
170170
Emitted when the connection is closed by any side
171171

172172
## Event: 'error(err)'
173-
Emitted in case of error (like trying to send text data while still sending binary data)
173+
Emitted in case of error (like trying to send text data while still sending binary data).
174+
In case of an invalid handshake response will also be emited.
174175

175176
## Event: 'text(str)'
176177
Emitted when a text is received. `str` is a string

0 commit comments

Comments
 (0)