Comparing version 6.1.1 to 6.1.2
'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" | ||
} | ||
} |
116
README.md
@@ -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 |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
101241
10
2802
450