Socket
Socket
Sign inDemoInstall

ws

Package Overview
Dependencies
Maintainers
4
Versions
169
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ws - npm Package Compare versions

Comparing version 6.2.1 to 7.0.0

10

lib/buffer-util.js

@@ -18,5 +18,5 @@ 'use strict';

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];

@@ -41,3 +41,3 @@ buf.copy(target, offset);

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];

@@ -57,3 +57,3 @@ }

const length = buffer.length;
for (var i = 0; i < length; i++) {
for (let i = 0; i < length; i++) {
buffer[i] ^= mask[i & 3];

@@ -91,3 +91,3 @@ }

var buf;
let buf;

@@ -94,0 +94,0 @@ if (data instanceof ArrayBuffer) {

@@ -162,3 +162,3 @@ 'use strict';

for (var i = 0; i < listeners.length; i++) {
for (let i = 0; i < listeners.length; i++) {
if (listeners[i] === listener || listeners[i]._listener === listener) {

@@ -165,0 +165,0 @@ this.removeListener(method, listeners[i]);

@@ -37,4 +37,4 @@ 'use strict';

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);
}

@@ -50,16 +50,17 @@

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);

@@ -81,3 +82,3 @@

push(offers, name, params);
params = {};
params = Object.create(null);
} else {

@@ -105,3 +106,3 @@ extensionName = name;

push(offers, extensionName, params);
params = {};
params = Object.create(null);
extensionName = undefined;

@@ -153,3 +154,3 @@ }

if (end === -1) end = i;
var value = header.slice(start, end);
let value = header.slice(start, end);
if (mustUnescape) {

@@ -162,3 +163,3 @@ value = value.replace(/\\/g, '');

push(offers, extensionName, params);
params = {};
params = Object.create(null);
extensionName = undefined;

@@ -182,3 +183,3 @@ }

if (extensionName === undefined) {
push(offers, token, {});
push(offers, token, params);
} else {

@@ -208,3 +209,3 @@ if (paramName === undefined) {

.map((extension) => {
var configurations = extensions[extension];
let configurations = extensions[extension];
if (!Array.isArray(configurations)) configurations = [configurations];

@@ -216,3 +217,3 @@ return configurations

Object.keys(params).map((k) => {
var values = params[k];
let values = params[k];
if (!Array.isArray(values)) values = [values];

@@ -219,0 +220,0 @@ return values

@@ -236,3 +236,3 @@ 'use strict';

Object.keys(params).forEach((key) => {
var value = params[key];
let value = params[key];

@@ -339,5 +339,6 @@ if (value.length > 1) {

this._inflate = zlib.createInflateRaw(
Object.assign({}, this._options.zlibInflateOptions, { windowBits })
);
this._inflate = zlib.createInflateRaw({
...this._options.zlibInflateOptions,
windowBits
});
this._inflate[kPerMessageDeflate] = this;

@@ -405,5 +406,6 @@ this._inflate[kTotalLength] = 0;

this._deflate = zlib.createDeflateRaw(
Object.assign({}, this._options.zlibDeflateOptions, { windowBits })
);
this._deflate = zlib.createDeflateRaw({
...this._options.zlibDeflateOptions,
windowBits
});

@@ -435,3 +437,3 @@ this._deflate[kTotalLength] = 0;

var data = bufferUtil.concat(
let data = bufferUtil.concat(
this._deflate[kBuffers],

@@ -438,0 +440,0 @@ this._deflate[kTotalLength]

@@ -120,3 +120,3 @@ 'use strict';

startLoop(cb) {
var err;
let err;
this._loop = true;

@@ -324,3 +324,3 @@

getData(cb) {
var data = EMPTY_BUFFER;
let data = EMPTY_BUFFER;

@@ -405,3 +405,3 @@ if (this._payloadLength) {

if (this._opcode === 2) {
var data;
let data;

@@ -408,0 +408,0 @@ if (this._binaryType === 'nodebuffer') {

'use strict';
const { randomBytes } = require('crypto');
const { randomFillSync } = require('crypto');

@@ -10,2 +10,4 @@ const PerMessageDeflate = require('./permessage-deflate');

const mask = Buffer.alloc(4);
/**

@@ -48,4 +50,4 @@ * HyBi Sender implementation.

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;

@@ -76,3 +78,3 @@ if (data.length >= 65536) {

const mask = randomBytes(4);
randomFillSync(mask, 0, 4);

@@ -104,3 +106,3 @@ target[1] |= 0x80;

close(code, data, mask, cb) {
var buf;
let buf;

@@ -243,4 +245,4 @@ if (code === undefined) {

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;

@@ -329,3 +331,3 @@ if (this._firstFragment) {

this._bufferedBytes -= params[1].length;
params[0].apply(this, params.slice(1));
Reflect.apply(params[0], this, params.slice(1));
}

@@ -332,0 +334,0 @@ }

'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 { format, parse } = require('./extension');
const { GUID } = require('./constants');

@@ -43,18 +43,16 @@

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
};

@@ -68,4 +66,4 @@ if (options.port == null && !options.server && !options.noServer) {

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];

@@ -213,3 +211,3 @@ res.writeHead(426, {

try {
const offers = extension.parse(req.headers['sec-websocket-extensions']);
const offers = parse(req.headers['sec-websocket-extensions']);

@@ -270,4 +268,3 @@ if (offers[PerMessageDeflate.extensionName]) {

const digest = crypto
.createHash('sha1')
const digest = createHash('sha1')
.update(key + GUID)

@@ -284,3 +281,3 @@ .digest('base64');

const ws = new WebSocket(null);
var protocol = req.headers['sec-websocket-protocol'];
let protocol = req.headers['sec-websocket-protocol'];

@@ -307,3 +304,3 @@ if (protocol) {

const params = extensions[PerMessageDeflate.extensionName].params;
const value = extension.format({
const value = format({
[PerMessageDeflate.extensionName]: [params]

@@ -385,14 +382,12 @@ });

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)

@@ -399,0 +394,0 @@ .map((h) => `${h}: ${headers[h]}`)

'use strict';
const EventEmitter = require('events');
const crypto = require('crypto');
const https = require('https');

@@ -9,7 +8,6 @@ const http = require('http');

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');

@@ -25,2 +23,5 @@ const Sender = require('./sender');

} = require('./constants');
const { addEventListener, removeEventListener } = require('./event-target');
const { format, parse } = require('./extension');
const { toBuffer } = require('./buffer-util');

@@ -40,3 +41,3 @@ const readyStates = ['CONNECTING', 'OPEN', 'CLOSING', 'CLOSED'];

*
* @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

@@ -63,2 +64,3 @@ * @param {Object} options Connection options

if (address !== null) {
this._bufferedAmount = 0;
this._isServer = false;

@@ -119,3 +121,3 @@ this._redirects = 0;

get bufferedAmount() {
if (!this._socket) return 0;
if (!this._socket) return this._bufferedAmount;

@@ -260,2 +262,6 @@ //

ping(data, mask, cb) {
if (this.readyState === WebSocket.CONNECTING) {
throw new Error('WebSocket is not open: readyState 0 (CONNECTING)');
}
if (typeof data === 'function') {

@@ -269,13 +275,9 @@ cb = data;

if (typeof data === 'number') data = data.toString();
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;
sendAfterClose(this, data, cb);
return;
}
if (typeof data === 'number') data = data.toString();
if (mask === undefined) mask = !this._isServer;

@@ -294,2 +296,6 @@ this._sender.ping(data || EMPTY_BUFFER, mask, cb);

pong(data, mask, cb) {
if (this.readyState === WebSocket.CONNECTING) {
throw new Error('WebSocket is not open: readyState 0 (CONNECTING)');
}
if (typeof data === 'function') {

@@ -303,13 +309,9 @@ cb = data;

if (typeof data === 'number') data = data.toString();
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;
sendAfterClose(this, data, cb);
return;
}
if (typeof data === 'number') data = data.toString();
if (mask === undefined) mask = !this._isServer;

@@ -324,3 +326,4 @@ this._sender.pong(data || EMPTY_BUFFER, mask, cb);

* @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

@@ -333,2 +336,6 @@ * @param {Boolean} options.fin Specifies whether the fragment is the last one

send(data, options, cb) {
if (this.readyState === WebSocket.CONNECTING) {
throw new Error('WebSocket is not open: readyState 0 (CONNECTING)');
}
if (typeof options === 'function') {

@@ -339,24 +346,17 @@ cb = options;

if (typeof data === 'number') data = data.toString();
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;
sendAfterClose(this, data, cb);
return;
}
if (typeof data === 'number') data = data.toString();
const opts = {
binary: typeof data !== 'string',
mask: !this._isServer,
compress: true,
fin: true,
...options
};
const opts = Object.assign(
{
binary: typeof data !== 'string',
mask: !this._isServer,
compress: true,
fin: true
},
options
);
if (!this._extensions[PerMessageDeflate.extensionName]) {

@@ -406,3 +406,3 @@ opts.compress = false;

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;

@@ -421,3 +421,3 @@ }

const listeners = this.listeners(method);
for (var i = 0; i < listeners.length; i++) {
for (let i = 0; i < listeners.length; i++) {
//

@@ -433,4 +433,4 @@ // Remove only the listeners added via `addEventListener`.

WebSocket.prototype.addEventListener = EventTarget.addEventListener;
WebSocket.prototype.removeEventListener = EventTarget.removeEventListener;
WebSocket.prototype.addEventListener = addEventListener;
WebSocket.prototype.removeEventListener = removeEventListener;

@@ -443,3 +443,3 @@ module.exports = WebSocket;

* @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

@@ -461,24 +461,20 @@ * @param {Object} options Connection options

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,
auth: undefined,
host: undefined,
path: undefined,
port: undefined
};

@@ -492,12 +488,9 @@ if (!protocolVersions.includes(opts.protocolVersion)) {

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;

@@ -515,8 +508,5 @@ }

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;

@@ -529,12 +519,10 @@ opts.createConnection = isSecure ? tlsConnect : netConnect;

: 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;

@@ -548,3 +536,3 @@

);
opts.headers['Sec-WebSocket-Extensions'] = extension.format({
opts.headers['Sec-WebSocket-Extensions'] = format({
[PerMessageDeflate.extensionName]: perMessageDeflate.offer()

@@ -563,5 +551,3 @@ });

}
if (parsedUrl.auth) {
opts.auth = parsedUrl.auth;
} else if (parsedUrl.username || parsedUrl.password) {
if (parsedUrl.username || parsedUrl.password) {
opts.auth = `${parsedUrl.username}:${parsedUrl.password}`;

@@ -571,3 +557,3 @@ }

if (isUnixSocket) {
const parts = path.split(':');
const parts = opts.path.split(':');

@@ -578,3 +564,3 @@ opts.socketPath = parts[0];

var req = (websocket._req = get(opts));
let req = (websocket._req = get(opts));

@@ -613,5 +599,3 @@ if (opts.timeout) {

const addr = url.URL
? new url.URL(location, address)
: url.resolve(address, location);
const addr = new URL(location, address);

@@ -639,4 +623,3 @@ initAsClient(websocket, addr, protocols, options);

const digest = crypto
.createHash('sha1')
const digest = createHash('sha1')
.update(key + GUID)

@@ -652,3 +635,3 @@ .digest('base64');

const protList = (protocols || '').split(/, */);
var protError;
let protError;

@@ -672,5 +655,3 @@ if (!protocols && serverProt) {

try {
const extensions = extension.parse(
res.headers['sec-websocket-extensions']
);
const extensions = parse(res.headers['sec-websocket-extensions']);

@@ -705,9 +686,3 @@ if (extensions[PerMessageDeflate.extensionName]) {

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);

@@ -756,2 +731,34 @@ }

/**
* 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.

@@ -758,0 +765,0 @@ *

{
"name": "ws",
"version": "6.2.1",
"version": "7.0.0",
"description": "Simple to use, blazing fast and thoroughly tested websocket client and server for Node.js",

@@ -28,19 +28,25 @@ "keywords": [

"integration": "npm run lint && mocha test/*.integration.js",
"lint": "eslint --ignore-path .gitignore . && prettier --check --ignore-path .gitignore \"**/*.{json,md,yml}\""
"lint": "eslint --ignore-path .gitignore . && prettier --check --ignore-path .gitignore \"**/*.{json,md,yaml,yml}\""
},
"dependencies": {
"async-limiter": "~1.0.0"
"async-limiter": "^1.0.0"
},
"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": "^5.16.0",
"eslint-config-prettier": "^4.1.0",
"eslint-plugin-prettier": "^3.0.1",
"mocha": "^6.1.3",
"nyc": "^14.0.0",
"prettier": "^1.17.0",
"utf-8-validate": "^5.0.2"
},
"greenkeeper": {
"commitMessages": {
"dependencyUpdate": "[pkg] Update ${dependency} to version ${version}",
"devDependencyUpdate": "[pkg] Update ${dependency} to version ${version}"
}
}
}

@@ -38,3 +38,2 @@ # ws: a Node.js WebSocket library

- [Other examples](#other-examples)
- [Error handling best practices](#error-handling-best-practices)
- [FAQ](#faq)

@@ -197,3 +196,3 @@ - [How to get the IP address of the client?](#how-to-get-the-ip-address-of-the-client)

const server = new https.createServer({
const server = https.createServer({
cert: fs.readFileSync('/path/to/cert.pem'),

@@ -314,26 +313,2 @@ key: fs.readFileSync('/path/to/key.pem')

## 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

@@ -340,0 +315,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc