Comparing version 8.4.0 to 8.4.1
@@ -316,3 +316,3 @@ 'use strict'; | ||
* | ||
* @param {Buffer} data Data to compress | ||
* @param {(Buffer|String)} data Data to compress | ||
* @param {Boolean} fin Specifies whether or not this is the last fragment | ||
@@ -399,3 +399,3 @@ * @param {Function} callback Callback | ||
* | ||
* @param {Buffer} data Data to compress | ||
* @param {(Buffer|String)} data Data to compress | ||
* @param {Boolean} fin Specifies whether or not this is the last fragment | ||
@@ -402,0 +402,0 @@ * @param {Function} callback Callback |
@@ -14,2 +14,3 @@ /* eslint no-unused-vars: ["error", { "varsIgnorePattern": "^net|tls$" }] */ | ||
const kByteLength = Symbol('kByteLength'); | ||
const maskBuffer = Buffer.alloc(4); | ||
@@ -50,3 +51,3 @@ | ||
* | ||
* @param {Buffer} data The data to frame | ||
* @param {(Buffer|String)} data The data to frame | ||
* @param {Object} options Options object | ||
@@ -66,3 +67,3 @@ * @param {Boolean} [options.fin=false] Specifies whether or not to set the | ||
* RSV1 bit | ||
* @return {Buffer[]} The framed data as a list of `Buffer` instances | ||
* @return {(Buffer|String)[]} The framed data | ||
* @public | ||
@@ -86,9 +87,24 @@ */ | ||
skipMasking = (mask[0] | mask[1] | mask[2] | mask[3]) === 0; | ||
if (options.readOnly && !skipMasking) merge = true; | ||
offset = 6; | ||
} | ||
let payloadLength = data.length; | ||
let dataLength; | ||
if (typeof data === 'string') { | ||
if ( | ||
(!options.mask || skipMasking) && | ||
options[kByteLength] !== undefined | ||
) { | ||
dataLength = options[kByteLength]; | ||
} else { | ||
data = Buffer.from(data); | ||
dataLength = data.length; | ||
} | ||
} else { | ||
dataLength = data.length; | ||
merge = options.mask && options.readOnly && !skipMasking; | ||
} | ||
let payloadLength = dataLength; | ||
if (data.length >= 65536) { | ||
@@ -102,3 +118,3 @@ offset += 8; | ||
const target = Buffer.allocUnsafe(merge ? data.length + offset : offset); | ||
const target = Buffer.allocUnsafe(merge ? dataLength + offset : offset); | ||
@@ -111,6 +127,6 @@ target[0] = options.fin ? options.opcode | 0x80 : options.opcode; | ||
if (payloadLength === 126) { | ||
target.writeUInt16BE(data.length, 2); | ||
target.writeUInt16BE(dataLength, 2); | ||
} else if (payloadLength === 127) { | ||
target[2] = target[3] = 0; | ||
target.writeUIntBE(data.length, 4, 6); | ||
target.writeUIntBE(dataLength, 4, 6); | ||
} | ||
@@ -173,6 +189,17 @@ | ||
const options = { | ||
[kByteLength]: buf.length, | ||
fin: true, | ||
generateMask: this._generateMask, | ||
mask, | ||
maskBuffer: this._maskBuffer, | ||
opcode: 0x08, | ||
readOnly: false, | ||
rsv1: false | ||
}; | ||
if (this._deflating) { | ||
this.enqueue([this.doClose, buf, mask, cb]); | ||
this.enqueue([this.dispatch, buf, false, options, cb]); | ||
} else { | ||
this.doClose(buf, mask, cb); | ||
this.sendFrame(Sender.frame(buf, options), cb); | ||
} | ||
@@ -182,25 +209,2 @@ } | ||
/** | ||
* Frames and sends a close message. | ||
* | ||
* @param {Buffer} data The message to send | ||
* @param {Boolean} [mask=false] Specifies whether or not to mask `data` | ||
* @param {Function} [cb] Callback | ||
* @private | ||
*/ | ||
doClose(data, mask, cb) { | ||
this.sendFrame( | ||
Sender.frame(data, { | ||
fin: true, | ||
rsv1: false, | ||
opcode: 0x08, | ||
mask, | ||
maskBuffer: this._maskBuffer, | ||
generateMask: this._generateMask, | ||
readOnly: false | ||
}), | ||
cb | ||
); | ||
} | ||
/** | ||
* Sends a ping message to the other peer. | ||
@@ -214,12 +218,33 @@ * | ||
ping(data, mask, cb) { | ||
const buf = toBuffer(data); | ||
let byteLength; | ||
let readOnly; | ||
if (buf.length > 125) { | ||
if (typeof data === 'string') { | ||
byteLength = Buffer.byteLength(data); | ||
readOnly = false; | ||
} else { | ||
data = toBuffer(data); | ||
byteLength = data.length; | ||
readOnly = toBuffer.readOnly; | ||
} | ||
if (byteLength > 125) { | ||
throw new RangeError('The data size must not be greater than 125 bytes'); | ||
} | ||
const options = { | ||
[kByteLength]: byteLength, | ||
fin: true, | ||
generateMask: this._generateMask, | ||
mask, | ||
maskBuffer: this._maskBuffer, | ||
opcode: 0x09, | ||
readOnly, | ||
rsv1: false | ||
}; | ||
if (this._deflating) { | ||
this.enqueue([this.doPing, buf, mask, toBuffer.readOnly, cb]); | ||
this.enqueue([this.dispatch, data, false, options, cb]); | ||
} else { | ||
this.doPing(buf, mask, toBuffer.readOnly, cb); | ||
this.sendFrame(Sender.frame(data, options), cb); | ||
} | ||
@@ -229,26 +254,2 @@ } | ||
/** | ||
* Frames and sends a ping message. | ||
* | ||
* @param {Buffer} data The message to send | ||
* @param {Boolean} [mask=false] Specifies whether or not to mask `data` | ||
* @param {Boolean} [readOnly=false] Specifies whether `data` can be modified | ||
* @param {Function} [cb] Callback | ||
* @private | ||
*/ | ||
doPing(data, mask, readOnly, cb) { | ||
this.sendFrame( | ||
Sender.frame(data, { | ||
fin: true, | ||
rsv1: false, | ||
opcode: 0x09, | ||
mask, | ||
maskBuffer: this._maskBuffer, | ||
generateMask: this._generateMask, | ||
readOnly | ||
}), | ||
cb | ||
); | ||
} | ||
/** | ||
* Sends a pong message to the other peer. | ||
@@ -262,12 +263,33 @@ * | ||
pong(data, mask, cb) { | ||
const buf = toBuffer(data); | ||
let byteLength; | ||
let readOnly; | ||
if (buf.length > 125) { | ||
if (typeof data === 'string') { | ||
byteLength = Buffer.byteLength(data); | ||
readOnly = false; | ||
} else { | ||
data = toBuffer(data); | ||
byteLength = data.length; | ||
readOnly = toBuffer.readOnly; | ||
} | ||
if (byteLength > 125) { | ||
throw new RangeError('The data size must not be greater than 125 bytes'); | ||
} | ||
const options = { | ||
[kByteLength]: byteLength, | ||
fin: true, | ||
generateMask: this._generateMask, | ||
mask, | ||
maskBuffer: this._maskBuffer, | ||
opcode: 0x0a, | ||
readOnly, | ||
rsv1: false | ||
}; | ||
if (this._deflating) { | ||
this.enqueue([this.doPong, buf, mask, toBuffer.readOnly, cb]); | ||
this.enqueue([this.dispatch, data, false, options, cb]); | ||
} else { | ||
this.doPong(buf, mask, toBuffer.readOnly, cb); | ||
this.sendFrame(Sender.frame(data, options), cb); | ||
} | ||
@@ -277,26 +299,2 @@ } | ||
/** | ||
* Frames and sends a pong message. | ||
* | ||
* @param {Buffer} data The message to send | ||
* @param {Boolean} [mask=false] Specifies whether or not to mask `data` | ||
* @param {Boolean} [readOnly=false] Specifies whether `data` can be modified | ||
* @param {Function} [cb] Callback | ||
* @private | ||
*/ | ||
doPong(data, mask, readOnly, cb) { | ||
this.sendFrame( | ||
Sender.frame(data, { | ||
fin: true, | ||
rsv1: false, | ||
opcode: 0x0a, | ||
mask, | ||
maskBuffer: this._maskBuffer, | ||
generateMask: this._generateMask, | ||
readOnly | ||
}), | ||
cb | ||
); | ||
} | ||
/** | ||
* Sends a data message to the other peer. | ||
@@ -318,3 +316,2 @@ * | ||
send(data, options, cb) { | ||
const buf = toBuffer(data); | ||
const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName]; | ||
@@ -324,2 +321,14 @@ let opcode = options.binary ? 2 : 1; | ||
let byteLength; | ||
let readOnly; | ||
if (typeof data === 'string') { | ||
byteLength = Buffer.byteLength(data); | ||
readOnly = false; | ||
} else { | ||
data = toBuffer(data); | ||
byteLength = data.length; | ||
readOnly = toBuffer.readOnly; | ||
} | ||
if (this._firstFragment) { | ||
@@ -336,3 +345,3 @@ this._firstFragment = false; | ||
) { | ||
rsv1 = buf.length >= perMessageDeflate._threshold; | ||
rsv1 = byteLength >= perMessageDeflate._threshold; | ||
} | ||
@@ -349,26 +358,28 @@ this._compress = rsv1; | ||
const opts = { | ||
[kByteLength]: byteLength, | ||
fin: options.fin, | ||
rsv1, | ||
opcode, | ||
generateMask: this._generateMask, | ||
mask: options.mask, | ||
maskBuffer: this._maskBuffer, | ||
generateMask: this._generateMask, | ||
readOnly: toBuffer.readOnly | ||
opcode, | ||
readOnly, | ||
rsv1 | ||
}; | ||
if (this._deflating) { | ||
this.enqueue([this.dispatch, buf, this._compress, opts, cb]); | ||
this.enqueue([this.dispatch, data, this._compress, opts, cb]); | ||
} else { | ||
this.dispatch(buf, this._compress, opts, cb); | ||
this.dispatch(data, this._compress, opts, cb); | ||
} | ||
} else { | ||
this.sendFrame( | ||
Sender.frame(buf, { | ||
Sender.frame(data, { | ||
[kByteLength]: byteLength, | ||
fin: options.fin, | ||
rsv1: false, | ||
opcode, | ||
generateMask: this._generateMask, | ||
mask: options.mask, | ||
maskBuffer: this._maskBuffer, | ||
generateMask: this._generateMask, | ||
readOnly: toBuffer.readOnly | ||
opcode, | ||
readOnly, | ||
rsv1: false | ||
}), | ||
@@ -381,9 +392,8 @@ cb | ||
/** | ||
* Dispatches a data message. | ||
* Dispatches a message. | ||
* | ||
* @param {Buffer} data The message to send | ||
* @param {(Buffer|String)} data The message to send | ||
* @param {Boolean} [compress=false] Specifies whether or not to compress | ||
* `data` | ||
* @param {Object} options Options object | ||
* @param {Number} options.opcode The opcode | ||
* @param {Boolean} [options.fin=false] Specifies whether or not to set the | ||
@@ -397,2 +407,3 @@ * FIN bit | ||
* key | ||
* @param {Number} options.opcode The opcode | ||
* @param {Boolean} [options.readOnly=false] Specifies whether `data` can be | ||
@@ -413,3 +424,3 @@ * modified | ||
this._bufferedBytes += data.length; | ||
this._bufferedBytes += options[kByteLength]; | ||
this._deflating = true; | ||
@@ -425,3 +436,4 @@ perMessageDeflate.compress(data, options.fin, (_, buf) => { | ||
for (let i = 0; i < this._queue.length; i++) { | ||
const callback = this._queue[i][4]; | ||
const params = this._queue[i]; | ||
const callback = params[params.length - 1]; | ||
@@ -434,3 +446,3 @@ if (typeof callback === 'function') callback(err); | ||
this._bufferedBytes -= data.length; | ||
this._bufferedBytes -= options[kByteLength]; | ||
this._deflating = false; | ||
@@ -452,3 +464,3 @@ options.readOnly = false; | ||
this._bufferedBytes -= params[1].length; | ||
this._bufferedBytes -= params[3][kByteLength]; | ||
Reflect.apply(params[0], this, params.slice(1)); | ||
@@ -465,3 +477,3 @@ } | ||
enqueue(params) { | ||
this._bufferedBytes += params[1].length; | ||
this._bufferedBytes += params[3][kByteLength]; | ||
this._queue.push(params); | ||
@@ -468,0 +480,0 @@ } |
{ | ||
"name": "ws", | ||
"version": "8.4.0", | ||
"version": "8.4.1", | ||
"description": "Simple to use, blazing fast and thoroughly tested websocket client and server for Node.js", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
@@ -36,3 +36,3 @@ # ws: a Node.js WebSocket library | ||
- [Server broadcast](#server-broadcast) | ||
- [echo.websocket.org demo](#echowebsocketorg-demo) | ||
- [Round-trip time](#round-trip-time) | ||
- [Use the Node.js streams API](#use-the-nodejs-streams-api) | ||
@@ -328,3 +328,3 @@ - [Other examples](#other-examples) | ||
### echo.websocket.org demo | ||
### Round-trip time | ||
@@ -334,5 +334,3 @@ ```js | ||
const ws = new WebSocket('wss://echo.websocket.org/', { | ||
origin: 'https://websocket.org' | ||
}); | ||
const ws = new WebSocket('wss://websocket-echo.com/'); | ||
@@ -349,3 +347,3 @@ ws.on('open', function open() { | ||
ws.on('message', function message(data) { | ||
console.log(`Roundtrip time: ${Date.now() - data} ms`); | ||
console.log(`Round-trip time: ${Date.now() - data} ms`); | ||
@@ -363,5 +361,3 @@ setTimeout(function timeout() { | ||
const ws = new WebSocket('wss://echo.websocket.org/', { | ||
origin: 'https://websocket.org' | ||
}); | ||
const ws = new WebSocket('wss://websocket-echo.com/'); | ||
@@ -465,3 +461,3 @@ const duplex = createWebSocketStream(ws, { encoding: 'utf8' }); | ||
const client = new WebSocket('wss://echo.websocket.org/'); | ||
const client = new WebSocket('wss://websocket-echo.com/'); | ||
@@ -468,0 +464,0 @@ client.on('open', heartbeat); |
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
129316
3786
490