Comparing version 2.0.3 to 2.1.0
@@ -291,3 +291,4 @@ 'use strict'; | ||
if (!data || data.length === 0) { | ||
return callback(null, EMPTY_BLOCK); | ||
process.nextTick(callback, null, EMPTY_BLOCK); | ||
return; | ||
} | ||
@@ -294,0 +295,0 @@ |
@@ -19,7 +19,5 @@ /*! | ||
const GET_PAYLOAD_LENGTH_64 = 2; | ||
const HAVE_LENGTH = 3; | ||
const GET_MASK = 4; | ||
const GET_DATA = 5; | ||
const HANDLE_DATA = 6; | ||
const INFLATING = 7; | ||
const GET_MASK = 3; | ||
const GET_DATA = 4; | ||
const INFLATING = 5; | ||
@@ -58,2 +56,3 @@ /** | ||
this.dead = false; | ||
this.loop = false; | ||
@@ -122,2 +121,3 @@ this.onmessage = null; | ||
this.loop = false; | ||
if (this.dead) this.cleanup(this.cleanupCallback); | ||
@@ -146,17 +146,23 @@ return false; | ||
startLoop () { | ||
while (true) { | ||
if (this.state === GET_INFO) { | ||
if (!this.getInfo()) break; | ||
} else if (this.state === GET_PAYLOAD_LENGTH_16) { | ||
if (!this.getPayloadLength16()) break; | ||
} else if (this.state === GET_PAYLOAD_LENGTH_64) { | ||
if (!this.getPayloadLength64()) break; | ||
} else if (this.state === HAVE_LENGTH) { | ||
if (!this.haveLength()) break; | ||
} else if (this.state === GET_MASK) { | ||
if (!this.getMask()) break; | ||
} else if (this.state === GET_DATA) { | ||
if (!this.getData()) break; | ||
} else { // `HANDLE_DATA` or `INFLATING` | ||
break; | ||
this.loop = true; | ||
while (this.loop) { | ||
switch (this.state) { | ||
case GET_INFO: | ||
this.getInfo(); | ||
break; | ||
case GET_PAYLOAD_LENGTH_16: | ||
this.getPayloadLength16(); | ||
break; | ||
case GET_PAYLOAD_LENGTH_64: | ||
this.getPayloadLength64(); | ||
break; | ||
case GET_MASK: | ||
this.getMask(); | ||
break; | ||
case GET_DATA: | ||
this.getData(); | ||
break; | ||
default: // `INFLATING` | ||
this.loop = false; | ||
} | ||
@@ -169,7 +175,6 @@ } | ||
* | ||
* @return {Boolean} `true` if the operation is successful, else `false` | ||
* @private | ||
*/ | ||
getInfo () { | ||
if (!this.hasBufferedBytes(2)) return false; | ||
if (!this.hasBufferedBytes(2)) return; | ||
@@ -180,3 +185,3 @@ const buf = this.readBuffer(2); | ||
this.error(new Error('RSV2 and RSV3 must be clear'), 1002); | ||
return false; | ||
return; | ||
} | ||
@@ -188,3 +193,3 @@ | ||
this.error(new Error('RSV1 must be clear'), 1002); | ||
return false; | ||
return; | ||
} | ||
@@ -199,3 +204,3 @@ | ||
this.error(new Error('RSV1 must be clear'), 1002); | ||
return false; | ||
return; | ||
} | ||
@@ -205,3 +210,3 @@ | ||
this.error(new Error(`invalid opcode: ${this.opcode}`), 1002); | ||
return false; | ||
return; | ||
} else { | ||
@@ -213,3 +218,3 @@ this.opcode = this.fragmented; | ||
this.error(new Error(`invalid opcode: ${this.opcode}`), 1002); | ||
return false; | ||
return; | ||
} | ||
@@ -221,3 +226,3 @@ | ||
this.error(new Error('FIN must be set'), 1002); | ||
return false; | ||
return; | ||
} | ||
@@ -227,3 +232,3 @@ | ||
this.error(new Error('RSV1 must be clear'), 1002); | ||
return false; | ||
return; | ||
} | ||
@@ -233,7 +238,7 @@ | ||
this.error(new Error('invalid payload length'), 1002); | ||
return false; | ||
return; | ||
} | ||
} else { | ||
this.error(new Error(`invalid opcode: ${this.opcode}`), 1002); | ||
return false; | ||
return; | ||
} | ||
@@ -247,5 +252,3 @@ | ||
else if (this.payloadLength === 127) this.state = GET_PAYLOAD_LENGTH_64; | ||
else this.state = HAVE_LENGTH; | ||
return true; | ||
else this.haveLength(); | ||
} | ||
@@ -256,11 +259,9 @@ | ||
* | ||
* @return {Boolean} `true` if payload length has been read, else `false` | ||
* @private | ||
*/ | ||
getPayloadLength16 () { | ||
if (!this.hasBufferedBytes(2)) return false; | ||
if (!this.hasBufferedBytes(2)) return; | ||
this.payloadLength = this.readBuffer(2).readUInt16BE(0, true); | ||
this.state = HAVE_LENGTH; | ||
return true; | ||
this.haveLength(); | ||
} | ||
@@ -271,7 +272,6 @@ | ||
* | ||
* @return {Boolean} `true` if payload length has been read, else `false` | ||
* @private | ||
*/ | ||
getPayloadLength64 () { | ||
if (!this.hasBufferedBytes(8)) return false; | ||
if (!this.hasBufferedBytes(8)) return; | ||
@@ -287,8 +287,7 @@ const buf = this.readBuffer(8); | ||
this.error(new Error('max payload size exceeded'), 1009); | ||
return false; | ||
return; | ||
} | ||
this.payloadLength = num * Math.pow(2, 32) + buf.readUInt32BE(4, true); | ||
this.state = HAVE_LENGTH; | ||
return true; | ||
this.haveLength(); | ||
} | ||
@@ -299,3 +298,2 @@ | ||
* | ||
* @return {Boolean} `false` if payload length exceeds `maxPayload`, else `true` | ||
* @private | ||
@@ -305,3 +303,3 @@ */ | ||
if (this.opcode < 0x08 && this.maxPayloadExceeded(this.payloadLength)) { | ||
return false; | ||
return; | ||
} | ||
@@ -311,3 +309,2 @@ | ||
else this.state = GET_DATA; | ||
return true; | ||
} | ||
@@ -318,11 +315,9 @@ | ||
* | ||
* @return {Boolean} `true` if the mask has been read, else `false` | ||
* @private | ||
*/ | ||
getMask () { | ||
if (!this.hasBufferedBytes(4)) return false; | ||
if (!this.hasBufferedBytes(4)) return; | ||
this.mask = this.readBuffer(4); | ||
this.state = GET_DATA; | ||
return true; | ||
} | ||
@@ -333,3 +328,2 @@ | ||
* | ||
* @return {Boolean} `true` if the data bytes have been read, else `false` | ||
* @private | ||
@@ -341,3 +335,3 @@ */ | ||
if (this.payloadLength) { | ||
if (!this.hasBufferedBytes(this.payloadLength)) return false; | ||
if (!this.hasBufferedBytes(this.payloadLength)) return; | ||
@@ -348,4 +342,2 @@ data = this.readBuffer(this.payloadLength); | ||
this.state = HANDLE_DATA; | ||
if (this.opcode > 0x07) { | ||
@@ -359,4 +351,2 @@ this.controlMessage(data); | ||
} | ||
return true; | ||
} | ||
@@ -380,3 +370,3 @@ | ||
if (this.pushFragment(buf)) this.dataMessage(); | ||
if (this.state === GET_INFO) this.startLoop(); | ||
this.startLoop(); | ||
}); | ||
@@ -428,2 +418,3 @@ } | ||
this.onclose(1000, '', { masked: this.masked }); | ||
this.loop = false; | ||
this.cleanup(this.cleanupCallback); | ||
@@ -448,2 +439,3 @@ } else if (data.length === 1) { | ||
this.onclose(code, buf.toString(), { masked: this.masked }); | ||
this.loop = false; | ||
this.cleanup(this.cleanupCallback); | ||
@@ -473,2 +465,3 @@ } | ||
this.hadError = true; | ||
this.loop = false; | ||
this.cleanup(this.cleanupCallback); | ||
@@ -529,3 +522,3 @@ } | ||
if (!this.hadError && this.state === INFLATING) { | ||
if (!this.hadError && (this.loop || this.state === INFLATING)) { | ||
this.cleanupCallback = cb; | ||
@@ -532,0 +525,0 @@ } else { |
@@ -32,4 +32,4 @@ /*! | ||
this.processing = false; | ||
this.bufferedBytes = 0; | ||
this.deflating = false; | ||
this.queue = []; | ||
@@ -59,3 +59,3 @@ | ||
if (this.perMessageDeflate) { | ||
if (this.deflating) { | ||
this.enqueue([this.doClose, buf, mask, cb]); | ||
@@ -83,4 +83,2 @@ } else { | ||
}, cb); | ||
if (this.perMessageDeflate) this.continue(); | ||
} | ||
@@ -109,3 +107,3 @@ | ||
if (this.perMessageDeflate) { | ||
if (this.deflating) { | ||
this.enqueue([this.doPing, data, mask, readOnly]); | ||
@@ -133,4 +131,2 @@ } else { | ||
}); | ||
if (this.perMessageDeflate) this.continue(); | ||
} | ||
@@ -159,3 +155,3 @@ | ||
if (this.perMessageDeflate) { | ||
if (this.deflating) { | ||
this.enqueue([this.doPong, data, mask, readOnly]); | ||
@@ -183,4 +179,2 @@ } else { | ||
}); | ||
if (this.perMessageDeflate) this.continue(); | ||
} | ||
@@ -230,3 +224,3 @@ | ||
if (this.perMessageDeflate) { | ||
this.enqueue([this.dispatch, data, { | ||
const opts = { | ||
compress: this.compress, | ||
@@ -238,3 +232,9 @@ mask: options.mask, | ||
rsv1 | ||
}, cb]); | ||
}; | ||
if (this.deflating) { | ||
this.enqueue([this.dispatch, data, opts, cb]); | ||
} else { | ||
this.dispatch(data, opts, cb); | ||
} | ||
} else { | ||
@@ -268,6 +268,6 @@ this.frameAndSend(data, { | ||
this.frameAndSend(data, options, cb); | ||
this.continue(); | ||
return; | ||
} | ||
this.deflating = true; | ||
this.perMessageDeflate.compress(data, options.fin, (err, buf) => { | ||
@@ -282,3 +282,4 @@ if (err) { | ||
this.frameAndSend(buf, options, cb); | ||
this.continue(); | ||
this.deflating = false; | ||
this.dequeue(); | ||
}); | ||
@@ -363,3 +364,3 @@ } | ||
/** | ||
* Executes a queued send operation. | ||
* Executes queued send operations. | ||
* | ||
@@ -369,26 +370,11 @@ * @private | ||
dequeue () { | ||
if (this.processing) return; | ||
while (!this.deflating && this.queue.length) { | ||
const params = this.queue.shift(); | ||
const params = this.queue.shift(); | ||
if (!params) return; | ||
if (params[1]) this.bufferedBytes -= params[1].length; | ||
this.processing = true; | ||
params[0].apply(this, params.slice(1)); | ||
if (params[1]) this.bufferedBytes -= params[1].length; | ||
params[0].apply(this, params.slice(1)); | ||
} | ||
} | ||
/** | ||
* Signals the completion of a send operation. | ||
* | ||
* @private | ||
*/ | ||
continue () { | ||
process.nextTick(() => { | ||
this.processing = false; | ||
this.dequeue(); | ||
}); | ||
} | ||
/** | ||
* Enqueues a send operation. | ||
@@ -402,3 +388,2 @@ * | ||
this.queue.push(params); | ||
this.dequeue(); | ||
} | ||
@@ -405,0 +390,0 @@ } |
@@ -540,7 +540,8 @@ /*! | ||
if (!serverUrl.host && !isUnixSocket) throw new Error('invalid url'); | ||
if (!serverUrl.host && (!isUnixSocket || !serverUrl.path)) { | ||
throw new Error('invalid url'); | ||
} | ||
const isSecure = serverUrl.protocol === 'wss:' || serverUrl.protocol === 'https:'; | ||
const key = crypto.randomBytes(16).toString('base64'); | ||
const port = serverUrl.port || (isSecure ? 443 : 80); | ||
const httpObj = isSecure ? https : http; | ||
@@ -563,4 +564,4 @@ | ||
const requestOptions = { | ||
port: serverUrl.port || (isSecure ? 443 : 80), | ||
host: serverUrl.hostname, | ||
port, | ||
path: '/', | ||
@@ -590,12 +591,16 @@ headers: { | ||
if (options.host) requestOptions.headers.Host = options.host; | ||
if (options.family) requestOptions.family = options.family; | ||
if (serverUrl.auth) requestOptions.auth = serverUrl.auth; | ||
if (options.localAddress) requestOptions.localAddress = options.localAddress; | ||
if (isUnixSocket) requestOptions.socketPath = serverUrl.pathname; | ||
if (serverUrl.auth) requestOptions.auth = serverUrl.auth; | ||
if (options.family) requestOptions.family = options.family; | ||
// | ||
// Make sure that path starts with `/`. | ||
// | ||
if (serverUrl.path) { | ||
if (isUnixSocket) { | ||
const parts = serverUrl.path.split(':'); | ||
requestOptions.socketPath = parts[0]; | ||
requestOptions.path = parts[1]; | ||
} else if (serverUrl.path) { | ||
// | ||
// Make sure that path starts with `/`. | ||
// | ||
if (serverUrl.path.charAt(0) !== '/') { | ||
@@ -602,0 +607,0 @@ requestOptions.path = `/${serverUrl.path}`; |
@@ -156,7 +156,5 @@ /*! | ||
if ( | ||
!this.shouldHandle(req) || | ||
!req.headers.upgrade || | ||
req.headers.upgrade.toLowerCase() !== 'websocket' || | ||
!req.headers['sec-websocket-key'] || | ||
version !== 8 && version !== 13 | ||
req.method !== 'GET' || req.headers.upgrade.toLowerCase() !== 'websocket' || | ||
!req.headers['sec-websocket-key'] || version !== 8 && version !== 13 || | ||
!this.shouldHandle(req) | ||
) { | ||
@@ -163,0 +161,0 @@ return abortConnection(socket, 400); |
@@ -5,3 +5,3 @@ { | ||
"description": "Simple to use, blazing fast and thoroughly tested websocket client and server for Node.js", | ||
"version": "2.0.3", | ||
"version": "2.1.0", | ||
"license": "MIT", | ||
@@ -8,0 +8,0 @@ "main": "index.js", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
82600
2321