Commit 0a83127d authored by Medicean's avatar Medicean

Upgrade(ThirdParty): upgrade ws to 6.2.2

parent 01b488a9
{ {
"_args": [
[
"async-limiter@~1.0.0",
"/Users/m/workspace/antSword/node_modules/ws"
]
],
"_from": "async-limiter@>=1.0.0 <1.1.0",
"_hasShrinkwrap": false,
"_id": "async-limiter@1.0.1",
"_inCache": true,
"_installable": true,
"_location": "/async-limiter",
"_nodeVersion": "10.16.0",
"_npmOperationalInternal": {
"host": "s3://npm-registry-packages",
"tmp": "tmp/async-limiter_1.0.1_1564760633070_0.6974331182093105"
},
"_npmUser": {
"email": "samuel.trace.reed@gmail.com",
"name": "strml"
},
"_npmVersion": "6.9.0",
"_phantomChildren": {},
"_requested": {
"name": "async-limiter", "name": "async-limiter",
"version": "1.0.1", "raw": "async-limiter@~1.0.0",
"rawSpec": "~1.0.0",
"scope": null,
"spec": ">=1.0.0 <1.1.0",
"type": "range"
},
"_requiredBy": [
"/ws"
],
"_resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
"_shasum": "dd379e94f0db8310b08291f9d64c3209766617fd",
"_shrinkwrap": null,
"_spec": "async-limiter@~1.0.0",
"_where": "/Users/m/workspace/antSword/node_modules/ws",
"author": {
"name": "Samuel Reed"
},
"bugs": {
"url": "https://github.com/strml/async-limiter/issues"
},
"dependencies": {},
"description": "asynchronous function queue with adjustable concurrency", "description": "asynchronous function queue with adjustable concurrency",
"devDependencies": {
"coveralls": "^3.0.3",
"eslint": "^5.16.0",
"eslint-plugin-mocha": "^5.3.0",
"intelli-espower-loader": "^1.0.1",
"mocha": "^6.1.4",
"nyc": "^14.1.1",
"power-assert": "^1.6.1"
},
"directories": {},
"dist": {
"fileCount": 7,
"integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==",
"npm-signature": "-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdRFo5CRA9TVsSAnZWagAAE8EP/AoamQTvsA8uUcSUKc4L\nL7rKbbH4m5Cv1Z7qeBXLV3KJHI+dhn/mKU2hOpnXHgks5Az4ELlOX9O1vo9j\nLYtN8ZMGEkMIx+k7OcVexaXLcK9ALliEMNoNy4cIVc+exBS4eKFPmaEx5DmD\nNf+eCG6jkA9WY/kYSmFnus7C0B7d2PMdmtBZKdzWya9PAB5BYEoz3/GYhJZG\nEFYHmWKtMDB6LMSZ0FSXwABV6QXWn5kk3fXaPX1NtMHLw+QCT/sWt+0cOnIE\nak2s8WOry7Fsx5wXQmKbd8854LC+yVT1f7RR7eBhKAlTk74nwfNDr84UBJIr\n+0G0RdgISOzLghtRFu3SqYKynXTjdlycZG9vvcHW9oPGI2ZiC2cHuiqc4+K7\ndYX1HGQICjflTmb+RR0vGNXiy3v6YBWgpItdeziPO2K+0uN6SJr1BidQ8oKI\nd49psu/xNvMhdwOo19+/Bt7n7nT4uzej8K7uQO81BJC0ITeNfaC/z9M/4VOg\nFuixwvvzfs+/RABxzXKZqOMVlAnAb4U/PBcliklyUBeZ62PDkqnBxdrOekf5\nacstUU3K5bAaBV8taKHEa1+tqYUjVEcaolDDKgmO0dxD9FlKAMlhck9ildO7\nnjODiNgcSMUlMmHGUZCEvjSt1YptntzC0DHwxWUjszaR4p0Iz0c0AyOYGH7T\nRewy\r\n=MPQY\r\n-----END PGP SIGNATURE-----\r\n",
"shasum": "dd379e94f0db8310b08291f9d64c3209766617fd",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEUCIQCYVwf0HXqe0bWbc7zYVM/9lbWUqBw9ET6oj9oL/MIGvQIgagFO41z8Ssm5K6bLiDP0KO4AMvSxGKLjZzN2hdLQgpM="
}
],
"tarball": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
"unpackedSize": 6900
},
"gitHead": "f3bb66f26e69a5747a6483e32c775a02632020ee",
"homepage": "https://github.com/strml/async-limiter#readme",
"keywords": [ "keywords": [
"throttle", "throttle",
"async", "async",
...@@ -12,24 +82,26 @@ ...@@ -12,24 +82,26 @@
"concurrency", "concurrency",
"concurrent" "concurrent"
], ],
"dependencies": {}, "license": "MIT",
"devDependencies": { "maintainers": [
"coveralls": "^3.0.3", {
"eslint": "^5.16.0", "email": "samuel.trace.reed@gmail.com",
"eslint-plugin-mocha": "^5.3.0", "name": "strml"
"intelli-espower-loader": "^1.0.1", }
"mocha": "^6.1.4", ],
"nyc": "^14.1.1", "name": "async-limiter",
"power-assert": "^1.6.1" "optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git+https://github.com/strml/async-limiter.git"
}, },
"scripts": { "scripts": {
"test": "mocha --require intelli-espower-loader test/",
"travis": "npm run lint && npm run test",
"coverage": "nyc npm test && nyc report --reporter=text-lcov | coveralls", "coverage": "nyc npm test && nyc report --reporter=text-lcov | coveralls",
"example": "node example", "example": "node example",
"lint": "eslint ." "lint": "eslint .",
"test": "mocha --require intelli-espower-loader test/",
"travis": "npm run lint && npm run test"
}, },
"repository": "https://github.com/strml/async-limiter.git", "version": "1.0.1"
"author": "Samuel Reed <samuel.trace.reed@gmail.com",
"license": "MIT"
} }
# ws: a Node.js WebSocket library # ws: a Node.js WebSocket library
[![Version npm](https://img.shields.io/npm/v/ws.svg)](https://www.npmjs.com/package/ws) [![Version npm](https://img.shields.io/npm/v/ws.svg?logo=npm)](https://www.npmjs.com/package/ws)
[![Linux Build](https://img.shields.io/travis/websockets/ws/master.svg)](https://travis-ci.org/websockets/ws) [![Linux Build](https://img.shields.io/travis/websockets/ws/master.svg?logo=travis)](https://travis-ci.org/websockets/ws)
[![Windows Build](https://ci.appveyor.com/api/projects/status/github/websockets/ws?branch=master&svg=true)](https://ci.appveyor.com/project/lpinca/ws) [![Windows Build](https://img.shields.io/appveyor/ci/lpinca/ws/master.svg?logo=appveyor)](https://ci.appveyor.com/project/lpinca/ws)
[![Coverage Status](https://img.shields.io/coveralls/websockets/ws/master.svg)](https://coveralls.io/r/websockets/ws?branch=master) [![Coverage Status](https://img.shields.io/coveralls/websockets/ws/master.svg)](https://coveralls.io/github/websockets/ws)
ws is a simple to use, blazing fast, and thoroughly tested WebSocket client and ws is a simple to use, blazing fast, and thoroughly tested WebSocket client and
server implementation. server implementation.
......
'use strict'; 'use strict';
const { EMPTY_BUFFER } = require('./constants');
/** /**
* Merges an array of buffers into a new buffer. * Merges an array of buffers into a new buffer.
* *
...@@ -9,6 +11,9 @@ ...@@ -9,6 +11,9 @@
* @public * @public
*/ */
function concat(list, totalLength) { function concat(list, totalLength) {
if (list.length === 0) return EMPTY_BUFFER;
if (list.length === 1) return list[0];
const target = Buffer.allocUnsafe(totalLength); const target = Buffer.allocUnsafe(totalLength);
var offset = 0; var offset = 0;
...@@ -52,21 +57,88 @@ function _unmask(buffer, mask) { ...@@ -52,21 +57,88 @@ function _unmask(buffer, mask) {
} }
} }
/**
* Converts a buffer to an `ArrayBuffer`.
*
* @param {Buffer} buf The buffer to convert
* @return {ArrayBuffer} Converted buffer
* @public
*/
function toArrayBuffer(buf) {
if (buf.byteLength === buf.buffer.byteLength) {
return buf.buffer;
}
return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
}
/**
* Converts `data` to a `Buffer`.
*
* @param {*} data The data to convert
* @return {Buffer} The buffer
* @throws {TypeError}
* @public
*/
function toBuffer(data) {
toBuffer.readOnly = true;
if (Buffer.isBuffer(data)) return data;
var buf;
if (data instanceof ArrayBuffer) {
buf = Buffer.from(data);
} else if (ArrayBuffer.isView(data)) {
buf = viewToBuffer(data);
} else {
buf = Buffer.from(data);
toBuffer.readOnly = false;
}
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 { try {
const bufferUtil = require('bufferutil'); const bufferUtil = require('bufferutil');
const bu = bufferUtil.BufferUtil || bufferUtil; const bu = bufferUtil.BufferUtil || bufferUtil;
module.exports = { module.exports = {
concat,
mask(source, mask, output, offset, length) { mask(source, mask, output, offset, length) {
if (length < 48) _mask(source, mask, output, offset, length); if (length < 48) _mask(source, mask, output, offset, length);
else bu.mask(source, mask, output, offset, length); else bu.mask(source, mask, output, offset, length);
}, },
toArrayBuffer,
toBuffer,
unmask(buffer, mask) { unmask(buffer, mask) {
if (buffer.length < 32) _unmask(buffer, mask); if (buffer.length < 32) _unmask(buffer, mask);
else bu.unmask(buffer, mask); else bu.unmask(buffer, mask);
}, }
concat
}; };
} catch (e) /* istanbul ignore next */ { } catch (e) /* istanbul ignore next */ {
module.exports = { concat, mask: _mask, unmask: _unmask }; module.exports = {
concat,
mask: _mask,
toArrayBuffer,
toBuffer,
unmask: _unmask
};
} }
'use strict'; 'use strict';
const stream = require('stream'); const { Writable } = require('stream');
const PerMessageDeflate = require('./permessage-deflate'); const PerMessageDeflate = require('./permessage-deflate');
const bufferUtil = require('./buffer-util'); const {
const validation = require('./validation'); BINARY_TYPES,
const constants = require('./constants'); EMPTY_BUFFER,
kStatusCode,
kWebSocket
} = require('./constants');
const { concat, toArrayBuffer, unmask } = require('./buffer-util');
const { isValidStatusCode, isValidUTF8 } = require('./validation');
const GET_INFO = 0; const GET_INFO = 0;
const GET_PAYLOAD_LENGTH_16 = 1; const GET_PAYLOAD_LENGTH_16 = 1;
...@@ -19,7 +24,7 @@ const INFLATING = 5; ...@@ -19,7 +24,7 @@ const INFLATING = 5;
* *
* @extends stream.Writable * @extends stream.Writable
*/ */
class Receiver extends stream.Writable { class Receiver extends Writable {
/** /**
* Creates a Receiver instance. * Creates a Receiver instance.
* *
...@@ -30,8 +35,8 @@ class Receiver extends stream.Writable { ...@@ -30,8 +35,8 @@ class Receiver extends stream.Writable {
constructor(binaryType, extensions, maxPayload) { constructor(binaryType, extensions, maxPayload) {
super(); super();
this._binaryType = binaryType || constants.BINARY_TYPES[0]; this._binaryType = binaryType || BINARY_TYPES[0];
this[constants.kWebSocket] = undefined; this[kWebSocket] = undefined;
this._extensions = extensions || {}; this._extensions = extensions || {};
this._maxPayload = maxPayload | 0; this._maxPayload = maxPayload | 0;
...@@ -315,7 +320,7 @@ class Receiver extends stream.Writable { ...@@ -315,7 +320,7 @@ class Receiver extends stream.Writable {
* @private * @private
*/ */
getData(cb) { getData(cb) {
var data = constants.EMPTY_BUFFER; var data = EMPTY_BUFFER;
if (this._payloadLength) { if (this._payloadLength) {
if (this._bufferedBytes < this._payloadLength) { if (this._bufferedBytes < this._payloadLength) {
...@@ -324,7 +329,7 @@ class Receiver extends stream.Writable { ...@@ -324,7 +329,7 @@ class Receiver extends stream.Writable {
} }
data = this.consume(this._payloadLength); data = this.consume(this._payloadLength);
if (this._masked) bufferUtil.unmask(data, this._mask); if (this._masked) unmask(data, this._mask);
} }
if (this._opcode > 0x07) return this.controlMessage(data); if (this._opcode > 0x07) return this.controlMessage(data);
...@@ -398,18 +403,18 @@ class Receiver extends stream.Writable { ...@@ -398,18 +403,18 @@ class Receiver extends stream.Writable {
var data; var data;
if (this._binaryType === 'nodebuffer') { if (this._binaryType === 'nodebuffer') {
data = toBuffer(fragments, messageLength); data = concat(fragments, messageLength);
} else if (this._binaryType === 'arraybuffer') { } else if (this._binaryType === 'arraybuffer') {
data = toArrayBuffer(toBuffer(fragments, messageLength)); data = toArrayBuffer(concat(fragments, messageLength));
} else { } else {
data = fragments; data = fragments;
} }
this.emit('message', data); this.emit('message', data);
} else { } else {
const buf = toBuffer(fragments, messageLength); const buf = concat(fragments, messageLength);
if (!validation.isValidUTF8(buf)) { if (!isValidUTF8(buf)) {
this._loop = false; this._loop = false;
return error(Error, 'invalid UTF-8 sequence', true, 1007); return error(Error, 'invalid UTF-8 sequence', true, 1007);
} }
...@@ -440,13 +445,13 @@ class Receiver extends stream.Writable { ...@@ -440,13 +445,13 @@ class Receiver extends stream.Writable {
} else { } else {
const code = data.readUInt16BE(0); const code = data.readUInt16BE(0);
if (!validation.isValidStatusCode(code)) { if (!isValidStatusCode(code)) {
return error(RangeError, `invalid status code ${code}`, true, 1002); return error(RangeError, `invalid status code ${code}`, true, 1002);
} }
const buf = data.slice(2); const buf = data.slice(2);
if (!validation.isValidUTF8(buf)) { if (!isValidUTF8(buf)) {
return error(Error, 'invalid UTF-8 sequence', true, 1007); return error(Error, 'invalid UTF-8 sequence', true, 1007);
} }
...@@ -482,34 +487,6 @@ function error(ErrorCtor, message, prefix, statusCode) { ...@@ -482,34 +487,6 @@ function error(ErrorCtor, message, prefix, statusCode) {
); );
Error.captureStackTrace(err, error); Error.captureStackTrace(err, error);
err[constants.kStatusCode] = statusCode; err[kStatusCode] = statusCode;
return err; return err;
} }
/**
* Makes a buffer from a list of fragments.
*
* @param {Buffer[]} fragments The list of fragments composing the message
* @param {Number} messageLength The length of the message
* @return {Buffer}
* @private
*/
function toBuffer(fragments, messageLength) {
if (fragments.length === 1) return fragments[0];
if (fragments.length > 1) return bufferUtil.concat(fragments, messageLength);
return constants.EMPTY_BUFFER;
}
/**
* Converts a buffer to an `ArrayBuffer`.
*
* @param {Buffer} buf The buffer to convert
* @return {ArrayBuffer} Converted buffer
*/
function toArrayBuffer(buf) {
if (buf.byteLength === buf.buffer.byteLength) {
return buf.buffer;
}
return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
}
'use strict'; 'use strict';
const crypto = require('crypto'); const { randomBytes } = require('crypto');
const PerMessageDeflate = require('./permessage-deflate'); const PerMessageDeflate = require('./permessage-deflate');
const bufferUtil = require('./buffer-util'); const { EMPTY_BUFFER } = require('./constants');
const validation = require('./validation'); const { isValidStatusCode } = require('./validation');
const constants = require('./constants'); const { mask: applyMask, toBuffer } = require('./buffer-util');
/** /**
* HyBi Sender implementation. * HyBi Sender implementation.
...@@ -43,7 +43,7 @@ class Sender { ...@@ -43,7 +43,7 @@ class Sender {
* @public * @public
*/ */
static frame(data, options) { static frame(data, options) {
const merge = data.length < 1024 || (options.mask && options.readOnly); const merge = options.mask && options.readOnly;
var offset = options.mask ? 6 : 2; var offset = options.mask ? 6 : 2;
var payloadLength = data.length; var payloadLength = data.length;
...@@ -60,6 +60,8 @@ class Sender { ...@@ -60,6 +60,8 @@ class Sender {
target[0] = options.fin ? options.opcode | 0x80 : options.opcode; target[0] = options.fin ? options.opcode | 0x80 : options.opcode;
if (options.rsv1) target[0] |= 0x40; if (options.rsv1) target[0] |= 0x40;
target[1] = payloadLength;
if (payloadLength === 126) { if (payloadLength === 126) {
target.writeUInt16BE(data.length, 2); target.writeUInt16BE(data.length, 2);
} else if (payloadLength === 127) { } else if (payloadLength === 127) {
...@@ -67,30 +69,22 @@ class Sender { ...@@ -67,30 +69,22 @@ class Sender {
target.writeUInt32BE(data.length, 6); target.writeUInt32BE(data.length, 6);
} }
if (!options.mask) { if (!options.mask) return [target, data];
target[1] = payloadLength;
if (merge) {
data.copy(target, offset);
return [target];
}
return [target, data];
}
const mask = crypto.randomBytes(4); const mask = randomBytes(4);
target[1] = payloadLength | 0x80; target[1] |= 0x80;
target[offset - 4] = mask[0]; target[offset - 4] = mask[0];
target[offset - 3] = mask[1]; target[offset - 3] = mask[1];
target[offset - 2] = mask[2]; target[offset - 2] = mask[2];
target[offset - 1] = mask[3]; target[offset - 1] = mask[3];
if (merge) { if (merge) {
bufferUtil.mask(data, mask, target, offset, data.length); applyMask(data, mask, target, offset, data.length);
return [target]; return [target];
} }
bufferUtil.mask(data, mask, data, 0, data.length); applyMask(data, mask, data, 0, data.length);
return [target, data]; return [target, data];
} }
...@@ -107,11 +101,8 @@ class Sender { ...@@ -107,11 +101,8 @@ class Sender {
var buf; var buf;
if (code === undefined) { if (code === undefined) {
buf = constants.EMPTY_BUFFER; buf = EMPTY_BUFFER;
} else if ( } else if (typeof code !== 'number' || !isValidStatusCode(code)) {
typeof code !== 'number' ||
!validation.isValidStatusCode(code)
) {
throw new TypeError('First argument must be a valid error code number'); throw new TypeError('First argument must be a valid error code number');
} else if (data === undefined || data === '') { } else if (data === undefined || data === '') {
buf = Buffer.allocUnsafe(2); buf = Buffer.allocUnsafe(2);
...@@ -159,23 +150,12 @@ class Sender { ...@@ -159,23 +150,12 @@ class Sender {
* @public * @public
*/ */
ping(data, mask, cb) { ping(data, mask, cb) {
var readOnly = true; const buf = toBuffer(data);
if (!Buffer.isBuffer(data)) {
if (data instanceof ArrayBuffer) {
data = Buffer.from(data);
} else if (ArrayBuffer.isView(data)) {
data = viewToBuffer(data);
} else {
data = Buffer.from(data);
readOnly = false;
}
}
if (this._deflating) { if (this._deflating) {
this.enqueue([this.doPing, data, mask, readOnly, cb]); this.enqueue([this.doPing, buf, mask, toBuffer.readOnly, cb]);
} else { } else {
this.doPing(data, mask, readOnly, cb); this.doPing(buf, mask, toBuffer.readOnly, cb);
} }
} }
...@@ -210,23 +190,12 @@ class Sender { ...@@ -210,23 +190,12 @@ class Sender {
* @public * @public
*/ */
pong(data, mask, cb) { pong(data, mask, cb) {
var readOnly = true; const buf = toBuffer(data);
if (!Buffer.isBuffer(data)) {
if (data instanceof ArrayBuffer) {
data = Buffer.from(data);
} else if (ArrayBuffer.isView(data)) {
data = viewToBuffer(data);
} else {
data = Buffer.from(data);
readOnly = false;
}
}
if (this._deflating) { if (this._deflating) {
this.enqueue([this.doPong, data, mask, readOnly, cb]); this.enqueue([this.doPong, buf, mask, toBuffer.readOnly, cb]);
} else { } else {
this.doPong(data, mask, readOnly, cb); this.doPong(buf, mask, toBuffer.readOnly, cb);
} }
} }
...@@ -265,27 +234,15 @@ class Sender { ...@@ -265,27 +234,15 @@ class Sender {
* @public * @public
*/ */
send(data, options, cb) { send(data, options, cb) {
const buf = toBuffer(data);
const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName];
var opcode = options.binary ? 2 : 1; var opcode = options.binary ? 2 : 1;
var rsv1 = options.compress; var rsv1 = options.compress;
var readOnly = true;
if (!Buffer.isBuffer(data)) {
if (data instanceof ArrayBuffer) {
data = Buffer.from(data);
} else if (ArrayBuffer.isView(data)) {
data = viewToBuffer(data);
} else {
data = Buffer.from(data);
readOnly = false;
}
}
const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName];
if (this._firstFragment) { if (this._firstFragment) {
this._firstFragment = false; this._firstFragment = false;
if (rsv1 && perMessageDeflate) { if (rsv1 && perMessageDeflate) {
rsv1 = data.length >= perMessageDeflate._threshold; rsv1 = buf.length >= perMessageDeflate._threshold;
} }
this._compress = rsv1; this._compress = rsv1;
} else { } else {
...@@ -301,22 +258,22 @@ class Sender { ...@@ -301,22 +258,22 @@ class Sender {
rsv1, rsv1,
opcode, opcode,
mask: options.mask, mask: options.mask,
readOnly readOnly: toBuffer.readOnly
}; };
if (this._deflating) { if (this._deflating) {
this.enqueue([this.dispatch, data, this._compress, opts, cb]); this.enqueue([this.dispatch, buf, this._compress, opts, cb]);
} else { } else {
this.dispatch(data, this._compress, opts, cb); this.dispatch(buf, this._compress, opts, cb);
} }
} else { } else {
this.sendFrame( this.sendFrame(
Sender.frame(data, { Sender.frame(buf, {
fin: options.fin, fin: options.fin,
rsv1: false, rsv1: false,
opcode, opcode,
mask: options.mask, mask: options.mask,
readOnly readOnly: toBuffer.readOnly
}), }),
cb cb
); );
...@@ -388,8 +345,10 @@ class Sender { ...@@ -388,8 +345,10 @@ class Sender {
*/ */
sendFrame(list, cb) { sendFrame(list, cb) {
if (list.length === 2) { if (list.length === 2) {
this._socket.cork();
this._socket.write(list[0]); this._socket.write(list[0]);
this._socket.write(list[1], cb); this._socket.write(list[1], cb);
this._socket.uncork();
} else { } else {
this._socket.write(list[0], cb); this._socket.write(list[0], cb);
} }
...@@ -397,20 +356,3 @@ class Sender { ...@@ -397,20 +356,3 @@ class Sender {
} }
module.exports = Sender; module.exports = Sender;
/**
* 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;
}
...@@ -6,8 +6,10 @@ const http = require('http'); ...@@ -6,8 +6,10 @@ const http = require('http');
const PerMessageDeflate = require('./permessage-deflate'); const PerMessageDeflate = require('./permessage-deflate');
const extension = require('./extension'); const extension = require('./extension');
const constants = require('./constants');
const WebSocket = require('./websocket'); const WebSocket = require('./websocket');
const { GUID } = require('./constants');
const keyRegex = /^[+/0-9A-Za-z]{22}==$/;
/** /**
* Class representing a WebSocket server. * Class representing a WebSocket server.
...@@ -19,16 +21,20 @@ class WebSocketServer extends EventEmitter { ...@@ -19,16 +21,20 @@ class WebSocketServer extends EventEmitter {
* Create a `WebSocketServer` instance. * Create a `WebSocketServer` instance.
* *
* @param {Object} options Configuration options * @param {Object} options Configuration options
* @param {Number} options.backlog The maximum length of the queue of pending
* connections
* @param {Boolean} options.clientTracking Specifies whether or not to track
* clients
* @param {Function} options.handleProtocols An hook to handle protocols
* @param {String} options.host The hostname where to bind the server * @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
* @param {String} options.path Accept only connections matching this path
* @param {(Boolean|Object)} options.perMessageDeflate Enable/disable
* permessage-deflate
* @param {Number} options.port The port where to bind the server * @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 {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 An hook to reject connections
* @param {Function} options.handleProtocols An hook to handle protocols
* @param {String} options.path Accept only connections matching this path
* @param {Boolean} options.noServer Enable no server mode
* @param {Boolean} options.clientTracking Specifies whether or not to track clients
* @param {(Boolean|Object)} options.perMessageDeflate Enable/disable permessage-deflate
* @param {Number} options.maxPayload The maximum allowed message size
* @param {Function} callback A listener for the `listening` event * @param {Function} callback A listener for the `listening` event
*/ */
constructor(options, callback) { constructor(options, callback) {
...@@ -176,13 +182,18 @@ class WebSocketServer extends EventEmitter { ...@@ -176,13 +182,18 @@ class WebSocketServer extends EventEmitter {
handleUpgrade(req, socket, head, cb) { handleUpgrade(req, socket, head, cb) {
socket.on('error', socketOnError); socket.on('error', socketOnError);
const key =
req.headers['sec-websocket-key'] !== undefined
? req.headers['sec-websocket-key'].trim()
: false;
const version = +req.headers['sec-websocket-version']; const version = +req.headers['sec-websocket-version'];
const extensions = {}; const extensions = {};
if ( if (
req.method !== 'GET' || req.method !== 'GET' ||
req.headers.upgrade.toLowerCase() !== 'websocket' || req.headers.upgrade.toLowerCase() !== 'websocket' ||
!req.headers['sec-websocket-key'] || !key ||
!keyRegex.test(key) ||
(version !== 8 && version !== 13) || (version !== 8 && version !== 13) ||
!this.shouldHandle(req) !this.shouldHandle(req)
) { ) {
...@@ -225,7 +236,7 @@ class WebSocketServer extends EventEmitter { ...@@ -225,7 +236,7 @@ class WebSocketServer extends EventEmitter {
return abortHandshake(socket, code || 401, message, headers); return abortHandshake(socket, code || 401, message, headers);
} }
this.completeUpgrade(extensions, req, socket, head, cb); this.completeUpgrade(key, extensions, req, socket, head, cb);
}); });
return; return;
} }
...@@ -233,12 +244,13 @@ class WebSocketServer extends EventEmitter { ...@@ -233,12 +244,13 @@ class WebSocketServer extends EventEmitter {
if (!this.options.verifyClient(info)) return abortHandshake(socket, 401); if (!this.options.verifyClient(info)) return abortHandshake(socket, 401);
} }
this.completeUpgrade(extensions, req, socket, head, cb); this.completeUpgrade(key, extensions, req, socket, head, cb);
} }
/** /**
* Upgrade the connection to WebSocket. * Upgrade the connection to WebSocket.
* *
* @param {String} key The value of the `Sec-WebSocket-Key` header
* @param {Object} extensions The accepted extensions * @param {Object} extensions The accepted extensions
* @param {http.IncomingMessage} req The request object * @param {http.IncomingMessage} req The request object
* @param {net.Socket} socket The network socket between the server and client * @param {net.Socket} socket The network socket between the server and client
...@@ -246,29 +258,29 @@ class WebSocketServer extends EventEmitter { ...@@ -246,29 +258,29 @@ class WebSocketServer extends EventEmitter {
* @param {Function} cb Callback * @param {Function} cb Callback
* @private * @private
*/ */
completeUpgrade(extensions, req, socket, head, cb) { completeUpgrade(key, extensions, req, socket, head, cb) {
// //
// Destroy the socket if the client has already sent a FIN packet. // Destroy the socket if the client has already sent a FIN packet.
// //
if (!socket.readable || !socket.writable) return socket.destroy(); if (!socket.readable || !socket.writable) return socket.destroy();
const key = crypto const digest = crypto
.createHash('sha1') .createHash('sha1')
.update(req.headers['sec-websocket-key'] + constants.GUID, 'binary') .update(key + GUID)
.digest('base64'); .digest('base64');
const headers = [ const headers = [
'HTTP/1.1 101 Switching Protocols', 'HTTP/1.1 101 Switching Protocols',
'Upgrade: websocket', 'Upgrade: websocket',
'Connection: Upgrade', 'Connection: Upgrade',
`Sec-WebSocket-Accept: ${key}` `Sec-WebSocket-Accept: ${digest}`
]; ];
const ws = new WebSocket(null); const ws = new WebSocket(null);
var protocol = req.headers['sec-websocket-protocol']; var protocol = req.headers['sec-websocket-protocol'];
if (protocol) { if (protocol) {
protocol = protocol.trim().split(/ *, */); protocol = protocol.split(',').map(trim);
// //
// Optionally call external protocol selection handler. // Optionally call external protocol selection handler.
...@@ -387,3 +399,15 @@ function abortHandshake(socket, code, message, headers) { ...@@ -387,3 +399,15 @@ function abortHandshake(socket, code, message, headers) {
socket.removeListener('error', socketOnError); socket.removeListener('error', socketOnError);
socket.destroy(); socket.destroy();
} }
/**
* Remove whitespace characters from both ends of a string.
*
* @param {String} str The string
* @return {String} A new string representing `str` stripped of whitespace
* characters from both its beginning and end
* @private
*/
function trim(str) {
return str.trim();
}
This diff is collapsed.
{ {
"_args": [
[
"ws@6.2.2",
"/Users/m/workspace/antSword"
]
],
"_from": "ws@6.2.2",
"_hasShrinkwrap": false,
"_id": "ws@6.2.2",
"_inCache": true,
"_installable": true,
"_location": "/ws",
"_nodeVersion": "16.2.0",
"_npmOperationalInternal": {
"host": "s3://npm-registry-packages",
"tmp": "tmp/ws_6.2.2_1622572492507_0.791522012984119"
},
"_npmUser": {
"email": "luigipinca@gmail.com",
"name": "lpinca"
},
"_npmVersion": "7.13.0",
"_phantomChildren": {},
"_requested": {
"name": "ws", "name": "ws",
"version": "6.1.4", "raw": "ws@6.2.2",
"rawSpec": "6.2.2",
"scope": null,
"spec": "6.2.2",
"type": "version"
},
"_requiredBy": [
"#USER"
],
"_resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz",
"_shasum": "dd5cdbd57a9979916097652d78f1cc5faea0c32e",
"_shrinkwrap": null,
"_spec": "ws@6.2.2",
"_where": "/Users/m/workspace/antSword",
"author": {
"email": "einaros@gmail.com",
"name": "Einar Otto Stangvik",
"url": "http://2x.io"
},
"browser": "browser.js",
"bugs": {
"url": "https://github.com/websockets/ws/issues"
},
"dependencies": {
"async-limiter": "~1.0.0"
},
"description": "Simple to use, blazing fast and thoroughly tested websocket client and server for Node.js", "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"
},
"directories": {},
"dist": {
"fileCount": 15,
"integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==",
"npm-signature": "-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgtn3NCRA9TVsSAnZWagAAxFsP/jSEBOvCrZ5dtS/nj0ua\nqsCbU/Y1wqG/M0edJS6b9hM2SgKdmHPH9byqgrBs6SlEBSi8v0H0XEhvUjd0\nW3SNXps8SA0j7O1v6Sbb9YbJm0RU14Cq0gOngxJ/uad6XOOwCSsQqV9FfA9R\nnzx9QBXnJVks+q/LS3qDJ2XbvBDD4nA+YiIPJHu9nry21Z+lC48lsMQinLVZ\n4pAvCHAYNzgUg0J6B0qQQ+wc+i9Ml/3CRUmZMJ32h/yx2zzdwQ5zR5PDl3xb\nKhROfEE2kybahk7bYMIwBCVNPhe+WeoOKBJlu7V/Mzx3x/RnsSLUu6pF2alI\nvNfb4cS9B0ik9p8OdC9ULauDVKwHusfoxNjtmDFqDmxgh0zEnCQidhaWep0k\nwg30GmEkx3lzGWgjOJ8/1svW0TFVUUojGvQQc0qmgM+9Rn2tqcWkdV+xNm6A\nymtt9ZDpPPFBPmtipqbcRcLU7JuLM9PUz6xqRBCYyerBc1aqO0/oIevFuC/F\nifB8ZNPVvVwUJq2gz0KTkrnqpa1GDvaP4abFihpuXeodhN9QEF1YvCItdoAp\n4kWSOpVVpLfmJAxEgtHhkCKwfYJEP8lf7mjS+ilnkeP0cKO6Aq/N693fnH1W\nWE12+K2HXSmpWzoyKiFyU7psS9afANp4QbQsVh/mhQKSGRyIl4wmU1emJT9b\nv8eQ\r\n=1LXy\r\n-----END PGP SIGNATURE-----\r\n",
"shasum": "dd5cdbd57a9979916097652d78f1cc5faea0c32e",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEYCIQDTi3OXyBRVRRDbt1DkzzQvNJvHj01yrckBeI61CKkihAIhAJ20N24tK5ntCd8n0EL5JZEQVtwt2nYggGUWmIgr9pVY"
}
],
"tarball": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz",
"unpackedSize": 101735
},
"gitHead": "9bdb58070d64c33a9beeac7c732aac0f4e7e18b7",
"homepage": "https://github.com/websockets/ws",
"keywords": [ "keywords": [
"HyBi", "HyBi",
"Push", "Push",
...@@ -10,36 +88,37 @@ ...@@ -10,36 +88,37 @@
"WebSockets", "WebSockets",
"real-time" "real-time"
], ],
"homepage": "https://github.com/websockets/ws",
"bugs": "https://github.com/websockets/ws/issues",
"repository": "websockets/ws",
"author": "Einar Otto Stangvik <einaros@gmail.com> (http://2x.io)",
"license": "MIT", "license": "MIT",
"main": "index.js", "main": "index.js",
"browser": "browser.js", "maintainers": [
"files": [ {
"browser.js", "email": "einaros@gmail.com",
"index.js", "name": "einaros"
"lib/*.js" },
{
"email": "npm@3rd-Eden.com",
"name": "v1"
},
{
"email": "luigipinca@gmail.com",
"name": "lpinca"
},
{
"email": "npmjs@3rd-Eden.com",
"name": "3rdeden"
}
], ],
"name": "ws",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git+https://github.com/websockets/ws.git"
},
"scripts": { "scripts": {
"test": "npm run lint && nyc --reporter=html --reporter=text mocha test/*.test.js",
"integration": "npm run lint && mocha test/*.integration.js", "integration": "npm run lint && mocha test/*.integration.js",
"lint": "eslint . --ignore-path .gitignore && prettylint '**/*.{json,md}' --ignore-path .gitignore" "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"
}, },
"dependencies": { "version": "6.2.2"
"async-limiter": "~1.0.0"
},
"devDependencies": {
"benchmark": "~2.1.4",
"bufferutil": "~4.0.0",
"eslint": "~5.14.0",
"eslint-config-prettier": "~4.0.0",
"eslint-plugin-prettier": "~3.0.0",
"mocha": "~5.2.0",
"nyc": "~13.3.0",
"prettier": "~1.16.1",
"prettylint": "~1.0.0",
"utf-8-validate": "~5.0.0"
}
} }
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
"superagent-proxy": "3.0.0", "superagent-proxy": "3.0.0",
"tar": "4.4.18", "tar": "4.4.18",
"through": "2.3.8", "through": "2.3.8",
"ws": "6.1.4", "ws": "6.2.2",
"mime": "2.6.0", "mime": "2.6.0",
"xml2js": "0.4.23" "xml2js": "0.4.23"
}, },
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment