Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

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.1.1 to 6.1.2

2

browser.js
'use strict';
module.exports = function () {
module.exports = function() {
throw new Error(

@@ -5,0 +5,0 @@ 'ws does not work in the browser. Browser clients must use the native ' +

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

*/
function concat (list, totalLength) {
function concat(list, totalLength) {
const target = Buffer.allocUnsafe(totalLength);

@@ -35,3 +35,3 @@ var offset = 0;

*/
function _mask (source, mask, output, offset, length) {
function _mask(source, mask, output, offset, length) {
for (var i = 0; i < length; i++) {

@@ -49,3 +49,3 @@ output[offset + i] = source[i] ^ mask[i & 3];

*/
function _unmask (buffer, mask) {
function _unmask(buffer, mask) {
// Required until https://github.com/nodejs/node/issues/9006 is resolved.

@@ -63,7 +63,7 @@ const length = buffer.length;

module.exports = {
mask (source, mask, output, offset, length) {
mask(source, mask, output, offset, length) {
if (length < 48) _mask(source, mask, output, offset, length);
else bu.mask(source, mask, output, offset, length);
},
unmask (buffer, mask) {
unmask(buffer, mask) {
if (buffer.length < 32) _unmask(buffer, mask);

@@ -70,0 +70,0 @@ else bu.unmask(buffer, mask);

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

*/
constructor (type, target) {
constructor(type, target) {
this.target = target;

@@ -35,3 +35,3 @@ this.type = type;

*/
constructor (data, target) {
constructor(data, target) {
super('message', target);

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

*/
constructor (code, reason, target) {
constructor(code, reason, target) {
super('close', target);

@@ -79,3 +79,3 @@

*/
constructor (target) {
constructor(target) {
super('open', target);

@@ -98,3 +98,3 @@ }

*/
constructor (error, target) {
constructor(error, target) {
super('error', target);

@@ -121,18 +121,18 @@

*/
addEventListener (method, listener) {
addEventListener(method, listener) {
if (typeof listener !== 'function') return;
function onMessage (data) {
function onMessage(data) {
listener.call(this, new MessageEvent(data, this));
}
function onClose (code, message) {
function onClose(code, message) {
listener.call(this, new CloseEvent(code, message, this));
}
function onError (error) {
function onError(error) {
listener.call(this, new ErrorEvent(error, this));
}
function onOpen () {
function onOpen() {
listener.call(this, new OpenEvent(this));

@@ -165,3 +165,3 @@ }

*/
removeEventListener (method, listener) {
removeEventListener(method, listener) {
const listeners = this.listeners(method);

@@ -168,0 +168,0 @@

@@ -14,2 +14,3 @@ 'use strict';

//
// prettier-ignore
const tokenChars = [

@@ -36,3 +37,3 @@ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0 - 15

*/
function push (dest, name, elem) {
function push(dest, name, elem) {
if (Object.prototype.hasOwnProperty.call(dest, name)) dest[name].push(elem);

@@ -49,3 +50,3 @@ else dest[name] = [elem];

*/
function parse (header) {
function parse(header) {
const offers = {};

@@ -70,5 +71,5 @@

if (start === -1) start = i;
} else if (code === 0x20/* ' ' */ || code === 0x09/* '\t' */) {
} else if (code === 0x20 /* ' ' */ || code === 0x09 /* '\t' */) {
if (end === -1 && start !== -1) end = i;
} else if (code === 0x3b/* ';' */ || code === 0x2c/* ',' */) {
} else if (code === 0x3b /* ';' */ || code === 0x2c /* ',' */) {
if (start === -1) {

@@ -110,3 +111,3 @@ throw new SyntaxError(`Unexpected character at index ${i}`);

start = end = -1;
} else if (code === 0x3d/* '=' */ && start !== -1 && end === -1) {
} else if (code === 0x3d /* '=' */ && start !== -1 && end === -1) {
paramName = header.slice(start, i);

@@ -133,6 +134,6 @@ start = end = -1;

if (start === -1) start = i;
} else if (code === 0x22/* '"' */ && start !== -1) {
} else if (code === 0x22 /* '"' */ && start !== -1) {
inQuotes = false;
end = i;
} else if (code === 0x5c/* '\' */) {
} else if (code === 0x5c /* '\' */) {
isEscaping = true;

@@ -203,16 +204,26 @@ } else {

*/
function format (extensions) {
return Object.keys(extensions).map((extension) => {
var 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];
if (!Array.isArray(values)) values = [values];
return values.map((v) => v === true ? k : `${k}=${v}`).join('; ');
})).join('; ');
}).join(', ');
}).join(', ');
function format(extensions) {
return Object.keys(extensions)
.map((extension) => {
var 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];
if (!Array.isArray(values)) values = [values];
return values
.map((v) => (v === true ? k : `${k}=${v}`))
.join('; ');
})
)
.join('; ');
})
.join(', ');
})
.join(', ');
}
module.exports = { format, parse };

@@ -55,8 +55,7 @@ 'use strict';

*/
constructor (options, isServer, maxPayload) {
constructor(options, isServer, maxPayload) {
this._maxPayload = maxPayload | 0;
this._options = options || {};
this._threshold = this._options.threshold !== undefined
? this._options.threshold
: 1024;
this._threshold =
this._options.threshold !== undefined ? this._options.threshold : 1024;
this._isServer = !!isServer;

@@ -69,5 +68,6 @@ this._deflate = null;

if (!zlibLimiter) {
const concurrency = this._options.concurrencyLimit !== undefined
? this._options.concurrencyLimit
: 10;
const concurrency =
this._options.concurrencyLimit !== undefined
? this._options.concurrencyLimit
: 10;
zlibLimiter = new Limiter({ concurrency });

@@ -80,3 +80,3 @@ }

*/
static get extensionName () {
static get extensionName() {
return 'permessage-deflate';

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

*/
offer () {
offer() {
const params = {};

@@ -120,3 +120,3 @@

*/
accept (configurations) {
accept(configurations) {
configurations = this.normalizeParams(configurations);

@@ -136,3 +136,3 @@

*/
cleanup () {
cleanup() {
if (this._inflate) {

@@ -163,3 +163,3 @@ if (this._inflate[kWriteInProgress]) {

*/
acceptAsServer (offers) {
acceptAsServer(offers) {
const opts = this._options;

@@ -215,3 +215,3 @@ const accepted = offers.find((params) => {

*/
acceptAsClient (response) {
acceptAsClient(response) {
const params = response[0];

@@ -250,3 +250,3 @@

*/
normalizeParams (configurations) {
normalizeParams(configurations) {
configurations.forEach((params) => {

@@ -312,3 +312,3 @@ Object.keys(params).forEach((key) => {

*/
decompress (data, fin, callback) {
decompress(data, fin, callback) {
zlibLimiter.push((done) => {

@@ -330,3 +330,3 @@ this._decompress(data, fin, (err, result) => {

*/
compress (data, fin, callback) {
compress(data, fin, callback) {
zlibLimiter.push((done) => {

@@ -348,3 +348,3 @@ this._compress(data, fin, (err, result) => {

*/
_decompress (data, fin, callback) {
_decompress(data, fin, callback) {
const endpoint = this._isServer ? 'client' : 'server';

@@ -354,5 +354,6 @@

const key = `${endpoint}_max_window_bits`;
const windowBits = typeof this.params[key] !== 'number'
? zlib.Z_DEFAULT_WINDOWBITS
: this.params[key];
const windowBits =
typeof this.params[key] !== 'number'
? zlib.Z_DEFAULT_WINDOWBITS
: this.params[key];

@@ -414,3 +415,3 @@ this._inflate = zlib.createInflateRaw(

*/
_compress (data, fin, callback) {
_compress(data, fin, callback) {
if (!data || data.length === 0) {

@@ -425,5 +426,6 @@ process.nextTick(callback, null, EMPTY_BLOCK);

const key = `${endpoint}_max_window_bits`;
const windowBits = typeof this.params[key] !== 'number'
? zlib.Z_DEFAULT_WINDOWBITS
: this.params[key];
const windowBits =
typeof this.params[key] !== 'number'
? zlib.Z_DEFAULT_WINDOWBITS
: this.params[key];

@@ -481,3 +483,3 @@ this._deflate = zlib.createDeflateRaw(

*/
function deflateOnData (chunk) {
function deflateOnData(chunk) {
this[kBuffers].push(chunk);

@@ -493,3 +495,3 @@ this[kTotalLength] += chunk.length;

*/
function inflateOnData (chunk) {
function inflateOnData(chunk) {
this[kTotalLength] += chunk.length;

@@ -517,3 +519,3 @@

*/
function inflateOnError (err) {
function inflateOnError(err) {
//

@@ -520,0 +522,0 @@ // There is no need to call `Zlib#close()` as the handle is automatically

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

*/
constructor (binaryType, extensions, maxPayload) {
constructor(binaryType, extensions, maxPayload) {
super();

@@ -65,3 +65,3 @@

*/
_write (chunk, encoding, cb) {
_write(chunk, encoding, cb) {
if (this._opcode === 0x08) return cb();

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

*/
consume (n) {
consume(n) {
this._bufferedBytes -= n;

@@ -117,3 +117,3 @@

*/
startLoop (cb) {
startLoop(cb) {
var err;

@@ -139,3 +139,4 @@ this._loop = true;

break;
default: // `INFLATING`
default:
// `INFLATING`
this._loop = false;

@@ -155,3 +156,3 @@ return;

*/
getInfo () {
getInfo() {
if (this._bufferedBytes < 2) {

@@ -238,3 +239,3 @@ this._loop = false;

*/
getPayloadLength16 () {
getPayloadLength16() {
if (this._bufferedBytes < 2) {

@@ -255,3 +256,3 @@ this._loop = false;

*/
getPayloadLength64 () {
getPayloadLength64() {
if (this._bufferedBytes < 8) {

@@ -289,3 +290,3 @@ this._loop = false;

*/
haveLength () {
haveLength() {
if (this._payloadLength && this._opcode < 0x08) {

@@ -308,3 +309,3 @@ this._totalPayloadLength += this._payloadLength;

*/
getMask () {
getMask() {
if (this._bufferedBytes < 4) {

@@ -326,3 +327,3 @@ this._loop = false;

*/
getData (cb) {
getData(cb) {
var data = constants.EMPTY_BUFFER;

@@ -367,3 +368,3 @@

*/
decompress (data, cb) {
decompress(data, cb) {
const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName];

@@ -377,3 +378,5 @@

if (this._messageLength > this._maxPayload && this._maxPayload > 0) {
return cb(error(RangeError, 'Max payload size exceeded', false, 1009));
return cb(
error(RangeError, 'Max payload size exceeded', false, 1009)
);
}

@@ -397,3 +400,3 @@

*/
dataMessage () {
dataMessage() {
if (this._fin) {

@@ -442,3 +445,3 @@ const messageLength = this._messageLength;

*/
controlMessage (data) {
controlMessage(data) {
if (this._opcode === 0x08) {

@@ -492,3 +495,3 @@ this._loop = false;

*/
function error (ErrorCtor, message, prefix, statusCode) {
function error(ErrorCtor, message, prefix, statusCode) {
const err = new ErrorCtor(

@@ -511,3 +514,3 @@ prefix ? `Invalid WebSocket frame: ${message}` : message

*/
function toBuffer (fragments, messageLength) {
function toBuffer(fragments, messageLength) {
if (fragments.length === 1) return fragments[0];

@@ -524,3 +527,3 @@ if (fragments.length > 1) return bufferUtil.concat(fragments, messageLength);

*/
function toArrayBuffer (buf) {
function toArrayBuffer(buf) {
if (buf.byteOffset === 0 && buf.byteLength === buf.buffer.byteLength) {

@@ -527,0 +530,0 @@ return buf.buffer;

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

*/
constructor (socket, extensions) {
constructor(socket, extensions) {
this._extensions = extensions || {};

@@ -46,3 +46,3 @@ this._socket = socket;

*/
static frame (data, options) {
static frame(data, options) {
const merge = data.length < 1024 || (options.mask && options.readOnly);

@@ -108,3 +108,3 @@ var offset = options.mask ? 6 : 2;

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

@@ -114,3 +114,6 @@

buf = constants.EMPTY_BUFFER;
} else if (typeof code !== 'number' || !validation.isValidStatusCode(code)) {
} else if (
typeof code !== 'number' ||
!validation.isValidStatusCode(code)
) {
throw new TypeError('First argument must be a valid error code number');

@@ -141,10 +144,13 @@ } else if (data === undefined || data === '') {

*/
doClose (data, mask, cb) {
this.sendFrame(Sender.frame(data, {
fin: true,
rsv1: false,
opcode: 0x08,
mask,
readOnly: false
}), cb);
doClose(data, mask, cb) {
this.sendFrame(
Sender.frame(data, {
fin: true,
rsv1: false,
opcode: 0x08,
mask,
readOnly: false
}),
cb
);
}

@@ -160,3 +166,3 @@

*/
ping (data, mask, cb) {
ping(data, mask, cb) {
var readOnly = true;

@@ -191,10 +197,13 @@

*/
doPing (data, mask, readOnly, cb) {
this.sendFrame(Sender.frame(data, {
fin: true,
rsv1: false,
opcode: 0x09,
mask,
readOnly
}), cb);
doPing(data, mask, readOnly, cb) {
this.sendFrame(
Sender.frame(data, {
fin: true,
rsv1: false,
opcode: 0x09,
mask,
readOnly
}),
cb
);
}

@@ -210,3 +219,3 @@

*/
pong (data, mask, cb) {
pong(data, mask, cb) {
var readOnly = true;

@@ -241,10 +250,13 @@

*/
doPong (data, mask, readOnly, cb) {
this.sendFrame(Sender.frame(data, {
fin: true,
rsv1: false,
opcode: 0x0a,
mask,
readOnly
}), cb);
doPong(data, mask, readOnly, cb) {
this.sendFrame(
Sender.frame(data, {
fin: true,
rsv1: false,
opcode: 0x0a,
mask,
readOnly
}),
cb
);
}

@@ -264,3 +276,3 @@

*/
send (data, options, cb) {
send(data, options, cb) {
var opcode = options.binary ? 2 : 1;

@@ -311,9 +323,12 @@ var rsv1 = options.compress;

} else {
this.sendFrame(Sender.frame(data, {
fin: options.fin,
rsv1: false,
opcode,
mask: options.mask,
readOnly
}), cb);
this.sendFrame(
Sender.frame(data, {
fin: options.fin,
rsv1: false,
opcode,
mask: options.mask,
readOnly
}),
cb
);
}

@@ -336,3 +351,3 @@ }

*/
dispatch (data, compress, options, cb) {
dispatch(data, compress, options, cb) {
if (!compress) {

@@ -369,3 +384,3 @@ this.sendFrame(Sender.frame(data, options), cb);

*/
dequeue () {
dequeue() {
while (!this._deflating && this._queue.length) {

@@ -385,3 +400,3 @@ const params = this._queue.shift();

*/
enqueue (params) {
enqueue(params) {
this._bufferedBytes += params[1].length;

@@ -398,3 +413,3 @@ this._queue.push(params);

*/
sendFrame (list, cb) {
sendFrame(list, cb) {
if (list.length === 2) {

@@ -418,3 +433,3 @@ this._socket.write(list[0]);

*/
function viewToBuffer (view) {
function viewToBuffer(view) {
const buf = Buffer.from(view.buffer);

@@ -421,0 +436,0 @@

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

exports.isValidUTF8 = typeof isValidUTF8 === 'object'
? isValidUTF8.Validation.isValidUTF8 // utf-8-validate@<3.0.0
: isValidUTF8;
exports.isValidUTF8 =
typeof isValidUTF8 === 'object'
? isValidUTF8.Validation.isValidUTF8 // utf-8-validate@<3.0.0
: isValidUTF8;
} catch (e) /* istanbul ignore next */ {

@@ -11,0 +12,0 @@ exports.isValidUTF8 = () => true;

@@ -34,18 +34,21 @@ 'use strict';

*/
constructor (options, callback) {
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 = 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
);

@@ -68,3 +71,8 @@ if (options.port == null && !options.server && !options.noServer) {

});
this._server.listen(options.port, options.host, options.backlog, callback);
this._server.listen(
options.port,
options.host,
options.backlog,
callback
);
} else if (options.server) {

@@ -100,3 +108,3 @@ this._server = options.server;

*/
address () {
address() {
if (this.options.noServer) {

@@ -116,3 +124,3 @@ throw new Error('The server is operating in "noServer" mode');

*/
close (cb) {
close(cb) {
if (cb) this.once('close', cb);

@@ -152,3 +160,3 @@

*/
shouldHandle (req) {
shouldHandle(req) {
if (this.options.path) {

@@ -173,3 +181,3 @@ const index = req.url.indexOf('?');

*/
handleUpgrade (req, socket, head, cb) {
handleUpgrade(req, socket, head, cb) {
socket.on('error', socketOnError);

@@ -181,4 +189,6 @@

if (
req.method !== 'GET' || req.headers.upgrade.toLowerCase() !== 'websocket' ||
!req.headers['sec-websocket-key'] || (version !== 8 && version !== 13) ||
req.method !== 'GET' ||
req.headers.upgrade.toLowerCase() !== 'websocket' ||
!req.headers['sec-websocket-key'] ||
(version !== 8 && version !== 13) ||
!this.shouldHandle(req)

@@ -197,5 +207,3 @@ ) {

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

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

const info = {
origin: req.headers[`${version === 8 ? 'sec-websocket-origin' : 'origin'}`],
origin:
req.headers[`${version === 8 ? 'sec-websocket-origin' : 'origin'}`],
secure: !!(req.connection.authorized || req.connection.encrypted),

@@ -249,3 +258,3 @@ req

*/
completeUpgrade (extensions, req, socket, head, cb) {
completeUpgrade(extensions, req, socket, head, cb) {
//

@@ -256,3 +265,4 @@ // Destroy the socket if the client has already sent a FIN packet.

const key = crypto.createHash('sha1')
const key = crypto
.createHash('sha1')
.update(req.headers['sec-websocket-key'] + constants.GUID, 'binary')

@@ -328,6 +338,6 @@ .digest('base64');

*/
function addListeners (server, map) {
function addListeners(server, map) {
for (const event of Object.keys(map)) server.on(event, map[event]);
return function removeListeners () {
return function removeListeners() {
for (const event of Object.keys(map)) {

@@ -345,3 +355,3 @@ server.removeListener(event, map[event]);

*/
function emitClose (server) {
function emitClose(server) {
server.emit('close');

@@ -355,3 +365,3 @@ }

*/
function socketOnError () {
function socketOnError() {
this.destroy();

@@ -369,16 +379,21 @@ }

*/
function abortHandshake (socket, code, message, headers) {
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);
headers = Object.assign(
{
Connection: 'close',
'Content-type': 'text/html',
'Content-Length': Buffer.byteLength(message)
},
headers
);
socket.write(
`HTTP/1.1 ${code} ${http.STATUS_CODES[code]}\r\n` +
Object.keys(headers).map(h => `${h}: ${headers[h]}`).join('\r\n') +
'\r\n\r\n' +
message
Object.keys(headers)
.map((h) => `${h}: ${headers[h]}`)
.join('\r\n') +
'\r\n\r\n' +
message
);

@@ -385,0 +400,0 @@ }

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

const tls = require('tls');
const { URL } = require('url');
const url = require('url');

@@ -37,3 +37,3 @@ const PerMessageDeflate = require('./permessage-deflate');

*/
constructor (address, protocols, options) {
constructor(address, protocols, options) {
super();

@@ -68,6 +68,14 @@

get CONNECTING () { return WebSocket.CONNECTING; }
get CLOSING () { return WebSocket.CLOSING; }
get CLOSED () { return WebSocket.CLOSED; }
get OPEN () { return WebSocket.OPEN; }
get CONNECTING() {
return WebSocket.CONNECTING;
}
get CLOSING() {
return WebSocket.CLOSING;
}
get CLOSED() {
return WebSocket.CLOSED;
}
get OPEN() {
return WebSocket.OPEN;
}

@@ -80,7 +88,7 @@ /**

*/
get binaryType () {
get binaryType() {
return this._binaryType;
}
set binaryType (type) {
set binaryType(type) {
if (constants.BINARY_TYPES.indexOf(type) < 0) return;

@@ -99,3 +107,3 @@

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

@@ -112,3 +120,3 @@

*/
get extensions () {
get extensions() {
return Object.keys(this._extensions).join();

@@ -125,3 +133,3 @@ }

*/
setSocket (socket, head, maxPayload) {
setSocket(socket, head, maxPayload) {
const receiver = new Receiver(

@@ -166,3 +174,3 @@ this._binaryType,

*/
emitClose () {
emitClose() {
this.readyState = WebSocket.CLOSED;

@@ -202,3 +210,3 @@

*/
close (code, data) {
close(code, data) {
if (this.readyState === WebSocket.CLOSED) return;

@@ -248,3 +256,3 @@ if (this.readyState === WebSocket.CONNECTING) {

*/
ping (data, mask, cb) {
ping(data, mask, cb) {
if (typeof data === 'function') {

@@ -281,3 +289,3 @@ cb = data;

*/
pong (data, mask, cb) {
pong(data, mask, cb) {
if (typeof data === 'function') {

@@ -318,3 +326,3 @@ cb = data;

*/
send (data, options, cb) {
send(data, options, cb) {
if (typeof options === 'function') {

@@ -337,8 +345,11 @@ cb = options;

const opts = Object.assign({
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
);

@@ -357,3 +368,3 @@ if (!this._extensions[PerMessageDeflate.extensionName]) {

*/
terminate () {
terminate() {
if (this.readyState === WebSocket.CLOSED) return;

@@ -388,3 +399,3 @@ if (this.readyState === WebSocket.CONNECTING) {

*/
get () {
get() {
const listeners = this.listeners(method);

@@ -394,2 +405,4 @@ for (var i = 0; i < listeners.length; i++) {

}
return undefined;
},

@@ -402,3 +415,3 @@ /**

*/
set (listener) {
set(listener) {
const listeners = this.listeners(method);

@@ -434,19 +447,23 @@ for (var i = 0; i < listeners.length; i++) {

*/
function initAsClient (address, protocols, options) {
options = Object.assign({
protocolVersion: protocolVersions[1],
perMessageDeflate: true,
maxPayload: 100 * 1024 * 1024
}, options, {
createConnection: undefined,
socketPath: undefined,
hostname: undefined,
protocol: undefined,
timeout: undefined,
method: undefined,
auth: undefined,
host: undefined,
path: undefined,
port: undefined
});
function initAsClient(address, protocols, options) {
options = Object.assign(
{
protocolVersion: protocolVersions[1],
perMessageDeflate: true,
maxPayload: 100 * 1024 * 1024
},
options,
{
createConnection: undefined,
socketPath: undefined,
hostname: undefined,
protocol: undefined,
timeout: undefined,
method: undefined,
auth: undefined,
host: undefined,
path: undefined,
port: undefined
}
);

@@ -468,3 +485,6 @@ if (protocolVersions.indexOf(options.protocolVersion) === -1) {

} else {
parsedUrl = new URL(address);
//
// The WHATWG URL constructor is not available on Node.js < 6.13.0
//
parsedUrl = url.URL ? new url.URL(address) : url.parse(address);
this.url = address;

@@ -479,3 +499,4 @@ }

const isSecure = parsedUrl.protocol === 'wss:' || parsedUrl.protocol === 'https:';
const isSecure =
parsedUrl.protocol === 'wss:' || parsedUrl.protocol === 'https:';
const key = crypto.randomBytes(16).toString('base64');

@@ -493,8 +514,11 @@ const httpObj = isSecure ? https : http;

: parsedUrl.hostname;
options.headers = Object.assign({
'Sec-WebSocket-Version': options.protocolVersion,
'Sec-WebSocket-Key': key,
'Connection': 'Upgrade',
'Upgrade': 'websocket'
}, options.headers);
options.headers = Object.assign(
{
'Sec-WebSocket-Version': options.protocolVersion,
'Sec-WebSocket-Key': key,
Connection: 'Upgrade',
Upgrade: 'websocket'
},
options.headers
);
options.path = path;

@@ -535,8 +559,7 @@

var req = this._req = httpObj.get(options);
var req = (this._req = httpObj.get(options));
if (options.handshakeTimeout) {
req.setTimeout(
options.handshakeTimeout,
() => abortHandshake(this, req, 'Opening handshake has timed out')
req.setTimeout(options.handshakeTimeout, () =>
abortHandshake(this, req, 'Opening handshake has timed out')
);

@@ -571,3 +594,4 @@ }

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

@@ -607,5 +631,3 @@ .digest('base64');

if (extensions[PerMessageDeflate.extensionName]) {
perMessageDeflate.accept(
extensions[PerMessageDeflate.extensionName]
);
perMessageDeflate.accept(extensions[PerMessageDeflate.extensionName]);
this._extensions[PerMessageDeflate.extensionName] = perMessageDeflate;

@@ -630,3 +652,3 @@ }

*/
function netConnect (options) {
function netConnect(options) {
//

@@ -649,3 +671,3 @@ // Override `options.path` only if `options` is a copy of the original options

*/
function tlsConnect (options) {
function tlsConnect(options) {
options.path = undefined;

@@ -665,3 +687,3 @@ options.servername = options.servername || options.host;

*/
function abortHandshake (websocket, stream, message) {
function abortHandshake(websocket, stream, message) {
websocket.readyState = WebSocket.CLOSING;

@@ -690,3 +712,3 @@

*/
function receiverOnConclude (code, reason) {
function receiverOnConclude(code, reason) {
const websocket = this[kWebSocket];

@@ -710,3 +732,3 @@

*/
function receiverOnDrain () {
function receiverOnDrain() {
this[kWebSocket]._socket.resume();

@@ -721,3 +743,3 @@ }

*/
function receiverOnError (err) {
function receiverOnError(err) {
const websocket = this[kWebSocket];

@@ -738,3 +760,3 @@

*/
function receiverOnFinish () {
function receiverOnFinish() {
this[kWebSocket].emitClose();

@@ -749,3 +771,3 @@ }

*/
function receiverOnMessage (data) {
function receiverOnMessage(data) {
this[kWebSocket].emit('message', data);

@@ -760,3 +782,3 @@ }

*/
function receiverOnPing (data) {
function receiverOnPing(data) {
const websocket = this[kWebSocket];

@@ -774,3 +796,3 @@

*/
function receiverOnPong (data) {
function receiverOnPong(data) {
this[kWebSocket].emit('pong', data);

@@ -784,3 +806,3 @@ }

*/
function socketOnClose () {
function socketOnClose() {
const websocket = this[kWebSocket];

@@ -828,3 +850,3 @@

*/
function socketOnData (chunk) {
function socketOnData(chunk) {
if (!this[kWebSocket]._receiver.write(chunk)) {

@@ -840,3 +862,3 @@ this.pause();

*/
function socketOnEnd () {
function socketOnEnd() {
const websocket = this[kWebSocket];

@@ -854,3 +876,3 @@

*/
function socketOnError () {
function socketOnError() {
const websocket = this[kWebSocket];

@@ -857,0 +879,0 @@

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

@@ -26,5 +26,5 @@ "keywords": [

"scripts": {
"test": "eslint . && nyc --reporter=html --reporter=text mocha test/*.test.js",
"integration": "eslint . && mocha test/*.integration.js",
"lint": "eslint ."
"test": "npm run lint && nyc --reporter=html --reporter=text mocha test/*.test.js",
"integration": "npm run lint && mocha test/*.integration.js",
"lint": "eslint . --ignore-path .gitignore && prettylint '**/*.{json,md}' --ignore-path .gitignore"
},

@@ -38,11 +38,10 @@ "dependencies": {

"eslint": "~5.9.0",
"eslint-config-standard": "~12.0.0",
"eslint-plugin-import": "~2.14.0",
"eslint-plugin-node": "~8.0.0",
"eslint-plugin-promise": "~4.0.1",
"eslint-plugin-standard": "~4.0.0",
"eslint-config-prettier": "~3.3.0",
"eslint-plugin-prettier": "~3.0.0",
"mocha": "~5.2.0",
"nyc": "~13.1.0",
"prettier": "~1.15.2",
"prettylint": "~1.0.0",
"utf-8-validate": "~5.0.0"
}
}

@@ -8,4 +8,4 @@ # ws: a Node.js WebSocket library

ws is a simple to use, blazing fast, and thoroughly tested WebSocket client
and server implementation.
ws is a simple to use, blazing fast, and thoroughly tested WebSocket client and
server implementation.

@@ -18,5 +18,5 @@ Passes the quite extensive Autobahn test suite: [server][server-report],

communication. Browser clients must use the native
[`WebSocket`](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket) object.
To make the same code work seamlessly on Node.js and the browser, you can use
one of the many wrappers available on npm, like
[`WebSocket`](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket)
object. To make the same code work seamlessly on Node.js and the browser, you
can use one of the many wrappers available on npm, like
[isomorphic-ws](https://github.com/heineiuo/isomorphic-ws).

@@ -26,28 +26,29 @@

* [Protocol support](#protocol-support)
* [Installing](#installing)
+ [Opt-in for performance and spec compliance](#opt-in-for-performance-and-spec-compliance)
* [API docs](#api-docs)
* [WebSocket compression](#websocket-compression)
* [Usage examples](#usage-examples)
+ [Sending and receiving text data](#sending-and-receiving-text-data)
+ [Sending binary data](#sending-binary-data)
+ [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)
+ [Server broadcast](#server-broadcast)
+ [echo.websocket.org demo](#echowebsocketorg-demo)
+ [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)
+ [How to connect via a proxy?](#how-to-connect-via-a-proxy)
* [Changelog](#changelog)
* [License](#license)
- [Protocol support](#protocol-support)
- [Installing](#installing)
- [Opt-in for performance and spec compliance](#opt-in-for-performance-and-spec-compliance)
- [API docs](#api-docs)
- [WebSocket compression](#websocket-compression)
- [Usage examples](#usage-examples)
- [Sending and receiving text data](#sending-and-receiving-text-data)
- [Sending binary data](#sending-binary-data)
- [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)
- [Server broadcast](#server-broadcast)
- [echo.websocket.org demo](#echowebsocketorg-demo)
- [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)
- [How to connect via a proxy?](#how-to-connect-via-a-proxy)
- [Changelog](#changelog)
- [License](#license)
## Protocol support
* **HyBi drafts 07-12** (Use the option `protocolVersion: 8`)
* **HyBi drafts 13-17** (Current default, alternatively option `protocolVersion: 13`)
- **HyBi drafts 07-12** (Use the option `protocolVersion: 8`)
- **HyBi drafts 13-17** (Current default, alternatively option
`protocolVersion: 13`)

@@ -70,4 +71,4 @@ ## Installing

frames.
- `npm install --save-optional utf-8-validate`: Allows to efficiently check
if a message contains valid UTF-8 as required by the spec.
- `npm install --save-optional utf-8-validate`: Allows to efficiently check if a
message contains valid UTF-8 as required by the spec.

@@ -80,17 +81,16 @@ ## API docs

ws supports the [permessage-deflate extension][permessage-deflate] which
enables the client and server to negotiate a compression algorithm and its
parameters, and then selectively apply it to the data payloads of each
WebSocket message.
ws supports the [permessage-deflate extension][permessage-deflate] which enables
the client and server to negotiate a compression algorithm and its parameters,
and then selectively apply it to the data payloads of each WebSocket message.
The extension is disabled by default on the server and enabled by default on
the client. It adds a significant overhead in terms of performance and memory
The extension is disabled by default on the server and enabled by default on the
client. It adds a significant overhead in terms of performance and memory
consumption so we suggest to enable it only if it is really needed.
Note that Node.js has a variety of issues with high-performance compression,
where increased concurrency, especially on Linux, can lead to
[catastrophic memory fragmentation][node-zlib-bug] and slow performance.
If you intend to use permessage-deflate in production, it is worthwhile to set
up a test representative of your workload and ensure Node.js/zlib will handle
it with acceptable performance and memory usage.
where increased concurrency, especially on Linux, can lead to [catastrophic
memory fragmentation][node-zlib-bug] and slow performance. If you intend to use
permessage-deflate in production, it is worthwhile to set up a test
representative of your workload and ensure Node.js/zlib will handle it with
acceptable performance and memory usage.

@@ -109,6 +109,7 @@ Tuning of permessage-deflate can be done via the options defined below. You can

perMessageDeflate: {
zlibDeflateOptions: { // See zlib defaults.
zlibDeflateOptions: {
// See zlib defaults.
chunkSize: 1024,
memLevel: 7,
level: 3,
level: 3
},

@@ -121,7 +122,7 @@ zlibInflateOptions: {

serverNoContextTakeover: true, // Defaults to negotiated value.
serverMaxWindowBits: 10, // Defaults to negotiated value.
serverMaxWindowBits: 10, // Defaults to negotiated value.
// Below options specified as default values.
concurrencyLimit: 10, // Limits zlib concurrency for perf.
threshold: 1024, // Size (in bytes) below which messages
// should not be compressed.
concurrencyLimit: 10, // Limits zlib concurrency for perf.
threshold: 1024 // Size (in bytes) below which messages
// should not be compressed.
}

@@ -335,4 +336,7 @@ });

// captured when this technique is used.
try { ws.send('something'); }
catch (e) { /* handle error */ }
try {
ws.send('something');
} catch (e) {
/* handle error */
}
```

@@ -367,4 +371,4 @@

Sometimes the link between the server and the client can be interrupted in a
way that keeps both the server and the client unaware of the broken state of the
Sometimes the link between the server and the client can be interrupted in a way
that keeps both the server and the client unaware of the broken state of the
connection (e.g. when pulling the cord).

@@ -401,4 +405,4 @@

Pong messages are automatically sent in response to ping messages as required
by the spec.
Pong messages are automatically sent in response to ping messages as required by
the spec.

@@ -452,3 +456,5 @@ Just like the server example above your clients might as well lose connection

[node-zlib-bug]: https://github.com/nodejs/node/issues/8871
[node-zlib-deflaterawdocs]: https://nodejs.org/api/zlib.html#zlib_zlib_createdeflateraw_options
[ws-server-options]: https://github.com/websockets/ws/blob/master/doc/ws.md#new-websocketserveroptions-callback
[node-zlib-deflaterawdocs]:
https://nodejs.org/api/zlib.html#zlib_zlib_createdeflateraw_options
[ws-server-options]:
https://github.com/websockets/ws/blob/master/doc/ws.md#new-websocketserveroptions-callback
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