Comparing version 3.2.0 to 3.3.0
'use strict'; | ||
const safeBuffer = require('safe-buffer'); | ||
const Limiter = require('async-limiter'); | ||
const zlib = require('zlib'); | ||
const Limiter = require('async-limiter'); | ||
@@ -14,2 +14,10 @@ const bufferUtil = require('./BufferUtil'); | ||
const kWriteInProgress = Symbol('write-in-progress'); | ||
const kPendingClose = Symbol('pending-close'); | ||
const kTotalLength = Symbol('total-length'); | ||
const kCallback = Symbol('callback'); | ||
const kBuffers = Symbol('buffers'); | ||
const kError = Symbol('error'); | ||
const kOwner = Symbol('owner'); | ||
// We limit zlib concurrency, which prevents severe memory fragmentation | ||
@@ -106,4 +114,4 @@ // as documented in https://github.com/nodejs/node/issues/8871#issuecomment-250915913 | ||
if (this._inflate) { | ||
if (this._inflate.writeInProgress) { | ||
this._inflate.pendingClose = true; | ||
if (this._inflate[kWriteInProgress]) { | ||
this._inflate[kPendingClose] = true; | ||
} else { | ||
@@ -115,4 +123,4 @@ this._inflate.close(); | ||
if (this._deflate) { | ||
if (this._deflate.writeInProgress) { | ||
this._deflate.pendingClose = true; | ||
if (this._deflate[kWriteInProgress]) { | ||
this._deflate[kPendingClose] = true; | ||
} else { | ||
@@ -322,49 +330,43 @@ this._deflate.close(); | ||
this._inflate = zlib.createInflateRaw({ windowBits }); | ||
this._inflate[kTotalLength] = 0; | ||
this._inflate[kBuffers] = []; | ||
this._inflate[kOwner] = this; | ||
this._inflate.on('error', inflateOnError); | ||
this._inflate.on('data', inflateOnData); | ||
} | ||
this._inflate.writeInProgress = true; | ||
var totalLength = 0; | ||
const buffers = []; | ||
var err; | ||
this._inflate[kCallback] = callback; | ||
this._inflate[kWriteInProgress] = true; | ||
const onData = (data) => { | ||
totalLength += data.length; | ||
if (this._maxPayload < 1 || totalLength <= this._maxPayload) { | ||
return buffers.push(data); | ||
} | ||
this._inflate.write(data); | ||
if (fin) this._inflate.write(TRAILER); | ||
err = new Error('max payload size exceeded'); | ||
err.closeCode = 1009; | ||
this._inflate.reset(); | ||
}; | ||
this._inflate.flush(() => { | ||
const err = this._inflate[kError]; | ||
const onError = (err) => { | ||
cleanup(); | ||
callback(err); | ||
}; | ||
if (err) { | ||
this._inflate.close(); | ||
this._inflate = null; | ||
callback(err); | ||
return; | ||
} | ||
const cleanup = () => { | ||
if (!this._inflate) return; | ||
const data = bufferUtil.concat( | ||
this._inflate[kBuffers], | ||
this._inflate[kTotalLength] | ||
); | ||
this._inflate.removeListener('error', onError); | ||
this._inflate.removeListener('data', onData); | ||
this._inflate.writeInProgress = false; | ||
if ( | ||
(fin && this.params[`${endpoint}_no_context_takeover`]) || | ||
this._inflate.pendingClose | ||
this._inflate[kPendingClose] | ||
) { | ||
this._inflate.close(); | ||
this._inflate = null; | ||
} else { | ||
this._inflate[kWriteInProgress] = false; | ||
this._inflate[kTotalLength] = 0; | ||
this._inflate[kBuffers] = []; | ||
} | ||
}; | ||
this._inflate.on('error', onError).on('data', onData); | ||
this._inflate.write(data); | ||
if (fin) this._inflate.write(TRAILER); | ||
this._inflate.flush(() => { | ||
cleanup(); | ||
if (err) callback(err); | ||
else callback(null, bufferUtil.concat(buffers, totalLength)); | ||
callback(null, data); | ||
}); | ||
@@ -401,40 +403,37 @@ } | ||
}); | ||
} | ||
this._deflate.writeInProgress = true; | ||
var totalLength = 0; | ||
const buffers = []; | ||
this._deflate[kTotalLength] = 0; | ||
this._deflate[kBuffers] = []; | ||
const onData = (data) => { | ||
totalLength += data.length; | ||
buffers.push(data); | ||
}; | ||
// | ||
// `zlib.DeflateRaw` emits an `'error'` event only when an attempt to use | ||
// it is made after it has already been closed. This cannot happen here, | ||
// so we only add a listener for the `'data'` event. | ||
// | ||
this._deflate.on('data', deflateOnData); | ||
} | ||
const onError = (err) => { | ||
cleanup(); | ||
callback(err); | ||
}; | ||
this._deflate[kWriteInProgress] = true; | ||
const cleanup = () => { | ||
if (!this._deflate) return; | ||
this._deflate.write(data); | ||
this._deflate.flush(zlib.Z_SYNC_FLUSH, () => { | ||
var data = bufferUtil.concat( | ||
this._deflate[kBuffers], | ||
this._deflate[kTotalLength] | ||
); | ||
this._deflate.removeListener('error', onError); | ||
this._deflate.removeListener('data', onData); | ||
this._deflate.writeInProgress = false; | ||
if (fin) data = data.slice(0, data.length - 4); | ||
if ( | ||
(fin && this.params[`${endpoint}_no_context_takeover`]) || | ||
this._deflate.pendingClose | ||
this._deflate[kPendingClose] | ||
) { | ||
this._deflate.close(); | ||
this._deflate = null; | ||
} else { | ||
this._deflate[kWriteInProgress] = false; | ||
this._deflate[kTotalLength] = 0; | ||
this._deflate[kBuffers] = []; | ||
} | ||
}; | ||
this._deflate.on('error', onError).on('data', onData); | ||
this._deflate.write(data); | ||
this._deflate.flush(zlib.Z_SYNC_FLUSH, () => { | ||
cleanup(); | ||
var data = bufferUtil.concat(buffers, totalLength); | ||
if (fin) data = data.slice(0, data.length - 4); | ||
callback(null, data); | ||
@@ -446,1 +445,50 @@ }); | ||
module.exports = PerMessageDeflate; | ||
/** | ||
* The listener of the `zlib.DeflateRaw` stream `'data'` event. | ||
* | ||
* @param {Buffer} chunk A chunk of data | ||
* @private | ||
*/ | ||
function deflateOnData (chunk) { | ||
this[kBuffers].push(chunk); | ||
this[kTotalLength] += chunk.length; | ||
} | ||
/** | ||
* The listener of the `zlib.InflateRaw` stream `'data'` event. | ||
* | ||
* @param {Buffer} chunk A chunk of data | ||
* @private | ||
*/ | ||
function inflateOnData (chunk) { | ||
this[kTotalLength] += chunk.length; | ||
if ( | ||
this[kOwner]._maxPayload < 1 || | ||
this[kTotalLength] <= this[kOwner]._maxPayload | ||
) { | ||
this[kBuffers].push(chunk); | ||
return; | ||
} | ||
this[kError] = new Error('max payload size exceeded'); | ||
this[kError].closeCode = 1009; | ||
this.removeListener('data', inflateOnData); | ||
this.reset(); | ||
} | ||
/** | ||
* The listener of the `zlib.InflateRaw` stream `'error'` event. | ||
* | ||
* @param {Error} err The emitted error | ||
* @private | ||
*/ | ||
function inflateOnError (err) { | ||
// | ||
// There is no need to call `Zlib#close()` as the handle is automatically | ||
// closed when an error is emitted. | ||
// | ||
this[kOwner]._inflate = null; | ||
this[kCallback](err); | ||
} |
@@ -38,4 +38,2 @@ /*! | ||
this._queue = []; | ||
this.onerror = null; | ||
} | ||
@@ -335,9 +333,3 @@ | ||
this._deflating = true; | ||
perMessageDeflate.compress(data, options.fin, (err, buf) => { | ||
if (err) { | ||
if (cb) cb(err); | ||
else this.onerror(err); | ||
return; | ||
} | ||
perMessageDeflate.compress(data, options.fin, (_, buf) => { | ||
options.readOnly = false; | ||
@@ -344,0 +336,0 @@ this.sendFrame(Sender.frame(buf, options), cb); |
@@ -160,8 +160,2 @@ /*! | ||
// sender event handlers | ||
this._sender.onerror = (error) => { | ||
this.close(1002, ''); | ||
this.emit('error', error); | ||
}; | ||
this.readyState = WebSocket.OPEN; | ||
@@ -202,13 +196,8 @@ this.emit('open'); | ||
this._receiver.cleanup(() => this.emitClose()); | ||
this._receiver = null; | ||
this._sender = null; | ||
this._socket = null; | ||
this._ultron = null; | ||
} | ||
if (this._sender) { | ||
this._sender = this._sender.onerror = null; | ||
} | ||
if (this._receiver) { | ||
this._receiver.cleanup(() => this.emitClose()); | ||
this._receiver = null; | ||
} else { | ||
@@ -488,2 +477,3 @@ this.emitClose(); | ||
* @param {String} options.ciphers The ciphers to use or exclude | ||
* @param {String} options.ecdhCurve The curves for ECDH key agreement to use or exclude | ||
* @param {(String|String[]|Buffer|Buffer[])} options.cert The certificate key | ||
@@ -515,2 +505,3 @@ * @param {(String|String[]|Buffer|Buffer[])} options.key The private key | ||
ciphers: null, | ||
ecdhCurve: null, | ||
cert: null, | ||
@@ -616,2 +607,3 @@ key: null, | ||
options.ciphers || | ||
options.ecdhCurve || | ||
options.cert || | ||
@@ -624,2 +616,3 @@ options.key || | ||
if (options.ciphers) requestOptions.ciphers = options.ciphers; | ||
if (options.ecdhCurve) requestOptions.ecdhCurve = options.ecdhCurve; | ||
if (options.cert) requestOptions.cert = options.cert; | ||
@@ -626,0 +619,0 @@ if (options.key) requestOptions.key = options.key; |
{ | ||
"name": "ws", | ||
"version": "3.2.0", | ||
"version": "3.3.0", | ||
"description": "Simple to use, blazing fast and thoroughly tested websocket client and server for Node.js", | ||
@@ -36,12 +36,12 @@ "keywords": [ | ||
"bufferutil": "~3.0.0", | ||
"eslint": "~4.6.0", | ||
"eslint": "~4.10.0", | ||
"eslint-config-standard": "~10.2.0", | ||
"eslint-plugin-import": "~2.7.0", | ||
"eslint-plugin-node": "~5.1.0", | ||
"eslint-plugin-promise": "~3.5.0", | ||
"eslint-plugin-import": "~2.8.0", | ||
"eslint-plugin-node": "~5.2.0", | ||
"eslint-plugin-promise": "~3.6.0", | ||
"eslint-plugin-standard": "~3.0.0", | ||
"mocha": "~3.5.0", | ||
"nyc": "~11.2.0", | ||
"mocha": "~4.0.0", | ||
"nyc": "~11.3.0", | ||
"utf-8-validate": "~3.0.0" | ||
} | ||
} |
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
Native code
Supply chain riskContains native code (e.g., compiled binaries or shared libraries). Including native code can obscure malicious behavior.
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
94490
16
2455
4