mirror of
https://github.com/S2-/minifyfromhtml.git
synced 2025-08-02 12:00:03 +02:00
update modules
This commit is contained in:
139
node_modules/ws/README.md
generated
vendored
139
node_modules/ws/README.md
generated
vendored
@@ -1,8 +1,8 @@
|
||||
# ws: a Node.js WebSocket library
|
||||
|
||||
[](https://www.npmjs.com/package/ws)
|
||||
[](https://travis-ci.org/websockets/ws)
|
||||
[](https://ci.appveyor.com/project/lpinca/ws)
|
||||
[](https://travis-ci.com/websockets/ws)
|
||||
[](https://ci.appveyor.com/project/lpinca/ws)
|
||||
[](https://coveralls.io/github/websockets/ws)
|
||||
|
||||
ws is a simple to use, blazing fast, and thoroughly tested WebSocket client and
|
||||
@@ -32,10 +32,11 @@ can use one of the many wrappers available on npm, like
|
||||
- [Simple server](#simple-server)
|
||||
- [External HTTP/S server](#external-https-server)
|
||||
- [Multiple servers sharing a single HTTP/S server](#multiple-servers-sharing-a-single-https-server)
|
||||
- [Client authentication](#client-authentication)
|
||||
- [Server broadcast](#server-broadcast)
|
||||
- [echo.websocket.org demo](#echowebsocketorg-demo)
|
||||
- [Use the Node.js streams API](#use-the-nodejs-streams-api)
|
||||
- [Other examples](#other-examples)
|
||||
- [Error handling best practices](#error-handling-best-practices)
|
||||
- [FAQ](#faq)
|
||||
- [How to get the IP address of the client?](#how-to-get-the-ip-address-of-the-client)
|
||||
- [How to detect and close broken connections?](#how-to-detect-and-close-broken-connections)
|
||||
@@ -70,7 +71,8 @@ necessarily need to have a C++ compiler installed on your machine.
|
||||
|
||||
## API docs
|
||||
|
||||
See [`/doc/ws.md`](./doc/ws.md) for Node.js-like docs for the ws classes.
|
||||
See [`/doc/ws.md`](./doc/ws.md) for Node.js-like documentation of ws classes and
|
||||
utility functions.
|
||||
|
||||
## WebSocket compression
|
||||
|
||||
@@ -193,7 +195,7 @@ const fs = require('fs');
|
||||
const https = require('https');
|
||||
const WebSocket = require('ws');
|
||||
|
||||
const server = new https.createServer({
|
||||
const server = https.createServer({
|
||||
cert: fs.readFileSync('/path/to/cert.pem'),
|
||||
key: fs.readFileSync('/path/to/key.pem')
|
||||
});
|
||||
@@ -215,6 +217,7 @@ server.listen(8080);
|
||||
```js
|
||||
const http = require('http');
|
||||
const WebSocket = require('ws');
|
||||
const url = require('url');
|
||||
|
||||
const server = http.createServer();
|
||||
const wss1 = new WebSocket.Server({ noServer: true });
|
||||
@@ -247,25 +250,72 @@ server.on('upgrade', function upgrade(request, socket, head) {
|
||||
server.listen(8080);
|
||||
```
|
||||
|
||||
### Client authentication
|
||||
|
||||
```js
|
||||
const http = require('http');
|
||||
const WebSocket = require('ws');
|
||||
|
||||
const server = http.createServer();
|
||||
const wss = new WebSocket.Server({ noServer: true });
|
||||
|
||||
wss.on('connection', function connection(ws, request, client) {
|
||||
ws.on('message', function message(msg) {
|
||||
console.log(`Received message ${msg} from user ${client}`);
|
||||
});
|
||||
});
|
||||
|
||||
server.on('upgrade', function upgrade(request, socket, head) {
|
||||
// This function is not defined on purpose. Implement it with your own logic.
|
||||
authenticate(request, (err, client) => {
|
||||
if (err || !client) {
|
||||
socket.write('HTTP/1.1 401 Unauthorized\r\n\r\n');
|
||||
socket.destroy();
|
||||
return;
|
||||
}
|
||||
|
||||
wss.handleUpgrade(request, socket, head, function done(ws) {
|
||||
wss.emit('connection', ws, request, client);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
server.listen(8080);
|
||||
```
|
||||
|
||||
Also see the provided [example][session-parse-example] using `express-session`.
|
||||
|
||||
### Server broadcast
|
||||
|
||||
A client WebSocket broadcasting to all connected WebSocket clients, including
|
||||
itself.
|
||||
|
||||
```js
|
||||
const WebSocket = require('ws');
|
||||
|
||||
const wss = new WebSocket.Server({ port: 8080 });
|
||||
|
||||
// Broadcast to all.
|
||||
wss.broadcast = function broadcast(data) {
|
||||
wss.clients.forEach(function each(client) {
|
||||
if (client.readyState === WebSocket.OPEN) {
|
||||
client.send(data);
|
||||
}
|
||||
wss.on('connection', function connection(ws) {
|
||||
ws.on('message', function incoming(data) {
|
||||
wss.clients.forEach(function each(client) {
|
||||
if (client.readyState === WebSocket.OPEN) {
|
||||
client.send(data);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
});
|
||||
```
|
||||
|
||||
A client WebSocket broadcasting to every other connected WebSocket clients,
|
||||
excluding itself.
|
||||
|
||||
```js
|
||||
const WebSocket = require('ws');
|
||||
|
||||
const wss = new WebSocket.Server({ port: 8080 });
|
||||
|
||||
wss.on('connection', function connection(ws) {
|
||||
ws.on('message', function incoming(data) {
|
||||
// Broadcast to everyone else.
|
||||
wss.clients.forEach(function each(client) {
|
||||
if (client !== ws && client.readyState === WebSocket.OPEN) {
|
||||
client.send(data);
|
||||
@@ -302,6 +352,21 @@ ws.on('message', function incoming(data) {
|
||||
});
|
||||
```
|
||||
|
||||
### Use the Node.js streams API
|
||||
|
||||
```js
|
||||
const WebSocket = require('ws');
|
||||
|
||||
const ws = new WebSocket('wss://echo.websocket.org/', {
|
||||
origin: 'https://websocket.org'
|
||||
});
|
||||
|
||||
const duplex = WebSocket.createWebSocketStream(ws, { encoding: 'utf8' });
|
||||
|
||||
duplex.pipe(process.stdout);
|
||||
process.stdin.pipe(duplex);
|
||||
```
|
||||
|
||||
### Other examples
|
||||
|
||||
For a full example with a browser client communicating with a ws server, see the
|
||||
@@ -309,30 +374,6 @@ examples folder.
|
||||
|
||||
Otherwise, see the test cases.
|
||||
|
||||
## Error handling best practices
|
||||
|
||||
```js
|
||||
// If the WebSocket is closed before the following send is attempted
|
||||
ws.send('something');
|
||||
|
||||
// Errors (both immediate and async write errors) can be detected in an optional
|
||||
// callback. The callback is also the only way of being notified that data has
|
||||
// actually been sent.
|
||||
ws.send('something', function ack(error) {
|
||||
// If error is not defined, the send has been completed, otherwise the error
|
||||
// object will indicate what failed.
|
||||
});
|
||||
|
||||
// Immediate errors can also be handled with `try...catch`, but **note** that
|
||||
// since sends are inherently asynchronous, socket write failures will *not* be
|
||||
// captured when this technique is used.
|
||||
try {
|
||||
ws.send('something');
|
||||
} catch (e) {
|
||||
/* handle error */
|
||||
}
|
||||
```
|
||||
|
||||
## FAQ
|
||||
|
||||
### How to get the IP address of the client?
|
||||
@@ -345,7 +386,7 @@ const WebSocket = require('ws');
|
||||
const wss = new WebSocket.Server({ port: 8080 });
|
||||
|
||||
wss.on('connection', function connection(ws, req) {
|
||||
const ip = req.connection.remoteAddress;
|
||||
const ip = req.socket.remoteAddress;
|
||||
});
|
||||
```
|
||||
|
||||
@@ -391,6 +432,10 @@ const interval = setInterval(function ping() {
|
||||
ws.ping(noop);
|
||||
});
|
||||
}, 30000);
|
||||
|
||||
wss.on('close', function close() {
|
||||
clearInterval(interval);
|
||||
});
|
||||
```
|
||||
|
||||
Pong messages are automatically sent in response to ping messages as required by
|
||||
@@ -406,9 +451,10 @@ const WebSocket = require('ws');
|
||||
function heartbeat() {
|
||||
clearTimeout(this.pingTimeout);
|
||||
|
||||
// Use `WebSocket#terminate()` and not `WebSocket#close()`. Delay should be
|
||||
// equal to the interval at which your server sends out pings plus a
|
||||
// conservative assumption of the latency.
|
||||
// Use `WebSocket#terminate()`, which immediately destroys the connection,
|
||||
// instead of `WebSocket#close()`, which waits for the close timer.
|
||||
// Delay should be equal to the interval at which your server
|
||||
// sends out pings plus a conservative assumption of the latency.
|
||||
this.pingTimeout = setTimeout(() => {
|
||||
this.terminate();
|
||||
}, 30000 + 1000);
|
||||
@@ -436,14 +482,15 @@ We're using the GitHub [releases][changelog] for changelog entries.
|
||||
|
||||
[MIT](LICENSE)
|
||||
|
||||
[https-proxy-agent]: https://github.com/TooTallNate/node-https-proxy-agent
|
||||
[socks-proxy-agent]: https://github.com/TooTallNate/node-socks-proxy-agent
|
||||
[client-report]: http://websockets.github.io/ws/autobahn/clients/
|
||||
[server-report]: http://websockets.github.io/ws/autobahn/servers/
|
||||
[permessage-deflate]: https://tools.ietf.org/html/rfc7692
|
||||
[changelog]: https://github.com/websockets/ws/releases
|
||||
[client-report]: http://websockets.github.io/ws/autobahn/clients/
|
||||
[https-proxy-agent]: https://github.com/TooTallNate/node-https-proxy-agent
|
||||
[node-zlib-bug]: https://github.com/nodejs/node/issues/8871
|
||||
[node-zlib-deflaterawdocs]:
|
||||
https://nodejs.org/api/zlib.html#zlib_zlib_createdeflateraw_options
|
||||
[permessage-deflate]: https://tools.ietf.org/html/rfc7692
|
||||
[server-report]: http://websockets.github.io/ws/autobahn/servers/
|
||||
[session-parse-example]: ./examples/express-session-parse
|
||||
[socks-proxy-agent]: https://github.com/TooTallNate/node-socks-proxy-agent
|
||||
[ws-server-options]:
|
||||
https://github.com/websockets/ws/blob/master/doc/ws.md#new-websocketserveroptions-callback
|
||||
|
2
node_modules/ws/browser.js
generated
vendored
2
node_modules/ws/browser.js
generated
vendored
@@ -1,6 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = function() {
|
||||
module.exports = function () {
|
||||
throw new Error(
|
||||
'ws does not work in the browser. Browser clients must use the native ' +
|
||||
'WebSocket object'
|
||||
|
1
node_modules/ws/index.js
generated
vendored
1
node_modules/ws/index.js
generated
vendored
@@ -2,6 +2,7 @@
|
||||
|
||||
const WebSocket = require('./lib/websocket');
|
||||
|
||||
WebSocket.createWebSocketStream = require('./lib/stream');
|
||||
WebSocket.Server = require('./lib/websocket-server');
|
||||
WebSocket.Receiver = require('./lib/receiver');
|
||||
WebSocket.Sender = require('./lib/sender');
|
||||
|
33
node_modules/ws/lib/buffer-util.js
generated
vendored
33
node_modules/ws/lib/buffer-util.js
generated
vendored
@@ -15,14 +15,16 @@ function concat(list, totalLength) {
|
||||
if (list.length === 1) return list[0];
|
||||
|
||||
const target = Buffer.allocUnsafe(totalLength);
|
||||
var offset = 0;
|
||||
let offset = 0;
|
||||
|
||||
for (var i = 0; i < list.length; i++) {
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
const buf = list[i];
|
||||
buf.copy(target, offset);
|
||||
target.set(buf, offset);
|
||||
offset += buf.length;
|
||||
}
|
||||
|
||||
if (offset < totalLength) return target.slice(0, offset);
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
@@ -37,7 +39,7 @@ function concat(list, totalLength) {
|
||||
* @public
|
||||
*/
|
||||
function _mask(source, mask, output, offset, length) {
|
||||
for (var i = 0; i < length; i++) {
|
||||
for (let i = 0; i < length; i++) {
|
||||
output[offset + i] = source[i] ^ mask[i & 3];
|
||||
}
|
||||
}
|
||||
@@ -52,7 +54,7 @@ function _mask(source, mask, output, offset, length) {
|
||||
function _unmask(buffer, mask) {
|
||||
// Required until https://github.com/nodejs/node/issues/9006 is resolved.
|
||||
const length = buffer.length;
|
||||
for (var i = 0; i < length; i++) {
|
||||
for (let i = 0; i < length; i++) {
|
||||
buffer[i] ^= mask[i & 3];
|
||||
}
|
||||
}
|
||||
@@ -85,12 +87,12 @@ function toBuffer(data) {
|
||||
|
||||
if (Buffer.isBuffer(data)) return data;
|
||||
|
||||
var buf;
|
||||
let buf;
|
||||
|
||||
if (data instanceof ArrayBuffer) {
|
||||
buf = Buffer.from(data);
|
||||
} else if (ArrayBuffer.isView(data)) {
|
||||
buf = viewToBuffer(data);
|
||||
buf = Buffer.from(data.buffer, data.byteOffset, data.byteLength);
|
||||
} else {
|
||||
buf = Buffer.from(data);
|
||||
toBuffer.readOnly = false;
|
||||
@@ -99,23 +101,6 @@ function toBuffer(data) {
|
||||
return buf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an `ArrayBuffer` view into a buffer.
|
||||
*
|
||||
* @param {(DataView|TypedArray)} view The view to convert
|
||||
* @return {Buffer} Converted view
|
||||
* @private
|
||||
*/
|
||||
function viewToBuffer(view) {
|
||||
const buf = Buffer.from(view.buffer);
|
||||
|
||||
if (view.byteLength !== view.buffer.byteLength) {
|
||||
return buf.slice(view.byteOffset, view.byteOffset + view.byteLength);
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
try {
|
||||
const bufferUtil = require('bufferutil');
|
||||
const bu = bufferUtil.BufferUtil || bufferUtil;
|
||||
|
39
node_modules/ws/lib/event-target.js
generated
vendored
39
node_modules/ws/lib/event-target.js
generated
vendored
@@ -109,11 +109,16 @@ const EventTarget = {
|
||||
/**
|
||||
* Register an event listener.
|
||||
*
|
||||
* @param {String} method A string representing the event type to listen for
|
||||
* @param {String} type A string representing the event type to listen for
|
||||
* @param {Function} listener The listener to add
|
||||
* @param {Object} options An options object specifies characteristics about
|
||||
* the event listener
|
||||
* @param {Boolean} options.once A `Boolean`` indicating that the listener
|
||||
* should be invoked at most once after being added. If `true`, the
|
||||
* listener would be automatically removed when invoked.
|
||||
* @public
|
||||
*/
|
||||
addEventListener(method, listener) {
|
||||
addEventListener(type, listener, options) {
|
||||
if (typeof listener !== 'function') return;
|
||||
|
||||
function onMessage(data) {
|
||||
@@ -132,36 +137,38 @@ const EventTarget = {
|
||||
listener.call(this, new OpenEvent(this));
|
||||
}
|
||||
|
||||
if (method === 'message') {
|
||||
const method = options && options.once ? 'once' : 'on';
|
||||
|
||||
if (type === 'message') {
|
||||
onMessage._listener = listener;
|
||||
this.on(method, onMessage);
|
||||
} else if (method === 'close') {
|
||||
this[method](type, onMessage);
|
||||
} else if (type === 'close') {
|
||||
onClose._listener = listener;
|
||||
this.on(method, onClose);
|
||||
} else if (method === 'error') {
|
||||
this[method](type, onClose);
|
||||
} else if (type === 'error') {
|
||||
onError._listener = listener;
|
||||
this.on(method, onError);
|
||||
} else if (method === 'open') {
|
||||
this[method](type, onError);
|
||||
} else if (type === 'open') {
|
||||
onOpen._listener = listener;
|
||||
this.on(method, onOpen);
|
||||
this[method](type, onOpen);
|
||||
} else {
|
||||
this.on(method, listener);
|
||||
this[method](type, listener);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove an event listener.
|
||||
*
|
||||
* @param {String} method A string representing the event type to remove
|
||||
* @param {String} type A string representing the event type to remove
|
||||
* @param {Function} listener The listener to remove
|
||||
* @public
|
||||
*/
|
||||
removeEventListener(method, listener) {
|
||||
const listeners = this.listeners(method);
|
||||
removeEventListener(type, listener) {
|
||||
const listeners = this.listeners(type);
|
||||
|
||||
for (var i = 0; i < listeners.length; i++) {
|
||||
for (let i = 0; i < listeners.length; i++) {
|
||||
if (listeners[i] === listener || listeners[i]._listener === listener) {
|
||||
this.removeListener(method, listeners[i]);
|
||||
this.removeListener(type, listeners[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
39
node_modules/ws/lib/extension.js
generated
vendored
39
node_modules/ws/lib/extension.js
generated
vendored
@@ -34,8 +34,8 @@ const tokenChars = [
|
||||
* @private
|
||||
*/
|
||||
function push(dest, name, elem) {
|
||||
if (Object.prototype.hasOwnProperty.call(dest, name)) dest[name].push(elem);
|
||||
else dest[name] = [elem];
|
||||
if (dest[name] === undefined) dest[name] = [elem];
|
||||
else dest[name].push(elem);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -46,20 +46,21 @@ function push(dest, name, elem) {
|
||||
* @public
|
||||
*/
|
||||
function parse(header) {
|
||||
const offers = {};
|
||||
const offers = Object.create(null);
|
||||
|
||||
if (header === undefined || header === '') return offers;
|
||||
|
||||
var params = {};
|
||||
var mustUnescape = false;
|
||||
var isEscaping = false;
|
||||
var inQuotes = false;
|
||||
var extensionName;
|
||||
var paramName;
|
||||
var start = -1;
|
||||
var end = -1;
|
||||
let params = Object.create(null);
|
||||
let mustUnescape = false;
|
||||
let isEscaping = false;
|
||||
let inQuotes = false;
|
||||
let extensionName;
|
||||
let paramName;
|
||||
let start = -1;
|
||||
let end = -1;
|
||||
let i = 0;
|
||||
|
||||
for (var i = 0; i < header.length; i++) {
|
||||
for (; i < header.length; i++) {
|
||||
const code = header.charCodeAt(i);
|
||||
|
||||
if (extensionName === undefined) {
|
||||
@@ -76,7 +77,7 @@ function parse(header) {
|
||||
const name = header.slice(start, end);
|
||||
if (code === 0x2c) {
|
||||
push(offers, name, params);
|
||||
params = {};
|
||||
params = Object.create(null);
|
||||
} else {
|
||||
extensionName = name;
|
||||
}
|
||||
@@ -99,7 +100,7 @@ function parse(header) {
|
||||
push(params, header.slice(start, end), true);
|
||||
if (code === 0x2c) {
|
||||
push(offers, extensionName, params);
|
||||
params = {};
|
||||
params = Object.create(null);
|
||||
extensionName = undefined;
|
||||
}
|
||||
|
||||
@@ -146,7 +147,7 @@ function parse(header) {
|
||||
}
|
||||
|
||||
if (end === -1) end = i;
|
||||
var value = header.slice(start, end);
|
||||
let value = header.slice(start, end);
|
||||
if (mustUnescape) {
|
||||
value = value.replace(/\\/g, '');
|
||||
mustUnescape = false;
|
||||
@@ -154,7 +155,7 @@ function parse(header) {
|
||||
push(params, paramName, value);
|
||||
if (code === 0x2c) {
|
||||
push(offers, extensionName, params);
|
||||
params = {};
|
||||
params = Object.create(null);
|
||||
extensionName = undefined;
|
||||
}
|
||||
|
||||
@@ -173,7 +174,7 @@ function parse(header) {
|
||||
if (end === -1) end = i;
|
||||
const token = header.slice(start, end);
|
||||
if (extensionName === undefined) {
|
||||
push(offers, token, {});
|
||||
push(offers, token, params);
|
||||
} else {
|
||||
if (paramName === undefined) {
|
||||
push(params, token, true);
|
||||
@@ -198,14 +199,14 @@ function parse(header) {
|
||||
function format(extensions) {
|
||||
return Object.keys(extensions)
|
||||
.map((extension) => {
|
||||
var configurations = extensions[extension];
|
||||
let configurations = extensions[extension];
|
||||
if (!Array.isArray(configurations)) configurations = [configurations];
|
||||
return configurations
|
||||
.map((params) => {
|
||||
return [extension]
|
||||
.concat(
|
||||
Object.keys(params).map((k) => {
|
||||
var values = params[k];
|
||||
let values = params[k];
|
||||
if (!Array.isArray(values)) values = [values];
|
||||
return values
|
||||
.map((v) => (v === true ? k : `${k}=${v}`))
|
||||
|
54
node_modules/ws/lib/limiter.js
generated
vendored
Normal file
54
node_modules/ws/lib/limiter.js
generated
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
'use strict';
|
||||
|
||||
const kDone = Symbol('kDone');
|
||||
const kRun = Symbol('kRun');
|
||||
|
||||
/**
|
||||
* A very simple job queue with adjustable concurrency. Adapted from
|
||||
* https://github.com/STRML/async-limiter
|
||||
*/
|
||||
class Limiter {
|
||||
/**
|
||||
* Creates a new `Limiter`.
|
||||
*
|
||||
* @param {Number} concurrency The maximum number of jobs allowed to run
|
||||
* concurrently
|
||||
*/
|
||||
constructor(concurrency) {
|
||||
this[kDone] = () => {
|
||||
this.pending--;
|
||||
this[kRun]();
|
||||
};
|
||||
this.concurrency = concurrency || Infinity;
|
||||
this.jobs = [];
|
||||
this.pending = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a job to the queue.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
add(job) {
|
||||
this.jobs.push(job);
|
||||
this[kRun]();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a job from the queue and runs it if possible.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
[kRun]() {
|
||||
if (this.pending === this.concurrency) return;
|
||||
|
||||
if (this.jobs.length) {
|
||||
const job = this.jobs.shift();
|
||||
|
||||
this.pending++;
|
||||
job(this[kDone]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Limiter;
|
60
node_modules/ws/lib/permessage-deflate.js
generated
vendored
60
node_modules/ws/lib/permessage-deflate.js
generated
vendored
@@ -1,14 +1,12 @@
|
||||
'use strict';
|
||||
|
||||
const Limiter = require('async-limiter');
|
||||
const zlib = require('zlib');
|
||||
|
||||
const bufferUtil = require('./buffer-util');
|
||||
const Limiter = require('./limiter');
|
||||
const { kStatusCode, NOOP } = require('./constants');
|
||||
|
||||
const TRAILER = Buffer.from([0x00, 0x00, 0xff, 0xff]);
|
||||
const EMPTY_BLOCK = Buffer.from([0x00]);
|
||||
|
||||
const kPerMessageDeflate = Symbol('permessage-deflate');
|
||||
const kTotalLength = Symbol('total-length');
|
||||
const kCallback = Symbol('callback');
|
||||
@@ -66,7 +64,7 @@ class PerMessageDeflate {
|
||||
this._options.concurrencyLimit !== undefined
|
||||
? this._options.concurrencyLimit
|
||||
: 10;
|
||||
zlibLimiter = new Limiter({ concurrency });
|
||||
zlibLimiter = new Limiter(concurrency);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,8 +131,18 @@ class PerMessageDeflate {
|
||||
}
|
||||
|
||||
if (this._deflate) {
|
||||
const callback = this._deflate[kCallback];
|
||||
|
||||
this._deflate.close();
|
||||
this._deflate = null;
|
||||
|
||||
if (callback) {
|
||||
callback(
|
||||
new Error(
|
||||
'The deflate stream was closed while data was being processed'
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,7 +241,7 @@ class PerMessageDeflate {
|
||||
normalizeParams(configurations) {
|
||||
configurations.forEach((params) => {
|
||||
Object.keys(params).forEach((key) => {
|
||||
var value = params[key];
|
||||
let value = params[key];
|
||||
|
||||
if (value.length > 1) {
|
||||
throw new Error(`Parameter "${key}" must have only a single value`);
|
||||
@@ -284,7 +292,7 @@ class PerMessageDeflate {
|
||||
}
|
||||
|
||||
/**
|
||||
* Decompress data. Concurrency limited by async-limiter.
|
||||
* Decompress data. Concurrency limited.
|
||||
*
|
||||
* @param {Buffer} data Compressed data
|
||||
* @param {Boolean} fin Specifies whether or not this is the last fragment
|
||||
@@ -292,7 +300,7 @@ class PerMessageDeflate {
|
||||
* @public
|
||||
*/
|
||||
decompress(data, fin, callback) {
|
||||
zlibLimiter.push((done) => {
|
||||
zlibLimiter.add((done) => {
|
||||
this._decompress(data, fin, (err, result) => {
|
||||
done();
|
||||
callback(err, result);
|
||||
@@ -301,7 +309,7 @@ class PerMessageDeflate {
|
||||
}
|
||||
|
||||
/**
|
||||
* Compress data. Concurrency limited by async-limiter.
|
||||
* Compress data. Concurrency limited.
|
||||
*
|
||||
* @param {Buffer} data Data to compress
|
||||
* @param {Boolean} fin Specifies whether or not this is the last fragment
|
||||
@@ -309,7 +317,7 @@ class PerMessageDeflate {
|
||||
* @public
|
||||
*/
|
||||
compress(data, fin, callback) {
|
||||
zlibLimiter.push((done) => {
|
||||
zlibLimiter.add((done) => {
|
||||
this._compress(data, fin, (err, result) => {
|
||||
done();
|
||||
callback(err, result);
|
||||
@@ -335,9 +343,10 @@ class PerMessageDeflate {
|
||||
? zlib.Z_DEFAULT_WINDOWBITS
|
||||
: this.params[key];
|
||||
|
||||
this._inflate = zlib.createInflateRaw(
|
||||
Object.assign({}, this._options.zlibInflateOptions, { windowBits })
|
||||
);
|
||||
this._inflate = zlib.createInflateRaw({
|
||||
...this._options.zlibInflateOptions,
|
||||
windowBits
|
||||
});
|
||||
this._inflate[kPerMessageDeflate] = this;
|
||||
this._inflate[kTotalLength] = 0;
|
||||
this._inflate[kBuffers] = [];
|
||||
@@ -386,11 +395,6 @@ class PerMessageDeflate {
|
||||
* @private
|
||||
*/
|
||||
_compress(data, fin, callback) {
|
||||
if (!data || data.length === 0) {
|
||||
process.nextTick(callback, null, EMPTY_BLOCK);
|
||||
return;
|
||||
}
|
||||
|
||||
const endpoint = this._isServer ? 'server' : 'client';
|
||||
|
||||
if (!this._deflate) {
|
||||
@@ -400,9 +404,10 @@ class PerMessageDeflate {
|
||||
? zlib.Z_DEFAULT_WINDOWBITS
|
||||
: this.params[key];
|
||||
|
||||
this._deflate = zlib.createDeflateRaw(
|
||||
Object.assign({}, this._options.zlibDeflateOptions, { windowBits })
|
||||
);
|
||||
this._deflate = zlib.createDeflateRaw({
|
||||
...this._options.zlibDeflateOptions,
|
||||
windowBits
|
||||
});
|
||||
|
||||
this._deflate[kTotalLength] = 0;
|
||||
this._deflate[kBuffers] = [];
|
||||
@@ -417,25 +422,30 @@ class PerMessageDeflate {
|
||||
this._deflate.on('data', deflateOnData);
|
||||
}
|
||||
|
||||
this._deflate[kCallback] = callback;
|
||||
|
||||
this._deflate.write(data);
|
||||
this._deflate.flush(zlib.Z_SYNC_FLUSH, () => {
|
||||
if (!this._deflate) {
|
||||
//
|
||||
// This `if` statement is only needed for Node.js < 10.0.0 because as of
|
||||
// commit https://github.com/nodejs/node/commit/5e3f5164, the flush
|
||||
// callback is no longer called if the deflate stream is closed while
|
||||
// data is being processed.
|
||||
// The deflate stream was closed while data was being processed.
|
||||
//
|
||||
return;
|
||||
}
|
||||
|
||||
var data = bufferUtil.concat(
|
||||
let data = bufferUtil.concat(
|
||||
this._deflate[kBuffers],
|
||||
this._deflate[kTotalLength]
|
||||
);
|
||||
|
||||
if (fin) data = data.slice(0, data.length - 4);
|
||||
|
||||
//
|
||||
// Ensure that the callback will not be called again in
|
||||
// `PerMessageDeflate#cleanup()`.
|
||||
//
|
||||
this._deflate[kCallback] = null;
|
||||
|
||||
if (fin && this.params[`${endpoint}_no_context_takeover`]) {
|
||||
this._deflate.close();
|
||||
this._deflate = null;
|
||||
|
27
node_modules/ws/lib/receiver.js
generated
vendored
27
node_modules/ws/lib/receiver.js
generated
vendored
@@ -30,14 +30,17 @@ class Receiver extends Writable {
|
||||
*
|
||||
* @param {String} binaryType The type for binary data
|
||||
* @param {Object} extensions An object containing the negotiated extensions
|
||||
* @param {Boolean} isServer Specifies whether to operate in client or server
|
||||
* mode
|
||||
* @param {Number} maxPayload The maximum allowed message length
|
||||
*/
|
||||
constructor(binaryType, extensions, maxPayload) {
|
||||
constructor(binaryType, extensions, isServer, maxPayload) {
|
||||
super();
|
||||
|
||||
this._binaryType = binaryType || BINARY_TYPES[0];
|
||||
this[kWebSocket] = undefined;
|
||||
this._extensions = extensions || {};
|
||||
this._isServer = !!isServer;
|
||||
this._maxPayload = maxPayload | 0;
|
||||
|
||||
this._bufferedBytes = 0;
|
||||
@@ -65,6 +68,7 @@ class Receiver extends Writable {
|
||||
* @param {Buffer} chunk The chunk of data to write
|
||||
* @param {String} encoding The character encoding of `chunk`
|
||||
* @param {Function} cb Callback
|
||||
* @private
|
||||
*/
|
||||
_write(chunk, encoding, cb) {
|
||||
if (this._opcode === 0x08 && this._state == GET_INFO) return cb();
|
||||
@@ -96,11 +100,12 @@ class Receiver extends Writable {
|
||||
|
||||
do {
|
||||
const buf = this._buffers[0];
|
||||
const offset = dst.length - n;
|
||||
|
||||
if (n >= buf.length) {
|
||||
this._buffers.shift().copy(dst, dst.length - n);
|
||||
dst.set(this._buffers.shift(), offset);
|
||||
} else {
|
||||
buf.copy(dst, dst.length - n, 0, n);
|
||||
dst.set(new Uint8Array(buf.buffer, buf.byteOffset, n), offset);
|
||||
this._buffers[0] = buf.slice(n);
|
||||
}
|
||||
|
||||
@@ -117,7 +122,7 @@ class Receiver extends Writable {
|
||||
* @private
|
||||
*/
|
||||
startLoop(cb) {
|
||||
var err;
|
||||
let err;
|
||||
this._loop = true;
|
||||
|
||||
do {
|
||||
@@ -224,6 +229,16 @@ class Receiver extends Writable {
|
||||
if (!this._fin && !this._fragmented) this._fragmented = this._opcode;
|
||||
this._masked = (buf[1] & 0x80) === 0x80;
|
||||
|
||||
if (this._isServer) {
|
||||
if (!this._masked) {
|
||||
this._loop = false;
|
||||
return error(RangeError, 'MASK must be set', true, 1002);
|
||||
}
|
||||
} else if (this._masked) {
|
||||
this._loop = false;
|
||||
return error(RangeError, 'MASK must be clear', true, 1002);
|
||||
}
|
||||
|
||||
if (this._payloadLength === 126) this._state = GET_PAYLOAD_LENGTH_16;
|
||||
else if (this._payloadLength === 127) this._state = GET_PAYLOAD_LENGTH_64;
|
||||
else return this.haveLength();
|
||||
@@ -320,7 +335,7 @@ class Receiver extends Writable {
|
||||
* @private
|
||||
*/
|
||||
getData(cb) {
|
||||
var data = EMPTY_BUFFER;
|
||||
let data = EMPTY_BUFFER;
|
||||
|
||||
if (this._payloadLength) {
|
||||
if (this._bufferedBytes < this._payloadLength) {
|
||||
@@ -400,7 +415,7 @@ class Receiver extends Writable {
|
||||
this._fragments = [];
|
||||
|
||||
if (this._opcode === 2) {
|
||||
var data;
|
||||
let data;
|
||||
|
||||
if (this._binaryType === 'nodebuffer') {
|
||||
data = concat(fragments, messageLength);
|
||||
|
56
node_modules/ws/lib/sender.js
generated
vendored
56
node_modules/ws/lib/sender.js
generated
vendored
@@ -1,12 +1,14 @@
|
||||
'use strict';
|
||||
|
||||
const { randomBytes } = require('crypto');
|
||||
const { randomFillSync } = require('crypto');
|
||||
|
||||
const PerMessageDeflate = require('./permessage-deflate');
|
||||
const { EMPTY_BUFFER } = require('./constants');
|
||||
const { isValidStatusCode } = require('./validation');
|
||||
const { mask: applyMask, toBuffer } = require('./buffer-util');
|
||||
|
||||
const mask = Buffer.alloc(4);
|
||||
|
||||
/**
|
||||
* HyBi Sender implementation.
|
||||
*/
|
||||
@@ -44,8 +46,8 @@ class Sender {
|
||||
*/
|
||||
static frame(data, options) {
|
||||
const merge = options.mask && options.readOnly;
|
||||
var offset = options.mask ? 6 : 2;
|
||||
var payloadLength = data.length;
|
||||
let offset = options.mask ? 6 : 2;
|
||||
let payloadLength = data.length;
|
||||
|
||||
if (data.length >= 65536) {
|
||||
offset += 8;
|
||||
@@ -71,7 +73,7 @@ class Sender {
|
||||
|
||||
if (!options.mask) return [target, data];
|
||||
|
||||
const mask = randomBytes(4);
|
||||
randomFillSync(mask, 0, 4);
|
||||
|
||||
target[1] |= 0x80;
|
||||
target[offset - 4] = mask[0];
|
||||
@@ -98,7 +100,7 @@ class Sender {
|
||||
* @public
|
||||
*/
|
||||
close(code, data, mask, cb) {
|
||||
var buf;
|
||||
let buf;
|
||||
|
||||
if (code === undefined) {
|
||||
buf = EMPTY_BUFFER;
|
||||
@@ -108,7 +110,13 @@ class Sender {
|
||||
buf = Buffer.allocUnsafe(2);
|
||||
buf.writeUInt16BE(code, 0);
|
||||
} else {
|
||||
buf = Buffer.allocUnsafe(2 + Buffer.byteLength(data));
|
||||
const length = Buffer.byteLength(data);
|
||||
|
||||
if (length > 123) {
|
||||
throw new RangeError('The message must not be greater than 123 bytes');
|
||||
}
|
||||
|
||||
buf = Buffer.allocUnsafe(2 + length);
|
||||
buf.writeUInt16BE(code, 0);
|
||||
buf.write(data, 2);
|
||||
}
|
||||
@@ -152,6 +160,10 @@ class Sender {
|
||||
ping(data, mask, cb) {
|
||||
const buf = toBuffer(data);
|
||||
|
||||
if (buf.length > 125) {
|
||||
throw new RangeError('The data size must not be greater than 125 bytes');
|
||||
}
|
||||
|
||||
if (this._deflating) {
|
||||
this.enqueue([this.doPing, buf, mask, toBuffer.readOnly, cb]);
|
||||
} else {
|
||||
@@ -162,7 +174,7 @@ class Sender {
|
||||
/**
|
||||
* Frames and sends a ping message.
|
||||
*
|
||||
* @param {*} data The message to send
|
||||
* @param {Buffer} data The message to send
|
||||
* @param {Boolean} mask Specifies whether or not to mask `data`
|
||||
* @param {Boolean} readOnly Specifies whether `data` can be modified
|
||||
* @param {Function} cb Callback
|
||||
@@ -192,6 +204,10 @@ class Sender {
|
||||
pong(data, mask, cb) {
|
||||
const buf = toBuffer(data);
|
||||
|
||||
if (buf.length > 125) {
|
||||
throw new RangeError('The data size must not be greater than 125 bytes');
|
||||
}
|
||||
|
||||
if (this._deflating) {
|
||||
this.enqueue([this.doPong, buf, mask, toBuffer.readOnly, cb]);
|
||||
} else {
|
||||
@@ -202,7 +218,7 @@ class Sender {
|
||||
/**
|
||||
* Frames and sends a pong message.
|
||||
*
|
||||
* @param {*} data The message to send
|
||||
* @param {Buffer} data The message to send
|
||||
* @param {Boolean} mask Specifies whether or not to mask `data`
|
||||
* @param {Boolean} readOnly Specifies whether `data` can be modified
|
||||
* @param {Function} cb Callback
|
||||
@@ -236,8 +252,8 @@ class Sender {
|
||||
send(data, options, cb) {
|
||||
const buf = toBuffer(data);
|
||||
const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName];
|
||||
var opcode = options.binary ? 2 : 1;
|
||||
var rsv1 = options.compress;
|
||||
let opcode = options.binary ? 2 : 1;
|
||||
let rsv1 = options.compress;
|
||||
|
||||
if (this._firstFragment) {
|
||||
this._firstFragment = false;
|
||||
@@ -302,8 +318,26 @@ class Sender {
|
||||
|
||||
const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName];
|
||||
|
||||
this._bufferedBytes += data.length;
|
||||
this._deflating = true;
|
||||
perMessageDeflate.compress(data, options.fin, (_, buf) => {
|
||||
if (this._socket.destroyed) {
|
||||
const err = new Error(
|
||||
'The socket was closed while data was being compressed'
|
||||
);
|
||||
|
||||
if (typeof cb === 'function') cb(err);
|
||||
|
||||
for (let i = 0; i < this._queue.length; i++) {
|
||||
const callback = this._queue[i][4];
|
||||
|
||||
if (typeof callback === 'function') callback(err);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this._bufferedBytes -= data.length;
|
||||
this._deflating = false;
|
||||
options.readOnly = false;
|
||||
this.sendFrame(Sender.frame(buf, options), cb);
|
||||
@@ -321,7 +355,7 @@ class Sender {
|
||||
const params = this._queue.shift();
|
||||
|
||||
this._bufferedBytes -= params[1].length;
|
||||
params[0].apply(this, params.slice(1));
|
||||
Reflect.apply(params[0], this, params.slice(1));
|
||||
}
|
||||
}
|
||||
|
||||
|
164
node_modules/ws/lib/stream.js
generated
vendored
Normal file
164
node_modules/ws/lib/stream.js
generated
vendored
Normal file
@@ -0,0 +1,164 @@
|
||||
'use strict';
|
||||
|
||||
const { Duplex } = require('stream');
|
||||
|
||||
/**
|
||||
* Emits the `'close'` event on a stream.
|
||||
*
|
||||
* @param {stream.Duplex} The stream.
|
||||
* @private
|
||||
*/
|
||||
function emitClose(stream) {
|
||||
stream.emit('close');
|
||||
}
|
||||
|
||||
/**
|
||||
* The listener of the `'end'` event.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
function duplexOnEnd() {
|
||||
if (!this.destroyed && this._writableState.finished) {
|
||||
this.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The listener of the `'error'` event.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
function duplexOnError(err) {
|
||||
this.removeListener('error', duplexOnError);
|
||||
this.destroy();
|
||||
if (this.listenerCount('error') === 0) {
|
||||
// Do not suppress the throwing behavior.
|
||||
this.emit('error', err);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps a `WebSocket` in a duplex stream.
|
||||
*
|
||||
* @param {WebSocket} ws The `WebSocket` to wrap
|
||||
* @param {Object} options The options for the `Duplex` constructor
|
||||
* @return {stream.Duplex} The duplex stream
|
||||
* @public
|
||||
*/
|
||||
function createWebSocketStream(ws, options) {
|
||||
let resumeOnReceiverDrain = true;
|
||||
|
||||
function receiverOnDrain() {
|
||||
if (resumeOnReceiverDrain) ws._socket.resume();
|
||||
}
|
||||
|
||||
if (ws.readyState === ws.CONNECTING) {
|
||||
ws.once('open', function open() {
|
||||
ws._receiver.removeAllListeners('drain');
|
||||
ws._receiver.on('drain', receiverOnDrain);
|
||||
});
|
||||
} else {
|
||||
ws._receiver.removeAllListeners('drain');
|
||||
ws._receiver.on('drain', receiverOnDrain);
|
||||
}
|
||||
|
||||
const duplex = new Duplex({
|
||||
...options,
|
||||
autoDestroy: false,
|
||||
emitClose: false,
|
||||
objectMode: false,
|
||||
writableObjectMode: false
|
||||
});
|
||||
|
||||
ws.on('message', function message(msg) {
|
||||
if (!duplex.push(msg)) {
|
||||
resumeOnReceiverDrain = false;
|
||||
ws._socket.pause();
|
||||
}
|
||||
});
|
||||
|
||||
ws.once('error', function error(err) {
|
||||
if (duplex.destroyed) return;
|
||||
|
||||
duplex.destroy(err);
|
||||
});
|
||||
|
||||
ws.once('close', function close() {
|
||||
if (duplex.destroyed) return;
|
||||
|
||||
duplex.push(null);
|
||||
});
|
||||
|
||||
duplex._destroy = function (err, callback) {
|
||||
if (ws.readyState === ws.CLOSED) {
|
||||
callback(err);
|
||||
process.nextTick(emitClose, duplex);
|
||||
return;
|
||||
}
|
||||
|
||||
let called = false;
|
||||
|
||||
ws.once('error', function error(err) {
|
||||
called = true;
|
||||
callback(err);
|
||||
});
|
||||
|
||||
ws.once('close', function close() {
|
||||
if (!called) callback(err);
|
||||
process.nextTick(emitClose, duplex);
|
||||
});
|
||||
ws.terminate();
|
||||
};
|
||||
|
||||
duplex._final = function (callback) {
|
||||
if (ws.readyState === ws.CONNECTING) {
|
||||
ws.once('open', function open() {
|
||||
duplex._final(callback);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// If the value of the `_socket` property is `null` it means that `ws` is a
|
||||
// client websocket and the handshake failed. In fact, when this happens, a
|
||||
// socket is never assigned to the websocket. Wait for the `'error'` event
|
||||
// that will be emitted by the websocket.
|
||||
if (ws._socket === null) return;
|
||||
|
||||
if (ws._socket._writableState.finished) {
|
||||
callback();
|
||||
if (duplex._readableState.endEmitted) duplex.destroy();
|
||||
} else {
|
||||
ws._socket.once('finish', function finish() {
|
||||
// `duplex` is not destroyed here because the `'end'` event will be
|
||||
// emitted on `duplex` after this `'finish'` event. The EOF signaling
|
||||
// `null` chunk is, in fact, pushed when the websocket emits `'close'`.
|
||||
callback();
|
||||
});
|
||||
ws.close();
|
||||
}
|
||||
};
|
||||
|
||||
duplex._read = function () {
|
||||
if (ws.readyState === ws.OPEN && !resumeOnReceiverDrain) {
|
||||
resumeOnReceiverDrain = true;
|
||||
if (!ws._receiver._writableState.needDrain) ws._socket.resume();
|
||||
}
|
||||
};
|
||||
|
||||
duplex._write = function (chunk, encoding, callback) {
|
||||
if (ws.readyState === ws.CONNECTING) {
|
||||
ws.once('open', function open() {
|
||||
duplex._write(chunk, encoding, callback);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
ws.send(chunk, callback);
|
||||
};
|
||||
|
||||
duplex.on('end', duplexOnEnd);
|
||||
duplex.on('error', duplexOnError);
|
||||
return duplex;
|
||||
}
|
||||
|
||||
module.exports = createWebSocketStream;
|
2
node_modules/ws/lib/validation.js
generated
vendored
2
node_modules/ws/lib/validation.js
generated
vendored
@@ -21,7 +21,7 @@ try {
|
||||
exports.isValidStatusCode = (code) => {
|
||||
return (
|
||||
(code >= 1000 &&
|
||||
code <= 1013 &&
|
||||
code <= 1014 &&
|
||||
code !== 1004 &&
|
||||
code !== 1005 &&
|
||||
code !== 1006) ||
|
||||
|
81
node_modules/ws/lib/websocket-server.js
generated
vendored
81
node_modules/ws/lib/websocket-server.js
generated
vendored
@@ -1,13 +1,13 @@
|
||||
'use strict';
|
||||
|
||||
const EventEmitter = require('events');
|
||||
const crypto = require('crypto');
|
||||
const http = require('http');
|
||||
const { createHash } = require('crypto');
|
||||
const { createServer, STATUS_CODES } = require('http');
|
||||
|
||||
const PerMessageDeflate = require('./permessage-deflate');
|
||||
const extension = require('./extension');
|
||||
const WebSocket = require('./websocket');
|
||||
const { GUID } = require('./constants');
|
||||
const { format, parse } = require('./extension');
|
||||
const { GUID, kWebSocket } = require('./constants');
|
||||
|
||||
const keyRegex = /^[+/0-9A-Za-z]{22}==$/;
|
||||
|
||||
@@ -25,7 +25,7 @@ class WebSocketServer extends EventEmitter {
|
||||
* connections
|
||||
* @param {Boolean} options.clientTracking Specifies whether or not to track
|
||||
* clients
|
||||
* @param {Function} options.handleProtocols An hook to handle protocols
|
||||
* @param {Function} options.handleProtocols A hook to handle protocols
|
||||
* @param {String} options.host The hostname where to bind the server
|
||||
* @param {Number} options.maxPayload The maximum allowed message size
|
||||
* @param {Boolean} options.noServer Enable no server mode
|
||||
@@ -34,28 +34,26 @@ class WebSocketServer extends EventEmitter {
|
||||
* permessage-deflate
|
||||
* @param {Number} options.port The port where to bind the server
|
||||
* @param {http.Server} options.server A pre-created HTTP/S server to use
|
||||
* @param {Function} options.verifyClient An hook to reject connections
|
||||
* @param {Function} options.verifyClient A hook to reject connections
|
||||
* @param {Function} callback A listener for the `listening` event
|
||||
*/
|
||||
constructor(options, callback) {
|
||||
super();
|
||||
|
||||
options = Object.assign(
|
||||
{
|
||||
maxPayload: 100 * 1024 * 1024,
|
||||
perMessageDeflate: false,
|
||||
handleProtocols: null,
|
||||
clientTracking: true,
|
||||
verifyClient: null,
|
||||
noServer: false,
|
||||
backlog: null, // use default (511 as implemented in net.js)
|
||||
server: null,
|
||||
host: null,
|
||||
path: null,
|
||||
port: null
|
||||
},
|
||||
options
|
||||
);
|
||||
options = {
|
||||
maxPayload: 100 * 1024 * 1024,
|
||||
perMessageDeflate: false,
|
||||
handleProtocols: null,
|
||||
clientTracking: true,
|
||||
verifyClient: null,
|
||||
noServer: false,
|
||||
backlog: null, // use default (511 as implemented in net.js)
|
||||
server: null,
|
||||
host: null,
|
||||
path: null,
|
||||
port: null,
|
||||
...options
|
||||
};
|
||||
|
||||
if (options.port == null && !options.server && !options.noServer) {
|
||||
throw new TypeError(
|
||||
@@ -64,8 +62,8 @@ class WebSocketServer extends EventEmitter {
|
||||
}
|
||||
|
||||
if (options.port != null) {
|
||||
this._server = http.createServer((req, res) => {
|
||||
const body = http.STATUS_CODES[426];
|
||||
this._server = createServer((req, res) => {
|
||||
const body = STATUS_CODES[426];
|
||||
|
||||
res.writeHead(426, {
|
||||
'Content-Length': body.length,
|
||||
@@ -208,7 +206,7 @@ class WebSocketServer extends EventEmitter {
|
||||
);
|
||||
|
||||
try {
|
||||
const offers = extension.parse(req.headers['sec-websocket-extensions']);
|
||||
const offers = parse(req.headers['sec-websocket-extensions']);
|
||||
|
||||
if (offers[PerMessageDeflate.extensionName]) {
|
||||
perMessageDeflate.accept(offers[PerMessageDeflate.extensionName]);
|
||||
@@ -256,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) {
|
||||
@@ -264,8 +263,14 @@ class WebSocketServer extends EventEmitter {
|
||||
//
|
||||
if (!socket.readable || !socket.writable) return socket.destroy();
|
||||
|
||||
const digest = crypto
|
||||
.createHash('sha1')
|
||||
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');
|
||||
|
||||
@@ -277,7 +282,7 @@ class WebSocketServer extends EventEmitter {
|
||||
];
|
||||
|
||||
const ws = new WebSocket(null);
|
||||
var protocol = req.headers['sec-websocket-protocol'];
|
||||
let protocol = req.headers['sec-websocket-protocol'];
|
||||
|
||||
if (protocol) {
|
||||
protocol = protocol.trim().split(/ *, */);
|
||||
@@ -299,7 +304,7 @@ class WebSocketServer extends EventEmitter {
|
||||
|
||||
if (extensions[PerMessageDeflate.extensionName]) {
|
||||
const params = extensions[PerMessageDeflate.extensionName].params;
|
||||
const value = extension.format({
|
||||
const value = format({
|
||||
[PerMessageDeflate.extensionName]: [params]
|
||||
});
|
||||
headers.push(`Sec-WebSocket-Extensions: ${value}`);
|
||||
@@ -376,18 +381,16 @@ function socketOnError() {
|
||||
*/
|
||||
function abortHandshake(socket, code, message, headers) {
|
||||
if (socket.writable) {
|
||||
message = message || http.STATUS_CODES[code];
|
||||
headers = Object.assign(
|
||||
{
|
||||
Connection: 'close',
|
||||
'Content-type': 'text/html',
|
||||
'Content-Length': Buffer.byteLength(message)
|
||||
},
|
||||
headers
|
||||
);
|
||||
message = message || STATUS_CODES[code];
|
||||
headers = {
|
||||
Connection: 'close',
|
||||
'Content-Type': 'text/html',
|
||||
'Content-Length': Buffer.byteLength(message),
|
||||
...headers
|
||||
};
|
||||
|
||||
socket.write(
|
||||
`HTTP/1.1 ${code} ${http.STATUS_CODES[code]}\r\n` +
|
||||
`HTTP/1.1 ${code} ${STATUS_CODES[code]}\r\n` +
|
||||
Object.keys(headers)
|
||||
.map((h) => `${h}: ${headers[h]}`)
|
||||
.join('\r\n') +
|
||||
|
252
node_modules/ws/lib/websocket.js
generated
vendored
252
node_modules/ws/lib/websocket.js
generated
vendored
@@ -1,16 +1,14 @@
|
||||
'use strict';
|
||||
|
||||
const EventEmitter = require('events');
|
||||
const crypto = require('crypto');
|
||||
const https = require('https');
|
||||
const http = require('http');
|
||||
const net = require('net');
|
||||
const tls = require('tls');
|
||||
const url = require('url');
|
||||
const { randomBytes, createHash } = require('crypto');
|
||||
const { URL } = require('url');
|
||||
|
||||
const PerMessageDeflate = require('./permessage-deflate');
|
||||
const EventTarget = require('./event-target');
|
||||
const extension = require('./extension');
|
||||
const Receiver = require('./receiver');
|
||||
const Sender = require('./sender');
|
||||
const {
|
||||
@@ -21,6 +19,9 @@ const {
|
||||
kWebSocket,
|
||||
NOOP
|
||||
} = require('./constants');
|
||||
const { addEventListener, removeEventListener } = require('./event-target');
|
||||
const { format, parse } = require('./extension');
|
||||
const { toBuffer } = require('./buffer-util');
|
||||
|
||||
const readyStates = ['CONNECTING', 'OPEN', 'CLOSING', 'CLOSED'];
|
||||
const protocolVersions = [8, 13];
|
||||
@@ -35,7 +36,7 @@ class WebSocket extends EventEmitter {
|
||||
/**
|
||||
* Create a new `WebSocket`.
|
||||
*
|
||||
* @param {(String|url.Url|url.URL)} address The URL to which to connect
|
||||
* @param {(String|url.URL)} address The URL to which to connect
|
||||
* @param {(String|String[])} protocols The subprotocols
|
||||
* @param {Object} options Connection options
|
||||
*/
|
||||
@@ -57,6 +58,7 @@ class WebSocket extends EventEmitter {
|
||||
this._socket = null;
|
||||
|
||||
if (address !== null) {
|
||||
this._bufferedAmount = 0;
|
||||
this._isServer = false;
|
||||
this._redirects = 0;
|
||||
|
||||
@@ -112,12 +114,9 @@ class WebSocket extends EventEmitter {
|
||||
* @type {Number}
|
||||
*/
|
||||
get bufferedAmount() {
|
||||
if (!this._socket) return 0;
|
||||
if (!this._socket) return this._bufferedAmount;
|
||||
|
||||
//
|
||||
// `socket.bufferSize` is `undefined` if the socket is closed.
|
||||
//
|
||||
return (this._socket.bufferSize || 0) + this._sender._bufferedBytes;
|
||||
return this._socket._writableState.length + this._sender._bufferedBytes;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -139,6 +138,7 @@ class WebSocket extends EventEmitter {
|
||||
const receiver = new Receiver(
|
||||
this._binaryType,
|
||||
this._extensions,
|
||||
this._isServer,
|
||||
maxPayload
|
||||
);
|
||||
|
||||
@@ -176,9 +176,8 @@ class WebSocket extends EventEmitter {
|
||||
* @private
|
||||
*/
|
||||
emitClose() {
|
||||
this.readyState = WebSocket.CLOSED;
|
||||
|
||||
if (!this._socket) {
|
||||
this.readyState = WebSocket.CLOSED;
|
||||
this.emit('close', this._closeCode, this._closeMessage);
|
||||
return;
|
||||
}
|
||||
@@ -188,6 +187,7 @@ class WebSocket extends EventEmitter {
|
||||
}
|
||||
|
||||
this._receiver.removeAllListeners();
|
||||
this.readyState = WebSocket.CLOSED;
|
||||
this.emit('close', this._closeCode, this._closeMessage);
|
||||
}
|
||||
|
||||
@@ -252,6 +252,10 @@ class WebSocket extends EventEmitter {
|
||||
* @public
|
||||
*/
|
||||
ping(data, mask, cb) {
|
||||
if (this.readyState === WebSocket.CONNECTING) {
|
||||
throw new Error('WebSocket is not open: readyState 0 (CONNECTING)');
|
||||
}
|
||||
|
||||
if (typeof data === 'function') {
|
||||
cb = data;
|
||||
data = mask = undefined;
|
||||
@@ -260,17 +264,13 @@ class WebSocket extends EventEmitter {
|
||||
mask = undefined;
|
||||
}
|
||||
|
||||
if (this.readyState !== WebSocket.OPEN) {
|
||||
const err = new Error(
|
||||
`WebSocket is not open: readyState ${this.readyState} ` +
|
||||
`(${readyStates[this.readyState]})`
|
||||
);
|
||||
if (typeof data === 'number') data = data.toString();
|
||||
|
||||
if (cb) return cb(err);
|
||||
throw err;
|
||||
if (this.readyState !== WebSocket.OPEN) {
|
||||
sendAfterClose(this, data, cb);
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof data === 'number') data = data.toString();
|
||||
if (mask === undefined) mask = !this._isServer;
|
||||
this._sender.ping(data || EMPTY_BUFFER, mask, cb);
|
||||
}
|
||||
@@ -284,6 +284,10 @@ class WebSocket extends EventEmitter {
|
||||
* @public
|
||||
*/
|
||||
pong(data, mask, cb) {
|
||||
if (this.readyState === WebSocket.CONNECTING) {
|
||||
throw new Error('WebSocket is not open: readyState 0 (CONNECTING)');
|
||||
}
|
||||
|
||||
if (typeof data === 'function') {
|
||||
cb = data;
|
||||
data = mask = undefined;
|
||||
@@ -292,17 +296,13 @@ class WebSocket extends EventEmitter {
|
||||
mask = undefined;
|
||||
}
|
||||
|
||||
if (this.readyState !== WebSocket.OPEN) {
|
||||
const err = new Error(
|
||||
`WebSocket is not open: readyState ${this.readyState} ` +
|
||||
`(${readyStates[this.readyState]})`
|
||||
);
|
||||
if (typeof data === 'number') data = data.toString();
|
||||
|
||||
if (cb) return cb(err);
|
||||
throw err;
|
||||
if (this.readyState !== WebSocket.OPEN) {
|
||||
sendAfterClose(this, data, cb);
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof data === 'number') data = data.toString();
|
||||
if (mask === undefined) mask = !this._isServer;
|
||||
this._sender.pong(data || EMPTY_BUFFER, mask, cb);
|
||||
}
|
||||
@@ -312,7 +312,8 @@ class WebSocket extends EventEmitter {
|
||||
*
|
||||
* @param {*} data The message to send
|
||||
* @param {Object} options Options object
|
||||
* @param {Boolean} options.compress Specifies whether or not to compress `data`
|
||||
* @param {Boolean} options.compress Specifies whether or not to compress
|
||||
* `data`
|
||||
* @param {Boolean} options.binary Specifies whether `data` is binary or text
|
||||
* @param {Boolean} options.fin Specifies whether the fragment is the last one
|
||||
* @param {Boolean} options.mask Specifies whether or not to mask `data`
|
||||
@@ -320,32 +321,29 @@ class WebSocket extends EventEmitter {
|
||||
* @public
|
||||
*/
|
||||
send(data, options, cb) {
|
||||
if (this.readyState === WebSocket.CONNECTING) {
|
||||
throw new Error('WebSocket is not open: readyState 0 (CONNECTING)');
|
||||
}
|
||||
|
||||
if (typeof options === 'function') {
|
||||
cb = options;
|
||||
options = {};
|
||||
}
|
||||
|
||||
if (this.readyState !== WebSocket.OPEN) {
|
||||
const err = new Error(
|
||||
`WebSocket is not open: readyState ${this.readyState} ` +
|
||||
`(${readyStates[this.readyState]})`
|
||||
);
|
||||
|
||||
if (cb) return cb(err);
|
||||
throw err;
|
||||
}
|
||||
|
||||
if (typeof data === 'number') data = data.toString();
|
||||
|
||||
const opts = Object.assign(
|
||||
{
|
||||
binary: typeof data !== 'string',
|
||||
mask: !this._isServer,
|
||||
compress: true,
|
||||
fin: true
|
||||
},
|
||||
options
|
||||
);
|
||||
if (this.readyState !== WebSocket.OPEN) {
|
||||
sendAfterClose(this, data, cb);
|
||||
return;
|
||||
}
|
||||
|
||||
const opts = {
|
||||
binary: typeof data !== 'string',
|
||||
mask: !this._isServer,
|
||||
compress: true,
|
||||
fin: true,
|
||||
...options
|
||||
};
|
||||
|
||||
if (!this._extensions[PerMessageDeflate.extensionName]) {
|
||||
opts.compress = false;
|
||||
@@ -391,7 +389,7 @@ readyStates.forEach((readyState, i) => {
|
||||
*/
|
||||
get() {
|
||||
const listeners = this.listeners(method);
|
||||
for (var i = 0; i < listeners.length; i++) {
|
||||
for (let i = 0; i < listeners.length; i++) {
|
||||
if (listeners[i]._listener) return listeners[i]._listener;
|
||||
}
|
||||
|
||||
@@ -405,7 +403,7 @@ readyStates.forEach((readyState, i) => {
|
||||
*/
|
||||
set(listener) {
|
||||
const listeners = this.listeners(method);
|
||||
for (var i = 0; i < listeners.length; i++) {
|
||||
for (let i = 0; i < listeners.length; i++) {
|
||||
//
|
||||
// Remove only the listeners added via `addEventListener`.
|
||||
//
|
||||
@@ -416,8 +414,8 @@ readyStates.forEach((readyState, i) => {
|
||||
});
|
||||
});
|
||||
|
||||
WebSocket.prototype.addEventListener = EventTarget.addEventListener;
|
||||
WebSocket.prototype.removeEventListener = EventTarget.removeEventListener;
|
||||
WebSocket.prototype.addEventListener = addEventListener;
|
||||
WebSocket.prototype.removeEventListener = removeEventListener;
|
||||
|
||||
module.exports = WebSocket;
|
||||
|
||||
@@ -425,7 +423,7 @@ module.exports = WebSocket;
|
||||
* Initialize a WebSocket client.
|
||||
*
|
||||
* @param {WebSocket} websocket The client to initialize
|
||||
* @param {(String|url.Url|url.URL)} address The URL to which to connect
|
||||
* @param {(String|url.URL)} address The URL to which to connect
|
||||
* @param {String} protocols The subprotocols
|
||||
* @param {Object} options Connection options
|
||||
* @param {(Boolean|Object)} options.perMessageDeflate Enable/disable
|
||||
@@ -442,28 +440,23 @@ module.exports = WebSocket;
|
||||
* @private
|
||||
*/
|
||||
function initAsClient(websocket, address, protocols, options) {
|
||||
const opts = Object.assign(
|
||||
{
|
||||
protocolVersion: protocolVersions[1],
|
||||
maxPayload: 100 * 1024 * 1024,
|
||||
perMessageDeflate: true,
|
||||
followRedirects: false,
|
||||
maxRedirects: 10
|
||||
},
|
||||
options,
|
||||
{
|
||||
createConnection: undefined,
|
||||
socketPath: undefined,
|
||||
hostname: undefined,
|
||||
protocol: undefined,
|
||||
timeout: undefined,
|
||||
method: undefined,
|
||||
auth: undefined,
|
||||
host: undefined,
|
||||
path: undefined,
|
||||
port: undefined
|
||||
}
|
||||
);
|
||||
const opts = {
|
||||
protocolVersion: protocolVersions[1],
|
||||
maxPayload: 100 * 1024 * 1024,
|
||||
perMessageDeflate: true,
|
||||
followRedirects: false,
|
||||
maxRedirects: 10,
|
||||
...options,
|
||||
createConnection: undefined,
|
||||
socketPath: undefined,
|
||||
hostname: undefined,
|
||||
protocol: undefined,
|
||||
timeout: undefined,
|
||||
method: undefined,
|
||||
host: undefined,
|
||||
path: undefined,
|
||||
port: undefined
|
||||
};
|
||||
|
||||
if (!protocolVersions.includes(opts.protocolVersion)) {
|
||||
throw new RangeError(
|
||||
@@ -472,16 +465,13 @@ function initAsClient(websocket, address, protocols, options) {
|
||||
);
|
||||
}
|
||||
|
||||
var parsedUrl;
|
||||
let parsedUrl;
|
||||
|
||||
if (typeof address === 'object' && address.href !== undefined) {
|
||||
if (address instanceof URL) {
|
||||
parsedUrl = address;
|
||||
websocket.url = address.href;
|
||||
} else {
|
||||
//
|
||||
// The WHATWG URL constructor is not available on Node.js < 6.13.0
|
||||
//
|
||||
parsedUrl = url.URL ? new url.URL(address) : url.parse(address);
|
||||
parsedUrl = new URL(address);
|
||||
websocket.url = address;
|
||||
}
|
||||
|
||||
@@ -494,12 +484,9 @@ function initAsClient(websocket, address, protocols, options) {
|
||||
const isSecure =
|
||||
parsedUrl.protocol === 'wss:' || parsedUrl.protocol === 'https:';
|
||||
const defaultPort = isSecure ? 443 : 80;
|
||||
const key = crypto.randomBytes(16).toString('base64');
|
||||
const key = randomBytes(16).toString('base64');
|
||||
const get = isSecure ? https.get : http.get;
|
||||
const path = parsedUrl.search
|
||||
? `${parsedUrl.pathname || '/'}${parsedUrl.search}`
|
||||
: parsedUrl.pathname || '/';
|
||||
var perMessageDeflate;
|
||||
let perMessageDeflate;
|
||||
|
||||
opts.createConnection = isSecure ? tlsConnect : netConnect;
|
||||
opts.defaultPort = opts.defaultPort || defaultPort;
|
||||
@@ -507,16 +494,14 @@ function initAsClient(websocket, address, protocols, options) {
|
||||
opts.host = parsedUrl.hostname.startsWith('[')
|
||||
? parsedUrl.hostname.slice(1, -1)
|
||||
: parsedUrl.hostname;
|
||||
opts.headers = Object.assign(
|
||||
{
|
||||
'Sec-WebSocket-Version': opts.protocolVersion,
|
||||
'Sec-WebSocket-Key': key,
|
||||
Connection: 'Upgrade',
|
||||
Upgrade: 'websocket'
|
||||
},
|
||||
opts.headers
|
||||
);
|
||||
opts.path = path;
|
||||
opts.headers = {
|
||||
'Sec-WebSocket-Version': opts.protocolVersion,
|
||||
'Sec-WebSocket-Key': key,
|
||||
Connection: 'Upgrade',
|
||||
Upgrade: 'websocket',
|
||||
...opts.headers
|
||||
};
|
||||
opts.path = parsedUrl.pathname + parsedUrl.search;
|
||||
opts.timeout = opts.handshakeTimeout;
|
||||
|
||||
if (opts.perMessageDeflate) {
|
||||
@@ -525,7 +510,7 @@ function initAsClient(websocket, address, protocols, options) {
|
||||
false,
|
||||
opts.maxPayload
|
||||
);
|
||||
opts.headers['Sec-WebSocket-Extensions'] = extension.format({
|
||||
opts.headers['Sec-WebSocket-Extensions'] = format({
|
||||
[PerMessageDeflate.extensionName]: perMessageDeflate.offer()
|
||||
});
|
||||
}
|
||||
@@ -539,20 +524,18 @@ function initAsClient(websocket, address, protocols, options) {
|
||||
opts.headers.Origin = opts.origin;
|
||||
}
|
||||
}
|
||||
if (parsedUrl.auth) {
|
||||
opts.auth = parsedUrl.auth;
|
||||
} else if (parsedUrl.username || parsedUrl.password) {
|
||||
if (parsedUrl.username || parsedUrl.password) {
|
||||
opts.auth = `${parsedUrl.username}:${parsedUrl.password}`;
|
||||
}
|
||||
|
||||
if (isUnixSocket) {
|
||||
const parts = path.split(':');
|
||||
const parts = opts.path.split(':');
|
||||
|
||||
opts.socketPath = parts[0];
|
||||
opts.path = parts[1];
|
||||
}
|
||||
|
||||
var req = (websocket._req = get(opts));
|
||||
let req = (websocket._req = get(opts));
|
||||
|
||||
if (opts.timeout) {
|
||||
req.on('timeout', () => {
|
||||
@@ -586,9 +569,7 @@ function initAsClient(websocket, address, protocols, options) {
|
||||
|
||||
req.abort();
|
||||
|
||||
const addr = url.URL
|
||||
? new url.URL(location, address)
|
||||
: url.resolve(address, location);
|
||||
const addr = new URL(location, address);
|
||||
|
||||
initAsClient(websocket, addr, protocols, options);
|
||||
} else if (!websocket.emit('unexpected-response', req, res)) {
|
||||
@@ -611,8 +592,7 @@ function initAsClient(websocket, address, protocols, options) {
|
||||
|
||||
req = websocket._req = null;
|
||||
|
||||
const digest = crypto
|
||||
.createHash('sha1')
|
||||
const digest = createHash('sha1')
|
||||
.update(key + GUID)
|
||||
.digest('base64');
|
||||
|
||||
@@ -623,7 +603,7 @@ function initAsClient(websocket, address, protocols, options) {
|
||||
|
||||
const serverProt = res.headers['sec-websocket-protocol'];
|
||||
const protList = (protocols || '').split(/, */);
|
||||
var protError;
|
||||
let protError;
|
||||
|
||||
if (!protocols && serverProt) {
|
||||
protError = 'Server sent a subprotocol but none was requested';
|
||||
@@ -642,9 +622,7 @@ function initAsClient(websocket, address, protocols, options) {
|
||||
|
||||
if (perMessageDeflate) {
|
||||
try {
|
||||
const extensions = extension.parse(
|
||||
res.headers['sec-websocket-extensions']
|
||||
);
|
||||
const extensions = parse(res.headers['sec-websocket-extensions']);
|
||||
|
||||
if (extensions[PerMessageDeflate.extensionName]) {
|
||||
perMessageDeflate.accept(extensions[PerMessageDeflate.extensionName]);
|
||||
@@ -674,13 +652,7 @@ function initAsClient(websocket, address, protocols, options) {
|
||||
* @private
|
||||
*/
|
||||
function netConnect(options) {
|
||||
//
|
||||
// Override `options.path` only if `options` is a copy of the original options
|
||||
// object. This is always true on Node.js >= 8 but not on Node.js 6 where
|
||||
// `options.socketPath` might be `undefined` even if the `socketPath` option
|
||||
// was originally set.
|
||||
//
|
||||
if (options.protocolVersion) options.path = options.socketPath;
|
||||
options.path = options.socketPath;
|
||||
return net.connect(options);
|
||||
}
|
||||
|
||||
@@ -693,7 +665,11 @@ function netConnect(options) {
|
||||
*/
|
||||
function tlsConnect(options) {
|
||||
options.path = undefined;
|
||||
options.servername = options.servername || options.host;
|
||||
|
||||
if (!options.servername && options.servername !== '') {
|
||||
options.servername = options.host;
|
||||
}
|
||||
|
||||
return tls.connect(options);
|
||||
}
|
||||
|
||||
@@ -723,6 +699,38 @@ function abortHandshake(websocket, stream, message) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle cases where the `ping()`, `pong()`, or `send()` methods are called
|
||||
* when the `readyState` attribute is `CLOSING` or `CLOSED`.
|
||||
*
|
||||
* @param {WebSocket} websocket The WebSocket instance
|
||||
* @param {*} data The data to send
|
||||
* @param {Function} cb Callback
|
||||
* @private
|
||||
*/
|
||||
function sendAfterClose(websocket, data, cb) {
|
||||
if (data) {
|
||||
const length = toBuffer(data).length;
|
||||
|
||||
//
|
||||
// The `_bufferedAmount` property is used only when the peer is a client and
|
||||
// the opening handshake fails. Under these circumstances, in fact, the
|
||||
// `setSocket()` method is not called, so the `_socket` and `_sender`
|
||||
// properties are set to `null`.
|
||||
//
|
||||
if (websocket._socket) websocket._sender._bufferedBytes += length;
|
||||
else websocket._bufferedAmount += length;
|
||||
}
|
||||
|
||||
if (cb) {
|
||||
const err = new Error(
|
||||
`WebSocket is not open: readyState ${websocket.readyState} ` +
|
||||
`(${readyStates[websocket.readyState]})`
|
||||
);
|
||||
cb(err);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The listener of the `Receiver` `'conclude'` event.
|
||||
*
|
||||
@@ -890,6 +898,8 @@ function socketOnError() {
|
||||
this.removeListener('error', socketOnError);
|
||||
this.on('error', NOOP);
|
||||
|
||||
websocket.readyState = WebSocket.CLOSING;
|
||||
this.destroy();
|
||||
if (websocket) {
|
||||
websocket.readyState = WebSocket.CLOSING;
|
||||
this.destroy();
|
||||
}
|
||||
}
|
||||
|
66
node_modules/ws/package.json
generated
vendored
66
node_modules/ws/package.json
generated
vendored
@@ -1,27 +1,27 @@
|
||||
{
|
||||
"_from": "ws@^6.1.2",
|
||||
"_id": "ws@6.2.1",
|
||||
"_from": "ws@^7.2.3",
|
||||
"_id": "ws@7.3.1",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==",
|
||||
"_integrity": "sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA==",
|
||||
"_location": "/ws",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "ws@^6.1.2",
|
||||
"raw": "ws@^7.2.3",
|
||||
"name": "ws",
|
||||
"escapedName": "ws",
|
||||
"rawSpec": "^6.1.2",
|
||||
"rawSpec": "^7.2.3",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "^6.1.2"
|
||||
"fetchSpec": "^7.2.3"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/jsdom"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz",
|
||||
"_shasum": "442fdf0a47ed64f59b6a5d8ff130f4748ed524fb",
|
||||
"_spec": "ws@^6.1.2",
|
||||
"_where": "F:\\projects\\p\\minifyfromhtml\\node_modules\\jsdom",
|
||||
"_resolved": "https://registry.npmjs.org/ws/-/ws-7.3.1.tgz",
|
||||
"_shasum": "d0547bf67f7ce4f12a72dfe31262c68d7dc551c8",
|
||||
"_spec": "ws@^7.2.3",
|
||||
"_where": "D:\\Projects\\minifyfromhtml\\node_modules\\jsdom",
|
||||
"author": {
|
||||
"name": "Einar Otto Stangvik",
|
||||
"email": "einaros@gmail.com",
|
||||
@@ -32,22 +32,22 @@
|
||||
"url": "https://github.com/websockets/ws/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"dependencies": {
|
||||
"async-limiter": "~1.0.0"
|
||||
},
|
||||
"deprecated": false,
|
||||
"description": "Simple to use, blazing fast and thoroughly tested websocket client and server for Node.js",
|
||||
"devDependencies": {
|
||||
"benchmark": "~2.1.4",
|
||||
"bufferutil": "~4.0.0",
|
||||
"coveralls": "~3.0.3",
|
||||
"eslint": "~5.15.0",
|
||||
"eslint-config-prettier": "~4.1.0",
|
||||
"eslint-plugin-prettier": "~3.0.0",
|
||||
"mocha": "~6.0.0",
|
||||
"nyc": "~13.3.0",
|
||||
"prettier": "~1.16.1",
|
||||
"utf-8-validate": "~5.0.0"
|
||||
"benchmark": "^2.1.4",
|
||||
"bufferutil": "^4.0.1",
|
||||
"coveralls": "^3.0.3",
|
||||
"eslint": "^7.2.0",
|
||||
"eslint-config-prettier": "^6.0.0",
|
||||
"eslint-plugin-prettier": "^3.0.1",
|
||||
"mocha": "^7.0.0",
|
||||
"nyc": "^15.0.0",
|
||||
"prettier": "^2.0.5",
|
||||
"utf-8-validate": "^5.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.3.0"
|
||||
},
|
||||
"files": [
|
||||
"browser.js",
|
||||
@@ -66,14 +66,26 @@
|
||||
"license": "MIT",
|
||||
"main": "index.js",
|
||||
"name": "ws",
|
||||
"peerDependencies": {
|
||||
"bufferutil": "^4.0.1",
|
||||
"utf-8-validate": "^5.0.2"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"bufferutil": {
|
||||
"optional": true
|
||||
},
|
||||
"utf-8-validate": {
|
||||
"optional": true
|
||||
}
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/websockets/ws.git"
|
||||
},
|
||||
"scripts": {
|
||||
"integration": "npm run lint && mocha test/*.integration.js",
|
||||
"lint": "eslint --ignore-path .gitignore . && prettier --check --ignore-path .gitignore \"**/*.{json,md,yml}\"",
|
||||
"test": "npm run lint && nyc --reporter=html --reporter=text mocha test/*.test.js"
|
||||
"integration": "mocha --throw-deprecation test/*.integration.js",
|
||||
"lint": "eslint --ignore-path .gitignore . && prettier --check --ignore-path .gitignore \"**/*.{json,md,yaml,yml}\"",
|
||||
"test": "nyc --reporter=html --reporter=text mocha --throw-deprecation test/*.test.js"
|
||||
},
|
||||
"version": "6.2.1"
|
||||
"version": "7.3.1"
|
||||
}
|
||||
|
Reference in New Issue
Block a user