rtsp2web 2.4.5 → 2.4.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"rtsp2web.min.js","sources":["../node_modules/base-64/base64.js","../node_modules/ws/lib/constants.js","../node_modules/ws/lib/buffer-util.js","../node_modules/ws/lib/limiter.js","../node_modules/ws/lib/permessage-deflate.js","../node_modules/ws/lib/validation.js","../node_modules/ws/lib/receiver.js","../node_modules/ws/lib/sender.js","../node_modules/ws/lib/event-target.js","../node_modules/ws/lib/extension.js","../node_modules/ws/lib/websocket.js","../node_modules/ws/lib/stream.js","../node_modules/ws/lib/subprotocol.js","../node_modules/ws/lib/websocket-server.js","../node_modules/ws/index.js","../main.js"],"sourcesContent":["/*! https://mths.be/base64 v1.0.0 by @mathias | MIT license */\n;(function(root) {\n\n\t// Detect free variables `exports`.\n\tvar freeExports = typeof exports == 'object' && exports;\n\n\t// Detect free variable `module`.\n\tvar freeModule = typeof module == 'object' && module &&\n\t\tmodule.exports == freeExports && module;\n\n\t// Detect free variable `global`, from Node.js or Browserified code, and use\n\t// it as `root`.\n\tvar freeGlobal = typeof global == 'object' && global;\n\tif (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) {\n\t\troot = freeGlobal;\n\t}\n\n\t/*--------------------------------------------------------------------------*/\n\n\tvar InvalidCharacterError = function(message) {\n\t\tthis.message = message;\n\t};\n\tInvalidCharacterError.prototype = new Error;\n\tInvalidCharacterError.prototype.name = 'InvalidCharacterError';\n\n\tvar error = function(message) {\n\t\t// Note: the error messages used throughout this file match those used by\n\t\t// the native `atob`/`btoa` implementation in Chromium.\n\t\tthrow new InvalidCharacterError(message);\n\t};\n\n\tvar TABLE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n\t// http://whatwg.org/html/common-microsyntaxes.html#space-character\n\tvar REGEX_SPACE_CHARACTERS = /[\\t\\n\\f\\r ]/g;\n\n\t// `decode` is designed to be fully compatible with `atob` as described in the\n\t// HTML Standard. http://whatwg.org/html/webappapis.html#dom-windowbase64-atob\n\t// The optimized base64-decoding algorithm used is based on @atk’s excellent\n\t// implementation. https://gist.github.com/atk/1020396\n\tvar decode = function(input) {\n\t\tinput = String(input)\n\t\t\t.replace(REGEX_SPACE_CHARACTERS, '');\n\t\tvar length = input.length;\n\t\tif (length % 4 == 0) {\n\t\t\tinput = input.replace(/==?$/, '');\n\t\t\tlength = input.length;\n\t\t}\n\t\tif (\n\t\t\tlength % 4 == 1 ||\n\t\t\t// http://whatwg.org/C#alphanumeric-ascii-characters\n\t\t\t/[^+a-zA-Z0-9/]/.test(input)\n\t\t) {\n\t\t\terror(\n\t\t\t\t'Invalid character: the string to be decoded is not correctly encoded.'\n\t\t\t);\n\t\t}\n\t\tvar bitCounter = 0;\n\t\tvar bitStorage;\n\t\tvar buffer;\n\t\tvar output = '';\n\t\tvar position = -1;\n\t\twhile (++position < length) {\n\t\t\tbuffer = TABLE.indexOf(input.charAt(position));\n\t\t\tbitStorage = bitCounter % 4 ? bitStorage * 64 + buffer : buffer;\n\t\t\t// Unless this is the first of a group of 4 characters…\n\t\t\tif (bitCounter++ % 4) {\n\t\t\t\t// …convert the first 8 bits to a single ASCII character.\n\t\t\t\toutput += String.fromCharCode(\n\t\t\t\t\t0xFF & bitStorage >> (-2 * bitCounter & 6)\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\treturn output;\n\t};\n\n\t// `encode` is designed to be fully compatible with `btoa` as described in the\n\t// HTML Standard: http://whatwg.org/html/webappapis.html#dom-windowbase64-btoa\n\tvar encode = function(input) {\n\t\tinput = String(input);\n\t\tif (/[^\\0-\\xFF]/.test(input)) {\n\t\t\t// Note: no need to special-case astral symbols here, as surrogates are\n\t\t\t// matched, and the input is supposed to only contain ASCII anyway.\n\t\t\terror(\n\t\t\t\t'The string to be encoded contains characters outside of the ' +\n\t\t\t\t'Latin1 range.'\n\t\t\t);\n\t\t}\n\t\tvar padding = input.length % 3;\n\t\tvar output = '';\n\t\tvar position = -1;\n\t\tvar a;\n\t\tvar b;\n\t\tvar c;\n\t\tvar buffer;\n\t\t// Make sure any padding is handled outside of the loop.\n\t\tvar length = input.length - padding;\n\n\t\twhile (++position < length) {\n\t\t\t// Read three bytes, i.e. 24 bits.\n\t\t\ta = input.charCodeAt(position) << 16;\n\t\t\tb = input.charCodeAt(++position) << 8;\n\t\t\tc = input.charCodeAt(++position);\n\t\t\tbuffer = a + b + c;\n\t\t\t// Turn the 24 bits into four chunks of 6 bits each, and append the\n\t\t\t// matching character for each of them to the output.\n\t\t\toutput += (\n\t\t\t\tTABLE.charAt(buffer >> 18 & 0x3F) +\n\t\t\t\tTABLE.charAt(buffer >> 12 & 0x3F) +\n\t\t\t\tTABLE.charAt(buffer >> 6 & 0x3F) +\n\t\t\t\tTABLE.charAt(buffer & 0x3F)\n\t\t\t);\n\t\t}\n\n\t\tif (padding == 2) {\n\t\t\ta = input.charCodeAt(position) << 8;\n\t\t\tb = input.charCodeAt(++position);\n\t\t\tbuffer = a + b;\n\t\t\toutput += (\n\t\t\t\tTABLE.charAt(buffer >> 10) +\n\t\t\t\tTABLE.charAt((buffer >> 4) & 0x3F) +\n\t\t\t\tTABLE.charAt((buffer << 2) & 0x3F) +\n\t\t\t\t'='\n\t\t\t);\n\t\t} else if (padding == 1) {\n\t\t\tbuffer = input.charCodeAt(position);\n\t\t\toutput += (\n\t\t\t\tTABLE.charAt(buffer >> 2) +\n\t\t\t\tTABLE.charAt((buffer << 4) & 0x3F) +\n\t\t\t\t'=='\n\t\t\t);\n\t\t}\n\n\t\treturn output;\n\t};\n\n\tvar base64 = {\n\t\t'encode': encode,\n\t\t'decode': decode,\n\t\t'version': '1.0.0'\n\t};\n\n\t// Some AMD build optimizers, like r.js, check for specific condition patterns\n\t// like the following:\n\tif (\n\t\ttypeof define == 'function' &&\n\t\ttypeof define.amd == 'object' &&\n\t\tdefine.amd\n\t) {\n\t\tdefine(function() {\n\t\t\treturn base64;\n\t\t});\n\t}\telse if (freeExports && !freeExports.nodeType) {\n\t\tif (freeModule) { // in Node.js or RingoJS v0.8.0+\n\t\t\tfreeModule.exports = base64;\n\t\t} else { // in Narwhal or RingoJS v0.7.0-\n\t\t\tfor (var key in base64) {\n\t\t\t\tbase64.hasOwnProperty(key) && (freeExports[key] = base64[key]);\n\t\t\t}\n\t\t}\n\t} else { // in Rhino or a web browser\n\t\troot.base64 = base64;\n\t}\n\n}(this));\n","'use strict';\n\nmodule.exports = {\n BINARY_TYPES: ['nodebuffer', 'arraybuffer', 'fragments'],\n EMPTY_BUFFER: Buffer.alloc(0),\n GUID: '258EAFA5-E914-47DA-95CA-C5AB0DC85B11',\n kForOnEventAttribute: Symbol('kIsForOnEventAttribute'),\n kListener: Symbol('kListener'),\n kStatusCode: Symbol('status-code'),\n kWebSocket: Symbol('websocket'),\n NOOP: () => {}\n};\n","'use strict';\n\nconst { EMPTY_BUFFER } = require('./constants');\n\n/**\n * Merges an array of buffers into a new buffer.\n *\n * @param {Buffer[]} list The array of buffers to concat\n * @param {Number} totalLength The total length of buffers in the list\n * @return {Buffer} The resulting buffer\n * @public\n */\nfunction concat(list, totalLength) {\n if (list.length === 0) return EMPTY_BUFFER;\n if (list.length === 1) return list[0];\n\n const target = Buffer.allocUnsafe(totalLength);\n let offset = 0;\n\n for (let i = 0; i < list.length; i++) {\n const buf = list[i];\n target.set(buf, offset);\n offset += buf.length;\n }\n\n if (offset < totalLength) return target.slice(0, offset);\n\n return target;\n}\n\n/**\n * Masks a buffer using the given mask.\n *\n * @param {Buffer} source The buffer to mask\n * @param {Buffer} mask The mask to use\n * @param {Buffer} output The buffer where to store the result\n * @param {Number} offset The offset at which to start writing\n * @param {Number} length The number of bytes to mask.\n * @public\n */\nfunction _mask(source, mask, output, offset, length) {\n for (let i = 0; i < length; i++) {\n output[offset + i] = source[i] ^ mask[i & 3];\n }\n}\n\n/**\n * Unmasks a buffer using the given mask.\n *\n * @param {Buffer} buffer The buffer to unmask\n * @param {Buffer} mask The mask to use\n * @public\n */\nfunction _unmask(buffer, mask) {\n for (let i = 0; i < buffer.length; i++) {\n buffer[i] ^= mask[i & 3];\n }\n}\n\n/**\n * Converts a buffer to an `ArrayBuffer`.\n *\n * @param {Buffer} buf The buffer to convert\n * @return {ArrayBuffer} Converted buffer\n * @public\n */\nfunction toArrayBuffer(buf) {\n if (buf.byteLength === buf.buffer.byteLength) {\n return buf.buffer;\n }\n\n return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);\n}\n\n/**\n * Converts `data` to a `Buffer`.\n *\n * @param {*} data The data to convert\n * @return {Buffer} The buffer\n * @throws {TypeError}\n * @public\n */\nfunction toBuffer(data) {\n toBuffer.readOnly = true;\n\n if (Buffer.isBuffer(data)) return data;\n\n let buf;\n\n if (data instanceof ArrayBuffer) {\n buf = Buffer.from(data);\n } else if (ArrayBuffer.isView(data)) {\n buf = Buffer.from(data.buffer, data.byteOffset, data.byteLength);\n } else {\n buf = Buffer.from(data);\n toBuffer.readOnly = false;\n }\n\n return buf;\n}\n\ntry {\n const bufferUtil = require('bufferutil');\n\n module.exports = {\n concat,\n mask(source, mask, output, offset, length) {\n if (length < 48) _mask(source, mask, output, offset, length);\n else bufferUtil.mask(source, mask, output, offset, length);\n },\n toArrayBuffer,\n toBuffer,\n unmask(buffer, mask) {\n if (buffer.length < 32) _unmask(buffer, mask);\n else bufferUtil.unmask(buffer, mask);\n }\n };\n} catch (e) /* istanbul ignore next */ {\n module.exports = {\n concat,\n mask: _mask,\n toArrayBuffer,\n toBuffer,\n unmask: _unmask\n };\n}\n","'use strict';\n\nconst kDone = Symbol('kDone');\nconst kRun = Symbol('kRun');\n\n/**\n * A very simple job queue with adjustable concurrency. Adapted from\n * https://github.com/STRML/async-limiter\n */\nclass Limiter {\n /**\n * Creates a new `Limiter`.\n *\n * @param {Number} [concurrency=Infinity] The maximum number of jobs allowed\n * to run concurrently\n */\n constructor(concurrency) {\n this[kDone] = () => {\n this.pending--;\n this[kRun]();\n };\n this.concurrency = concurrency || Infinity;\n this.jobs = [];\n this.pending = 0;\n }\n\n /**\n * Adds a job to the queue.\n *\n * @param {Function} job The job to run\n * @public\n */\n add(job) {\n this.jobs.push(job);\n this[kRun]();\n }\n\n /**\n * Removes a job from the queue and runs it if possible.\n *\n * @private\n */\n [kRun]() {\n if (this.pending === this.concurrency) return;\n\n if (this.jobs.length) {\n const job = this.jobs.shift();\n\n this.pending++;\n job(this[kDone]);\n }\n }\n}\n\nmodule.exports = Limiter;\n","'use strict';\n\nconst zlib = require('zlib');\n\nconst bufferUtil = require('./buffer-util');\nconst Limiter = require('./limiter');\nconst { kStatusCode } = require('./constants');\n\nconst TRAILER = Buffer.from([0x00, 0x00, 0xff, 0xff]);\nconst kPerMessageDeflate = Symbol('permessage-deflate');\nconst kTotalLength = Symbol('total-length');\nconst kCallback = Symbol('callback');\nconst kBuffers = Symbol('buffers');\nconst kError = Symbol('error');\n\n//\n// We limit zlib concurrency, which prevents severe memory fragmentation\n// as documented in https://github.com/nodejs/node/issues/8871#issuecomment-250915913\n// and https://github.com/websockets/ws/issues/1202\n//\n// Intentionally global; it's the global thread pool that's an issue.\n//\nlet zlibLimiter;\n\n/**\n * permessage-deflate implementation.\n */\nclass PerMessageDeflate {\n /**\n * Creates a PerMessageDeflate instance.\n *\n * @param {Object} [options] Configuration options\n * @param {(Boolean|Number)} [options.clientMaxWindowBits] Advertise support\n * for, or request, a custom client window size\n * @param {Boolean} [options.clientNoContextTakeover=false] Advertise/\n * acknowledge disabling of client context takeover\n * @param {Number} [options.concurrencyLimit=10] The number of concurrent\n * calls to zlib\n * @param {(Boolean|Number)} [options.serverMaxWindowBits] Request/confirm the\n * use of a custom server window size\n * @param {Boolean} [options.serverNoContextTakeover=false] Request/accept\n * disabling of server context takeover\n * @param {Number} [options.threshold=1024] Size (in bytes) below which\n * messages should not be compressed if context takeover is disabled\n * @param {Object} [options.zlibDeflateOptions] Options to pass to zlib on\n * deflate\n * @param {Object} [options.zlibInflateOptions] Options to pass to zlib on\n * inflate\n * @param {Boolean} [isServer=false] Create the instance in either server or\n * client mode\n * @param {Number} [maxPayload=0] The maximum allowed message length\n */\n constructor(options, isServer, maxPayload) {\n this._maxPayload = maxPayload | 0;\n this._options = options || {};\n this._threshold =\n this._options.threshold !== undefined ? this._options.threshold : 1024;\n this._isServer = !!isServer;\n this._deflate = null;\n this._inflate = null;\n\n this.params = null;\n\n if (!zlibLimiter) {\n const concurrency =\n this._options.concurrencyLimit !== undefined\n ? this._options.concurrencyLimit\n : 10;\n zlibLimiter = new Limiter(concurrency);\n }\n }\n\n /**\n * @type {String}\n */\n static get extensionName() {\n return 'permessage-deflate';\n }\n\n /**\n * Create an extension negotiation offer.\n *\n * @return {Object} Extension parameters\n * @public\n */\n offer() {\n const params = {};\n\n if (this._options.serverNoContextTakeover) {\n params.server_no_context_takeover = true;\n }\n if (this._options.clientNoContextTakeover) {\n params.client_no_context_takeover = true;\n }\n if (this._options.serverMaxWindowBits) {\n params.server_max_window_bits = this._options.serverMaxWindowBits;\n }\n if (this._options.clientMaxWindowBits) {\n params.client_max_window_bits = this._options.clientMaxWindowBits;\n } else if (this._options.clientMaxWindowBits == null) {\n params.client_max_window_bits = true;\n }\n\n return params;\n }\n\n /**\n * Accept an extension negotiation offer/response.\n *\n * @param {Array} configurations The extension negotiation offers/reponse\n * @return {Object} Accepted configuration\n * @public\n */\n accept(configurations) {\n configurations = this.normalizeParams(configurations);\n\n this.params = this._isServer\n ? this.acceptAsServer(configurations)\n : this.acceptAsClient(configurations);\n\n return this.params;\n }\n\n /**\n * Releases all resources used by the extension.\n *\n * @public\n */\n cleanup() {\n if (this._inflate) {\n this._inflate.close();\n this._inflate = null;\n }\n\n if (this._deflate) {\n const callback = this._deflate[kCallback];\n\n this._deflate.close();\n this._deflate = null;\n\n if (callback) {\n callback(\n new Error(\n 'The deflate stream was closed while data was being processed'\n )\n );\n }\n }\n }\n\n /**\n * Accept an extension negotiation offer.\n *\n * @param {Array} offers The extension negotiation offers\n * @return {Object} Accepted configuration\n * @private\n */\n acceptAsServer(offers) {\n const opts = this._options;\n const accepted = offers.find((params) => {\n if (\n (opts.serverNoContextTakeover === false &&\n params.server_no_context_takeover) ||\n (params.server_max_window_bits &&\n (opts.serverMaxWindowBits === false ||\n (typeof opts.serverMaxWindowBits === 'number' &&\n opts.serverMaxWindowBits > params.server_max_window_bits))) ||\n (typeof opts.clientMaxWindowBits === 'number' &&\n !params.client_max_window_bits)\n ) {\n return false;\n }\n\n return true;\n });\n\n if (!accepted) {\n throw new Error('None of the extension offers can be accepted');\n }\n\n if (opts.serverNoContextTakeover) {\n accepted.server_no_context_takeover = true;\n }\n if (opts.clientNoContextTakeover) {\n accepted.client_no_context_takeover = true;\n }\n if (typeof opts.serverMaxWindowBits === 'number') {\n accepted.server_max_window_bits = opts.serverMaxWindowBits;\n }\n if (typeof opts.clientMaxWindowBits === 'number') {\n accepted.client_max_window_bits = opts.clientMaxWindowBits;\n } else if (\n accepted.client_max_window_bits === true ||\n opts.clientMaxWindowBits === false\n ) {\n delete accepted.client_max_window_bits;\n }\n\n return accepted;\n }\n\n /**\n * Accept the extension negotiation response.\n *\n * @param {Array} response The extension negotiation response\n * @return {Object} Accepted configuration\n * @private\n */\n acceptAsClient(response) {\n const params = response[0];\n\n if (\n this._options.clientNoContextTakeover === false &&\n params.client_no_context_takeover\n ) {\n throw new Error('Unexpected parameter \"client_no_context_takeover\"');\n }\n\n if (!params.client_max_window_bits) {\n if (typeof this._options.clientMaxWindowBits === 'number') {\n params.client_max_window_bits = this._options.clientMaxWindowBits;\n }\n } else if (\n this._options.clientMaxWindowBits === false ||\n (typeof this._options.clientMaxWindowBits === 'number' &&\n params.client_max_window_bits > this._options.clientMaxWindowBits)\n ) {\n throw new Error(\n 'Unexpected or invalid parameter \"client_max_window_bits\"'\n );\n }\n\n return params;\n }\n\n /**\n * Normalize parameters.\n *\n * @param {Array} configurations The extension negotiation offers/reponse\n * @return {Array} The offers/response with normalized parameters\n * @private\n */\n normalizeParams(configurations) {\n configurations.forEach((params) => {\n Object.keys(params).forEach((key) => {\n let value = params[key];\n\n if (value.length > 1) {\n throw new Error(`Parameter \"${key}\" must have only a single value`);\n }\n\n value = value[0];\n\n if (key === 'client_max_window_bits') {\n if (value !== true) {\n const num = +value;\n if (!Number.isInteger(num) || num < 8 || num > 15) {\n throw new TypeError(\n `Invalid value for parameter \"${key}\": ${value}`\n );\n }\n value = num;\n } else if (!this._isServer) {\n throw new TypeError(\n `Invalid value for parameter \"${key}\": ${value}`\n );\n }\n } else if (key === 'server_max_window_bits') {\n const num = +value;\n if (!Number.isInteger(num) || num < 8 || num > 15) {\n throw new TypeError(\n `Invalid value for parameter \"${key}\": ${value}`\n );\n }\n value = num;\n } else if (\n key === 'client_no_context_takeover' ||\n key === 'server_no_context_takeover'\n ) {\n if (value !== true) {\n throw new TypeError(\n `Invalid value for parameter \"${key}\": ${value}`\n );\n }\n } else {\n throw new Error(`Unknown parameter \"${key}\"`);\n }\n\n params[key] = value;\n });\n });\n\n return configurations;\n }\n\n /**\n * Decompress data. Concurrency limited.\n *\n * @param {Buffer} data Compressed data\n * @param {Boolean} fin Specifies whether or not this is the last fragment\n * @param {Function} callback Callback\n * @public\n */\n decompress(data, fin, callback) {\n zlibLimiter.add((done) => {\n this._decompress(data, fin, (err, result) => {\n done();\n callback(err, result);\n });\n });\n }\n\n /**\n * Compress data. Concurrency limited.\n *\n * @param {(Buffer|String)} data Data to compress\n * @param {Boolean} fin Specifies whether or not this is the last fragment\n * @param {Function} callback Callback\n * @public\n */\n compress(data, fin, callback) {\n zlibLimiter.add((done) => {\n this._compress(data, fin, (err, result) => {\n done();\n callback(err, result);\n });\n });\n }\n\n /**\n * Decompress data.\n *\n * @param {Buffer} data Compressed data\n * @param {Boolean} fin Specifies whether or not this is the last fragment\n * @param {Function} callback Callback\n * @private\n */\n _decompress(data, fin, callback) {\n const endpoint = this._isServer ? 'client' : 'server';\n\n if (!this._inflate) {\n const key = `${endpoint}_max_window_bits`;\n const windowBits =\n typeof this.params[key] !== 'number'\n ? zlib.Z_DEFAULT_WINDOWBITS\n : this.params[key];\n\n this._inflate = zlib.createInflateRaw({\n ...this._options.zlibInflateOptions,\n windowBits\n });\n this._inflate[kPerMessageDeflate] = this;\n this._inflate[kTotalLength] = 0;\n this._inflate[kBuffers] = [];\n this._inflate.on('error', inflateOnError);\n this._inflate.on('data', inflateOnData);\n }\n\n this._inflate[kCallback] = callback;\n\n this._inflate.write(data);\n if (fin) this._inflate.write(TRAILER);\n\n this._inflate.flush(() => {\n const err = this._inflate[kError];\n\n if (err) {\n this._inflate.close();\n this._inflate = null;\n callback(err);\n return;\n }\n\n const data = bufferUtil.concat(\n this._inflate[kBuffers],\n this._inflate[kTotalLength]\n );\n\n if (this._inflate._readableState.endEmitted) {\n this._inflate.close();\n this._inflate = null;\n } else {\n this._inflate[kTotalLength] = 0;\n this._inflate[kBuffers] = [];\n\n if (fin && this.params[`${endpoint}_no_context_takeover`]) {\n this._inflate.reset();\n }\n }\n\n callback(null, data);\n });\n }\n\n /**\n * Compress data.\n *\n * @param {(Buffer|String)} data Data to compress\n * @param {Boolean} fin Specifies whether or not this is the last fragment\n * @param {Function} callback Callback\n * @private\n */\n _compress(data, fin, callback) {\n const endpoint = this._isServer ? 'server' : 'client';\n\n if (!this._deflate) {\n const key = `${endpoint}_max_window_bits`;\n const windowBits =\n typeof this.params[key] !== 'number'\n ? zlib.Z_DEFAULT_WINDOWBITS\n : this.params[key];\n\n this._deflate = zlib.createDeflateRaw({\n ...this._options.zlibDeflateOptions,\n windowBits\n });\n\n this._deflate[kTotalLength] = 0;\n this._deflate[kBuffers] = [];\n\n this._deflate.on('data', deflateOnData);\n }\n\n this._deflate[kCallback] = callback;\n\n this._deflate.write(data);\n this._deflate.flush(zlib.Z_SYNC_FLUSH, () => {\n if (!this._deflate) {\n //\n // The deflate stream was closed while data was being processed.\n //\n return;\n }\n\n let data = bufferUtil.concat(\n this._deflate[kBuffers],\n this._deflate[kTotalLength]\n );\n\n if (fin) data = data.slice(0, data.length - 4);\n\n //\n // Ensure that the callback will not be called again in\n // `PerMessageDeflate#cleanup()`.\n //\n this._deflate[kCallback] = null;\n\n this._deflate[kTotalLength] = 0;\n this._deflate[kBuffers] = [];\n\n if (fin && this.params[`${endpoint}_no_context_takeover`]) {\n this._deflate.reset();\n }\n\n callback(null, data);\n });\n }\n}\n\nmodule.exports = PerMessageDeflate;\n\n/**\n * The listener of the `zlib.DeflateRaw` stream `'data'` event.\n *\n * @param {Buffer} chunk A chunk of data\n * @private\n */\nfunction deflateOnData(chunk) {\n this[kBuffers].push(chunk);\n this[kTotalLength] += chunk.length;\n}\n\n/**\n * The listener of the `zlib.InflateRaw` stream `'data'` event.\n *\n * @param {Buffer} chunk A chunk of data\n * @private\n */\nfunction inflateOnData(chunk) {\n this[kTotalLength] += chunk.length;\n\n if (\n this[kPerMessageDeflate]._maxPayload < 1 ||\n this[kTotalLength] <= this[kPerMessageDeflate]._maxPayload\n ) {\n this[kBuffers].push(chunk);\n return;\n }\n\n this[kError] = new RangeError('Max payload size exceeded');\n this[kError].code = 'WS_ERR_UNSUPPORTED_MESSAGE_LENGTH';\n this[kError][kStatusCode] = 1009;\n this.removeListener('data', inflateOnData);\n this.reset();\n}\n\n/**\n * The listener of the `zlib.InflateRaw` stream `'error'` event.\n *\n * @param {Error} err The emitted error\n * @private\n */\nfunction inflateOnError(err) {\n //\n // There is no need to call `Zlib#close()` as the handle is automatically\n // closed when an error is emitted.\n //\n this[kPerMessageDeflate]._inflate = null;\n err[kStatusCode] = 1007;\n this[kCallback](err);\n}\n","'use strict';\n\n//\n// Allowed token characters:\n//\n// '!', '#', '$', '%', '&', ''', '*', '+', '-',\n// '.', 0-9, A-Z, '^', '_', '`', a-z, '|', '~'\n//\n// tokenChars[32] === 0 // ' '\n// tokenChars[33] === 1 // '!'\n// tokenChars[34] === 0 // '\"'\n// ...\n//\n// prettier-ignore\nconst tokenChars = [\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0 - 15\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16 - 31\n 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, // 32 - 47\n 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, // 48 - 63\n 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 64 - 79\n 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, // 80 - 95\n 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 96 - 111\n 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0 // 112 - 127\n];\n\n/**\n * Checks if a status code is allowed in a close frame.\n *\n * @param {Number} code The status code\n * @return {Boolean} `true` if the status code is valid, else `false`\n * @public\n */\nfunction isValidStatusCode(code) {\n return (\n (code >= 1000 &&\n code <= 1014 &&\n code !== 1004 &&\n code !== 1005 &&\n code !== 1006) ||\n (code >= 3000 && code <= 4999)\n );\n}\n\n/**\n * Checks if a given buffer contains only correct UTF-8.\n * Ported from https://www.cl.cam.ac.uk/%7Emgk25/ucs/utf8_check.c by\n * Markus Kuhn.\n *\n * @param {Buffer} buf The buffer to check\n * @return {Boolean} `true` if `buf` contains only correct UTF-8, else `false`\n * @public\n */\nfunction _isValidUTF8(buf) {\n const len = buf.length;\n let i = 0;\n\n while (i < len) {\n if ((buf[i] & 0x80) === 0) {\n // 0xxxxxxx\n i++;\n } else if ((buf[i] & 0xe0) === 0xc0) {\n // 110xxxxx 10xxxxxx\n if (\n i + 1 === len ||\n (buf[i + 1] & 0xc0) !== 0x80 ||\n (buf[i] & 0xfe) === 0xc0 // Overlong\n ) {\n return false;\n }\n\n i += 2;\n } else if ((buf[i] & 0xf0) === 0xe0) {\n // 1110xxxx 10xxxxxx 10xxxxxx\n if (\n i + 2 >= len ||\n (buf[i + 1] & 0xc0) !== 0x80 ||\n (buf[i + 2] & 0xc0) !== 0x80 ||\n (buf[i] === 0xe0 && (buf[i + 1] & 0xe0) === 0x80) || // Overlong\n (buf[i] === 0xed && (buf[i + 1] & 0xe0) === 0xa0) // Surrogate (U+D800 - U+DFFF)\n ) {\n return false;\n }\n\n i += 3;\n } else if ((buf[i] & 0xf8) === 0xf0) {\n // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx\n if (\n i + 3 >= len ||\n (buf[i + 1] & 0xc0) !== 0x80 ||\n (buf[i + 2] & 0xc0) !== 0x80 ||\n (buf[i + 3] & 0xc0) !== 0x80 ||\n (buf[i] === 0xf0 && (buf[i + 1] & 0xf0) === 0x80) || // Overlong\n (buf[i] === 0xf4 && buf[i + 1] > 0x8f) ||\n buf[i] > 0xf4 // > U+10FFFF\n ) {\n return false;\n }\n\n i += 4;\n } else {\n return false;\n }\n }\n\n return true;\n}\n\ntry {\n const isValidUTF8 = require('utf-8-validate');\n\n module.exports = {\n isValidStatusCode,\n isValidUTF8(buf) {\n return buf.length < 150 ? _isValidUTF8(buf) : isValidUTF8(buf);\n },\n tokenChars\n };\n} catch (e) /* istanbul ignore next */ {\n module.exports = {\n isValidStatusCode,\n isValidUTF8: _isValidUTF8,\n tokenChars\n };\n}\n","'use strict';\n\nconst { Writable } = require('stream');\n\nconst PerMessageDeflate = require('./permessage-deflate');\nconst {\n BINARY_TYPES,\n EMPTY_BUFFER,\n kStatusCode,\n kWebSocket\n} = require('./constants');\nconst { concat, toArrayBuffer, unmask } = require('./buffer-util');\nconst { isValidStatusCode, isValidUTF8 } = require('./validation');\n\nconst GET_INFO = 0;\nconst GET_PAYLOAD_LENGTH_16 = 1;\nconst GET_PAYLOAD_LENGTH_64 = 2;\nconst GET_MASK = 3;\nconst GET_DATA = 4;\nconst INFLATING = 5;\n\n/**\n * HyBi Receiver implementation.\n *\n * @extends Writable\n */\nclass Receiver extends Writable {\n /**\n * Creates a Receiver instance.\n *\n * @param {Object} [options] Options object\n * @param {String} [options.binaryType=nodebuffer] The type for binary data\n * @param {Object} [options.extensions] An object containing the negotiated\n * extensions\n * @param {Boolean} [options.isServer=false] Specifies whether to operate in\n * client or server mode\n * @param {Number} [options.maxPayload=0] The maximum allowed message length\n * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or\n * not to skip UTF-8 validation for text and close messages\n */\n constructor(options = {}) {\n super();\n\n this._binaryType = options.binaryType || BINARY_TYPES[0];\n this._extensions = options.extensions || {};\n this._isServer = !!options.isServer;\n this._maxPayload = options.maxPayload | 0;\n this._skipUTF8Validation = !!options.skipUTF8Validation;\n this[kWebSocket] = undefined;\n\n this._bufferedBytes = 0;\n this._buffers = [];\n\n this._compressed = false;\n this._payloadLength = 0;\n this._mask = undefined;\n this._fragmented = 0;\n this._masked = false;\n this._fin = false;\n this._opcode = 0;\n\n this._totalPayloadLength = 0;\n this._messageLength = 0;\n this._fragments = [];\n\n this._state = GET_INFO;\n this._loop = false;\n }\n\n /**\n * Implements `Writable.prototype._write()`.\n *\n * @param {Buffer} chunk The chunk of data to write\n * @param {String} encoding The character encoding of `chunk`\n * @param {Function} cb Callback\n * @private\n */\n _write(chunk, encoding, cb) {\n if (this._opcode === 0x08 && this._state == GET_INFO) return cb();\n\n this._bufferedBytes += chunk.length;\n this._buffers.push(chunk);\n this.startLoop(cb);\n }\n\n /**\n * Consumes `n` bytes from the buffered data.\n *\n * @param {Number} n The number of bytes to consume\n * @return {Buffer} The consumed bytes\n * @private\n */\n consume(n) {\n this._bufferedBytes -= n;\n\n if (n === this._buffers[0].length) return this._buffers.shift();\n\n if (n < this._buffers[0].length) {\n const buf = this._buffers[0];\n this._buffers[0] = buf.slice(n);\n return buf.slice(0, n);\n }\n\n const dst = Buffer.allocUnsafe(n);\n\n do {\n const buf = this._buffers[0];\n const offset = dst.length - n;\n\n if (n >= buf.length) {\n dst.set(this._buffers.shift(), offset);\n } else {\n dst.set(new Uint8Array(buf.buffer, buf.byteOffset, n), offset);\n this._buffers[0] = buf.slice(n);\n }\n\n n -= buf.length;\n } while (n > 0);\n\n return dst;\n }\n\n /**\n * Starts the parsing loop.\n *\n * @param {Function} cb Callback\n * @private\n */\n startLoop(cb) {\n let err;\n this._loop = true;\n\n do {\n switch (this._state) {\n case GET_INFO:\n err = this.getInfo();\n break;\n case GET_PAYLOAD_LENGTH_16:\n err = this.getPayloadLength16();\n break;\n case GET_PAYLOAD_LENGTH_64:\n err = this.getPayloadLength64();\n break;\n case GET_MASK:\n this.getMask();\n break;\n case GET_DATA:\n err = this.getData(cb);\n break;\n default:\n // `INFLATING`\n this._loop = false;\n return;\n }\n } while (this._loop);\n\n cb(err);\n }\n\n /**\n * Reads the first two bytes of a frame.\n *\n * @return {(RangeError|undefined)} A possible error\n * @private\n */\n getInfo() {\n if (this._bufferedBytes < 2) {\n this._loop = false;\n return;\n }\n\n const buf = this.consume(2);\n\n if ((buf[0] & 0x30) !== 0x00) {\n this._loop = false;\n return error(\n RangeError,\n 'RSV2 and RSV3 must be clear',\n true,\n 1002,\n 'WS_ERR_UNEXPECTED_RSV_2_3'\n );\n }\n\n const compressed = (buf[0] & 0x40) === 0x40;\n\n if (compressed && !this._extensions[PerMessageDeflate.extensionName]) {\n this._loop = false;\n return error(\n RangeError,\n 'RSV1 must be clear',\n true,\n 1002,\n 'WS_ERR_UNEXPECTED_RSV_1'\n );\n }\n\n this._fin = (buf[0] & 0x80) === 0x80;\n this._opcode = buf[0] & 0x0f;\n this._payloadLength = buf[1] & 0x7f;\n\n if (this._opcode === 0x00) {\n if (compressed) {\n this._loop = false;\n return error(\n RangeError,\n 'RSV1 must be clear',\n true,\n 1002,\n 'WS_ERR_UNEXPECTED_RSV_1'\n );\n }\n\n if (!this._fragmented) {\n this._loop = false;\n return error(\n RangeError,\n 'invalid opcode 0',\n true,\n 1002,\n 'WS_ERR_INVALID_OPCODE'\n );\n }\n\n this._opcode = this._fragmented;\n } else if (this._opcode === 0x01 || this._opcode === 0x02) {\n if (this._fragmented) {\n this._loop = false;\n return error(\n RangeError,\n `invalid opcode ${this._opcode}`,\n true,\n 1002,\n 'WS_ERR_INVALID_OPCODE'\n );\n }\n\n this._compressed = compressed;\n } else if (this._opcode > 0x07 && this._opcode < 0x0b) {\n if (!this._fin) {\n this._loop = false;\n return error(\n RangeError,\n 'FIN must be set',\n true,\n 1002,\n 'WS_ERR_EXPECTED_FIN'\n );\n }\n\n if (compressed) {\n this._loop = false;\n return error(\n RangeError,\n 'RSV1 must be clear',\n true,\n 1002,\n 'WS_ERR_UNEXPECTED_RSV_1'\n );\n }\n\n if (this._payloadLength > 0x7d) {\n this._loop = false;\n return error(\n RangeError,\n `invalid payload length ${this._payloadLength}`,\n true,\n 1002,\n 'WS_ERR_INVALID_CONTROL_PAYLOAD_LENGTH'\n );\n }\n } else {\n this._loop = false;\n return error(\n RangeError,\n `invalid opcode ${this._opcode}`,\n true,\n 1002,\n 'WS_ERR_INVALID_OPCODE'\n );\n }\n\n if (!this._fin && !this._fragmented) this._fragmented = this._opcode;\n this._masked = (buf[1] & 0x80) === 0x80;\n\n if (this._isServer) {\n if (!this._masked) {\n this._loop = false;\n return error(\n RangeError,\n 'MASK must be set',\n true,\n 1002,\n 'WS_ERR_EXPECTED_MASK'\n );\n }\n } else if (this._masked) {\n this._loop = false;\n return error(\n RangeError,\n 'MASK must be clear',\n true,\n 1002,\n 'WS_ERR_UNEXPECTED_MASK'\n );\n }\n\n if (this._payloadLength === 126) this._state = GET_PAYLOAD_LENGTH_16;\n else if (this._payloadLength === 127) this._state = GET_PAYLOAD_LENGTH_64;\n else return this.haveLength();\n }\n\n /**\n * Gets extended payload length (7+16).\n *\n * @return {(RangeError|undefined)} A possible error\n * @private\n */\n getPayloadLength16() {\n if (this._bufferedBytes < 2) {\n this._loop = false;\n return;\n }\n\n this._payloadLength = this.consume(2).readUInt16BE(0);\n return this.haveLength();\n }\n\n /**\n * Gets extended payload length (7+64).\n *\n * @return {(RangeError|undefined)} A possible error\n * @private\n */\n getPayloadLength64() {\n if (this._bufferedBytes < 8) {\n this._loop = false;\n return;\n }\n\n const buf = this.consume(8);\n const num = buf.readUInt32BE(0);\n\n //\n // The maximum safe integer in JavaScript is 2^53 - 1. An error is returned\n // if payload length is greater than this number.\n //\n if (num > Math.pow(2, 53 - 32) - 1) {\n this._loop = false;\n return error(\n RangeError,\n 'Unsupported WebSocket frame: payload length > 2^53 - 1',\n false,\n 1009,\n 'WS_ERR_UNSUPPORTED_DATA_PAYLOAD_LENGTH'\n );\n }\n\n this._payloadLength = num * Math.pow(2, 32) + buf.readUInt32BE(4);\n return this.haveLength();\n }\n\n /**\n * Payload length has been read.\n *\n * @return {(RangeError|undefined)} A possible error\n * @private\n */\n haveLength() {\n if (this._payloadLength && this._opcode < 0x08) {\n this._totalPayloadLength += this._payloadLength;\n if (this._totalPayloadLength > this._maxPayload && this._maxPayload > 0) {\n this._loop = false;\n return error(\n RangeError,\n 'Max payload size exceeded',\n false,\n 1009,\n 'WS_ERR_UNSUPPORTED_MESSAGE_LENGTH'\n );\n }\n }\n\n if (this._masked) this._state = GET_MASK;\n else this._state = GET_DATA;\n }\n\n /**\n * Reads mask bytes.\n *\n * @private\n */\n getMask() {\n if (this._bufferedBytes < 4) {\n this._loop = false;\n return;\n }\n\n this._mask = this.consume(4);\n this._state = GET_DATA;\n }\n\n /**\n * Reads data bytes.\n *\n * @param {Function} cb Callback\n * @return {(Error|RangeError|undefined)} A possible error\n * @private\n */\n getData(cb) {\n let data = EMPTY_BUFFER;\n\n if (this._payloadLength) {\n if (this._bufferedBytes < this._payloadLength) {\n this._loop = false;\n return;\n }\n\n data = this.consume(this._payloadLength);\n\n if (\n this._masked &&\n (this._mask[0] | this._mask[1] | this._mask[2] | this._mask[3]) !== 0\n ) {\n unmask(data, this._mask);\n }\n }\n\n if (this._opcode > 0x07) return this.controlMessage(data);\n\n if (this._compressed) {\n this._state = INFLATING;\n this.decompress(data, cb);\n return;\n }\n\n if (data.length) {\n //\n // This message is not compressed so its length is the sum of the payload\n // length of all fragments.\n //\n this._messageLength = this._totalPayloadLength;\n this._fragments.push(data);\n }\n\n return this.dataMessage();\n }\n\n /**\n * Decompresses data.\n *\n * @param {Buffer} data Compressed data\n * @param {Function} cb Callback\n * @private\n */\n decompress(data, cb) {\n const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName];\n\n perMessageDeflate.decompress(data, this._fin, (err, buf) => {\n if (err) return cb(err);\n\n if (buf.length) {\n this._messageLength += buf.length;\n if (this._messageLength > this._maxPayload && this._maxPayload > 0) {\n return cb(\n error(\n RangeError,\n 'Max payload size exceeded',\n false,\n 1009,\n 'WS_ERR_UNSUPPORTED_MESSAGE_LENGTH'\n )\n );\n }\n\n this._fragments.push(buf);\n }\n\n const er = this.dataMessage();\n if (er) return cb(er);\n\n this.startLoop(cb);\n });\n }\n\n /**\n * Handles a data message.\n *\n * @return {(Error|undefined)} A possible error\n * @private\n */\n dataMessage() {\n if (this._fin) {\n const messageLength = this._messageLength;\n const fragments = this._fragments;\n\n this._totalPayloadLength = 0;\n this._messageLength = 0;\n this._fragmented = 0;\n this._fragments = [];\n\n if (this._opcode === 2) {\n let data;\n\n if (this._binaryType === 'nodebuffer') {\n data = concat(fragments, messageLength);\n } else if (this._binaryType === 'arraybuffer') {\n data = toArrayBuffer(concat(fragments, messageLength));\n } else {\n data = fragments;\n }\n\n this.emit('message', data, true);\n } else {\n const buf = concat(fragments, messageLength);\n\n if (!this._skipUTF8Validation && !isValidUTF8(buf)) {\n this._loop = false;\n return error(\n Error,\n 'invalid UTF-8 sequence',\n true,\n 1007,\n 'WS_ERR_INVALID_UTF8'\n );\n }\n\n this.emit('message', buf, false);\n }\n }\n\n this._state = GET_INFO;\n }\n\n /**\n * Handles a control message.\n *\n * @param {Buffer} data Data to handle\n * @return {(Error|RangeError|undefined)} A possible error\n * @private\n */\n controlMessage(data) {\n if (this._opcode === 0x08) {\n this._loop = false;\n\n if (data.length === 0) {\n this.emit('conclude', 1005, EMPTY_BUFFER);\n this.end();\n } else if (data.length === 1) {\n return error(\n RangeError,\n 'invalid payload length 1',\n true,\n 1002,\n 'WS_ERR_INVALID_CONTROL_PAYLOAD_LENGTH'\n );\n } else {\n const code = data.readUInt16BE(0);\n\n if (!isValidStatusCode(code)) {\n return error(\n RangeError,\n `invalid status code ${code}`,\n true,\n 1002,\n 'WS_ERR_INVALID_CLOSE_CODE'\n );\n }\n\n const buf = data.slice(2);\n\n if (!this._skipUTF8Validation && !isValidUTF8(buf)) {\n return error(\n Error,\n 'invalid UTF-8 sequence',\n true,\n 1007,\n 'WS_ERR_INVALID_UTF8'\n );\n }\n\n this.emit('conclude', code, buf);\n this.end();\n }\n } else if (this._opcode === 0x09) {\n this.emit('ping', data);\n } else {\n this.emit('pong', data);\n }\n\n this._state = GET_INFO;\n }\n}\n\nmodule.exports = Receiver;\n\n/**\n * Builds an error object.\n *\n * @param {function(new:Error|RangeError)} ErrorCtor The error constructor\n * @param {String} message The error message\n * @param {Boolean} prefix Specifies whether or not to add a default prefix to\n * `message`\n * @param {Number} statusCode The status code\n * @param {String} errorCode The exposed error code\n * @return {(Error|RangeError)} The error\n * @private\n */\nfunction error(ErrorCtor, message, prefix, statusCode, errorCode) {\n const err = new ErrorCtor(\n prefix ? `Invalid WebSocket frame: ${message}` : message\n );\n\n Error.captureStackTrace(err, error);\n err.code = errorCode;\n err[kStatusCode] = statusCode;\n return err;\n}\n","/* eslint no-unused-vars: [\"error\", { \"varsIgnorePattern\": \"^net|tls$\" }] */\n\n'use strict';\n\nconst net = require('net');\nconst tls = require('tls');\nconst { randomFillSync } = require('crypto');\n\nconst PerMessageDeflate = require('./permessage-deflate');\nconst { EMPTY_BUFFER } = require('./constants');\nconst { isValidStatusCode } = require('./validation');\nconst { mask: applyMask, toBuffer } = require('./buffer-util');\n\nconst kByteLength = Symbol('kByteLength');\nconst maskBuffer = Buffer.alloc(4);\n\n/**\n * HyBi Sender implementation.\n */\nclass Sender {\n /**\n * Creates a Sender instance.\n *\n * @param {(net.Socket|tls.Socket)} socket The connection socket\n * @param {Object} [extensions] An object containing the negotiated extensions\n * @param {Function} [generateMask] The function used to generate the masking\n * key\n */\n constructor(socket, extensions, generateMask) {\n this._extensions = extensions || {};\n\n if (generateMask) {\n this._generateMask = generateMask;\n this._maskBuffer = Buffer.alloc(4);\n }\n\n this._socket = socket;\n\n this._firstFragment = true;\n this._compress = false;\n\n this._bufferedBytes = 0;\n this._deflating = false;\n this._queue = [];\n }\n\n /**\n * Frames a piece of data according to the HyBi WebSocket protocol.\n *\n * @param {(Buffer|String)} data The data to frame\n * @param {Object} options Options object\n * @param {Boolean} [options.fin=false] Specifies whether or not to set the\n * FIN bit\n * @param {Function} [options.generateMask] The function used to generate the\n * masking key\n * @param {Boolean} [options.mask=false] Specifies whether or not to mask\n * `data`\n * @param {Buffer} [options.maskBuffer] The buffer used to store the masking\n * key\n * @param {Number} options.opcode The opcode\n * @param {Boolean} [options.readOnly=false] Specifies whether `data` can be\n * modified\n * @param {Boolean} [options.rsv1=false] Specifies whether or not to set the\n * RSV1 bit\n * @return {(Buffer|String)[]} The framed data\n * @public\n */\n static frame(data, options) {\n let mask;\n let merge = false;\n let offset = 2;\n let skipMasking = false;\n\n if (options.mask) {\n mask = options.maskBuffer || maskBuffer;\n\n if (options.generateMask) {\n options.generateMask(mask);\n } else {\n randomFillSync(mask, 0, 4);\n }\n\n skipMasking = (mask[0] | mask[1] | mask[2] | mask[3]) === 0;\n offset = 6;\n }\n\n let dataLength;\n\n if (typeof data === 'string') {\n if (\n (!options.mask || skipMasking) &&\n options[kByteLength] !== undefined\n ) {\n dataLength = options[kByteLength];\n } else {\n data = Buffer.from(data);\n dataLength = data.length;\n }\n } else {\n dataLength = data.length;\n merge = options.mask && options.readOnly && !skipMasking;\n }\n\n let payloadLength = dataLength;\n\n if (dataLength >= 65536) {\n offset += 8;\n payloadLength = 127;\n } else if (dataLength > 125) {\n offset += 2;\n payloadLength = 126;\n }\n\n const target = Buffer.allocUnsafe(merge ? dataLength + offset : offset);\n\n target[0] = options.fin ? options.opcode | 0x80 : options.opcode;\n if (options.rsv1) target[0] |= 0x40;\n\n target[1] = payloadLength;\n\n if (payloadLength === 126) {\n target.writeUInt16BE(dataLength, 2);\n } else if (payloadLength === 127) {\n target[2] = target[3] = 0;\n target.writeUIntBE(dataLength, 4, 6);\n }\n\n if (!options.mask) return [target, data];\n\n target[1] |= 0x80;\n target[offset - 4] = mask[0];\n target[offset - 3] = mask[1];\n target[offset - 2] = mask[2];\n target[offset - 1] = mask[3];\n\n if (skipMasking) return [target, data];\n\n if (merge) {\n applyMask(data, mask, target, offset, dataLength);\n return [target];\n }\n\n applyMask(data, mask, data, 0, dataLength);\n return [target, data];\n }\n\n /**\n * Sends a close message to the other peer.\n *\n * @param {Number} [code] The status code component of the body\n * @param {(String|Buffer)} [data] The message component of the body\n * @param {Boolean} [mask=false] Specifies whether or not to mask the message\n * @param {Function} [cb] Callback\n * @public\n */\n close(code, data, mask, cb) {\n let buf;\n\n if (code === undefined) {\n buf = EMPTY_BUFFER;\n } else if (typeof code !== 'number' || !isValidStatusCode(code)) {\n throw new TypeError('First argument must be a valid error code number');\n } else if (data === undefined || !data.length) {\n buf = Buffer.allocUnsafe(2);\n buf.writeUInt16BE(code, 0);\n } else {\n const length = Buffer.byteLength(data);\n\n if (length > 123) {\n throw new RangeError('The message must not be greater than 123 bytes');\n }\n\n buf = Buffer.allocUnsafe(2 + length);\n buf.writeUInt16BE(code, 0);\n\n if (typeof data === 'string') {\n buf.write(data, 2);\n } else {\n buf.set(data, 2);\n }\n }\n\n const options = {\n [kByteLength]: buf.length,\n fin: true,\n generateMask: this._generateMask,\n mask,\n maskBuffer: this._maskBuffer,\n opcode: 0x08,\n readOnly: false,\n rsv1: false\n };\n\n if (this._deflating) {\n this.enqueue([this.dispatch, buf, false, options, cb]);\n } else {\n this.sendFrame(Sender.frame(buf, options), cb);\n }\n }\n\n /**\n * Sends a ping message to the other peer.\n *\n * @param {*} data The message to send\n * @param {Boolean} [mask=false] Specifies whether or not to mask `data`\n * @param {Function} [cb] Callback\n * @public\n */\n ping(data, mask, cb) {\n let byteLength;\n let readOnly;\n\n if (typeof data === 'string') {\n byteLength = Buffer.byteLength(data);\n readOnly = false;\n } else {\n data = toBuffer(data);\n byteLength = data.length;\n readOnly = toBuffer.readOnly;\n }\n\n if (byteLength > 125) {\n throw new RangeError('The data size must not be greater than 125 bytes');\n }\n\n const options = {\n [kByteLength]: byteLength,\n fin: true,\n generateMask: this._generateMask,\n mask,\n maskBuffer: this._maskBuffer,\n opcode: 0x09,\n readOnly,\n rsv1: false\n };\n\n if (this._deflating) {\n this.enqueue([this.dispatch, data, false, options, cb]);\n } else {\n this.sendFrame(Sender.frame(data, options), cb);\n }\n }\n\n /**\n * Sends a pong message to the other peer.\n *\n * @param {*} data The message to send\n * @param {Boolean} [mask=false] Specifies whether or not to mask `data`\n * @param {Function} [cb] Callback\n * @public\n */\n pong(data, mask, cb) {\n let byteLength;\n let readOnly;\n\n if (typeof data === 'string') {\n byteLength = Buffer.byteLength(data);\n readOnly = false;\n } else {\n data = toBuffer(data);\n byteLength = data.length;\n readOnly = toBuffer.readOnly;\n }\n\n if (byteLength > 125) {\n throw new RangeError('The data size must not be greater than 125 bytes');\n }\n\n const options = {\n [kByteLength]: byteLength,\n fin: true,\n generateMask: this._generateMask,\n mask,\n maskBuffer: this._maskBuffer,\n opcode: 0x0a,\n readOnly,\n rsv1: false\n };\n\n if (this._deflating) {\n this.enqueue([this.dispatch, data, false, options, cb]);\n } else {\n this.sendFrame(Sender.frame(data, options), cb);\n }\n }\n\n /**\n * Sends a data message to the other peer.\n *\n * @param {*} data The message to send\n * @param {Object} options Options object\n * @param {Boolean} [options.binary=false] Specifies whether `data` is binary\n * or text\n * @param {Boolean} [options.compress=false] Specifies whether or not to\n * compress `data`\n * @param {Boolean} [options.fin=false] Specifies whether the fragment is the\n * last one\n * @param {Boolean} [options.mask=false] Specifies whether or not to mask\n * `data`\n * @param {Function} [cb] Callback\n * @public\n */\n send(data, options, cb) {\n const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName];\n let opcode = options.binary ? 2 : 1;\n let rsv1 = options.compress;\n\n let byteLength;\n let readOnly;\n\n if (typeof data === 'string') {\n byteLength = Buffer.byteLength(data);\n readOnly = false;\n } else {\n data = toBuffer(data);\n byteLength = data.length;\n readOnly = toBuffer.readOnly;\n }\n\n if (this._firstFragment) {\n this._firstFragment = false;\n if (\n rsv1 &&\n perMessageDeflate &&\n perMessageDeflate.params[\n perMessageDeflate._isServer\n ? 'server_no_context_takeover'\n : 'client_no_context_takeover'\n ]\n ) {\n rsv1 = byteLength >= perMessageDeflate._threshold;\n }\n this._compress = rsv1;\n } else {\n rsv1 = false;\n opcode = 0;\n }\n\n if (options.fin) this._firstFragment = true;\n\n if (perMessageDeflate) {\n const opts = {\n [kByteLength]: byteLength,\n fin: options.fin,\n generateMask: this._generateMask,\n mask: options.mask,\n maskBuffer: this._maskBuffer,\n opcode,\n readOnly,\n rsv1\n };\n\n if (this._deflating) {\n this.enqueue([this.dispatch, data, this._compress, opts, cb]);\n } else {\n this.dispatch(data, this._compress, opts, cb);\n }\n } else {\n this.sendFrame(\n Sender.frame(data, {\n [kByteLength]: byteLength,\n fin: options.fin,\n generateMask: this._generateMask,\n mask: options.mask,\n maskBuffer: this._maskBuffer,\n opcode,\n readOnly,\n rsv1: false\n }),\n cb\n );\n }\n }\n\n /**\n * Dispatches a message.\n *\n * @param {(Buffer|String)} data The message to send\n * @param {Boolean} [compress=false] Specifies whether or not to compress\n * `data`\n * @param {Object} options Options object\n * @param {Boolean} [options.fin=false] Specifies whether or not to set the\n * FIN bit\n * @param {Function} [options.generateMask] The function used to generate the\n * masking key\n * @param {Boolean} [options.mask=false] Specifies whether or not to mask\n * `data`\n * @param {Buffer} [options.maskBuffer] The buffer used to store the masking\n * key\n * @param {Number} options.opcode The opcode\n * @param {Boolean} [options.readOnly=false] Specifies whether `data` can be\n * modified\n * @param {Boolean} [options.rsv1=false] Specifies whether or not to set the\n * RSV1 bit\n * @param {Function} [cb] Callback\n * @private\n */\n dispatch(data, compress, options, cb) {\n if (!compress) {\n this.sendFrame(Sender.frame(data, options), cb);\n return;\n }\n\n const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName];\n\n this._bufferedBytes += options[kByteLength];\n this._deflating = true;\n perMessageDeflate.compress(data, options.fin, (_, buf) => {\n if (this._socket.destroyed) {\n const err = new Error(\n 'The socket was closed while data was being compressed'\n );\n\n if (typeof cb === 'function') cb(err);\n\n for (let i = 0; i < this._queue.length; i++) {\n const params = this._queue[i];\n const callback = params[params.length - 1];\n\n if (typeof callback === 'function') callback(err);\n }\n\n return;\n }\n\n this._bufferedBytes -= options[kByteLength];\n this._deflating = false;\n options.readOnly = false;\n this.sendFrame(Sender.frame(buf, options), cb);\n this.dequeue();\n });\n }\n\n /**\n * Executes queued send operations.\n *\n * @private\n */\n dequeue() {\n while (!this._deflating && this._queue.length) {\n const params = this._queue.shift();\n\n this._bufferedBytes -= params[3][kByteLength];\n Reflect.apply(params[0], this, params.slice(1));\n }\n }\n\n /**\n * Enqueues a send operation.\n *\n * @param {Array} params Send operation parameters.\n * @private\n */\n enqueue(params) {\n this._bufferedBytes += params[3][kByteLength];\n this._queue.push(params);\n }\n\n /**\n * Sends a frame.\n *\n * @param {Buffer[]} list The frame to send\n * @param {Function} [cb] Callback\n * @private\n */\n sendFrame(list, cb) {\n if (list.length === 2) {\n this._socket.cork();\n this._socket.write(list[0]);\n this._socket.write(list[1], cb);\n this._socket.uncork();\n } else {\n this._socket.write(list[0], cb);\n }\n }\n}\n\nmodule.exports = Sender;\n","'use strict';\n\nconst { kForOnEventAttribute, kListener } = require('./constants');\n\nconst kCode = Symbol('kCode');\nconst kData = Symbol('kData');\nconst kError = Symbol('kError');\nconst kMessage = Symbol('kMessage');\nconst kReason = Symbol('kReason');\nconst kTarget = Symbol('kTarget');\nconst kType = Symbol('kType');\nconst kWasClean = Symbol('kWasClean');\n\n/**\n * Class representing an event.\n */\nclass Event {\n /**\n * Create a new `Event`.\n *\n * @param {String} type The name of the event\n * @throws {TypeError} If the `type` argument is not specified\n */\n constructor(type) {\n this[kTarget] = null;\n this[kType] = type;\n }\n\n /**\n * @type {*}\n */\n get target() {\n return this[kTarget];\n }\n\n /**\n * @type {String}\n */\n get type() {\n return this[kType];\n }\n}\n\nObject.defineProperty(Event.prototype, 'target', { enumerable: true });\nObject.defineProperty(Event.prototype, 'type', { enumerable: true });\n\n/**\n * Class representing a close event.\n *\n * @extends Event\n */\nclass CloseEvent extends Event {\n /**\n * Create a new `CloseEvent`.\n *\n * @param {String} type The name of the event\n * @param {Object} [options] A dictionary object that allows for setting\n * attributes via object members of the same name\n * @param {Number} [options.code=0] The status code explaining why the\n * connection was closed\n * @param {String} [options.reason=''] A human-readable string explaining why\n * the connection was closed\n * @param {Boolean} [options.wasClean=false] Indicates whether or not the\n * connection was cleanly closed\n */\n constructor(type, options = {}) {\n super(type);\n\n this[kCode] = options.code === undefined ? 0 : options.code;\n this[kReason] = options.reason === undefined ? '' : options.reason;\n this[kWasClean] = options.wasClean === undefined ? false : options.wasClean;\n }\n\n /**\n * @type {Number}\n */\n get code() {\n return this[kCode];\n }\n\n /**\n * @type {String}\n */\n get reason() {\n return this[kReason];\n }\n\n /**\n * @type {Boolean}\n */\n get wasClean() {\n return this[kWasClean];\n }\n}\n\nObject.defineProperty(CloseEvent.prototype, 'code', { enumerable: true });\nObject.defineProperty(CloseEvent.prototype, 'reason', { enumerable: true });\nObject.defineProperty(CloseEvent.prototype, 'wasClean', { enumerable: true });\n\n/**\n * Class representing an error event.\n *\n * @extends Event\n */\nclass ErrorEvent extends Event {\n /**\n * Create a new `ErrorEvent`.\n *\n * @param {String} type The name of the event\n * @param {Object} [options] A dictionary object that allows for setting\n * attributes via object members of the same name\n * @param {*} [options.error=null] The error that generated this event\n * @param {String} [options.message=''] The error message\n */\n constructor(type, options = {}) {\n super(type);\n\n this[kError] = options.error === undefined ? null : options.error;\n this[kMessage] = options.message === undefined ? '' : options.message;\n }\n\n /**\n * @type {*}\n */\n get error() {\n return this[kError];\n }\n\n /**\n * @type {String}\n */\n get message() {\n return this[kMessage];\n }\n}\n\nObject.defineProperty(ErrorEvent.prototype, 'error', { enumerable: true });\nObject.defineProperty(ErrorEvent.prototype, 'message', { enumerable: true });\n\n/**\n * Class representing a message event.\n *\n * @extends Event\n */\nclass MessageEvent extends Event {\n /**\n * Create a new `MessageEvent`.\n *\n * @param {String} type The name of the event\n * @param {Object} [options] A dictionary object that allows for setting\n * attributes via object members of the same name\n * @param {*} [options.data=null] The message content\n */\n constructor(type, options = {}) {\n super(type);\n\n this[kData] = options.data === undefined ? null : options.data;\n }\n\n /**\n * @type {*}\n */\n get data() {\n return this[kData];\n }\n}\n\nObject.defineProperty(MessageEvent.prototype, 'data', { enumerable: true });\n\n/**\n * This provides methods for emulating the `EventTarget` interface. It's not\n * meant to be used directly.\n *\n * @mixin\n */\nconst EventTarget = {\n /**\n * Register an event listener.\n *\n * @param {String} type A string representing the event type to listen for\n * @param {Function} listener The listener to add\n * @param {Object} [options] An options object specifies characteristics about\n * the event listener\n * @param {Boolean} [options.once=false] A `Boolean` indicating that the\n * listener should be invoked at most once after being added. If `true`,\n * the listener would be automatically removed when invoked.\n * @public\n */\n addEventListener(type, listener, options = {}) {\n let wrapper;\n\n if (type === 'message') {\n wrapper = function onMessage(data, isBinary) {\n const event = new MessageEvent('message', {\n data: isBinary ? data : data.toString()\n });\n\n event[kTarget] = this;\n listener.call(this, event);\n };\n } else if (type === 'close') {\n wrapper = function onClose(code, message) {\n const event = new CloseEvent('close', {\n code,\n reason: message.toString(),\n wasClean: this._closeFrameReceived && this._closeFrameSent\n });\n\n event[kTarget] = this;\n listener.call(this, event);\n };\n } else if (type === 'error') {\n wrapper = function onError(error) {\n const event = new ErrorEvent('error', {\n error,\n message: error.message\n });\n\n event[kTarget] = this;\n listener.call(this, event);\n };\n } else if (type === 'open') {\n wrapper = function onOpen() {\n const event = new Event('open');\n\n event[kTarget] = this;\n listener.call(this, event);\n };\n } else {\n return;\n }\n\n wrapper[kForOnEventAttribute] = !!options[kForOnEventAttribute];\n wrapper[kListener] = listener;\n\n if (options.once) {\n this.once(type, wrapper);\n } else {\n this.on(type, wrapper);\n }\n },\n\n /**\n * Remove an event listener.\n *\n * @param {String} type A string representing the event type to remove\n * @param {Function} handler The listener to remove\n * @public\n */\n removeEventListener(type, handler) {\n for (const listener of this.listeners(type)) {\n if (listener[kListener] === handler && !listener[kForOnEventAttribute]) {\n this.removeListener(type, listener);\n break;\n }\n }\n }\n};\n\nmodule.exports = {\n CloseEvent,\n ErrorEvent,\n Event,\n EventTarget,\n MessageEvent\n};\n","'use strict';\n\nconst { tokenChars } = require('./validation');\n\n/**\n * Adds an offer to the map of extension offers or a parameter to the map of\n * parameters.\n *\n * @param {Object} dest The map of extension offers or parameters\n * @param {String} name The extension or parameter name\n * @param {(Object|Boolean|String)} elem The extension parameters or the\n * parameter value\n * @private\n */\nfunction push(dest, name, elem) {\n if (dest[name] === undefined) dest[name] = [elem];\n else dest[name].push(elem);\n}\n\n/**\n * Parses the `Sec-WebSocket-Extensions` header into an object.\n *\n * @param {String} header The field value of the header\n * @return {Object} The parsed object\n * @public\n */\nfunction parse(header) {\n const offers = Object.create(null);\n let params = Object.create(null);\n let mustUnescape = false;\n let isEscaping = false;\n let inQuotes = false;\n let extensionName;\n let paramName;\n let start = -1;\n let code = -1;\n let end = -1;\n let i = 0;\n\n for (; i < header.length; i++) {\n code = header.charCodeAt(i);\n\n if (extensionName === undefined) {\n if (end === -1 && tokenChars[code] === 1) {\n if (start === -1) start = i;\n } else if (\n i !== 0 &&\n (code === 0x20 /* ' ' */ || code === 0x09) /* '\\t' */\n ) {\n if (end === -1 && start !== -1) end = i;\n } else if (code === 0x3b /* ';' */ || code === 0x2c /* ',' */) {\n if (start === -1) {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n\n if (end === -1) end = i;\n const name = header.slice(start, end);\n if (code === 0x2c) {\n push(offers, name, params);\n params = Object.create(null);\n } else {\n extensionName = name;\n }\n\n start = end = -1;\n } else {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n } else if (paramName === undefined) {\n if (end === -1 && tokenChars[code] === 1) {\n if (start === -1) start = i;\n } else if (code === 0x20 || code === 0x09) {\n if (end === -1 && start !== -1) end = i;\n } else if (code === 0x3b || code === 0x2c) {\n if (start === -1) {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n\n if (end === -1) end = i;\n push(params, header.slice(start, end), true);\n if (code === 0x2c) {\n push(offers, extensionName, params);\n params = Object.create(null);\n extensionName = undefined;\n }\n\n start = end = -1;\n } else if (code === 0x3d /* '=' */ && start !== -1 && end === -1) {\n paramName = header.slice(start, i);\n start = end = -1;\n } else {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n } else {\n //\n // The value of a quoted-string after unescaping must conform to the\n // token ABNF, so only token characters are valid.\n // Ref: https://tools.ietf.org/html/rfc6455#section-9.1\n //\n if (isEscaping) {\n if (tokenChars[code] !== 1) {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n if (start === -1) start = i;\n else if (!mustUnescape) mustUnescape = true;\n isEscaping = false;\n } else if (inQuotes) {\n if (tokenChars[code] === 1) {\n if (start === -1) start = i;\n } else if (code === 0x22 /* '\"' */ && start !== -1) {\n inQuotes = false;\n end = i;\n } else if (code === 0x5c /* '\\' */) {\n isEscaping = true;\n } else {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n } else if (code === 0x22 && header.charCodeAt(i - 1) === 0x3d) {\n inQuotes = true;\n } else if (end === -1 && tokenChars[code] === 1) {\n if (start === -1) start = i;\n } else if (start !== -1 && (code === 0x20 || code === 0x09)) {\n if (end === -1) end = i;\n } else if (code === 0x3b || code === 0x2c) {\n if (start === -1) {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n\n if (end === -1) end = i;\n let value = header.slice(start, end);\n if (mustUnescape) {\n value = value.replace(/\\\\/g, '');\n mustUnescape = false;\n }\n push(params, paramName, value);\n if (code === 0x2c) {\n push(offers, extensionName, params);\n params = Object.create(null);\n extensionName = undefined;\n }\n\n paramName = undefined;\n start = end = -1;\n } else {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n }\n }\n\n if (start === -1 || inQuotes || code === 0x20 || code === 0x09) {\n throw new SyntaxError('Unexpected end of input');\n }\n\n if (end === -1) end = i;\n const token = header.slice(start, end);\n if (extensionName === undefined) {\n push(offers, token, params);\n } else {\n if (paramName === undefined) {\n push(params, token, true);\n } else if (mustUnescape) {\n push(params, paramName, token.replace(/\\\\/g, ''));\n } else {\n push(params, paramName, token);\n }\n push(offers, extensionName, params);\n }\n\n return offers;\n}\n\n/**\n * Builds the `Sec-WebSocket-Extensions` header field value.\n *\n * @param {Object} extensions The map of extensions and parameters to format\n * @return {String} A string representing the given object\n * @public\n */\nfunction format(extensions) {\n return Object.keys(extensions)\n .map((extension) => {\n let configurations = extensions[extension];\n if (!Array.isArray(configurations)) configurations = [configurations];\n return configurations\n .map((params) => {\n return [extension]\n .concat(\n Object.keys(params).map((k) => {\n let values = params[k];\n if (!Array.isArray(values)) values = [values];\n return values\n .map((v) => (v === true ? k : `${k}=${v}`))\n .join('; ');\n })\n )\n .join('; ');\n })\n .join(', ');\n })\n .join(', ');\n}\n\nmodule.exports = { format, parse };\n","/* eslint no-unused-vars: [\"error\", { \"varsIgnorePattern\": \"^Readable$\" }] */\n\n'use strict';\n\nconst EventEmitter = require('events');\nconst https = require('https');\nconst http = require('http');\nconst net = require('net');\nconst tls = require('tls');\nconst { randomBytes, createHash } = require('crypto');\nconst { Readable } = require('stream');\nconst { URL } = require('url');\n\nconst PerMessageDeflate = require('./permessage-deflate');\nconst Receiver = require('./receiver');\nconst Sender = require('./sender');\nconst {\n BINARY_TYPES,\n EMPTY_BUFFER,\n GUID,\n kForOnEventAttribute,\n kListener,\n kStatusCode,\n kWebSocket,\n NOOP\n} = require('./constants');\nconst {\n EventTarget: { addEventListener, removeEventListener }\n} = require('./event-target');\nconst { format, parse } = require('./extension');\nconst { toBuffer } = require('./buffer-util');\n\nconst readyStates = ['CONNECTING', 'OPEN', 'CLOSING', 'CLOSED'];\nconst subprotocolRegex = /^[!#$%&'*+\\-.0-9A-Z^_`|a-z~]+$/;\nconst protocolVersions = [8, 13];\nconst closeTimeout = 30 * 1000;\n\n/**\n * Class representing a WebSocket.\n *\n * @extends EventEmitter\n */\nclass WebSocket extends EventEmitter {\n /**\n * Create a new `WebSocket`.\n *\n * @param {(String|URL)} address The URL to which to connect\n * @param {(String|String[])} [protocols] The subprotocols\n * @param {Object} [options] Connection options\n */\n constructor(address, protocols, options) {\n super();\n\n this._binaryType = BINARY_TYPES[0];\n this._closeCode = 1006;\n this._closeFrameReceived = false;\n this._closeFrameSent = false;\n this._closeMessage = EMPTY_BUFFER;\n this._closeTimer = null;\n this._extensions = {};\n this._paused = false;\n this._protocol = '';\n this._readyState = WebSocket.CONNECTING;\n this._receiver = null;\n this._sender = null;\n this._socket = null;\n\n if (address !== null) {\n this._bufferedAmount = 0;\n this._isServer = false;\n this._redirects = 0;\n\n if (protocols === undefined) {\n protocols = [];\n } else if (!Array.isArray(protocols)) {\n if (typeof protocols === 'object' && protocols !== null) {\n options = protocols;\n protocols = [];\n } else {\n protocols = [protocols];\n }\n }\n\n initAsClient(this, address, protocols, options);\n } else {\n this._isServer = true;\n }\n }\n\n /**\n * This deviates from the WHATWG interface since ws doesn't support the\n * required default \"blob\" type (instead we define a custom \"nodebuffer\"\n * type).\n *\n * @type {String}\n */\n get binaryType() {\n return this._binaryType;\n }\n\n set binaryType(type) {\n if (!BINARY_TYPES.includes(type)) return;\n\n this._binaryType = type;\n\n //\n // Allow to change `binaryType` on the fly.\n //\n if (this._receiver) this._receiver._binaryType = type;\n }\n\n /**\n * @type {Number}\n */\n get bufferedAmount() {\n if (!this._socket) return this._bufferedAmount;\n\n return this._socket._writableState.length + this._sender._bufferedBytes;\n }\n\n /**\n * @type {String}\n */\n get extensions() {\n return Object.keys(this._extensions).join();\n }\n\n /**\n * @type {Boolean}\n */\n get isPaused() {\n return this._paused;\n }\n\n /**\n * @type {Function}\n */\n /* istanbul ignore next */\n get onclose() {\n return null;\n }\n\n /**\n * @type {Function}\n */\n /* istanbul ignore next */\n get onerror() {\n return null;\n }\n\n /**\n * @type {Function}\n */\n /* istanbul ignore next */\n get onopen() {\n return null;\n }\n\n /**\n * @type {Function}\n */\n /* istanbul ignore next */\n get onmessage() {\n return null;\n }\n\n /**\n * @type {String}\n */\n get protocol() {\n return this._protocol;\n }\n\n /**\n * @type {Number}\n */\n get readyState() {\n return this._readyState;\n }\n\n /**\n * @type {String}\n */\n get url() {\n return this._url;\n }\n\n /**\n * Set up the socket and the internal resources.\n *\n * @param {(net.Socket|tls.Socket)} socket The network socket between the\n * server and client\n * @param {Buffer} head The first packet of the upgraded stream\n * @param {Object} options Options object\n * @param {Function} [options.generateMask] The function used to generate the\n * masking key\n * @param {Number} [options.maxPayload=0] The maximum allowed message size\n * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or\n * not to skip UTF-8 validation for text and close messages\n * @private\n */\n setSocket(socket, head, options) {\n const receiver = new Receiver({\n binaryType: this.binaryType,\n extensions: this._extensions,\n isServer: this._isServer,\n maxPayload: options.maxPayload,\n skipUTF8Validation: options.skipUTF8Validation\n });\n\n this._sender = new Sender(socket, this._extensions, options.generateMask);\n this._receiver = receiver;\n this._socket = socket;\n\n receiver[kWebSocket] = this;\n socket[kWebSocket] = this;\n\n receiver.on('conclude', receiverOnConclude);\n receiver.on('drain', receiverOnDrain);\n receiver.on('error', receiverOnError);\n receiver.on('message', receiverOnMessage);\n receiver.on('ping', receiverOnPing);\n receiver.on('pong', receiverOnPong);\n\n socket.setTimeout(0);\n socket.setNoDelay();\n\n if (head.length > 0) socket.unshift(head);\n\n socket.on('close', socketOnClose);\n socket.on('data', socketOnData);\n socket.on('end', socketOnEnd);\n socket.on('error', socketOnError);\n\n this._readyState = WebSocket.OPEN;\n this.emit('open');\n }\n\n /**\n * Emit the `'close'` event.\n *\n * @private\n */\n emitClose() {\n if (!this._socket) {\n this._readyState = WebSocket.CLOSED;\n this.emit('close', this._closeCode, this._closeMessage);\n return;\n }\n\n if (this._extensions[PerMessageDeflate.extensionName]) {\n this._extensions[PerMessageDeflate.extensionName].cleanup();\n }\n\n this._receiver.removeAllListeners();\n this._readyState = WebSocket.CLOSED;\n this.emit('close', this._closeCode, this._closeMessage);\n }\n\n /**\n * Start a closing handshake.\n *\n * +----------+ +-----------+ +----------+\n * - - -|ws.close()|-->|close frame|-->|ws.close()|- - -\n * | +----------+ +-----------+ +----------+ |\n * +----------+ +-----------+ |\n * CLOSING |ws.close()|<--|close frame|<--+-----+ CLOSING\n * +----------+ +-----------+ |\n * | | | +---+ |\n * +------------------------+-->|fin| - - - -\n * | +---+ | +---+\n * - - - - -|fin|<---------------------+\n * +---+\n *\n * @param {Number} [code] Status code explaining why the connection is closing\n * @param {(String|Buffer)} [data] The reason why the connection is\n * closing\n * @public\n */\n close(code, data) {\n if (this.readyState === WebSocket.CLOSED) return;\n if (this.readyState === WebSocket.CONNECTING) {\n const msg = 'WebSocket was closed before the connection was established';\n return abortHandshake(this, this._req, msg);\n }\n\n if (this.readyState === WebSocket.CLOSING) {\n if (\n this._closeFrameSent &&\n (this._closeFrameReceived || this._receiver._writableState.errorEmitted)\n ) {\n this._socket.end();\n }\n\n return;\n }\n\n this._readyState = WebSocket.CLOSING;\n this._sender.close(code, data, !this._isServer, (err) => {\n //\n // This error is handled by the `'error'` listener on the socket. We only\n // want to know if the close frame has been sent here.\n //\n if (err) return;\n\n this._closeFrameSent = true;\n\n if (\n this._closeFrameReceived ||\n this._receiver._writableState.errorEmitted\n ) {\n this._socket.end();\n }\n });\n\n //\n // Specify a timeout for the closing handshake to complete.\n //\n this._closeTimer = setTimeout(\n this._socket.destroy.bind(this._socket),\n closeTimeout\n );\n }\n\n /**\n * Pause the socket.\n *\n * @public\n */\n pause() {\n if (\n this.readyState === WebSocket.CONNECTING ||\n this.readyState === WebSocket.CLOSED\n ) {\n return;\n }\n\n this._paused = true;\n this._socket.pause();\n }\n\n /**\n * Send a ping.\n *\n * @param {*} [data] The data to send\n * @param {Boolean} [mask] Indicates whether or not to mask `data`\n * @param {Function} [cb] Callback which is executed when the ping is sent\n * @public\n */\n ping(data, mask, cb) {\n if (this.readyState === WebSocket.CONNECTING) {\n throw new Error('WebSocket is not open: readyState 0 (CONNECTING)');\n }\n\n if (typeof data === 'function') {\n cb = data;\n data = mask = undefined;\n } else if (typeof mask === 'function') {\n cb = mask;\n mask = undefined;\n }\n\n if (typeof data === 'number') data = data.toString();\n\n if (this.readyState !== WebSocket.OPEN) {\n sendAfterClose(this, data, cb);\n return;\n }\n\n if (mask === undefined) mask = !this._isServer;\n this._sender.ping(data || EMPTY_BUFFER, mask, cb);\n }\n\n /**\n * Send a pong.\n *\n * @param {*} [data] The data to send\n * @param {Boolean} [mask] Indicates whether or not to mask `data`\n * @param {Function} [cb] Callback which is executed when the pong is sent\n * @public\n */\n pong(data, mask, cb) {\n if (this.readyState === WebSocket.CONNECTING) {\n throw new Error('WebSocket is not open: readyState 0 (CONNECTING)');\n }\n\n if (typeof data === 'function') {\n cb = data;\n data = mask = undefined;\n } else if (typeof mask === 'function') {\n cb = mask;\n mask = undefined;\n }\n\n if (typeof data === 'number') data = data.toString();\n\n if (this.readyState !== WebSocket.OPEN) {\n sendAfterClose(this, data, cb);\n return;\n }\n\n if (mask === undefined) mask = !this._isServer;\n this._sender.pong(data || EMPTY_BUFFER, mask, cb);\n }\n\n /**\n * Resume the socket.\n *\n * @public\n */\n resume() {\n if (\n this.readyState === WebSocket.CONNECTING ||\n this.readyState === WebSocket.CLOSED\n ) {\n return;\n }\n\n this._paused = false;\n if (!this._receiver._writableState.needDrain) this._socket.resume();\n }\n\n /**\n * Send a data message.\n *\n * @param {*} data The message to send\n * @param {Object} [options] Options object\n * @param {Boolean} [options.binary] Specifies whether `data` is binary or\n * text\n * @param {Boolean} [options.compress] Specifies whether or not to compress\n * `data`\n * @param {Boolean} [options.fin=true] Specifies whether the fragment is the\n * last one\n * @param {Boolean} [options.mask] Specifies whether or not to mask `data`\n * @param {Function} [cb] Callback which is executed when data is written out\n * @public\n */\n send(data, options, cb) {\n if (this.readyState === WebSocket.CONNECTING) {\n throw new Error('WebSocket is not open: readyState 0 (CONNECTING)');\n }\n\n if (typeof options === 'function') {\n cb = options;\n options = {};\n }\n\n if (typeof data === 'number') data = data.toString();\n\n if (this.readyState !== WebSocket.OPEN) {\n sendAfterClose(this, data, cb);\n return;\n }\n\n const opts = {\n binary: typeof data !== 'string',\n mask: !this._isServer,\n compress: true,\n fin: true,\n ...options\n };\n\n if (!this._extensions[PerMessageDeflate.extensionName]) {\n opts.compress = false;\n }\n\n this._sender.send(data || EMPTY_BUFFER, opts, cb);\n }\n\n /**\n * Forcibly close the connection.\n *\n * @public\n */\n terminate() {\n if (this.readyState === WebSocket.CLOSED) return;\n if (this.readyState === WebSocket.CONNECTING) {\n const msg = 'WebSocket was closed before the connection was established';\n return abortHandshake(this, this._req, msg);\n }\n\n if (this._socket) {\n this._readyState = WebSocket.CLOSING;\n this._socket.destroy();\n }\n }\n}\n\n/**\n * @constant {Number} CONNECTING\n * @memberof WebSocket\n */\nObject.defineProperty(WebSocket, 'CONNECTING', {\n enumerable: true,\n value: readyStates.indexOf('CONNECTING')\n});\n\n/**\n * @constant {Number} CONNECTING\n * @memberof WebSocket.prototype\n */\nObject.defineProperty(WebSocket.prototype, 'CONNECTING', {\n enumerable: true,\n value: readyStates.indexOf('CONNECTING')\n});\n\n/**\n * @constant {Number} OPEN\n * @memberof WebSocket\n */\nObject.defineProperty(WebSocket, 'OPEN', {\n enumerable: true,\n value: readyStates.indexOf('OPEN')\n});\n\n/**\n * @constant {Number} OPEN\n * @memberof WebSocket.prototype\n */\nObject.defineProperty(WebSocket.prototype, 'OPEN', {\n enumerable: true,\n value: readyStates.indexOf('OPEN')\n});\n\n/**\n * @constant {Number} CLOSING\n * @memberof WebSocket\n */\nObject.defineProperty(WebSocket, 'CLOSING', {\n enumerable: true,\n value: readyStates.indexOf('CLOSING')\n});\n\n/**\n * @constant {Number} CLOSING\n * @memberof WebSocket.prototype\n */\nObject.defineProperty(WebSocket.prototype, 'CLOSING', {\n enumerable: true,\n value: readyStates.indexOf('CLOSING')\n});\n\n/**\n * @constant {Number} CLOSED\n * @memberof WebSocket\n */\nObject.defineProperty(WebSocket, 'CLOSED', {\n enumerable: true,\n value: readyStates.indexOf('CLOSED')\n});\n\n/**\n * @constant {Number} CLOSED\n * @memberof WebSocket.prototype\n */\nObject.defineProperty(WebSocket.prototype, 'CLOSED', {\n enumerable: true,\n value: readyStates.indexOf('CLOSED')\n});\n\n[\n 'binaryType',\n 'bufferedAmount',\n 'extensions',\n 'isPaused',\n 'protocol',\n 'readyState',\n 'url'\n].forEach((property) => {\n Object.defineProperty(WebSocket.prototype, property, { enumerable: true });\n});\n\n//\n// Add the `onopen`, `onerror`, `onclose`, and `onmessage` attributes.\n// See https://html.spec.whatwg.org/multipage/comms.html#the-websocket-interface\n//\n['open', 'error', 'close', 'message'].forEach((method) => {\n Object.defineProperty(WebSocket.prototype, `on${method}`, {\n enumerable: true,\n get() {\n for (const listener of this.listeners(method)) {\n if (listener[kForOnEventAttribute]) return listener[kListener];\n }\n\n return null;\n },\n set(handler) {\n for (const listener of this.listeners(method)) {\n if (listener[kForOnEventAttribute]) {\n this.removeListener(method, listener);\n break;\n }\n }\n\n if (typeof handler !== 'function') return;\n\n this.addEventListener(method, handler, {\n [kForOnEventAttribute]: true\n });\n }\n });\n});\n\nWebSocket.prototype.addEventListener = addEventListener;\nWebSocket.prototype.removeEventListener = removeEventListener;\n\nmodule.exports = WebSocket;\n\n/**\n * Initialize a WebSocket client.\n *\n * @param {WebSocket} websocket The client to initialize\n * @param {(String|URL)} address The URL to which to connect\n * @param {Array} protocols The subprotocols\n * @param {Object} [options] Connection options\n * @param {Boolean} [options.followRedirects=false] Whether or not to follow\n * redirects\n * @param {Function} [options.generateMask] The function used to generate the\n * masking key\n * @param {Number} [options.handshakeTimeout] Timeout in milliseconds for the\n * handshake request\n * @param {Number} [options.maxPayload=104857600] The maximum allowed message\n * size\n * @param {Number} [options.maxRedirects=10] The maximum number of redirects\n * allowed\n * @param {String} [options.origin] Value of the `Origin` or\n * `Sec-WebSocket-Origin` header\n * @param {(Boolean|Object)} [options.perMessageDeflate=true] Enable/disable\n * permessage-deflate\n * @param {Number} [options.protocolVersion=13] Value of the\n * `Sec-WebSocket-Version` header\n * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or\n * not to skip UTF-8 validation for text and close messages\n * @private\n */\nfunction initAsClient(websocket, address, protocols, options) {\n const opts = {\n protocolVersion: protocolVersions[1],\n maxPayload: 100 * 1024 * 1024,\n skipUTF8Validation: false,\n perMessageDeflate: true,\n followRedirects: false,\n maxRedirects: 10,\n ...options,\n createConnection: undefined,\n socketPath: undefined,\n hostname: undefined,\n protocol: undefined,\n timeout: undefined,\n method: undefined,\n host: undefined,\n path: undefined,\n port: undefined\n };\n\n if (!protocolVersions.includes(opts.protocolVersion)) {\n throw new RangeError(\n `Unsupported protocol version: ${opts.protocolVersion} ` +\n `(supported versions: ${protocolVersions.join(', ')})`\n );\n }\n\n let parsedUrl;\n\n if (address instanceof URL) {\n parsedUrl = address;\n websocket._url = address.href;\n } else {\n try {\n parsedUrl = new URL(address);\n } catch (e) {\n throw new SyntaxError(`Invalid URL: ${address}`);\n }\n\n websocket._url = address;\n }\n\n const isSecure = parsedUrl.protocol === 'wss:';\n const isUnixSocket = parsedUrl.protocol === 'ws+unix:';\n let invalidURLMessage;\n\n if (parsedUrl.protocol !== 'ws:' && !isSecure && !isUnixSocket) {\n invalidURLMessage =\n 'The URL\\'s protocol must be one of \"ws:\", \"wss:\", or \"ws+unix:\"';\n } else if (isUnixSocket && !parsedUrl.pathname) {\n invalidURLMessage = \"The URL's pathname is empty\";\n } else if (parsedUrl.hash) {\n invalidURLMessage = 'The URL contains a fragment identifier';\n }\n\n if (invalidURLMessage) {\n const err = new SyntaxError(invalidURLMessage);\n\n if (websocket._redirects === 0) {\n throw err;\n } else {\n emitErrorAndClose(websocket, err);\n return;\n }\n }\n\n const defaultPort = isSecure ? 443 : 80;\n const key = randomBytes(16).toString('base64');\n const get = isSecure ? https.get : http.get;\n const protocolSet = new Set();\n let perMessageDeflate;\n\n opts.createConnection = isSecure ? tlsConnect : netConnect;\n opts.defaultPort = opts.defaultPort || defaultPort;\n opts.port = parsedUrl.port || defaultPort;\n opts.host = parsedUrl.hostname.startsWith('[')\n ? parsedUrl.hostname.slice(1, -1)\n : parsedUrl.hostname;\n opts.headers = {\n 'Sec-WebSocket-Version': opts.protocolVersion,\n 'Sec-WebSocket-Key': key,\n Connection: 'Upgrade',\n Upgrade: 'websocket',\n ...opts.headers\n };\n opts.path = parsedUrl.pathname + parsedUrl.search;\n opts.timeout = opts.handshakeTimeout;\n\n if (opts.perMessageDeflate) {\n perMessageDeflate = new PerMessageDeflate(\n opts.perMessageDeflate !== true ? opts.perMessageDeflate : {},\n false,\n opts.maxPayload\n );\n opts.headers['Sec-WebSocket-Extensions'] = format({\n [PerMessageDeflate.extensionName]: perMessageDeflate.offer()\n });\n }\n if (protocols.length) {\n for (const protocol of protocols) {\n if (\n typeof protocol !== 'string' ||\n !subprotocolRegex.test(protocol) ||\n protocolSet.has(protocol)\n ) {\n throw new SyntaxError(\n 'An invalid or duplicated subprotocol was specified'\n );\n }\n\n protocolSet.add(protocol);\n }\n\n opts.headers['Sec-WebSocket-Protocol'] = protocols.join(',');\n }\n if (opts.origin) {\n if (opts.protocolVersion < 13) {\n opts.headers['Sec-WebSocket-Origin'] = opts.origin;\n } else {\n opts.headers.Origin = opts.origin;\n }\n }\n if (parsedUrl.username || parsedUrl.password) {\n opts.auth = `${parsedUrl.username}:${parsedUrl.password}`;\n }\n\n if (isUnixSocket) {\n const parts = opts.path.split(':');\n\n opts.socketPath = parts[0];\n opts.path = parts[1];\n }\n\n if (opts.followRedirects) {\n if (websocket._redirects === 0) {\n websocket._originalHost = parsedUrl.host;\n\n const headers = options && options.headers;\n\n //\n // Shallow copy the user provided options so that headers can be changed\n // without mutating the original object.\n //\n options = { ...options, headers: {} };\n\n if (headers) {\n for (const [key, value] of Object.entries(headers)) {\n options.headers[key.toLowerCase()] = value;\n }\n }\n } else if (parsedUrl.host !== websocket._originalHost) {\n //\n // Match curl 7.77.0 behavior and drop the following headers. These\n // headers are also dropped when following a redirect to a subdomain.\n //\n delete opts.headers.authorization;\n delete opts.headers.cookie;\n delete opts.headers.host;\n opts.auth = undefined;\n }\n\n //\n // Match curl 7.77.0 behavior and make the first `Authorization` header win.\n // If the `Authorization` header is set, then there is nothing to do as it\n // will take precedence.\n //\n if (opts.auth && !options.headers.authorization) {\n options.headers.authorization =\n 'Basic ' + Buffer.from(opts.auth).toString('base64');\n }\n }\n\n let req = (websocket._req = get(opts));\n\n if (opts.timeout) {\n req.on('timeout', () => {\n abortHandshake(websocket, req, 'Opening handshake has timed out');\n });\n }\n\n req.on('error', (err) => {\n if (req === null || req.aborted) return;\n\n req = websocket._req = null;\n emitErrorAndClose(websocket, err);\n });\n\n req.on('response', (res) => {\n const location = res.headers.location;\n const statusCode = res.statusCode;\n\n if (\n location &&\n opts.followRedirects &&\n statusCode >= 300 &&\n statusCode < 400\n ) {\n if (++websocket._redirects > opts.maxRedirects) {\n abortHandshake(websocket, req, 'Maximum redirects exceeded');\n return;\n }\n\n req.abort();\n\n let addr;\n\n try {\n addr = new URL(location, address);\n } catch (e) {\n const err = new SyntaxError(`Invalid URL: ${location}`);\n emitErrorAndClose(websocket, err);\n return;\n }\n\n initAsClient(websocket, addr, protocols, options);\n } else if (!websocket.emit('unexpected-response', req, res)) {\n abortHandshake(\n websocket,\n req,\n `Unexpected server response: ${res.statusCode}`\n );\n }\n });\n\n req.on('upgrade', (res, socket, head) => {\n websocket.emit('upgrade', res);\n\n //\n // The user may have closed the connection from a listener of the `upgrade`\n // event.\n //\n if (websocket.readyState !== WebSocket.CONNECTING) return;\n\n req = websocket._req = null;\n\n const digest = createHash('sha1')\n .update(key + GUID)\n .digest('base64');\n\n if (res.headers['sec-websocket-accept'] !== digest) {\n abortHandshake(websocket, socket, 'Invalid Sec-WebSocket-Accept header');\n return;\n }\n\n const serverProt = res.headers['sec-websocket-protocol'];\n let protError;\n\n if (serverProt !== undefined) {\n if (!protocolSet.size) {\n protError = 'Server sent a subprotocol but none was requested';\n } else if (!protocolSet.has(serverProt)) {\n protError = 'Server sent an invalid subprotocol';\n }\n } else if (protocolSet.size) {\n protError = 'Server sent no subprotocol';\n }\n\n if (protError) {\n abortHandshake(websocket, socket, protError);\n return;\n }\n\n if (serverProt) websocket._protocol = serverProt;\n\n const secWebSocketExtensions = res.headers['sec-websocket-extensions'];\n\n if (secWebSocketExtensions !== undefined) {\n if (!perMessageDeflate) {\n const message =\n 'Server sent a Sec-WebSocket-Extensions header but no extension ' +\n 'was requested';\n abortHandshake(websocket, socket, message);\n return;\n }\n\n let extensions;\n\n try {\n extensions = parse(secWebSocketExtensions);\n } catch (err) {\n const message = 'Invalid Sec-WebSocket-Extensions header';\n abortHandshake(websocket, socket, message);\n return;\n }\n\n const extensionNames = Object.keys(extensions);\n\n if (\n extensionNames.length !== 1 ||\n extensionNames[0] !== PerMessageDeflate.extensionName\n ) {\n const message = 'Server indicated an extension that was not requested';\n abortHandshake(websocket, socket, message);\n return;\n }\n\n try {\n perMessageDeflate.accept(extensions[PerMessageDeflate.extensionName]);\n } catch (err) {\n const message = 'Invalid Sec-WebSocket-Extensions header';\n abortHandshake(websocket, socket, message);\n return;\n }\n\n websocket._extensions[PerMessageDeflate.extensionName] =\n perMessageDeflate;\n }\n\n websocket.setSocket(socket, head, {\n generateMask: opts.generateMask,\n maxPayload: opts.maxPayload,\n skipUTF8Validation: opts.skipUTF8Validation\n });\n });\n}\n\n/**\n * Emit the `'error'` and `'close'` event.\n *\n * @param {WebSocket} websocket The WebSocket instance\n * @param {Error} The error to emit\n * @private\n */\nfunction emitErrorAndClose(websocket, err) {\n websocket._readyState = WebSocket.CLOSING;\n websocket.emit('error', err);\n websocket.emitClose();\n}\n\n/**\n * Create a `net.Socket` and initiate a connection.\n *\n * @param {Object} options Connection options\n * @return {net.Socket} The newly created socket used to start the connection\n * @private\n */\nfunction netConnect(options) {\n options.path = options.socketPath;\n return net.connect(options);\n}\n\n/**\n * Create a `tls.TLSSocket` and initiate a connection.\n *\n * @param {Object} options Connection options\n * @return {tls.TLSSocket} The newly created socket used to start the connection\n * @private\n */\nfunction tlsConnect(options) {\n options.path = undefined;\n\n if (!options.servername && options.servername !== '') {\n options.servername = net.isIP(options.host) ? '' : options.host;\n }\n\n return tls.connect(options);\n}\n\n/**\n * Abort the handshake and emit an error.\n *\n * @param {WebSocket} websocket The WebSocket instance\n * @param {(http.ClientRequest|net.Socket|tls.Socket)} stream The request to\n * abort or the socket to destroy\n * @param {String} message The error message\n * @private\n */\nfunction abortHandshake(websocket, stream, message) {\n websocket._readyState = WebSocket.CLOSING;\n\n const err = new Error(message);\n Error.captureStackTrace(err, abortHandshake);\n\n if (stream.setHeader) {\n stream.abort();\n\n if (stream.socket && !stream.socket.destroyed) {\n //\n // On Node.js >= 14.3.0 `request.abort()` does not destroy the socket if\n // called after the request completed. See\n // https://github.com/websockets/ws/issues/1869.\n //\n stream.socket.destroy();\n }\n\n stream.once('abort', websocket.emitClose.bind(websocket));\n websocket.emit('error', err);\n } else {\n stream.destroy(err);\n stream.once('error', websocket.emit.bind(websocket, 'error'));\n stream.once('close', websocket.emitClose.bind(websocket));\n }\n}\n\n/**\n * Handle cases where the `ping()`, `pong()`, or `send()` methods are called\n * when the `readyState` attribute is `CLOSING` or `CLOSED`.\n *\n * @param {WebSocket} websocket The WebSocket instance\n * @param {*} [data] The data to send\n * @param {Function} [cb] Callback\n * @private\n */\nfunction sendAfterClose(websocket, data, cb) {\n if (data) {\n const length = toBuffer(data).length;\n\n //\n // The `_bufferedAmount` property is used only when the peer is a client and\n // the opening handshake fails. Under these circumstances, in fact, the\n // `setSocket()` method is not called, so the `_socket` and `_sender`\n // properties are set to `null`.\n //\n if (websocket._socket) websocket._sender._bufferedBytes += length;\n else websocket._bufferedAmount += length;\n }\n\n if (cb) {\n const err = new Error(\n `WebSocket is not open: readyState ${websocket.readyState} ` +\n `(${readyStates[websocket.readyState]})`\n );\n cb(err);\n }\n}\n\n/**\n * The listener of the `Receiver` `'conclude'` event.\n *\n * @param {Number} code The status code\n * @param {Buffer} reason The reason for closing\n * @private\n */\nfunction receiverOnConclude(code, reason) {\n const websocket = this[kWebSocket];\n\n websocket._closeFrameReceived = true;\n websocket._closeMessage = reason;\n websocket._closeCode = code;\n\n if (websocket._socket[kWebSocket] === undefined) return;\n\n websocket._socket.removeListener('data', socketOnData);\n process.nextTick(resume, websocket._socket);\n\n if (code === 1005) websocket.close();\n else websocket.close(code, reason);\n}\n\n/**\n * The listener of the `Receiver` `'drain'` event.\n *\n * @private\n */\nfunction receiverOnDrain() {\n const websocket = this[kWebSocket];\n\n if (!websocket.isPaused) websocket._socket.resume();\n}\n\n/**\n * The listener of the `Receiver` `'error'` event.\n *\n * @param {(RangeError|Error)} err The emitted error\n * @private\n */\nfunction receiverOnError(err) {\n const websocket = this[kWebSocket];\n\n if (websocket._socket[kWebSocket] !== undefined) {\n websocket._socket.removeListener('data', socketOnData);\n\n //\n // On Node.js < 14.0.0 the `'error'` event is emitted synchronously. See\n // https://github.com/websockets/ws/issues/1940.\n //\n process.nextTick(resume, websocket._socket);\n\n websocket.close(err[kStatusCode]);\n }\n\n websocket.emit('error', err);\n}\n\n/**\n * The listener of the `Receiver` `'finish'` event.\n *\n * @private\n */\nfunction receiverOnFinish() {\n this[kWebSocket].emitClose();\n}\n\n/**\n * The listener of the `Receiver` `'message'` event.\n *\n * @param {Buffer|ArrayBuffer|Buffer[])} data The message\n * @param {Boolean} isBinary Specifies whether the message is binary or not\n * @private\n */\nfunction receiverOnMessage(data, isBinary) {\n this[kWebSocket].emit('message', data, isBinary);\n}\n\n/**\n * The listener of the `Receiver` `'ping'` event.\n *\n * @param {Buffer} data The data included in the ping frame\n * @private\n */\nfunction receiverOnPing(data) {\n const websocket = this[kWebSocket];\n\n websocket.pong(data, !websocket._isServer, NOOP);\n websocket.emit('ping', data);\n}\n\n/**\n * The listener of the `Receiver` `'pong'` event.\n *\n * @param {Buffer} data The data included in the pong frame\n * @private\n */\nfunction receiverOnPong(data) {\n this[kWebSocket].emit('pong', data);\n}\n\n/**\n * Resume a readable stream\n *\n * @param {Readable} stream The readable stream\n * @private\n */\nfunction resume(stream) {\n stream.resume();\n}\n\n/**\n * The listener of the `net.Socket` `'close'` event.\n *\n * @private\n */\nfunction socketOnClose() {\n const websocket = this[kWebSocket];\n\n this.removeListener('close', socketOnClose);\n this.removeListener('data', socketOnData);\n this.removeListener('end', socketOnEnd);\n\n websocket._readyState = WebSocket.CLOSING;\n\n let chunk;\n\n //\n // The close frame might not have been received or the `'end'` event emitted,\n // for example, if the socket was destroyed due to an error. Ensure that the\n // `receiver` stream is closed after writing any remaining buffered data to\n // it. If the readable side of the socket is in flowing mode then there is no\n // buffered data as everything has been already written and `readable.read()`\n // will return `null`. If instead, the socket is paused, any possible buffered\n // data will be read as a single chunk.\n //\n if (\n !this._readableState.endEmitted &&\n !websocket._closeFrameReceived &&\n !websocket._receiver._writableState.errorEmitted &&\n (chunk = websocket._socket.read()) !== null\n ) {\n websocket._receiver.write(chunk);\n }\n\n websocket._receiver.end();\n\n this[kWebSocket] = undefined;\n\n clearTimeout(websocket._closeTimer);\n\n if (\n websocket._receiver._writableState.finished ||\n websocket._receiver._writableState.errorEmitted\n ) {\n websocket.emitClose();\n } else {\n websocket._receiver.on('error', receiverOnFinish);\n websocket._receiver.on('finish', receiverOnFinish);\n }\n}\n\n/**\n * The listener of the `net.Socket` `'data'` event.\n *\n * @param {Buffer} chunk A chunk of data\n * @private\n */\nfunction socketOnData(chunk) {\n if (!this[kWebSocket]._receiver.write(chunk)) {\n this.pause();\n }\n}\n\n/**\n * The listener of the `net.Socket` `'end'` event.\n *\n * @private\n */\nfunction socketOnEnd() {\n const websocket = this[kWebSocket];\n\n websocket._readyState = WebSocket.CLOSING;\n websocket._receiver.end();\n this.end();\n}\n\n/**\n * The listener of the `net.Socket` `'error'` event.\n *\n * @private\n */\nfunction socketOnError() {\n const websocket = this[kWebSocket];\n\n this.removeListener('error', socketOnError);\n this.on('error', NOOP);\n\n if (websocket) {\n websocket._readyState = WebSocket.CLOSING;\n this.destroy();\n }\n}\n","'use strict';\n\nconst { Duplex } = require('stream');\n\n/**\n * Emits the `'close'` event on a stream.\n *\n * @param {Duplex} stream The stream.\n * @private\n */\nfunction emitClose(stream) {\n stream.emit('close');\n}\n\n/**\n * The listener of the `'end'` event.\n *\n * @private\n */\nfunction duplexOnEnd() {\n if (!this.destroyed && this._writableState.finished) {\n this.destroy();\n }\n}\n\n/**\n * The listener of the `'error'` event.\n *\n * @param {Error} err The error\n * @private\n */\nfunction duplexOnError(err) {\n this.removeListener('error', duplexOnError);\n this.destroy();\n if (this.listenerCount('error') === 0) {\n // Do not suppress the throwing behavior.\n this.emit('error', err);\n }\n}\n\n/**\n * Wraps a `WebSocket` in a duplex stream.\n *\n * @param {WebSocket} ws The `WebSocket` to wrap\n * @param {Object} [options] The options for the `Duplex` constructor\n * @return {Duplex} The duplex stream\n * @public\n */\nfunction createWebSocketStream(ws, options) {\n let terminateOnDestroy = true;\n\n const duplex = new Duplex({\n ...options,\n autoDestroy: false,\n emitClose: false,\n objectMode: false,\n writableObjectMode: false\n });\n\n ws.on('message', function message(msg, isBinary) {\n const data =\n !isBinary && duplex._readableState.objectMode ? msg.toString() : msg;\n\n if (!duplex.push(data)) ws.pause();\n });\n\n ws.once('error', function error(err) {\n if (duplex.destroyed) return;\n\n // Prevent `ws.terminate()` from being called by `duplex._destroy()`.\n //\n // - If the `'error'` event is emitted before the `'open'` event, then\n // `ws.terminate()` is a noop as no socket is assigned.\n // - Otherwise, the error is re-emitted by the listener of the `'error'`\n // event of the `Receiver` object. The listener already closes the\n // connection by calling `ws.close()`. This allows a close frame to be\n // sent to the other peer. If `ws.terminate()` is called right after this,\n // then the close frame might not be sent.\n terminateOnDestroy = false;\n duplex.destroy(err);\n });\n\n ws.once('close', function close() {\n if (duplex.destroyed) return;\n\n duplex.push(null);\n });\n\n duplex._destroy = function (err, callback) {\n if (ws.readyState === ws.CLOSED) {\n callback(err);\n process.nextTick(emitClose, duplex);\n return;\n }\n\n let called = false;\n\n ws.once('error', function error(err) {\n called = true;\n callback(err);\n });\n\n ws.once('close', function close() {\n if (!called) callback(err);\n process.nextTick(emitClose, duplex);\n });\n\n if (terminateOnDestroy) ws.terminate();\n };\n\n duplex._final = function (callback) {\n if (ws.readyState === ws.CONNECTING) {\n ws.once('open', function open() {\n duplex._final(callback);\n });\n return;\n }\n\n // If the value of the `_socket` property is `null` it means that `ws` is a\n // client websocket and the handshake failed. In fact, when this happens, a\n // socket is never assigned to the websocket. Wait for the `'error'` event\n // that will be emitted by the websocket.\n if (ws._socket === null) return;\n\n if (ws._socket._writableState.finished) {\n callback();\n if (duplex._readableState.endEmitted) duplex.destroy();\n } else {\n ws._socket.once('finish', function finish() {\n // `duplex` is not destroyed here because the `'end'` event will be\n // emitted on `duplex` after this `'finish'` event. The EOF signaling\n // `null` chunk is, in fact, pushed when the websocket emits `'close'`.\n callback();\n });\n ws.close();\n }\n };\n\n duplex._read = function () {\n if (ws.isPaused) ws.resume();\n };\n\n duplex._write = function (chunk, encoding, callback) {\n if (ws.readyState === ws.CONNECTING) {\n ws.once('open', function open() {\n duplex._write(chunk, encoding, callback);\n });\n return;\n }\n\n ws.send(chunk, callback);\n };\n\n duplex.on('end', duplexOnEnd);\n duplex.on('error', duplexOnError);\n return duplex;\n}\n\nmodule.exports = createWebSocketStream;\n","'use strict';\n\nconst { tokenChars } = require('./validation');\n\n/**\n * Parses the `Sec-WebSocket-Protocol` header into a set of subprotocol names.\n *\n * @param {String} header The field value of the header\n * @return {Set} The subprotocol names\n * @public\n */\nfunction parse(header) {\n const protocols = new Set();\n let start = -1;\n let end = -1;\n let i = 0;\n\n for (i; i < header.length; i++) {\n const code = header.charCodeAt(i);\n\n if (end === -1 && tokenChars[code] === 1) {\n if (start === -1) start = i;\n } else if (\n i !== 0 &&\n (code === 0x20 /* ' ' */ || code === 0x09) /* '\\t' */\n ) {\n if (end === -1 && start !== -1) end = i;\n } else if (code === 0x2c /* ',' */) {\n if (start === -1) {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n\n if (end === -1) end = i;\n\n const protocol = header.slice(start, end);\n\n if (protocols.has(protocol)) {\n throw new SyntaxError(`The \"${protocol}\" subprotocol is duplicated`);\n }\n\n protocols.add(protocol);\n start = end = -1;\n } else {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n }\n\n if (start === -1 || end !== -1) {\n throw new SyntaxError('Unexpected end of input');\n }\n\n const protocol = header.slice(start, i);\n\n if (protocols.has(protocol)) {\n throw new SyntaxError(`The \"${protocol}\" subprotocol is duplicated`);\n }\n\n protocols.add(protocol);\n return protocols;\n}\n\nmodule.exports = { parse };\n","/* eslint no-unused-vars: [\"error\", { \"varsIgnorePattern\": \"^net|tls|https$\" }] */\n\n'use strict';\n\nconst EventEmitter = require('events');\nconst http = require('http');\nconst https = require('https');\nconst net = require('net');\nconst tls = require('tls');\nconst { createHash } = require('crypto');\n\nconst extension = require('./extension');\nconst PerMessageDeflate = require('./permessage-deflate');\nconst subprotocol = require('./subprotocol');\nconst WebSocket = require('./websocket');\nconst { GUID, kWebSocket } = require('./constants');\n\nconst keyRegex = /^[+/0-9A-Za-z]{22}==$/;\n\nconst RUNNING = 0;\nconst CLOSING = 1;\nconst CLOSED = 2;\n\n/**\n * Class representing a WebSocket server.\n *\n * @extends EventEmitter\n */\nclass WebSocketServer extends EventEmitter {\n /**\n * Create a `WebSocketServer` instance.\n *\n * @param {Object} options Configuration options\n * @param {Number} [options.backlog=511] The maximum length of the queue of\n * pending connections\n * @param {Boolean} [options.clientTracking=true] Specifies whether or not to\n * track clients\n * @param {Function} [options.handleProtocols] A hook to handle protocols\n * @param {String} [options.host] The hostname where to bind the server\n * @param {Number} [options.maxPayload=104857600] The maximum allowed message\n * size\n * @param {Boolean} [options.noServer=false] Enable no server mode\n * @param {String} [options.path] Accept only connections matching this path\n * @param {(Boolean|Object)} [options.perMessageDeflate=false] Enable/disable\n * permessage-deflate\n * @param {Number} [options.port] The port where to bind the server\n * @param {(http.Server|https.Server)} [options.server] A pre-created HTTP/S\n * server to use\n * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or\n * not to skip UTF-8 validation for text and close messages\n * @param {Function} [options.verifyClient] A hook to reject connections\n * @param {Function} [options.WebSocket=WebSocket] Specifies the `WebSocket`\n * class to use. It must be the `WebSocket` class or class that extends it\n * @param {Function} [callback] A listener for the `listening` event\n */\n constructor(options, callback) {\n super();\n\n options = {\n maxPayload: 100 * 1024 * 1024,\n skipUTF8Validation: false,\n perMessageDeflate: false,\n handleProtocols: null,\n clientTracking: true,\n verifyClient: null,\n noServer: false,\n backlog: null, // use default (511 as implemented in net.js)\n server: null,\n host: null,\n path: null,\n port: null,\n WebSocket,\n ...options\n };\n\n if (\n (options.port == null && !options.server && !options.noServer) ||\n (options.port != null && (options.server || options.noServer)) ||\n (options.server && options.noServer)\n ) {\n throw new TypeError(\n 'One and only one of the \"port\", \"server\", or \"noServer\" options ' +\n 'must be specified'\n );\n }\n\n if (options.port != null) {\n this._server = http.createServer((req, res) => {\n const body = http.STATUS_CODES[426];\n\n res.writeHead(426, {\n 'Content-Length': body.length,\n 'Content-Type': 'text/plain'\n });\n res.end(body);\n });\n this._server.listen(\n options.port,\n options.host,\n options.backlog,\n callback\n );\n } else if (options.server) {\n this._server = options.server;\n }\n\n if (this._server) {\n const emitConnection = this.emit.bind(this, 'connection');\n\n this._removeListeners = addListeners(this._server, {\n listening: this.emit.bind(this, 'listening'),\n error: this.emit.bind(this, 'error'),\n upgrade: (req, socket, head) => {\n this.handleUpgrade(req, socket, head, emitConnection);\n }\n });\n }\n\n if (options.perMessageDeflate === true) options.perMessageDeflate = {};\n if (options.clientTracking) {\n this.clients = new Set();\n this._shouldEmitClose = false;\n }\n\n this.options = options;\n this._state = RUNNING;\n }\n\n /**\n * Returns the bound address, the address family name, and port of the server\n * as reported by the operating system if listening on an IP socket.\n * If the server is listening on a pipe or UNIX domain socket, the name is\n * returned as a string.\n *\n * @return {(Object|String|null)} The address of the server\n * @public\n */\n address() {\n if (this.options.noServer) {\n throw new Error('The server is operating in \"noServer\" mode');\n }\n\n if (!this._server) return null;\n return this._server.address();\n }\n\n /**\n * Stop the server from accepting new connections and emit the `'close'` event\n * when all existing connections are closed.\n *\n * @param {Function} [cb] A one-time listener for the `'close'` event\n * @public\n */\n close(cb) {\n if (this._state === CLOSED) {\n if (cb) {\n this.once('close', () => {\n cb(new Error('The server is not running'));\n });\n }\n\n process.nextTick(emitClose, this);\n return;\n }\n\n if (cb) this.once('close', cb);\n\n if (this._state === CLOSING) return;\n this._state = CLOSING;\n\n if (this.options.noServer || this.options.server) {\n if (this._server) {\n this._removeListeners();\n this._removeListeners = this._server = null;\n }\n\n if (this.clients) {\n if (!this.clients.size) {\n process.nextTick(emitClose, this);\n } else {\n this._shouldEmitClose = true;\n }\n } else {\n process.nextTick(emitClose, this);\n }\n } else {\n const server = this._server;\n\n this._removeListeners();\n this._removeListeners = this._server = null;\n\n //\n // The HTTP/S server was created internally. Close it, and rely on its\n // `'close'` event.\n //\n server.close(() => {\n emitClose(this);\n });\n }\n }\n\n /**\n * See if a given request should be handled by this server instance.\n *\n * @param {http.IncomingMessage} req Request object to inspect\n * @return {Boolean} `true` if the request is valid, else `false`\n * @public\n */\n shouldHandle(req) {\n if (this.options.path) {\n const index = req.url.indexOf('?');\n const pathname = index !== -1 ? req.url.slice(0, index) : req.url;\n\n if (pathname !== this.options.path) return false;\n }\n\n return true;\n }\n\n /**\n * Handle a HTTP Upgrade request.\n *\n * @param {http.IncomingMessage} req The request object\n * @param {(net.Socket|tls.Socket)} socket The network socket between the\n * server and client\n * @param {Buffer} head The first packet of the upgraded stream\n * @param {Function} cb Callback\n * @public\n */\n handleUpgrade(req, socket, head, cb) {\n socket.on('error', socketOnError);\n\n const key =\n req.headers['sec-websocket-key'] !== undefined\n ? req.headers['sec-websocket-key']\n : false;\n const version = +req.headers['sec-websocket-version'];\n\n if (\n req.method !== 'GET' ||\n req.headers.upgrade.toLowerCase() !== 'websocket' ||\n !key ||\n !keyRegex.test(key) ||\n (version !== 8 && version !== 13) ||\n !this.shouldHandle(req)\n ) {\n return abortHandshake(socket, 400);\n }\n\n const secWebSocketProtocol = req.headers['sec-websocket-protocol'];\n let protocols = new Set();\n\n if (secWebSocketProtocol !== undefined) {\n try {\n protocols = subprotocol.parse(secWebSocketProtocol);\n } catch (err) {\n return abortHandshake(socket, 400);\n }\n }\n\n const secWebSocketExtensions = req.headers['sec-websocket-extensions'];\n const extensions = {};\n\n if (\n this.options.perMessageDeflate &&\n secWebSocketExtensions !== undefined\n ) {\n const perMessageDeflate = new PerMessageDeflate(\n this.options.perMessageDeflate,\n true,\n this.options.maxPayload\n );\n\n try {\n const offers = extension.parse(secWebSocketExtensions);\n\n if (offers[PerMessageDeflate.extensionName]) {\n perMessageDeflate.accept(offers[PerMessageDeflate.extensionName]);\n extensions[PerMessageDeflate.extensionName] = perMessageDeflate;\n }\n } catch (err) {\n return abortHandshake(socket, 400);\n }\n }\n\n //\n // Optionally call external client verification handler.\n //\n if (this.options.verifyClient) {\n const info = {\n origin:\n req.headers[`${version === 8 ? 'sec-websocket-origin' : 'origin'}`],\n secure: !!(req.socket.authorized || req.socket.encrypted),\n req\n };\n\n if (this.options.verifyClient.length === 2) {\n this.options.verifyClient(info, (verified, code, message, headers) => {\n if (!verified) {\n return abortHandshake(socket, code || 401, message, headers);\n }\n\n this.completeUpgrade(\n extensions,\n key,\n protocols,\n req,\n socket,\n head,\n cb\n );\n });\n return;\n }\n\n if (!this.options.verifyClient(info)) return abortHandshake(socket, 401);\n }\n\n this.completeUpgrade(extensions, key, protocols, req, socket, head, cb);\n }\n\n /**\n * Upgrade the connection to WebSocket.\n *\n * @param {Object} extensions The accepted extensions\n * @param {String} key The value of the `Sec-WebSocket-Key` header\n * @param {Set} protocols The subprotocols\n * @param {http.IncomingMessage} req The request object\n * @param {(net.Socket|tls.Socket)} socket The network socket between the\n * server and client\n * @param {Buffer} head The first packet of the upgraded stream\n * @param {Function} cb Callback\n * @throws {Error} If called more than once with the same socket\n * @private\n */\n completeUpgrade(extensions, key, protocols, req, socket, head, cb) {\n //\n // Destroy the socket if the client has already sent a FIN packet.\n //\n if (!socket.readable || !socket.writable) return socket.destroy();\n\n if (socket[kWebSocket]) {\n throw new Error(\n 'server.handleUpgrade() was called more than once with the same ' +\n 'socket, possibly due to a misconfiguration'\n );\n }\n\n if (this._state > RUNNING) return abortHandshake(socket, 503);\n\n const digest = createHash('sha1')\n .update(key + GUID)\n .digest('base64');\n\n const headers = [\n 'HTTP/1.1 101 Switching Protocols',\n 'Upgrade: websocket',\n 'Connection: Upgrade',\n `Sec-WebSocket-Accept: ${digest}`\n ];\n\n const ws = new this.options.WebSocket(null);\n\n if (protocols.size) {\n //\n // Optionally call external protocol selection handler.\n //\n const protocol = this.options.handleProtocols\n ? this.options.handleProtocols(protocols, req)\n : protocols.values().next().value;\n\n if (protocol) {\n headers.push(`Sec-WebSocket-Protocol: ${protocol}`);\n ws._protocol = protocol;\n }\n }\n\n if (extensions[PerMessageDeflate.extensionName]) {\n const params = extensions[PerMessageDeflate.extensionName].params;\n const value = extension.format({\n [PerMessageDeflate.extensionName]: [params]\n });\n headers.push(`Sec-WebSocket-Extensions: ${value}`);\n ws._extensions = extensions;\n }\n\n //\n // Allow external modification/inspection of handshake headers.\n //\n this.emit('headers', headers, req);\n\n socket.write(headers.concat('\\r\\n').join('\\r\\n'));\n socket.removeListener('error', socketOnError);\n\n ws.setSocket(socket, head, {\n maxPayload: this.options.maxPayload,\n skipUTF8Validation: this.options.skipUTF8Validation\n });\n\n if (this.clients) {\n this.clients.add(ws);\n ws.on('close', () => {\n this.clients.delete(ws);\n\n if (this._shouldEmitClose && !this.clients.size) {\n process.nextTick(emitClose, this);\n }\n });\n }\n\n cb(ws, req);\n }\n}\n\nmodule.exports = WebSocketServer;\n\n/**\n * Add event listeners on an `EventEmitter` using a map of <event, listener>\n * pairs.\n *\n * @param {EventEmitter} server The event emitter\n * @param {Object.<String, Function>} map The listeners to add\n * @return {Function} A function that will remove the added listeners when\n * called\n * @private\n */\nfunction addListeners(server, map) {\n for (const event of Object.keys(map)) server.on(event, map[event]);\n\n return function removeListeners() {\n for (const event of Object.keys(map)) {\n server.removeListener(event, map[event]);\n }\n };\n}\n\n/**\n * Emit a `'close'` event on an `EventEmitter`.\n *\n * @param {EventEmitter} server The event emitter\n * @private\n */\nfunction emitClose(server) {\n server._state = CLOSED;\n server.emit('close');\n}\n\n/**\n * Handle premature socket errors.\n *\n * @private\n */\nfunction socketOnError() {\n this.destroy();\n}\n\n/**\n * Close the connection when preconditions are not fulfilled.\n *\n * @param {(net.Socket|tls.Socket)} socket The socket of the upgrade request\n * @param {Number} code The HTTP response status code\n * @param {String} [message] The HTTP response body\n * @param {Object} [headers] Additional HTTP response headers\n * @private\n */\nfunction abortHandshake(socket, code, message, headers) {\n if (socket.writable) {\n message = message || http.STATUS_CODES[code];\n headers = {\n Connection: 'close',\n 'Content-Type': 'text/html',\n 'Content-Length': Buffer.byteLength(message),\n ...headers\n };\n\n socket.write(\n `HTTP/1.1 ${code} ${http.STATUS_CODES[code]}\\r\\n` +\n Object.keys(headers)\n .map((h) => `${h}: ${headers[h]}`)\n .join('\\r\\n') +\n '\\r\\n\\r\\n' +\n message\n );\n }\n\n socket.removeListener('error', socketOnError);\n socket.destroy();\n}\n","'use strict';\n\nconst WebSocket = require('./lib/websocket');\n\nWebSocket.createWebSocketStream = require('./lib/stream');\nWebSocket.Server = require('./lib/websocket-server');\nWebSocket.Receiver = require('./lib/receiver');\nWebSocket.Sender = require('./lib/sender');\n\nWebSocket.WebSocket = WebSocket;\nWebSocket.WebSocketServer = WebSocket.Server;\n\nmodule.exports = WebSocket;\n","/*!\n * name: main.js\n * desc: 为了将rtsp2web发布为一个 npm 包。\n * 由于resource.js中require了一些第三方node包,在使用rollup打包时,\n * 不符合模块打包的规范(import是符合模块打包规范的)\n * main.js就是将resource.js进行轻微的改动;以及精简(为了打包产物最小化)\n * 这样可以使用rollup进行打包处理,以及做一些压缩和babel的处理\n * 在npm项目中使用rtsp2web,使用方法可以参考example目录的示例\n * (c) begin with 2022 by NeverYu\n * Released under the ISC License.\n */\nconst child = require('child_process')\nimport http from 'http'\nimport https from 'https'\n// import { createServer } from 'https'\nimport fs from 'fs'\nconst events = require('events')\nconst url = require('url')\nimport { decode } from 'base-64'\nimport { Server } from 'ws'\nconst WebSocketServer = Server\n\n// 默认的ffmpeg路径(一般正常安装的ffmpeg,名称(路径)是:ffmpeg)\nconst FFmpegPath = 'ffmpeg'\n// 默认的端口\nconst defaultPort = 9999\n// 默认的视频视口框架大小\nlet videoSize = '1920x1080'\n// 视频场景比例缩放\nlet videoScale = '-1:-1'\n// 视频的码率(默认不传)\nlet videoBit = '2000k'\n// 视频的解码器\nlet vcodecValue = 'mpeg1video'\n// 默认的filter参数\nlet vfValue =\n 'drawtext=x=w-tw-100:y=100:fontcolor=white:fontsize=36:text=水印QQ:421354532:box=1:boxcolor=black,scale=-1:-1,eq='\nlet noWMvfValue = 'scale=-1:-1,eq='\n\n/**\n * 配置vcodec时,可传入的参数形式包含:\n * vcodec, c:v, -c:v, codec:v\n */\nconst config_vcodec = ['vcodec', 'c:v', '-c:v', 'codec:v']\n\n/**\n * 支持的可配置参数\n */\nconst isConfigKey = [\n '-s',\n '-b:v',\n 'scale',\n 'contrast',\n 'brightness',\n 'saturation',\n 'gamma',\n ...config_vcodec\n]\n// -vf 的配置参数\nconst isVFConfigKey = ['scale', 'contrast', 'brightness', 'saturation', 'gamma']\n\n/**\n * 对应的参数校验规则\n */\nconst validValueRules = (key, value) => {\n switch (key) {\n case '-s':\n if (value.includes('x')) {\n if (\n value.split('x')[0] &&\n value.split('x')[0] > 0 &&\n value.split('x')[1] &&\n value.split('x')[1] > 0\n ) {\n return true\n }\n }\n break\n case 'vcodec':\n case 'c:v':\n case '-c:v':\n case 'codec:v':\n if (value) {\n return true\n }\n break\n case '-b:v':\n if (value.endsWith('k')) {\n return true\n }\n break\n case 'scale':\n if (value.includes(':')) {\n if (value.split(':')[0] && value.split(':')[1]) {\n return true\n }\n }\n break\n case 'contrast':\n if (value) {\n return true\n }\n break\n case 'brightness':\n if (value) {\n return true\n }\n break\n case 'saturation':\n if (value) {\n return true\n }\n break\n case 'gamma':\n if (value) {\n return true\n }\n break\n }\n}\n\n/**\n * configFreeTime:空闲时间;单位:秒(s)\n * 一个已启动的视频通道,如果在一段时间(configFreeTime)内没有被使用,则销毁该视频通道\n * 建议:值为10的倍数,取值范围60-120\n */\nlet configFreeTime = 60\n/**\n * intervalTime:定时器循环时间;单位:秒(s)\n * 用于计时,来定时检测当前是否有空闲的视频通道(执行的是RTSP2web类中的checkFree方法)\n * 建议:值为5的倍数,取值范围5-20\n */\nlet intervalTime = 10\n\n/**\n * 用于创建一个新的视频转码流类\n */\nclass Mpeg2Muxer extends events.EventEmitter {\n exitCode = undefined\n // 额外的 ffmpeg 参数\n additionalFlags = []\n stream = null\n inputStreamStarted = false\n constructor(options) {\n super()\n this.options = options\n this.ffmpegPath = options.ffmpegPath || FFmpegPath\n this.url = options.url\n this.ffmpegOptions = options.ffmpegOptions\n this.initMpeg2Muxer()\n }\n initMpeg2Muxer() {\n // ffmpeg参数解析\n if (this.ffmpegOptions) {\n for (let key in this.ffmpegOptions) {\n this.additionalFlags.push(key)\n if (String(this.ffmpegOptions[key]) !== '') {\n this.additionalFlags.push(String(this.ffmpegOptions[key]))\n }\n }\n }\n // 参数整合拼接\n this.spawnOptions = [\n '-rtsp_transport',\n 'tcp',\n '-thread_queue_size',\n '256',\n '-i',\n this.url,\n '-f',\n 'mpegts',\n // '-codec:a',\n // 'mp2',\n // '-vf',\n // 'scale=-1:-1,eq=brightness=0.2:saturation=2.8:',\n // additional ffmpeg options go here\n ...this.additionalFlags,\n '-nostats',\n // '-b:v',\n // '2000k',\n // '-b:a',\n // '128k',\n '-r',\n '29.97',\n '-'\n ]\n // 创建一个命令行子进程\n this.stream = child.spawn(this.ffmpegPath, this.spawnOptions, {\n detached: false\n })\n\n this.stream.on('error', (code, signal) => {\n console.error(\n '启动ffmpeg时出错,请确保你安装了ffmpeg,然后检查路径或者命令参数'\n )\n })\n this.stream.on('close', (code, signal) => {\n console.log('ffmpeg关闭,code:', code)\n return this.emit('ffmpegClosed')\n })\n this.stream.on('exit', (code, signal) => {\n if (code === 1) {\n console.error(\n '***由于ffmpeg退出,ffmpeg启动不成功,请检查ffmpeg参数或相关情况或联系作者***'\n )\n this.exitCode = 1\n return this.emit('exitWithError')\n }\n })\n\n this.inputStreamStarted = true\n this.stream.stdout.on('data', (data) => {\n return this.emit('mpeg2data', data)\n })\n this.stream.stderr.on('data', (data) => {\n return this.emit('ffmpegStderr', data)\n })\n }\n}\n\n/**\n * 一个视频通道可能对应多个客户端(也就是多个ws句柄)\n * 为什么呢\n * 因为一个rtsp视频流可能有多个客户端(多台电脑)在同时播放的情况\n * 视频转码(依赖ffmpeg)是需要消耗运行电脑cpu的\n * 为了避免资源的浪费,同一个rtsp视频流只开启一个转码程序,也就是一个视频通道\n * 多个ws句柄可以共用一个视频通道\n */\nclass Channel {\n /**\n * freeTime: 用于记录该视频通道空闲的时间\n * 如果这个视频通道的空闲时间超过一个设定值\n * 我们就可以关闭这个视频通道了,停掉转码服务,释放电脑资源\n * @type {Number}\n */\n freeTime = 0\n /* 视频通道是否正在封装码流 */\n isStreamWrap = false\n clients = []\n mpeg2Muxer = {\n instance: null,\n stream: null,\n data: null\n }\n\n constructor(config) {\n // 前端传过来的参数\n this.config = config\n this.url = config.url\n }\n // 创建一个rtsp的视频转码\n createStream() {\n if (this.isStreamWrap) {\n return\n }\n console.log('创建一个新的ffmpeg子进程')\n this.isStreamWrap = true\n this.mpeg2Muxer.instance = new Mpeg2Muxer({\n ffmpegOptions: this.formatParams(this.config),\n url: this.url,\n ffmpegPath: 'ffmpeg'\n })\n this.mpeg2Muxer.stream = this.mpeg2Muxer.instance.stream\n /**\n * 监听到子进程发送过来的数据\n */\n this.mpeg2Muxer.instance.on('mpeg2data', (data) => {\n /**\n * 【广播数据】\n * rtsp视频流实时转帧之后,当前视频流通道实时进行广播\n * 将图像数据广播给它的所有client(也就是它的每个ws句柄)\n */\n this.broadcast(data)\n // this.mpeg2Muxer.data = data\n })\n\n /**\n * 监听到创建的子进程ffmpeg由于error退出了\n */\n this.mpeg2Muxer.instance.on('exitWithError', () => {\n // console.log('监听到有一个ffmpeg进程退出了!')\n })\n\n /**\n * 监听到创建的子进程ffmpeg关闭了\n * 该视频通道的子进程ffmpeg都关闭了,那么要注销掉该视频通道\n * 以及和该视频通道关联的ws句柄\n */\n this.mpeg2Muxer.instance.on('ffmpegClosed', () => {\n // console.log('监听到有一个ffmpeg进程关闭了!')\n this.destroy()\n })\n }\n formatParams(params) {\n // 是否有视频过滤的参数配置(包括eq,scale)\n let result = {\n '-codec:v': vcodecValue,\n '-vf': vfValue\n }\n for (let [key, value] of Object.entries(params)) {\n if (key === 'wm' && value === '0') {\n result['-vf'] = noWMvfValue\n }\n // 是支持的可配置的参数\n if (isConfigKey.includes(key)) {\n // 是配置vf相关的参数\n if (isVFConfigKey.includes(key)) {\n // todo: 加validValueRules验证\n if (key === 'scale') {\n result['-vf'] = result['-vf'].replace(\n /scale=[x0-9\\:\\-]*/g,\n `scale=${value}`\n )\n } else {\n result['-vf'] += `${key}=${value}:`\n }\n } else if (config_vcodec.includes(key)) {\n // 修改指定的视频解码器\n result['-codec:v'] = value\n } else {\n // 值校验\n if (validValueRules(key, value)) {\n result[key] = value\n }\n }\n }\n }\n return result\n }\n destroy() {\n this.mpeg2Muxer.stream?.kill()\n this.mpeg2Muxer.stream = null\n this.mpeg2Muxer.instance?.removeAllListeners()\n this.mpeg2Muxer.instance = null\n this.isStreamWrap = false\n this.dropAllClient()\n }\n broadcast(data) {\n for (let client of this.clients) {\n if (client.isSegment) {\n client.send(data)\n }\n }\n }\n // client就是每个ws连接成功后的句柄\n addClient(client) {\n /**\n * 当用户关闭客户端页面时,或者当客户端页面关闭视频播放窗口时\n */\n client.once('close', () => {\n this.dropClient(client)\n })\n this.clients.push(client)\n if (!this.isStreamWrap) {\n this.createStream()\n }\n // isSegment是一个标志位,标识这个ws句柄正在使用中\n client.isSegment = true\n }\n /**\n * 销毁一个ws句柄\n * @param {ws} client\n */\n dropClient(client) {\n let index = this.clients.indexOf(client)\n client.isSegment = false\n // 强制关闭连接;客户端、服务端实例都可调用\n client.terminate()\n client = null\n console.log('视频关闭,销毁一个client(ws句柄)')\n if (index > -1) {\n this.clients.splice(index, 1)\n }\n }\n dropAllClient() {\n for (let client of this.clients) {\n client.isSegment = false\n // 强制关闭连接;客户端、服务端实例都可调用\n client.terminate()\n }\n this.clients = []\n }\n}\n\nimport { version } from './package.json'\n\n/**\n * 入口类\n */\nclass RTSP2web {\n static version = version\n // 视频实例列表(以rtsp_url作为唯一区分)\n channels = []\n /**\n * 实例化一个流媒体服务器对象\n * @param http HTTP服务\n */\n constructor(config) {\n /**\n * 创建RTSP2web时,配置全局参数\n */\n if (config && typeof config.wm === 'boolean' && !config.wm) {\n vfValue = noWMvfValue\n }\n\n /**\n * 创建rtsp2web实例时,配置视频解码器\n */\n if (\n config &&\n typeof config.vcodec === 'string' &&\n config.vcodec.length > 0\n ) {\n vcodecValue = config.vcodec\n }\n\n /**\n * RTSP2web是入口类,在入口类中起一个定时器,对所有的视频通道进行空闲检测\n */\n setInterval(() => this.checkFree(), intervalTime * 1000)\n\n let httpServer = http.createServer()\n /**\n * wss协议\n */\n if (config && typeof config.wss === 'object') {\n console.log('wss启动中....')\n if (config.wss.hasOwnProperty('pfx')) {\n if (!config.wss.hasOwnProperty('passphrase')) {\n console.error(\n '【wss启动失败;请传入正确的pfx文件指定密码:passphrase】'\n )\n } else {\n try {\n httpServer = https.createServer({\n // pfxPath\n pfx: fs.readFileSync(config.wss.pfx),\n // passphrasePath\n passphrase: config.wss.passphrase\n })\n } catch (err) {\n console.error(\n '--【读取pfx安全证书文件出错,wss启动失败,退回到ws;错误信息如下,有问题请联系我】--'\n )\n console.log(err)\n }\n }\n } else {\n if (!config.wss.hasOwnProperty('cert')) {\n console.error('【wss启动失败;请传入正确的安全证书公钥:cert】')\n } else if (!config.wss.hasOwnProperty('key')) {\n console.error('【wss启动失败;请传入正确的安全证书私钥:key】')\n } else {\n try {\n httpServer = https.createServer({\n // certPath\n cert: fs.readFileSync(config.wss.cert),\n // keyPath\n key: fs.readFileSync(config.wss.key)\n })\n } catch (err) {\n console.error(\n '--【读取cert安全证书文件出错,wss启动失败,退回到ws;错误信息如下,有问题请联系我】--'\n )\n console.log(err)\n }\n }\n }\n }\n\n // 创建websocket服务\n this.wss = new WebSocketServer({\n server: httpServer\n })\n\n /**\n * Event: 'connection'成功握手连接时触发\n * [socket] {WebSocket} socket连接句柄(解释:每一个成功连接到这个websocket服务器的链接就是一个句柄,句柄之间是独立的)\n * [request] {http.IncomingMessage}\n */\n this.wss.on('connection', (ws, request) => {\n // 通过 ws 对象,就可以获取到客户端发送过来的信息和主动推送信息给客户端\n // 1、解析url\n const params = url.parse(request.url, true)\n // console.log(params.query.url)\n\n // 2、每一个新的长连接连接成功以后,给它注册一下(其实就是记录一下)\n if (params.query.url) {\n // 因为我定义的是,前端的rtsp_url用btoa处理后以参数的形式传入,所有这里需要解析一下\n const url = decode(params.query.url.toString())\n params.query.url = url\n // console.log(url)\n this.registeClient(ws, {\n url,\n options: params.query\n })\n }\n console.log('一个新的client(ws句柄)连接成功')\n })\n\n httpServer.listen(config ? config.port || defaultPort : defaultPort)\n }\n\n registeClient(ws, data) {\n let channel = this.getChannel(data.url)\n if (!channel) {\n channel = this.createChannel(data.options, ws)\n }\n channel.addClient(ws)\n }\n\n getChannel(url) {\n for (let channel of this.channels) {\n if (channel.url === url) {\n return channel\n }\n }\n return null\n }\n\n /**\n * 创建一个视频通道\n * @Author Author\n * @DateTime 2022-05-06T14:40:28+0800\n * @param {[type]} data [description]\n * @param {[type]} ws [description]\n * @return {[type]} [description]\n */\n createChannel(data, ws) {\n // 一个channel就是一个视频通道\n const channel = new Channel(data, ws)\n this.channels.push(channel)\n return channel\n }\n\n /**\n * 空闲检测,视频通道空间超过1分钟,则移除对应的视频通道\n * @Author Author\n * @DateTime 2022-02-15T14:25:47+0800\n * @return {[type]} [description]\n */\n checkFree() {\n for (let channel of this.channels) {\n if (channel.clients.length > 0) {\n channel.freeTime = 0\n } else {\n channel.freeTime += intervalTime\n }\n if (channel.freeTime >= configFreeTime) {\n this.destroyedChannel(channel)\n }\n }\n }\n\n /**\n * 销毁/停掉一个视频通道\n * @Author Author\n * @DateTime 2022-02-15T14:29:35+0800\n * @param {[type]} channel [description]\n * @return {[type]} [description]\n */\n destroyedChannel(channel) {\n let index = this.channels.indexOf(channel)\n if (index > -1) {\n this.channels.splice(index, 1)\n channel.destroy()\n }\n }\n}\n\nmodule.exports = RTSP2web\n"],"names":["root","freeExports","exports","freeModule","module","freeGlobal","global","window","InvalidCharacterError","message","this","prototype","Error","name","error","TABLE","REGEX_SPACE_CHARACTERS","base64","encode","input","String","test","a","b","c","buffer","padding","length","output","position","charCodeAt","charAt","decode","replace","bitStorage","bitCounter","indexOf","fromCharCode","version","nodeType","key","hasOwnProperty","constants","BINARY_TYPES","EMPTY_BUFFER","Buffer","alloc","GUID","kForOnEventAttribute","Symbol","kListener","kStatusCode","kWebSocket","NOOP","require$$0","concat","list","totalLength","target","allocUnsafe","offset","i","buf","set","slice","_mask","source","mask","_unmask","toArrayBuffer","byteLength","byteOffset","toBuffer","data","readOnly","isBuffer","ArrayBuffer","from","isView","bufferUtil","require","bufferUtilModule","unmask","e","kDone","kRun","limiter","constructor","concurrency","pending","Infinity","jobs","add","job","push","shift","zlib","require$$1","Limiter","require$$2","require$$3","TRAILER","kPerMessageDeflate","kTotalLength","kCallback","kBuffers","kError","zlibLimiter","permessageDeflate","options","isServer","maxPayload","_maxPayload","_options","_threshold","undefined","threshold","_isServer","_deflate","_inflate","params","concurrencyLimit","extensionName","offer","serverNoContextTakeover","server_no_context_takeover","clientNoContextTakeover","client_no_context_takeover","serverMaxWindowBits","server_max_window_bits","clientMaxWindowBits","client_max_window_bits","accept","configurations","normalizeParams","acceptAsServer","acceptAsClient","cleanup","close","callback","offers","opts","accepted","find","response","forEach","Object","keys","value","num","Number","isInteger","TypeError","decompress","fin","done","_decompress","err","result","compress","_compress","endpoint","windowBits","Z_DEFAULT_WINDOWBITS","createInflateRaw","zlibInflateOptions","on","inflateOnError","inflateOnData","write","flush","_readableState","endEmitted","reset","createDeflateRaw","zlibDeflateOptions","deflateOnData","Z_SYNC_FLUSH","chunk","RangeError","code","removeListener","tokenChars","isValidStatusCode","_isValidUTF8","len","isValidUTF8","validationModule","Writable","PerMessageDeflate","require$$4","receiver","super","_binaryType","binaryType","_extensions","extensions","_skipUTF8Validation","skipUTF8Validation","_bufferedBytes","_buffers","_compressed","_payloadLength","_fragmented","_masked","_fin","_opcode","_totalPayloadLength","_messageLength","_fragments","_state","_loop","_write","encoding","cb","startLoop","consume","n","dst","Uint8Array","getInfo","getPayloadLength16","getPayloadLength64","getMask","getData","compressed","haveLength","readUInt16BE","readUInt32BE","Math","pow","controlMessage","dataMessage","er","messageLength","fragments","emit","end","ErrorCtor","prefix","statusCode","errorCode","captureStackTrace","randomFillSync","require$$5","applyMask","require$$6","kByteLength","maskBuffer","Sender","socket","generateMask","_generateMask","_maskBuffer","_socket","_firstFragment","_deflating","_queue","static","dataLength","merge","skipMasking","payloadLength","opcode","rsv1","writeUInt16BE","writeUIntBE","enqueue","dispatch","sendFrame","frame","ping","pong","send","perMessageDeflate","binary","_","destroyed","dequeue","Reflect","apply","cork","uncork","sender","kCode","kData","kMessage","kReason","kTarget","kType","kWasClean","Event","type","defineProperty","enumerable","CloseEvent","reason","wasClean","ErrorEvent","MessageEvent","EventTarget","addEventListener","listener","wrapper","isBinary","event","toString","call","_closeFrameReceived","_closeFrameSent","once","removeEventListener","handler","listeners","eventTarget","dest","elem","extension","format","map","Array","isArray","k","values","v","join","parse","header","create","paramName","mustUnescape","isEscaping","inQuotes","start","SyntaxError","token","EventEmitter","https","http","net","tls","randomBytes","createHash","URL","require$$7","require$$8","Receiver","require$$9","require$$10","require$$11","require$$12","require$$13","require$$14","readyStates","subprotocolRegex","protocolVersions","WebSocket","address","protocols","_closeCode","_closeMessage","_closeTimer","_paused","_protocol","_readyState","CONNECTING","_receiver","_sender","_bufferedAmount","_redirects","initAsClient","includes","bufferedAmount","_writableState","isPaused","onclose","onerror","onopen","onmessage","protocol","readyState","url","_url","setSocket","head","receiverOnConclude","receiverOnDrain","receiverOnError","receiverOnMessage","receiverOnPing","receiverOnPong","setTimeout","setNoDelay","unshift","socketOnClose","socketOnData","socketOnEnd","socketOnError","OPEN","emitClose","CLOSED","removeAllListeners","msg","abortHandshake","_req","CLOSING","errorEmitted","destroy","bind","pause","sendAfterClose","resume","needDrain","terminate","property","method","get","websocket","protocolVersion","followRedirects","maxRedirects","createConnection","socketPath","hostname","timeout","host","path","port","parsedUrl","href","isSecure","isUnixSocket","invalidURLMessage","pathname","hash","emitErrorAndClose","defaultPort","protocolSet","Set","tlsConnect","netConnect","startsWith","headers","Connection","Upgrade","search","handshakeTimeout","has","origin","Origin","username","password","auth","parts","split","_originalHost","entries","toLowerCase","authorization","cookie","req","aborted","res","location","addr","abort","digest","update","serverProt","protError","size","secWebSocketExtensions","extensionNames","connect","servername","isIP","stream","setHeader","process","nextTick","receiverOnFinish","read","clearTimeout","finished","Duplex","duplexOnEnd","duplexOnError","listenerCount","ws","terminateOnDestroy","duplex","autoDestroy","objectMode","writableObjectMode","_destroy","called","_final","_read","subprotocol","keyRegex","websocketServer","handleProtocols","clientTracking","verifyClient","noServer","backlog","server","_server","createServer","body","STATUS_CODES","writeHead","listen","emitConnection","_removeListeners","addListeners","listening","upgrade","handleUpgrade","clients","_shouldEmitClose","shouldHandle","index","secWebSocketProtocol","info","secure","authorized","encrypted","verified","completeUpgrade","readable","writable","next","delete","h","createWebSocketStream","Server","WebSocketServer","child","events","vcodecValue","vfValue","config_vcodec","isConfigKey","isVFConfigKey","validValueRules","endsWith","Mpeg2Muxer","_this","_classCallCheck","_defineProperty","_assertThisInitialized","_super","ffmpegPath","ffmpegOptions","initMpeg2Muxer","_this2","additionalFlags","spawnOptions","spawn","detached","signal","console","log","exitCode","inputStreamStarted","stdout","stderr","Channel","config","instance","_this3","isStreamWrap","mpeg2Muxer","formatParams","broadcast","_i","_Object$entries","_Object$entries$_i","_slicedToArray","_this$mpeg2Muxer$stre","_this$mpeg2Muxer$inst","kill","dropAllClient","_step","_iterator","_createForOfIteratorHelper","s","client","isSegment","f","_this4","dropClient","createStream","splice","_step2","_iterator2","RTSP2web","_this5","wm","vcodec","setInterval","checkFree","intervalTime","httpServer","_typeof","wss","pfx","fs","readFileSync","passphrase","cert","request","query","registeClient","channel","getChannel","createChannel","addClient","_step3","_iterator3","channels","_step4","_iterator4","freeTime","destroyedChannel"],"mappings":"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"}
1
+ {"version":3,"file":"rtsp2web.min.js","sources":["../node_modules/es6-promisify/dist/promisify.js","../node_modules/os-tmpdir/index.js","../node_modules/pem/lib/helper.js","../node_modules/isexe/windows.js","../node_modules/isexe/mode.js","../node_modules/isexe/index.js","../node_modules/which/which.js","../node_modules/pem/lib/openssl.js","../node_modules/pem/lib/convert.js","../node_modules/pem/lib/pem.js","../node_modules/base-64/base64.js","../node_modules/ws/lib/constants.js","../node_modules/ws/lib/buffer-util.js","../node_modules/ws/lib/limiter.js","../node_modules/ws/lib/permessage-deflate.js","../node_modules/ws/lib/validation.js","../node_modules/ws/lib/receiver.js","../node_modules/ws/lib/sender.js","../node_modules/ws/lib/event-target.js","../node_modules/ws/lib/extension.js","../node_modules/ws/lib/websocket.js","../node_modules/ws/lib/stream.js","../node_modules/ws/lib/subprotocol.js","../node_modules/ws/lib/websocket-server.js","../node_modules/ws/index.js","../main.js"],"sourcesContent":["\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.promisify = promisify;\n// Symbols is a better way to do this, but not all browsers have good support,\n// so instead we'll just make do with a very unlikely string.\nvar customArgumentsToken = \"__ES6-PROMISIFY--CUSTOM-ARGUMENTS__\";\n/**\n * promisify()\n * Transforms callback-based function -- func(arg1, arg2 .. argN, callback) --\n * into an ES6-compatible Promise. Promisify provides a default callback of the\n * form (error, result) and rejects when `error` is truthy.\n *\n * @param {function} original - The function to promisify\n * @return {function} A promisified version of `original`\n */\n\nfunction promisify(original) {\n // Ensure the argument is a function\n if (typeof original !== \"function\") {\n throw new TypeError(\"Argument to promisify must be a function\");\n } // If the user has asked us to decode argument names for them, honour that\n\n\n var argumentNames = original[customArgumentsToken]; // If the user has supplied a custom Promise implementation, use it.\n // Otherwise fall back to whatever we can find on the global object.\n\n var ES6Promise = promisify.Promise || Promise; // If we can find no Promise implemention, then fail now.\n\n if (typeof ES6Promise !== \"function\") {\n throw new Error(\"No Promise implementation found; do you need a polyfill?\");\n }\n\n return function () {\n var _this = this;\n\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n return new ES6Promise(function (resolve, reject) {\n // Append the callback bound to the context\n args.push(function callback(err) {\n if (err) {\n return reject(err);\n }\n\n for (var _len2 = arguments.length, values = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {\n values[_key2 - 1] = arguments[_key2];\n }\n\n if (values.length === 1 || !argumentNames) {\n return resolve(values[0]);\n }\n\n var o = {};\n values.forEach(function (value, index) {\n var name = argumentNames[index];\n\n if (name) {\n o[name] = value;\n }\n });\n resolve(o);\n }); // Call the function.\n\n original.apply(_this, args);\n });\n };\n} // Attach this symbol to the exported function, so users can use it\n\n\npromisify.argumentNames = customArgumentsToken;\npromisify.Promise = undefined; // Export the public API","'use strict';\nvar isWindows = process.platform === 'win32';\nvar trailingSlashRe = isWindows ? /[^:]\\\\$/ : /.\\/$/;\n\n// https://github.com/nodejs/node/blob/3e7a14381497a3b73dda68d05b5130563cdab420/lib/os.js#L25-L43\nmodule.exports = function () {\n\tvar path;\n\n\tif (isWindows) {\n\t\tpath = process.env.TEMP ||\n\t\t\tprocess.env.TMP ||\n\t\t\t(process.env.SystemRoot || process.env.windir) + '\\\\temp';\n\t} else {\n\t\tpath = process.env.TMPDIR ||\n\t\t\tprocess.env.TMP ||\n\t\t\tprocess.env.TEMP ||\n\t\t\t'/tmp';\n\t}\n\n\tif (trailingSlashRe.test(path)) {\n\t\tpath = path.slice(0, -1);\n\t}\n\n\treturn path;\n};\n","'use strict'\r\n\r\nvar pathlib = require('path')\r\nvar fs = require('fs')\r\nvar crypto = require('crypto')\r\nvar osTmpdir = require('os-tmpdir')\r\nvar tempDir = process.env.PEMJS_TMPDIR || osTmpdir()\r\n\r\n/**\r\n * pem helper module\r\n *\r\n * @module helper\r\n */\r\n\r\n/**\r\n * helper function to check is the string a number or not\r\n * @param {String} str String that should be checked to be a number\r\n */\r\nmodule.exports.isNumber = function (str) {\r\n if (Array.isArray(str)) {\r\n return false\r\n }\r\n /*\r\n var bstr = str && str.toString()\r\n str = str + ''\r\n\r\n return bstr - parseFloat(bstr) + 1 >= 0 &&\r\n !/^\\s+|\\s+$/g.test(str) && /^\\d+$/g.test(str) &&\r\n !isNaN(str) && !isNaN(parseFloat(str))\r\n */\r\n return /^\\d+$/g.test(str)\r\n}\r\n\r\n/**\r\n * helper function to check is the string a hexaceximal value\r\n * @param {String} hex String that should be checked to be a hexaceximal\r\n */\r\nmodule.exports.isHex = function isHex (hex) {\r\n return /^(0x){0,1}([0-9A-F]{1,40}|[0-9A-F]{1,40})$/gi.test(hex)\r\n}\r\n\r\n/**\r\n * helper function to convert a string to a hexaceximal value\r\n * @param {String} str String that should be converted to a hexaceximal\r\n */\r\nmodule.exports.toHex = function toHex (str) {\r\n var hex = ''\r\n for (var i = 0; i < str.length; i++) {\r\n hex += '' + str.charCodeAt(i).toString(16)\r\n }\r\n return hex\r\n}\r\n\r\n// cipherPassword returns an array of supported ciphers.\r\n/**\r\n * list of supported ciphers\r\n * @type {Array}\r\n */\r\nmodule.exports.ciphers = ['aes128', 'aes192', 'aes256', 'camellia128', 'camellia192', 'camellia256', 'des', 'des3', 'idea']\r\nvar ciphers = module.exports.ciphers\r\n\r\n/**\r\n * Creates a PasswordFile to hide the password form process infos via `ps auxf` etc.\r\n * @param {Object} options object of cipher, password and passType, mustPass, {cipher:'aes128', password:'xxxx', passType:\"in/out/word\"}, if the object empty we do nothing\r\n * @param {String} options.cipher cipher like 'aes128', 'aes192', 'aes256', 'camellia128', 'camellia192', 'camellia256', 'des', 'des3', 'idea'\r\n * @param {String} options.password password can be empty or at last 4 to 1023 chars\r\n * @param {String} options.passType passType: can be in/out/word for passIN/passOUT/passWORD\r\n * @param {Boolean} options.mustPass mustPass is used when you need to set the pass like as \"-password pass:\" most needed when empty password\r\n * @param {Object} params params will be extended with the data that need for the openssl command. IS USED AS POINTER!\r\n * @param {String} PasswordFileArray PasswordFileArray is an array of filePaths that later need to deleted ,after the openssl command. IS USED AS POINTER!\r\n * @return {Boolean} result\r\n */\r\nmodule.exports.createPasswordFile = function (options, params, PasswordFileArray) {\r\n if (!options || !Object.prototype.hasOwnProperty.call(options, 'password') || !Object.prototype.hasOwnProperty.call(options, 'passType') || !/^(word|in|out)$/.test(options.passType)) {\r\n return false\r\n }\r\n var PasswordFile = pathlib.join(tempDir, crypto.randomBytes(20).toString('hex'))\r\n PasswordFileArray.push(PasswordFile)\r\n options.password = options.password.trim()\r\n if (options.password === '') {\r\n options.mustPass = true\r\n }\r\n if (options.cipher && (ciphers.indexOf(options.cipher) !== -1)) {\r\n params.push('-' + options.cipher)\r\n }\r\n params.push('-pass' + options.passType)\r\n if (options.mustPass) {\r\n params.push('pass:' + options.password)\r\n } else {\r\n fs.writeFileSync(PasswordFile, options.password)\r\n params.push('file:' + PasswordFile)\r\n }\r\n return true\r\n}\r\n\r\n/**\r\n * Deletes a file or an array of files\r\n * @param {Array} files array of files that shoudld be deleted\r\n * @param {errorCallback} callback Callback function with an error object\r\n */\r\nmodule.exports.deleteTempFiles = function (files, callback) {\r\n var rmFiles = []\r\n if (typeof files === 'string') {\r\n rmFiles.push(files)\r\n } else if (Array.isArray(files)) {\r\n rmFiles = files\r\n } else {\r\n return callback(new Error('Unexcepted files parameter type; only string or array supported'))\r\n }\r\n var deleteSeries = function (list, finalCallback) {\r\n if (list.length) {\r\n var file = list.shift()\r\n var myCallback = function (err) {\r\n if (err && err.code === 'ENOENT') {\r\n // file doens't exist\r\n return deleteSeries(list, finalCallback)\r\n } else if (err) {\r\n // other errors, e.g. maybe we don't have enough permission\r\n return finalCallback(err)\r\n } else {\r\n return deleteSeries(list, finalCallback)\r\n }\r\n }\r\n if (file && typeof file === 'string') {\r\n fs.unlink(file, myCallback)\r\n } else {\r\n return deleteSeries(list, finalCallback)\r\n }\r\n } else {\r\n return finalCallback(null) // no errors\r\n }\r\n }\r\n deleteSeries(rmFiles, callback)\r\n}\r\n/**\r\n * Callback for return an error object.\r\n * @callback errorCallback\r\n * @param {Error} err - An Error Object or null\r\n */\n","module.exports = isexe\nisexe.sync = sync\n\nvar fs = require('fs')\n\nfunction checkPathExt (path, options) {\n var pathext = options.pathExt !== undefined ?\n options.pathExt : process.env.PATHEXT\n\n if (!pathext) {\n return true\n }\n\n pathext = pathext.split(';')\n if (pathext.indexOf('') !== -1) {\n return true\n }\n for (var i = 0; i < pathext.length; i++) {\n var p = pathext[i].toLowerCase()\n if (p && path.substr(-p.length).toLowerCase() === p) {\n return true\n }\n }\n return false\n}\n\nfunction checkStat (stat, path, options) {\n if (!stat.isSymbolicLink() && !stat.isFile()) {\n return false\n }\n return checkPathExt(path, options)\n}\n\nfunction isexe (path, options, cb) {\n fs.stat(path, function (er, stat) {\n cb(er, er ? false : checkStat(stat, path, options))\n })\n}\n\nfunction sync (path, options) {\n return checkStat(fs.statSync(path), path, options)\n}\n","module.exports = isexe\nisexe.sync = sync\n\nvar fs = require('fs')\n\nfunction isexe (path, options, cb) {\n fs.stat(path, function (er, stat) {\n cb(er, er ? false : checkStat(stat, options))\n })\n}\n\nfunction sync (path, options) {\n return checkStat(fs.statSync(path), options)\n}\n\nfunction checkStat (stat, options) {\n return stat.isFile() && checkMode(stat, options)\n}\n\nfunction checkMode (stat, options) {\n var mod = stat.mode\n var uid = stat.uid\n var gid = stat.gid\n\n var myUid = options.uid !== undefined ?\n options.uid : process.getuid && process.getuid()\n var myGid = options.gid !== undefined ?\n options.gid : process.getgid && process.getgid()\n\n var u = parseInt('100', 8)\n var g = parseInt('010', 8)\n var o = parseInt('001', 8)\n var ug = u | g\n\n var ret = (mod & o) ||\n (mod & g) && gid === myGid ||\n (mod & u) && uid === myUid ||\n (mod & ug) && myUid === 0\n\n return ret\n}\n","var fs = require('fs')\nvar core\nif (process.platform === 'win32' || global.TESTING_WINDOWS) {\n core = require('./windows.js')\n} else {\n core = require('./mode.js')\n}\n\nmodule.exports = isexe\nisexe.sync = sync\n\nfunction isexe (path, options, cb) {\n if (typeof options === 'function') {\n cb = options\n options = {}\n }\n\n if (!cb) {\n if (typeof Promise !== 'function') {\n throw new TypeError('callback not provided')\n }\n\n return new Promise(function (resolve, reject) {\n isexe(path, options || {}, function (er, is) {\n if (er) {\n reject(er)\n } else {\n resolve(is)\n }\n })\n })\n }\n\n core(path, options || {}, function (er, is) {\n // ignore EACCES because that just means we aren't allowed to run it\n if (er) {\n if (er.code === 'EACCES' || options && options.ignoreErrors) {\n er = null\n is = false\n }\n }\n cb(er, is)\n })\n}\n\nfunction sync (path, options) {\n // my kingdom for a filtered catch\n try {\n return core.sync(path, options || {})\n } catch (er) {\n if (options && options.ignoreErrors || er.code === 'EACCES') {\n return false\n } else {\n throw er\n }\n }\n}\n","const isWindows = process.platform === 'win32' ||\n process.env.OSTYPE === 'cygwin' ||\n process.env.OSTYPE === 'msys'\n\nconst path = require('path')\nconst COLON = isWindows ? ';' : ':'\nconst isexe = require('isexe')\n\nconst getNotFoundError = (cmd) =>\n Object.assign(new Error(`not found: ${cmd}`), { code: 'ENOENT' })\n\nconst getPathInfo = (cmd, opt) => {\n const colon = opt.colon || COLON\n\n // If it has a slash, then we don't bother searching the pathenv.\n // just check the file itself, and that's it.\n const pathEnv = cmd.match(/\\//) || isWindows && cmd.match(/\\\\/) ? ['']\n : (\n [\n // windows always checks the cwd first\n ...(isWindows ? [process.cwd()] : []),\n ...(opt.path || process.env.PATH ||\n /* istanbul ignore next: very unusual */ '').split(colon),\n ]\n )\n const pathExtExe = isWindows\n ? opt.pathExt || process.env.PATHEXT || '.EXE;.CMD;.BAT;.COM'\n : ''\n const pathExt = isWindows ? pathExtExe.split(colon) : ['']\n\n if (isWindows) {\n if (cmd.indexOf('.') !== -1 && pathExt[0] !== '')\n pathExt.unshift('')\n }\n\n return {\n pathEnv,\n pathExt,\n pathExtExe,\n }\n}\n\nconst which = (cmd, opt, cb) => {\n if (typeof opt === 'function') {\n cb = opt\n opt = {}\n }\n if (!opt)\n opt = {}\n\n const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt)\n const found = []\n\n const step = i => new Promise((resolve, reject) => {\n if (i === pathEnv.length)\n return opt.all && found.length ? resolve(found)\n : reject(getNotFoundError(cmd))\n\n const ppRaw = pathEnv[i]\n const pathPart = /^\".*\"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw\n\n const pCmd = path.join(pathPart, cmd)\n const p = !pathPart && /^\\.[\\\\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd\n : pCmd\n\n resolve(subStep(p, i, 0))\n })\n\n const subStep = (p, i, ii) => new Promise((resolve, reject) => {\n if (ii === pathExt.length)\n return resolve(step(i + 1))\n const ext = pathExt[ii]\n isexe(p + ext, { pathExt: pathExtExe }, (er, is) => {\n if (!er && is) {\n if (opt.all)\n found.push(p + ext)\n else\n return resolve(p + ext)\n }\n return resolve(subStep(p, i, ii + 1))\n })\n })\n\n return cb ? step(0).then(res => cb(null, res), cb) : step(0)\n}\n\nconst whichSync = (cmd, opt) => {\n opt = opt || {}\n\n const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt)\n const found = []\n\n for (let i = 0; i < pathEnv.length; i ++) {\n const ppRaw = pathEnv[i]\n const pathPart = /^\".*\"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw\n\n const pCmd = path.join(pathPart, cmd)\n const p = !pathPart && /^\\.[\\\\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd\n : pCmd\n\n for (let j = 0; j < pathExt.length; j ++) {\n const cur = p + pathExt[j]\n try {\n const is = isexe.sync(cur, { pathExt: pathExtExe })\n if (is) {\n if (opt.all)\n found.push(cur)\n else\n return cur\n }\n } catch (ex) {}\n }\n }\n\n if (opt.all && found.length)\n return found\n\n if (opt.nothrow)\n return null\n\n throw getNotFoundError(cmd)\n}\n\nmodule.exports = which\nwhich.sync = whichSync\n","var helper = require('./helper.js')\nvar cpspawn = require('child_process').spawn\nvar pathlib = require('path')\nvar fs = require('fs')\nvar osTmpdir = require('os-tmpdir')\nvar crypto = require('crypto')\nvar which = require('which')\nvar settings = {}\nvar tempDir = process.env.PEMJS_TMPDIR || osTmpdir()\n\n/**\n * pem openssl module\n *\n * @module openssl\n */\n\n/**\n * configue this openssl module\n *\n * @static\n * @param {String} option name e.g. pathOpenSSL, openSslVersion; TODO rethink nomenclature\n * @param {*} value value\n */\nfunction set (option, value) {\n settings[option] = value\n}\n\n/**\n * get configuration setting value\n *\n * @static\n * @param {String} option name\n */\nfunction get (option) {\n return settings[option] || null\n}\n\n/**\n * Spawn an openssl command\n *\n * @static\n * @param {Array} params Array of openssl command line parameters\n * @param {String} searchStr String to use to find data\n * @param {Array} [tmpfiles] list of temporary files\n * @param {Function} callback Called with (error, stdout-substring)\n */\nfunction exec (params, searchStr, tmpfiles, callback) {\n if (!callback && typeof tmpfiles === 'function') {\n callback = tmpfiles\n tmpfiles = false\n }\n\n spawnWrapper(params, tmpfiles, function (err, code, stdout, stderr) {\n var start, end\n\n if (err) {\n return callback(err)\n }\n\n if ((start = stdout.match(new RegExp('\\\\-+BEGIN ' + searchStr + '\\\\-+$', 'm')))) {\n start = start.index\n } else {\n start = -1\n }\n\n // To get the full EC key with parameters and private key\n if (searchStr === 'EC PARAMETERS') {\n searchStr = 'EC PRIVATE KEY'\n }\n\n if ((end = stdout.match(new RegExp('^\\\\-+END ' + searchStr + '\\\\-+', 'm')))) {\n end = end.index + end[0].length\n } else {\n end = -1\n }\n\n if (start >= 0 && end >= 0) {\n return callback(null, stdout.substring(start, end))\n } else {\n return callback(new Error(searchStr + ' not found from openssl output:\\n---stdout---\\n' + stdout + '\\n---stderr---\\n' + stderr + '\\ncode: ' + code))\n }\n })\n}\n\n/**\n * Spawn an openssl command and get binary output\n *\n * @static\n * @param {Array} params Array of openssl command line parameters\n * @param {Array} [tmpfiles] list of temporary files\n * @param {Function} callback Called with (error, stdout)\n*/\nfunction execBinary (params, tmpfiles, callback) {\n if (!callback && typeof tmpfiles === 'function') {\n callback = tmpfiles\n tmpfiles = false\n }\n spawnWrapper(params, tmpfiles, true, function (err, code, stdout, stderr) {\n if (err) {\n return callback(err)\n }\n return callback(null, stdout)\n })\n}\n\n/**\n * Generically spawn openSSL, without processing the result\n *\n * @static\n * @param {Array} params The parameters to pass to openssl\n * @param {Boolean} binary Output of openssl is binary or text\n * @param {Function} callback Called with (error, exitCode, stdout, stderr)\n */\nfunction spawn (params, binary, callback) {\n var pathBin = get('pathOpenSSL') || process.env.OPENSSL_BIN || 'openssl'\n\n testOpenSSLPath(pathBin, function (err) {\n if (err) {\n return callback(err)\n }\n var openssl = cpspawn(pathBin, params)\n var stderr = ''\n\n var stdout = (binary ? Buffer.alloc(0) : '')\n openssl.stdout.on('data', function (data) {\n if (!binary) {\n stdout += data.toString('binary')\n } else {\n stdout = Buffer.concat([stdout, data])\n }\n })\n\n openssl.stderr.on('data', function (data) {\n stderr += data.toString('binary')\n })\n // We need both the return code and access to all of stdout. Stdout isn't\n // *really* available until the close event fires; the timing nuance was\n // making this fail periodically.\n var needed = 2 // wait for both exit and close.\n var code = -1\n var finished = false\n var done = function (err) {\n if (finished) {\n return\n }\n\n if (err) {\n finished = true\n return callback(err)\n }\n\n if (--needed < 1) {\n finished = true\n if (code) {\n if (code === 2 && (stderr === '' || /depth lookup: unable to/.test(stderr))) {\n return callback(null, code, stdout, stderr)\n }\n return callback(new Error('Invalid openssl exit code: ' + code + '\\n% openssl ' + params.join(' ') + '\\n' + stderr), code)\n } else {\n return callback(null, code, stdout, stderr)\n }\n }\n }\n\n openssl.on('error', done)\n\n openssl.on('exit', function (ret) {\n code = ret\n done()\n })\n\n openssl.on('close', function () {\n stdout = (binary ? stdout : Buffer.from(stdout, 'binary').toString('utf-8'))\n stderr = Buffer.from(stderr, 'binary').toString('utf-8')\n done()\n })\n })\n}\n\n/**\n * Wrapper for spawn method\n *\n * @static\n * @param {Array} params The parameters to pass to openssl\n * @param {Array} [tmpfiles] list of temporary files\n * @param {Boolean} [binary] Output of openssl is binary or text\n * @param {Function} callback Called with (error, exitCode, stdout, stderr)\n */\nfunction spawnWrapper (params, tmpfiles, binary, callback) {\n if (!callback && typeof binary === 'function') {\n callback = binary\n binary = false\n }\n\n var files = []\n var delTempPWFiles = []\n\n if (tmpfiles) {\n tmpfiles = [].concat(tmpfiles)\n var fpath, i\n for (i = 0; i < params.length; i++) {\n if (params[i] === '--TMPFILE--') {\n fpath = pathlib.join(tempDir, crypto.randomBytes(20).toString('hex'))\n files.push({\n path: fpath,\n contents: tmpfiles.shift()\n })\n params[i] = fpath\n delTempPWFiles.push(fpath)\n }\n }\n }\n\n var file\n for (i = 0; i < files.length; i++) {\n file = files[i]\n fs.writeFileSync(file.path, file.contents)\n }\n\n spawn(params, binary, function (err, code, stdout, stderr) {\n helper.deleteTempFiles(delTempPWFiles, function (fsErr) {\n callback(err || fsErr, code, stdout, stderr)\n })\n })\n}\n\n/**\n * Validates the pathBin for the openssl command\n *\n * @private\n * @param {String} pathBin The path to OpenSSL Bin\n * @param {Function} callback Callback function with an error object\n */\nfunction testOpenSSLPath (pathBin, callback) {\n which(pathBin, function (error) {\n if (error) {\n return callback(new Error('Could not find openssl on your system on this path: ' + pathBin))\n }\n callback()\n })\n}\n\n/* Once PEM is imported, the openSslVersion is set with this function. */\nspawn(['version'], false, function (err, code, stdout, stderr) {\n var text = String(stdout) + '\\n' + String(stderr) + '\\n' + String(err)\n var tmp = text.match(/^LibreSSL/i)\n set('openSslVersion', (tmp && tmp[0] ? 'LibreSSL' : 'openssl').toUpperCase())\n})\n\nmodule.exports = {\n exec: exec,\n execBinary: execBinary,\n spawn: spawn,\n spawnWrapper: spawnWrapper,\n set: set,\n get: get\n}\n","'use strict'\n\nvar openssl = require('./openssl.js')\nvar helper = require('./helper.js')\n\n// PEM format: .pem, .crt, .cer (!bin), .key\n// base64 encoded; the cert file might also include the private key; so key file is optional\n\n// DER format: .der, .cer (bin)\n// binary encoded format; cannot include key file\n\n// PKCS#7 / P7B format: .p7b, .p7c\n// contains cert and ca chain cert files, but not the key file\n// A PKCS7 certificate is serialized using either PEM or DER format.\n\n// PKCS#12 / PFX format: .pfx, .p12\n// contains all files: key file, cert and ca chain cert files\n\n/**\n * pem convert module\n *\n * @module convert\n */\n\n/**\n * conversion from PEM to DER format\n * if private key is included in PEM encoded file, it won't be included in DER file\n * use this method with type 'rsa' to export private key in that case\n * @param {String} pathIN path of the PEM encoded certificate file\n * @param {String} pathOUT path of the DER encoded certificate file to generate\n * @param {String} [type] type of file, use 'rsa' for key file, 'x509' otherwise or leave this parameter out\n * @param {Function} callback callback method called with error, boolean result\n */\nmodule.exports.PEM2DER = function (pathIN, pathOUT, type, callback) {\n if (!callback && typeof type === 'function') {\n callback = type\n type = 'x509'\n }\n var params = [\n type,\n '-outform',\n 'der',\n '-in',\n pathIN,\n '-out',\n pathOUT\n ]\n openssl.spawnWrapper(params, false, function (error, code) {\n if (error) {\n callback(error)\n } else {\n callback(null, code === 0)\n }\n })\n}\n\n/**\n * conversion from DER to PEM format\n * @param {String} pathIN path of the DER encoded certificate file\n * @param {String} pathOUT path of the PEM encoded certificate file to generate\n * @param {String} [type] type of file, use 'rsa' for key file, 'x509' otherwise or leave this parameter out\n * @param {Function} callback callback method called with error, boolean result\n */\nmodule.exports.DER2PEM = function (pathIN, pathOUT, type, callback) {\n if (!callback && typeof type === 'function') {\n callback = type\n type = 'x509'\n }\n var params = [\n type,\n '-inform',\n 'der',\n '-in',\n pathIN,\n '-out',\n pathOUT\n ]\n openssl.spawnWrapper(params, false, function (error, code) {\n if (error) {\n callback(error)\n } else {\n callback(null, code === 0)\n }\n })\n}\n\n/**\n * conversion from PEM to P7B format\n * @param {Object} pathBundleIN paths of the PEM encoded certificate files ({cert: '...', ca: '...' or ['...', ...]})\n * @param {String} pathOUT path of the P7B encoded certificate file to generate\n * @param {Function} callback callback method called with error, boolean result\n */\nmodule.exports.PEM2P7B = function (pathBundleIN, pathOUT, callback) {\n var params = [\n 'crl2pkcs7',\n '-nocrl',\n '-certfile',\n pathBundleIN.cert,\n '-out',\n pathOUT\n ]\n if (pathBundleIN.ca) {\n if (!Array.isArray(pathBundleIN.ca)) {\n pathBundleIN.ca = [pathBundleIN.ca]\n }\n pathBundleIN.ca.forEach(function (ca) {\n params.push('-certfile')\n params.push(ca)\n })\n }\n openssl.spawnWrapper(params, false, function (error, code) {\n if (error) {\n callback(error)\n } else {\n callback(null, code === 0)\n }\n })\n}\n\n/**\n * conversion from P7B to PEM format\n * @param {String} pathIN path of the P7B encoded certificate file\n * @param {String} pathOUT path of the PEM encoded certificate file to generate\n * @param {Function} callback callback method called with error, boolean result\n */\nmodule.exports.P7B2PEM = function (pathIN, pathOUT, callback) {\n var params = [\n 'pkcs7',\n '-print_certs',\n '-in',\n pathIN,\n '-out',\n pathOUT\n ]\n openssl.spawnWrapper(params, false, function (error, code) {\n if (error) {\n callback(error)\n } else {\n callback(null, code === 0)\n }\n })\n}// TODO: CA also included?\n\n/**\n * conversion from PEM to PFX\n * @param {Object} pathBundleIN paths of the PEM encoded certificate files ({cert: '...', key: '...', ca: '...' or ['...', ...]})\n * @param {String} pathOUT path of the PFX encoded certificate file to generate\n * @param {String} password password to set for accessing the PFX file\n * @param {Function} callback callback method called with error, boolean result\n */\nmodule.exports.PEM2PFX = function (pathBundleIN, pathOUT, password, callback) {\n var params = [\n 'pkcs12',\n '-export',\n '-out',\n pathOUT,\n '-inkey',\n pathBundleIN.key,\n '-in',\n pathBundleIN.cert\n ]\n if (pathBundleIN.ca) {\n if (!Array.isArray(pathBundleIN.ca)) {\n pathBundleIN.ca = [pathBundleIN.ca]\n }\n pathBundleIN.ca.forEach(function (ca) {\n params.push('-certfile')\n params.push(ca)\n })\n }\n var delTempPWFiles = []\n helper.createPasswordFile({ cipher: '', password: password, passType: 'in' }, params, delTempPWFiles)\n helper.createPasswordFile({ cipher: '', password: password, passType: 'out' }, params, delTempPWFiles)\n openssl.spawnWrapper(params, false, function (error, code) {\n function done (error) {\n if (error) {\n callback(error)\n } else {\n callback(null, code === 0)\n }\n }\n helper.deleteTempFiles(delTempPWFiles, function (fsErr) {\n done(error || fsErr)\n })\n })\n}\n\n/**\n * conversion from PFX to PEM\n * @param {Object} pathIN path of the PFX encoded certificate file\n * @param {String} pathOUT path of the PEM encoded certificate file to generate\n * @param {String} password password to set for accessing the PFX file\n * @param {Function} callback callback method called with error, boolean result\n */\nmodule.exports.PFX2PEM = function (pathIN, pathOUT, password, callback) {\n var params = [\n 'pkcs12',\n '-in',\n pathIN,\n '-out',\n pathOUT,\n '-nodes'\n ]\n var delTempPWFiles = []\n helper.createPasswordFile({ cipher: '', password: password, passType: 'in' }, params, delTempPWFiles)\n helper.createPasswordFile({ cipher: '', password: password, passType: 'out' }, params, delTempPWFiles)\n openssl.spawnWrapper(params, false, function (error, code) {\n function done (error) {\n if (error) {\n callback(error)\n } else {\n callback(null, code === 0)\n }\n }\n helper.deleteTempFiles(delTempPWFiles, function (fsErr) {\n done(error || fsErr)\n })\n })\n}\n\n/**\n * conversion from P7B to PFX/PKCS#12\n * @param {Object} pathBundleIN paths of the PEM encoded certificate files ({cert: '...', key: '...', ca: '...' or ['...', ...]})\n * @param {String} pathOUT path of the PFX certificate file to generate\n * @param {String} password password to be set for the PFX file and to be used to access the key file\n * @param {Function} callback callback method called with error, boolean result\n */\nmodule.exports.P7B2PFX = function (pathBundleIN, pathOUT, password, callback) {\n var tmpfile = pathBundleIN.cert.replace(/\\.[^.]+$/, '.cer')\n var params = [\n 'pkcs7',\n '-print_certs',\n '-in',\n pathBundleIN.cert,\n '-out',\n tmpfile\n ]\n openssl.spawnWrapper(params, false, function (error, code) {\n if (error) {\n callback(error)\n } else {\n var params = [\n 'pkcs12',\n '-export',\n '-in',\n tmpfile,\n '-inkey',\n pathBundleIN.key,\n '-out',\n pathOUT\n ]\n if (pathBundleIN.ca) {\n if (!Array.isArray(pathBundleIN.ca)) {\n pathBundleIN.ca = [pathBundleIN.ca]\n }\n pathBundleIN.ca.forEach(function (ca) {\n params.push('-certfile')\n params.push(ca)\n })\n }\n var delTempPWFiles = [tmpfile]\n helper.createPasswordFile({ cipher: '', password: password, passType: 'in' }, params, delTempPWFiles)\n helper.createPasswordFile({ cipher: '', password: password, passType: 'out' }, params, delTempPWFiles)\n openssl.spawnWrapper(params, false, function (error, code) {\n function done (error) {\n if (error) {\n callback(error)\n } else {\n callback(null, code === 0)\n }\n }\n helper.deleteTempFiles(delTempPWFiles, function (fsErr) {\n done(error || fsErr)\n })\n })\n }\n })\n}\n","'use strict'\n\n/**\n * pem module\n *\n * @module pem\n */\n\nconst { promisify } = require('es6-promisify')\nvar net = require('net')\nvar helper = require('./helper.js')\nvar openssl = require('./openssl.js')\n\nmodule.exports.createPrivateKey = createPrivateKey\nmodule.exports.createDhparam = createDhparam\nmodule.exports.createEcparam = createEcparam\nmodule.exports.createCSR = createCSR\nmodule.exports.createCertificate = createCertificate\nmodule.exports.readCertificateInfo = readCertificateInfo\nmodule.exports.getPublicKey = getPublicKey\nmodule.exports.getFingerprint = getFingerprint\nmodule.exports.getModulus = getModulus\nmodule.exports.getDhparamInfo = getDhparamInfo\nmodule.exports.createPkcs12 = createPkcs12\nmodule.exports.readPkcs12 = readPkcs12\nmodule.exports.verifySigningChain = verifySigningChain\nmodule.exports.checkCertificate = checkCertificate\nmodule.exports.checkPkcs12 = checkPkcs12\nmodule.exports.config = config\n\n/**\n * quick access the convert module\n * @type {module:convert}\n */\nmodule.exports.convert = require('./convert.js')\n\nvar KEY_START = '-----BEGIN PRIVATE KEY-----'\nvar KEY_END = '-----END PRIVATE KEY-----'\nvar RSA_KEY_START = '-----BEGIN RSA PRIVATE KEY-----'\nvar RSA_KEY_END = '-----END RSA PRIVATE KEY-----'\nvar ENCRYPTED_KEY_START = '-----BEGIN ENCRYPTED PRIVATE KEY-----'\nvar ENCRYPTED_KEY_END = '-----END ENCRYPTED PRIVATE KEY-----'\nvar CERT_START = '-----BEGIN CERTIFICATE-----'\nvar CERT_END = '-----END CERTIFICATE-----'\n\n/**\n * Creates a private key\n *\n * @static\n * @param {Number} [keyBitsize=2048] Size of the key, defaults to 2048bit\n * @param {Object} [options] object of cipher and password {cipher:'aes128',password:'xxx'}, defaults empty object\n * @param {String} [options.cipher] string of the cipher for the encryption - needed with password\n * @param {String} [options.password] string of the cipher password for the encryption needed with cipher\n * @param {Function} callback Callback function with an error object and {key}\n */\nfunction createPrivateKey (keyBitsize, options, callback) {\n if (!callback && !options && typeof keyBitsize === 'function') {\n callback = keyBitsize\n keyBitsize = undefined\n options = {}\n } else if (!callback && keyBitsize && typeof options === 'function') {\n callback = options\n options = {}\n }\n\n keyBitsize = Number(keyBitsize) || 2048\n\n var params = ['genrsa']\n var delTempPWFiles = []\n\n if (options && options.cipher && (Number(helper.ciphers.indexOf(options.cipher)) !== -1) && options.password) {\n helper.createPasswordFile({ cipher: options.cipher, password: options.password, passType: 'out' }, params, delTempPWFiles)\n }\n\n params.push(keyBitsize)\n\n openssl.exec(params, 'RSA PRIVATE KEY', function (sslErr, key) {\n function done (err) {\n if (err) {\n return callback(err)\n }\n callback(null, {\n key: key\n })\n }\n helper.deleteTempFiles(delTempPWFiles, function (fsErr) {\n done(sslErr || fsErr)\n })\n })\n}\n\n/**\n * Creates a dhparam key\n *\n * @static\n * @param {Number} [keyBitsize=512] Size of the key, defaults to 512bit\n * @param {Function} callback Callback function with an error object and {dhparam}\n */\nfunction createDhparam (keyBitsize, callback) {\n if (!callback && typeof keyBitsize === 'function') {\n callback = keyBitsize\n keyBitsize = undefined\n }\n\n keyBitsize = Number(keyBitsize) || 512\n\n var params = ['dhparam',\n '-outform',\n 'PEM',\n keyBitsize\n ]\n\n openssl.exec(params, 'DH PARAMETERS', function (error, dhparam) {\n if (error) {\n return callback(error)\n }\n return callback(null, {\n dhparam: dhparam\n })\n })\n}\n\n/**\n * Creates a ecparam key\n * @static\n * @param {String} [keyName=secp256k1] Name of the key, defaults to secp256k1\n * @param {String} [paramEnc=explicit] Encoding of the elliptic curve parameters, defaults to explicit\n * @param {Boolean} [noOut=false] This option inhibits the output of the encoded version of the parameters.\n * @param {Function} callback Callback function with an error object and {ecparam}\n */\nfunction createEcparam (keyName, paramEnc, noOut, callback) {\n if (!callback && typeof noOut === 'undefined' && !paramEnc && typeof keyName === 'function') {\n callback = keyName\n keyName = undefined\n } else if (!callback && typeof noOut === 'undefined' && keyName && typeof paramEnc === 'function') {\n callback = paramEnc\n paramEnc = undefined\n } else if (!callback && typeof noOut === 'function' && keyName && paramEnc) {\n callback = noOut\n noOut = undefined\n }\n\n keyName = keyName || 'secp256k1'\n paramEnc = paramEnc || 'explicit'\n noOut = noOut || false\n\n var params = ['ecparam',\n '-name',\n keyName,\n '-genkey',\n '-param_enc',\n paramEnc\n ]\n\n var searchString = 'EC PARAMETERS'\n if (noOut) {\n params.push('-noout')\n searchString = 'EC PRIVATE KEY'\n }\n\n openssl.exec(params, searchString, function (error, ecparam) {\n if (error) {\n return callback(error)\n }\n return callback(null, {\n ecparam: ecparam\n })\n })\n}\n\n/**\n * Creates a Certificate Signing Request\n * If client key is undefined, a new key is created automatically. The used key is included\n * in the callback return as clientKey\n * @static\n * @param {Object} [options] Optional options object\n * @param {String} [options.clientKey] Optional client key to use\n * @param {Number} [options.keyBitsize] If clientKey is undefined, bit size to use for generating a new key (defaults to 2048)\n * @param {String} [options.hash] Hash function to use (either md5 sha1 or sha256, defaults to sha256)\n * @param {String} [options.country] CSR country field\n * @param {String} [options.state] CSR state field\n * @param {String} [options.locality] CSR locality field\n * @param {String} [options.organization] CSR organization field\n * @param {String} [options.organizationUnit] CSR organizational unit field\n * @param {String} [options.commonName='localhost'] CSR common name field\n * @param {String} [options.emailAddress] CSR email address field\n * @param {String} [options.csrConfigFile] CSR config file\n * @param {Array} [options.altNames] is a list of subjectAltNames in the subjectAltName field\n * @param {Function} callback Callback function with an error object and {csr, clientKey}\n */\nfunction createCSR (options, callback) {\n if (!callback && typeof options === 'function') {\n callback = options\n options = undefined\n }\n\n options = options || {}\n\n // http://stackoverflow.com/questions/14089872/why-does-node-js-accept-ip-addresses-in-certificates-only-for-san-not-for-cn\n if (options.commonName && (net.isIPv4(options.commonName) || net.isIPv6(options.commonName))) {\n if (!options.altNames) {\n options.altNames = [options.commonName]\n } else if (options.altNames.indexOf(options.commonName) === -1) {\n options.altNames = options.altNames.concat([options.commonName])\n }\n }\n\n if (!options.clientKey) {\n createPrivateKey(options.keyBitsize || 2048, function (error, keyData) {\n if (error) {\n return callback(error)\n }\n options.clientKey = keyData.key\n createCSR(options, callback)\n })\n return\n }\n\n var params = ['req',\n '-new',\n '-' + (options.hash || 'sha256')\n ]\n\n if (options.csrConfigFile) {\n params.push('-config')\n params.push(options.csrConfigFile)\n } else {\n params.push('-subj')\n params.push(generateCSRSubject(options))\n }\n\n params.push('-key')\n params.push('--TMPFILE--')\n\n var tmpfiles = [options.clientKey]\n var config = null\n\n if (options.altNames && Array.isArray(options.altNames) && options.altNames.length) {\n params.push('-extensions')\n params.push('v3_req')\n params.push('-config')\n params.push('--TMPFILE--')\n var altNamesRep = []\n for (var i = 0; i < options.altNames.length; i++) {\n altNamesRep.push((net.isIP(options.altNames[i]) ? 'IP' : 'DNS') + '.' + (i + 1) + ' = ' + options.altNames[i])\n }\n\n tmpfiles.push(config = [\n '[req]',\n 'req_extensions = v3_req',\n 'distinguished_name = req_distinguished_name',\n '[v3_req]',\n 'subjectAltName = @alt_names',\n '[alt_names]',\n altNamesRep.join('\\n'),\n '[req_distinguished_name]',\n 'commonName = Common Name',\n 'commonName_max = 64'\n ].join('\\n'))\n } else if (options.config) {\n config = options.config\n }\n\n var delTempPWFiles = []\n if (options.clientKeyPassword) {\n helper.createPasswordFile({ cipher: '', password: options.clientKeyPassword, passType: 'in' }, params, delTempPWFiles)\n }\n\n openssl.exec(params, 'CERTIFICATE REQUEST', tmpfiles, function (sslErr, data) {\n function done (err) {\n if (err) {\n return callback(err)\n }\n callback(null, {\n csr: data,\n config: config,\n clientKey: options.clientKey\n })\n }\n helper.deleteTempFiles(delTempPWFiles, function (fsErr) {\n done(sslErr || fsErr)\n })\n })\n}\n\n/**\n * Creates a certificate based on a CSR. If CSR is not defined, a new one\n * will be generated automatically. For CSR generation all the options values\n * can be used as with createCSR.\n * @static\n * @param {Object} [options] Optional options object\n * @param {String} [options.serviceCertificate] PEM encoded certificate\n * @param {String} [options.serviceKey] Private key for signing the certificate, if not defined a new one is generated\n * @param {String} [options.serviceKeyPassword] Password of the service key\n * @param {Boolean} [options.selfSigned] If set to true and serviceKey is not defined, use clientKey for signing\n * @param {String|Number} [options.serial] Set a serial max. 20 octets - only together with options.serviceCertificate\n * @param {String} [options.serialFile] Set the name of the serial file, without extension. - only together with options.serviceCertificate and never in tandem with options.serial\n * @param {String} [options.hash] Hash function to use (either md5 sha1 or sha256, defaults to sha256)\n * @param {String} [options.csr] CSR for the certificate, if not defined a new one is generated\n * @param {Number} [options.days] Certificate expire time in days\n * @param {String} [options.clientKeyPassword] Password of the client key\n * @param {String} [options.extFile] extension config file - without '-extensions v3_req'\n * @param {String} [options.config] extension config file - with '-extensions v3_req'\n * @param {String} [options.csrConfigFile] CSR config file - only used if no options.csr is provided\n * @param {Array} [options.altNames] is a list of subjectAltNames in the subjectAltName field - only used if no options.csr is provided\n * @param {Function} callback Callback function with an error object and {certificate, csr, clientKey, serviceKey}\n */\nfunction createCertificate (options, callback) {\n if (!callback && typeof options === 'function') {\n callback = options\n options = undefined\n }\n\n options = options || {}\n\n if (!options.csr) {\n createCSR(options, function (error, keyData) {\n if (error) {\n return callback(error)\n }\n options.csr = keyData.csr\n options.config = keyData.config\n options.clientKey = keyData.clientKey\n createCertificate(options, callback)\n })\n return\n }\n\n if (!options.clientKey) {\n options.clientKey = ''\n }\n\n if (!options.serviceKey) {\n if (options.selfSigned) {\n options.serviceKey = options.clientKey\n } else {\n createPrivateKey(options.keyBitsize || 2048, function (error, keyData) {\n if (error) {\n return callback(error)\n }\n options.serviceKey = keyData.key\n createCertificate(options, callback)\n })\n return\n }\n }\n\n readCertificateInfo(options.csr, function (error2, data2) {\n if (error2) {\n return callback(error2)\n }\n\n var params = ['x509',\n '-req',\n '-' + (options.hash || 'sha256'),\n '-days',\n Number(options.days) || '365',\n '-in',\n '--TMPFILE--'\n ]\n var tmpfiles = [options.csr]\n var delTempPWFiles = []\n\n if (options.serviceCertificate) {\n params.push('-CA')\n params.push('--TMPFILE--')\n params.push('-CAkey')\n params.push('--TMPFILE--')\n if (options.serial) {\n params.push('-set_serial')\n if (helper.isNumber(options.serial)) {\n // set the serial to the max lenth of 20 octets ()\n // A certificate serial number is not decimal conforming. That is the\n // bytes in a serial number do not necessarily map to a printable ASCII\n // character.\n // eg: 0x00 is a valid serial number and can not be represented in a\n // human readable format (atleast one that can be directly mapped to\n // the ACSII table).\n params.push('0x' + ('0000000000000000000000000000000000000000' + options.serial.toString(16)).slice(-40))\n } else {\n if (helper.isHex(options.serial)) {\n if (options.serial.startsWith('0x')) {\n options.serial = options.serial.substring(2, options.serial.length)\n }\n params.push('0x' + ('0000000000000000000000000000000000000000' + options.serial).slice(-40))\n } else {\n params.push('0x' + ('0000000000000000000000000000000000000000' + helper.toHex(options.serial)).slice(-40))\n }\n }\n } else {\n params.push('-CAcreateserial')\n if (options.serialFile) {\n params.push('-CAserial')\n params.push(options.serialFile + '.srl')\n }\n }\n if (options.serviceKeyPassword) {\n helper.createPasswordFile({ cipher: '', password: options.serviceKeyPassword, passType: 'in' }, params, delTempPWFiles)\n }\n tmpfiles.push(options.serviceCertificate)\n tmpfiles.push(options.serviceKey)\n } else {\n params.push('-signkey')\n params.push('--TMPFILE--')\n if (options.serviceKeyPassword) {\n helper.createPasswordFile({ cipher: '', password: options.serviceKeyPassword, passType: 'in' }, params, delTempPWFiles)\n }\n tmpfiles.push(options.serviceKey)\n }\n\n if (options.config) {\n params.push('-extensions')\n params.push('v3_req')\n params.push('-extfile')\n params.push('--TMPFILE--')\n tmpfiles.push(options.config)\n } else if (options.extFile) {\n params.push('-extfile')\n params.push(options.extFile)\n } else {\n var altNamesRep = []\n if (data2 && data2.san) {\n for (var i = 0; i < data2.san.dns.length; i++) {\n altNamesRep.push('DNS' + '.' + (i + 1) + ' = ' + data2.san.dns[i])\n }\n for (var i2 = 0; i2 < data2.san.ip.length; i2++) {\n altNamesRep.push('IP' + '.' + (i2 + 1) + ' = ' + data2.san.ip[i2])\n }\n for (var i3 = 0; i3 < data2.san.email.length; i3++) {\n altNamesRep.push('email' + '.' + (i3 + 1) + ' = ' + data2.san.email[i3])\n }\n params.push('-extensions')\n params.push('v3_req')\n params.push('-extfile')\n params.push('--TMPFILE--')\n tmpfiles.push([\n '[v3_req]',\n 'subjectAltName = @alt_names',\n '[alt_names]',\n altNamesRep.join('\\n')\n ].join('\\n'))\n }\n }\n\n if (options.clientKeyPassword) {\n helper.createPasswordFile({ cipher: '', password: options.clientKeyPassword, passType: 'in' }, params, delTempPWFiles)\n }\n\n openssl.exec(params, 'CERTIFICATE', tmpfiles, function (sslErr, data) {\n function done (err) {\n if (err) {\n return callback(err)\n }\n var response = {\n csr: options.csr,\n clientKey: options.clientKey,\n certificate: data,\n serviceKey: options.serviceKey\n }\n return callback(null, response)\n }\n\n helper.deleteTempFiles(delTempPWFiles, function (fsErr) {\n done(sslErr || fsErr)\n })\n })\n })\n}\n\n/**\n * Exports a public key from a private key, CSR or certificate\n * @static\n * @param {String} certificate PEM encoded private key, CSR or certificate\n * @param {Function} callback Callback function with an error object and {publicKey}\n */\nfunction getPublicKey (certificate, callback) {\n if (!callback && typeof certificate === 'function') {\n callback = certificate\n certificate = undefined\n }\n\n certificate = (certificate || '').toString()\n\n var params\n\n if (certificate.match(/BEGIN(\\sNEW)? CERTIFICATE REQUEST/)) {\n params = ['req',\n '-in',\n '--TMPFILE--',\n '-pubkey',\n '-noout'\n ]\n } else if (certificate.match(/BEGIN RSA PRIVATE KEY/) || certificate.match(/BEGIN PRIVATE KEY/)) {\n params = ['rsa',\n '-in',\n '--TMPFILE--',\n '-pubout'\n ]\n } else {\n params = ['x509',\n '-in',\n '--TMPFILE--',\n '-pubkey',\n '-noout'\n ]\n }\n\n openssl.exec(params, 'PUBLIC KEY', certificate, function (error, key) {\n if (error) {\n return callback(error)\n }\n return callback(null, {\n publicKey: key\n })\n })\n}\n\n/**\n * Reads subject data from a certificate or a CSR\n * @static\n * @param {String} certificate PEM encoded CSR or certificate\n * @param {Function} callback Callback function with an error object and {country, state, locality, organization, organizationUnit, commonName, emailAddress}\n */\nfunction readCertificateInfo (certificate, callback) {\n if (!callback && typeof certificate === 'function') {\n callback = certificate\n certificate = undefined\n }\n\n certificate = (certificate || '').toString()\n var isMatch = certificate.match(/BEGIN(\\sNEW)? CERTIFICATE REQUEST/)\n var type = isMatch ? 'req' : 'x509'\n var params = [type,\n '-noout',\n '-nameopt',\n 'RFC2253,sep_multiline,space_eq,-esc_msb,utf8',\n '-text',\n '-in',\n '--TMPFILE--'\n ]\n openssl.spawnWrapper(params, certificate, function (err, code, stdout, stderr) {\n if (err) {\n return callback(err)\n } else if (stderr) {\n return callback(stderr)\n }\n return fetchCertificateData(stdout, callback)\n })\n}\n\n/**\n * get the modulus from a certificate, a CSR or a private key\n * @static\n * @param {String} certificate PEM encoded, CSR PEM encoded, or private key\n * @param {String} [password] password for the certificate\n * @param {String} [hash] hash function to use (up to now `md5` supported) (default: none)\n * @param {Function} callback Callback function with an error object and {modulus}\n */\nfunction getModulus (certificate, password, hash, callback) {\n if (!callback && !hash && typeof password === 'function') {\n callback = password\n password = undefined\n hash = false\n } else if (!callback && hash && typeof hash === 'function') {\n callback = hash\n hash = false\n // password will be falsy if not provided\n }\n // adding hash function to params, is not supported by openssl.\n // process piping would be the right way (... | openssl md5)\n // No idea how this can be achieved in easy with the current build in methods\n // of pem.\n if (hash && hash !== 'md5') {\n hash = false\n }\n\n certificate = (Buffer.isBuffer(certificate) && certificate.toString()) || certificate\n\n var type = ''\n if (certificate.match(/BEGIN(\\sNEW)? CERTIFICATE REQUEST/)) {\n type = 'req'\n } else if (certificate.match(/BEGIN RSA PRIVATE KEY/) || certificate.match(/BEGIN PRIVATE KEY/)) {\n type = 'rsa'\n } else {\n type = 'x509'\n }\n var params = [\n type,\n '-noout',\n '-modulus',\n '-in',\n '--TMPFILE--'\n ]\n var delTempPWFiles = []\n if (password) {\n helper.createPasswordFile({ cipher: '', password: password, passType: 'in' }, params, delTempPWFiles)\n }\n\n openssl.spawnWrapper(params, certificate, function (sslErr, code, stdout, stderr) {\n function done (err) {\n if (err) {\n return callback(err)\n }\n var match = stdout.match(/Modulus=([0-9a-fA-F]+)$/m)\n if (match) {\n return callback(null, {\n modulus: hash ? require(hash)(match[1]) : match[1]\n })\n } else {\n return callback(new Error('No modulus'))\n }\n }\n helper.deleteTempFiles(delTempPWFiles, function (fsErr) {\n done(sslErr || fsErr || stderr)\n })\n })\n}\n\n/**\n * get the size and prime of DH parameters\n * @static\n * @param {String} DH parameters PEM encoded\n * @param {Function} callback Callback function with an error object and {size, prime}\n */\nfunction getDhparamInfo (dh, callback) {\n dh = (Buffer.isBuffer(dh) && dh.toString()) || dh\n\n var params = [\n 'dhparam',\n '-text',\n '-in',\n '--TMPFILE--'\n ]\n\n openssl.spawnWrapper(params, dh, function (err, code, stdout, stderr) {\n if (err) {\n return callback(err)\n } else if (stderr) {\n return callback(stderr)\n }\n\n var result = {}\n var match = stdout.match(/Parameters: \\((\\d+) bit\\)/)\n\n if (match) {\n result.size = Number(match[1])\n }\n\n var prime = ''\n stdout.split('\\n').forEach(function (line) {\n if (/\\s+([0-9a-f][0-9a-f]:)+[0-9a-f]?[0-9a-f]?/g.test(line)) {\n prime += line.trim()\n }\n })\n\n if (prime) {\n result.prime = prime\n }\n\n if (!match && !prime) {\n return callback(new Error('No DH info found'))\n }\n\n return callback(null, result)\n })\n}\n\n/**\n * config the pem module\n * @static\n * @param {Object} options\n */\nfunction config (options) {\n Object.keys(options).forEach(function (k) {\n openssl.set(k, options[k])\n })\n}\n\n/**\n * Gets the fingerprint for a certificate\n * @static\n * @param {String} PEM encoded certificate\n * @param {String} [hash] hash function to use (either `md5`, `sha1` or `sha256`, defaults to `sha1`)\n * @param {Function} callback Callback function with an error object and {fingerprint}\n */\nfunction getFingerprint (certificate, hash, callback) {\n if (!callback && typeof hash === 'function') {\n callback = hash\n hash = undefined\n }\n\n hash = hash || 'sha1'\n\n var params = ['x509',\n '-in',\n '--TMPFILE--',\n '-fingerprint',\n '-noout',\n '-' + hash\n ]\n\n openssl.spawnWrapper(params, certificate, function (err, code, stdout, stderr) {\n if (err) {\n return callback(err)\n } else if (stderr) {\n return callback(stderr)\n }\n var match = stdout.match(/Fingerprint=([0-9a-fA-F:]+)$/m)\n if (match) {\n return callback(null, {\n fingerprint: match[1]\n })\n } else {\n return callback(new Error('No fingerprint'))\n }\n })\n}\n\n/**\n * Export private key and certificate to a PKCS12 keystore\n * @static\n * @param {String} PEM encoded private key\n * @param {String} PEM encoded certificate\n * @param {String} Password of the result PKCS12 file\n * @param {Object} [options] object of cipher and optional client key password {cipher:'aes128', clientKeyPassword: 'xxxx', certFiles: ['file1','file2']}\n * @param {Function} callback Callback function with an error object and {pkcs12}\n */\nfunction createPkcs12 (key, certificate, password, options, callback) {\n if (!callback && typeof options === 'function') {\n callback = options\n options = {}\n }\n\n var params = ['pkcs12', '-export']\n var delTempPWFiles = []\n\n if (options.cipher && options.clientKeyPassword) {\n // NOTICE: The password field is needed! self if it is empty.\n // create password file for the import \"-passin\"\n helper.createPasswordFile({ cipher: options.cipher, password: options.clientKeyPassword, passType: 'in' }, params, delTempPWFiles)\n }\n // NOTICE: The password field is needed! self if it is empty.\n // create password file for the password \"-password\"\n helper.createPasswordFile({ cipher: '', password: password, passType: 'word' }, params, delTempPWFiles)\n\n params.push('-in')\n params.push('--TMPFILE--')\n params.push('-inkey')\n params.push('--TMPFILE--')\n\n var tmpfiles = [certificate, key]\n\n if (options.certFiles) {\n tmpfiles.push(options.certFiles.join(''))\n\n params.push('-certfile')\n params.push('--TMPFILE--')\n }\n\n openssl.execBinary(params, tmpfiles, function (sslErr, pkcs12) {\n function done (err) {\n if (err) {\n return callback(err)\n }\n return callback(null, {\n pkcs12: pkcs12\n })\n }\n helper.deleteTempFiles(delTempPWFiles, function (fsErr) {\n done(sslErr || fsErr)\n })\n })\n}\n\n/**\n * read sslcert data from Pkcs12 file. Results are provided in callback response in object notation ({cert: .., ca:..., key:...})\n * @static\n * @param {Buffer|String} bufferOrPath Buffer or path to file\n * @param {Object} [options] openssl options\n * @param {Function} callback Called with error object and sslcert bundle object\n */\nfunction readPkcs12 (bufferOrPath, options, callback) {\n if (!callback && typeof options === 'function') {\n callback = options\n options = {}\n }\n\n options.p12Password = options.p12Password || ''\n\n var tmpfiles = []\n var delTempPWFiles = []\n var args = ['pkcs12', '-in', bufferOrPath]\n\n helper.createPasswordFile({ cipher: '', password: options.p12Password, passType: 'in' }, args, delTempPWFiles)\n\n if (Buffer.isBuffer(bufferOrPath)) {\n tmpfiles = [bufferOrPath]\n args[2] = '--TMPFILE--'\n }\n\n if (options.clientKeyPassword) {\n helper.createPasswordFile({ cipher: '', password: options.clientKeyPassword, passType: 'out' }, args, delTempPWFiles)\n } else {\n args.push('-nodes')\n }\n\n openssl.execBinary(args, tmpfiles, function (sslErr, stdout) {\n function done (err) {\n var keybundle = {}\n\n if (err && err.message.indexOf('No such file or directory') !== -1) {\n err.code = 'ENOENT'\n }\n\n if (!err) {\n var certs = readFromString(stdout, CERT_START, CERT_END)\n keybundle.cert = certs.shift()\n keybundle.ca = certs\n keybundle.key = readFromString(stdout, KEY_START, KEY_END).pop()\n\n if (keybundle.key) {\n // convert to RSA key\n return openssl.exec(['rsa', '-in', '--TMPFILE--'], 'RSA PRIVATE KEY', [keybundle.key], function (err, key) {\n keybundle.key = key\n\n return callback(err, keybundle)\n })\n }\n\n if (options.clientKeyPassword) {\n keybundle.key = readFromString(stdout, ENCRYPTED_KEY_START, ENCRYPTED_KEY_END).pop()\n } else {\n keybundle.key = readFromString(stdout, RSA_KEY_START, RSA_KEY_END).pop()\n }\n }\n\n return callback(err, keybundle)\n }\n helper.deleteTempFiles(delTempPWFiles, function (fsErr) {\n done(sslErr || fsErr)\n })\n })\n}\n\n/**\n * Check a certificate\n * @static\n * @param {String} PEM encoded certificate\n * @param {String} [passphrase] password for the certificate\n * @param {Function} callback Callback function with an error object and a boolean valid\n */\nfunction checkCertificate (certificate, passphrase, callback) {\n var params\n var delTempPWFiles = []\n\n if (!callback && typeof passphrase === 'function') {\n callback = passphrase\n passphrase = undefined\n }\n certificate = (certificate || '').toString()\n\n if (certificate.match(/BEGIN(\\sNEW)? CERTIFICATE REQUEST/)) {\n params = ['req', '-text', '-noout', '-verify', '-in', '--TMPFILE--']\n } else if (certificate.match(/BEGIN RSA PRIVATE KEY/) || certificate.match(/BEGIN PRIVATE KEY/)) {\n params = ['rsa', '-noout', '-check', '-in', '--TMPFILE--']\n } else {\n params = ['x509', '-text', '-noout', '-in', '--TMPFILE--']\n }\n if (passphrase) {\n helper.createPasswordFile({ cipher: '', password: passphrase, passType: 'in' }, params, delTempPWFiles)\n }\n\n openssl.spawnWrapper(params, certificate, function (sslErr, code, stdout, stderr) {\n function done (err) {\n if (err && err.toString().trim() !== 'verify OK') {\n return callback(err)\n }\n var result\n switch (params[0]) {\n case 'rsa':\n result = /^Rsa key ok$/i.test(stdout.trim())\n break\n default:\n result = /Signature Algorithm/im.test(stdout)\n break\n }\n\n callback(null, result)\n }\n helper.deleteTempFiles(delTempPWFiles, function (fsErr) {\n done(sslErr || fsErr || stderr)\n })\n })\n}\n\n/**\n * check a PKCS#12 file (.pfx or.p12)\n * @static\n * @param {Buffer|String} bufferOrPath PKCS#12 certificate\n * @param {String} [passphrase] optional passphrase which will be used to open the keystore\n * @param {Function} callback Callback function with an error object and a boolean valid\n */\nfunction checkPkcs12 (bufferOrPath, passphrase, callback) {\n if (!callback && typeof passphrase === 'function') {\n callback = passphrase\n passphrase = ''\n }\n\n var tmpfiles = []\n var delTempPWFiles = []\n var args = ['pkcs12', '-info', '-in', bufferOrPath, '-noout', '-maciter', '-nodes']\n\n helper.createPasswordFile({ cipher: '', password: passphrase, passType: 'in' }, args, delTempPWFiles)\n\n if (Buffer.isBuffer(bufferOrPath)) {\n tmpfiles = [bufferOrPath]\n args[3] = '--TMPFILE--'\n }\n\n openssl.spawnWrapper(args, tmpfiles, function (sslErr, code, stdout, stderr) {\n function done (err) {\n if (err) {\n return callback(err)\n }\n callback(null, (/MAC verified OK/im.test(stderr) || (!(/MAC verified OK/im.test(stderr)) && !(/Mac verify error/im.test(stderr)))))\n }\n helper.deleteTempFiles(delTempPWFiles, function (fsErr) {\n done(sslErr || fsErr)\n })\n })\n}\n\n/**\n * Verifies the signing chain of the passed certificate\n * @static\n * @param {String|Array} PEM encoded certificate include intermediate certificates\n * @param {String|Array} [List] of CA certificates\n * @param {Function} callback Callback function with an error object and a boolean valid\n */\nfunction verifySigningChain (certificate, ca, callback) {\n if (!callback && typeof ca === 'function') {\n callback = ca\n ca = undefined\n }\n if (!Array.isArray(certificate)) {\n certificate = [certificate]\n }\n if (!Array.isArray(ca) && ca !== undefined) {\n if (ca !== '') {\n ca = [ca]\n }\n }\n\n var files = []\n\n if (ca !== undefined) {\n // ca certificates\n files.push(ca.join('\\n'))\n }\n // certificate incl. intermediate certificates\n files.push(certificate.join('\\n'))\n\n var params = ['verify']\n\n if (ca !== undefined) {\n // ca certificates\n params.push('-CAfile')\n params.push('--TMPFILE--')\n }\n // certificate incl. intermediate certificates\n params.push('--TMPFILE--')\n\n openssl.spawnWrapper(params, files, function (err, code, stdout, stderr) {\n if (err) {\n return callback(err)\n }\n\n callback(null, stdout.trim().slice(-4) === ': OK')\n })\n}\n\n// HELPER FUNCTIONS\nfunction fetchCertificateData (certData, callback) {\n // try catch : if something will fail in parsing it won't crash the calling code\n try {\n certData = (certData || '').toString()\n\n var serial, subject, tmp, issuer\n var certValues = {\n issuer: {}\n }\n var validity = {}\n var san\n\n var ky, i\n\n // serial\n if ((serial = certData.match(/\\s*Serial Number:\\r?\\n?\\s*([^\\r\\n]*)\\r?\\n\\s*\\b/)) && serial.length > 1) {\n certValues.serial = serial[1]\n }\n\n if ((subject = certData.match(/\\s*Subject:\\r?\\n(\\s*(([a-zA-Z0-9.]+)\\s=\\s[^\\r\\n]+\\r?\\n))*\\s*\\b/)) && subject.length > 1) {\n subject = subject[0]\n tmp = matchAll(subject, /\\s([a-zA-Z0-9.]+)\\s=\\s([^\\r\\n].*)/g)\n if (tmp) {\n for (i = 0; i < tmp.length; i++) {\n ky = tmp[i][1].trim()\n if (ky.match('(C|ST|L|O|OU|CN|emailAddress|DC)') || ky === '') {\n continue\n }\n certValues[ky] = tmp[i][2].trim()\n }\n }\n\n // country\n tmp = subject.match(/\\sC\\s=\\s([^\\r\\n].*?)[\\r\\n]/)\n certValues.country = (tmp && tmp[1]) || ''\n\n // state\n tmp = subject.match(/\\sST\\s=\\s([^\\r\\n].*?)[\\r\\n]/)\n certValues.state = (tmp && tmp[1]) || ''\n\n // locality\n tmp = subject.match(/\\sL\\s=\\s([^\\r\\n].*?)[\\r\\n]/)\n certValues.locality = (tmp && tmp[1]) || ''\n\n // organization\n tmp = matchAll(subject, /\\sO\\s=\\s([^\\r\\n].*)/g)\n certValues.organization = tmp ? (tmp.length > 1 ? tmp.sort(function (t, n) {\n var e = t[1].toUpperCase()\n var r = n[1].toUpperCase()\n return r > e ? -1 : e > r ? 1 : 0\n }).sort(function (t, n) {\n return t[1].length - n[1].length\n }).map(function (t) {\n return t[1]\n }) : tmp[0][1]) : ''\n\n // unit\n tmp = matchAll(subject, /\\sOU\\s=\\s([^\\r\\n].*)/g)\n certValues.organizationUnit = tmp ? (tmp.length > 1 ? tmp.sort(function (t, n) {\n var e = t[1].toUpperCase()\n var r = n[1].toUpperCase()\n return r > e ? -1 : e > r ? 1 : 0\n }).sort(function (t, n) {\n return t[1].length - n[1].length\n }).map(function (t) {\n return t[1]\n }) : tmp[0][1]) : ''\n\n // common name\n tmp = matchAll(subject, /\\sCN\\s=\\s([^\\r\\n].*)/g)\n certValues.commonName = tmp ? (tmp.length > 1 ? tmp.sort(function (t, n) {\n var e = t[1].toUpperCase()\n var r = n[1].toUpperCase()\n return r > e ? -1 : e > r ? 1 : 0\n }).sort(function (t, n) {\n return t[1].length - n[1].length\n }).map(function (t) {\n return t[1]\n }) : tmp[0][1]) : ''\n\n // email\n tmp = matchAll(subject, /emailAddress\\s=\\s([^\\r\\n].*)/g)\n certValues.emailAddress = tmp ? (tmp.length > 1 ? tmp.sort(function (t, n) {\n var e = t[1].toUpperCase()\n var r = n[1].toUpperCase()\n return r > e ? -1 : e > r ? 1 : 0\n }).sort(function (t, n) {\n return t[1].length - n[1].length\n }).map(function (t) {\n return t[1]\n }) : tmp[0][1]) : ''\n\n // DC name\n tmp = matchAll(subject, /\\sDC\\s=\\s([^\\r\\n].*)/g)\n certValues.dc = tmp ? (tmp.length > 1 ? tmp.sort(function (t, n) {\n var e = t[1].toUpperCase()\n var r = n[1].toUpperCase()\n return r > e ? -1 : e > r ? 1 : 0\n }).sort(function (t, n) {\n return t[1].length - n[1].length\n }).map(function (t) {\n return t[1]\n }) : tmp[0][1]) : ''\n }\n\n if ((issuer = certData.match(/\\s*Issuer:\\r?\\n(\\s*([a-zA-Z0-9.]+)\\s=\\s[^\\r\\n].*\\r?\\n)*\\s*\\b/)) && issuer.length > 1) {\n issuer = issuer[0]\n tmp = matchAll(issuer, /\\s([a-zA-Z0-9.]+)\\s=\\s([^\\r\\n].*)/g)\n for (i = 0; i < tmp.length; i++) {\n ky = tmp[i][1].toString()\n if (ky.match('(C|ST|L|O|OU|CN|emailAddress|DC)')) {\n continue\n }\n certValues.issuer[ky] = tmp[i][2].toString()\n }\n\n // country\n tmp = issuer.match(/\\sC\\s=\\s([^\\r\\n].*?)[\\r\\n]/)\n certValues.issuer.country = (tmp && tmp[1]) || ''\n\n // state\n tmp = issuer.match(/\\sST\\s=\\s([^\\r\\n].*?)[\\r\\n]/)\n certValues.issuer.state = (tmp && tmp[1]) || ''\n\n // locality\n tmp = issuer.match(/\\sL\\s=\\s([^\\r\\n].*?)[\\r\\n]/)\n certValues.issuer.locality = (tmp && tmp[1]) || ''\n\n // organization\n tmp = matchAll(issuer, /\\sO\\s=\\s([^\\r\\n].*)/g)\n certValues.issuer.organization = tmp ? (tmp.length > 1 ? tmp.sort(function (t, n) {\n var e = t[1].toUpperCase()\n var r = n[1].toUpperCase()\n return r > e ? -1 : e > r ? 1 : 0\n }).sort(function (t, n) {\n return t[1].length - n[1].length\n }).map(function (t) {\n return t[1]\n }) : tmp[0][1]) : ''\n\n // unit\n tmp = matchAll(issuer, /\\sOU\\s=\\s([^\\r\\n].*)/g)\n certValues.issuer.organizationUnit = tmp ? (tmp.length > 1 ? tmp.sort(function (t, n) {\n var e = t[1].toUpperCase()\n var\n r = n[1].toUpperCase()\n return r > e ? -1 : e > r ? 1 : 0\n }).sort(function (t, n) {\n return t[1].length - n[1].length\n }).map(function (t) {\n return t[1]\n }) : tmp[0][1]) : ''\n\n // common name\n tmp = matchAll(issuer, /\\sCN\\s=\\s([^\\r\\n].*)/g)\n certValues.issuer.commonName = tmp ? (tmp.length > 1 ? tmp.sort(function (t, n) {\n var e = t[1].toUpperCase()\n var\n r = n[1].toUpperCase()\n return r > e ? -1 : e > r ? 1 : 0\n }).sort(function (t, n) {\n return t[1].length - n[1].length\n }).map(function (t) {\n return t[1]\n }) : tmp[0][1]) : ''\n\n // DC name\n tmp = matchAll(issuer, /\\sDC\\s=\\s([^\\r\\n].*)/g)\n certValues.issuer.dc = tmp ? (tmp.length > 1 ? tmp.sort(function (t, n) {\n var e = t[1].toUpperCase()\n var\n r = n[1].toUpperCase()\n return r > e ? -1 : e > r ? 1 : 0\n }).sort(function (t, n) {\n return t[1].length - n[1].length\n }).map(function (t) {\n return t[1]\n }) : tmp[0][1]) : ''\n }\n\n // SAN\n if ((san = certData.match(/X509v3 Subject Alternative Name: \\r?\\n([^\\r\\n]*)\\r?\\n/)) && san.length > 1) {\n san = san[1].trim() + '\\n'\n certValues.san = {}\n\n // hostnames\n tmp = pregMatchAll('DNS:([^,\\\\r\\\\n].*?)[,\\\\r\\\\n\\\\s]', san)\n certValues.san.dns = tmp || ''\n\n // IP-Addresses IPv4 & IPv6\n tmp = pregMatchAll('IP Address:([^,\\\\r\\\\n].*?)[,\\\\r\\\\n\\\\s]', san)\n certValues.san.ip = tmp || ''\n\n // Email Addresses\n tmp = pregMatchAll('email:([^,\\\\r\\\\n].*?)[,\\\\r\\\\n\\\\s]', san)\n certValues.san.email = tmp || ''\n }\n\n // Validity\n if ((tmp = certData.match(/Not Before\\s?:\\s?([^\\r\\n]*)\\r?\\n/)) && tmp.length > 1) {\n validity.start = Date.parse((tmp && tmp[1]) || '')\n }\n\n if ((tmp = certData.match(/Not After\\s?:\\s?([^\\r\\n]*)\\r?\\n/)) && tmp.length > 1) {\n validity.end = Date.parse((tmp && tmp[1]) || '')\n }\n\n if (validity.start && validity.end) {\n certValues.validity = validity\n }\n // Validity end\n\n // Signature Algorithm\n if ((tmp = certData.match(/Signature Algorithm: ([^\\r\\n]*)\\r?\\n/)) && tmp.length > 1) {\n certValues.signatureAlgorithm = (tmp && tmp[1]) || ''\n }\n\n // Public Key\n if ((tmp = certData.match(/Public[ -]Key: ([^\\r\\n]*)\\r?\\n/)) && tmp.length > 1) {\n certValues.publicKeySize = ((tmp && tmp[1]) || '').replace(/[()]/g, '')\n }\n\n // Public Key Algorithm\n if ((tmp = certData.match(/Public Key Algorithm: ([^\\r\\n]*)\\r?\\n/)) && tmp.length > 1) {\n certValues.publicKeyAlgorithm = (tmp && tmp[1]) || ''\n }\n\n callback(null, certValues)\n } catch (err) {\n callback(err)\n }\n}\n\nfunction matchAll (str, regexp) {\n var matches = []\n str.replace(regexp, function () {\n var arr = ([]).slice.call(arguments, 0)\n var extras = arr.splice(-2)\n arr.index = extras[0]\n arr.input = extras[1]\n matches.push(arr)\n })\n return matches.length ? matches : null\n}\n\nfunction pregMatchAll (regex, haystack) {\n var globalRegex = new RegExp(regex, 'g')\n var globalMatch = haystack.match(globalRegex) || []\n var matchArray = []\n var nonGlobalRegex, nonGlobalMatch\n for (var i = 0; i < globalMatch.length; i++) {\n nonGlobalRegex = new RegExp(regex)\n nonGlobalMatch = globalMatch[i].match(nonGlobalRegex)\n matchArray.push(nonGlobalMatch[1])\n }\n return matchArray\n}\n\nfunction generateCSRSubject (options) {\n options = options || {}\n\n var csrData = {\n C: options.country || options.C,\n ST: options.state || options.ST,\n L: options.locality || options.L,\n O: options.organization || options.O,\n OU: options.organizationUnit || options.OU,\n CN: options.commonName || options.CN || 'localhost',\n DC: options.dc || options.DC || '',\n emailAddress: options.emailAddress\n }\n\n var csrBuilder = Object.keys(csrData).map(function (key) {\n if (csrData[key]) {\n if (typeof csrData[key] === 'object' && csrData[key].length >= 1) {\n var tmpStr = ''\n csrData[key].map(function (o) {\n tmpStr += '/' + key + '=' + o.replace(/[^\\w .*\\-,@']+/g, ' ').trim()\n })\n return tmpStr\n } else {\n return '/' + key + '=' + csrData[key].replace(/[^\\w .*\\-,@']+/g, ' ').trim()\n }\n }\n })\n\n return csrBuilder.join('')\n}\n\nfunction readFromString (string, start, end) {\n if (Buffer.isBuffer(string)) {\n string = string.toString('utf8')\n }\n\n var output = []\n\n if (!string) {\n return output\n }\n\n var offset = string.indexOf(start)\n\n while (offset !== -1) {\n string = string.substring(offset)\n\n var endOffset = string.indexOf(end)\n\n if (endOffset === -1) {\n break\n }\n\n endOffset += end.length\n\n output.push(string.substring(0, endOffset))\n offset = string.indexOf(start, endOffset)\n }\n\n return output\n}\n\n// promisify not tested yet\n/**\n * Verifies the signing chain of the passed certificate\n * @namespace\n * @name promisified\n * @property {function} createPrivateKey @see createPrivateKey\n * @property {function} createDhparam - The default number of players.\n * @property {function} createEcparam - The default level for the party.\n * @property {function} createCSR - The default treasure.\n * @property {function} createCertificate - How much gold the party starts with.\n */\nmodule.exports.promisified = {\n createPrivateKey: promisify(createPrivateKey),\n createDhparam: promisify(createDhparam),\n createEcparam: promisify(createEcparam),\n createCSR: promisify(createCSR),\n createCertificate: promisify(createCertificate),\n readCertificateInfo: promisify(readCertificateInfo),\n getPublicKey: promisify(getPublicKey),\n getFingerprint: promisify(getFingerprint),\n getModulus: promisify(getModulus),\n getDhparamInfo: promisify(getDhparamInfo),\n createPkcs12: promisify(createPkcs12),\n readPkcs12: promisify(readPkcs12),\n verifySigningChain: promisify(verifySigningChain),\n checkCertificate: promisify(checkCertificate),\n checkPkcs12: promisify(checkPkcs12)\n}\n","/*! https://mths.be/base64 v1.0.0 by @mathias | MIT license */\n;(function(root) {\n\n\t// Detect free variables `exports`.\n\tvar freeExports = typeof exports == 'object' && exports;\n\n\t// Detect free variable `module`.\n\tvar freeModule = typeof module == 'object' && module &&\n\t\tmodule.exports == freeExports && module;\n\n\t// Detect free variable `global`, from Node.js or Browserified code, and use\n\t// it as `root`.\n\tvar freeGlobal = typeof global == 'object' && global;\n\tif (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) {\n\t\troot = freeGlobal;\n\t}\n\n\t/*--------------------------------------------------------------------------*/\n\n\tvar InvalidCharacterError = function(message) {\n\t\tthis.message = message;\n\t};\n\tInvalidCharacterError.prototype = new Error;\n\tInvalidCharacterError.prototype.name = 'InvalidCharacterError';\n\n\tvar error = function(message) {\n\t\t// Note: the error messages used throughout this file match those used by\n\t\t// the native `atob`/`btoa` implementation in Chromium.\n\t\tthrow new InvalidCharacterError(message);\n\t};\n\n\tvar TABLE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n\t// http://whatwg.org/html/common-microsyntaxes.html#space-character\n\tvar REGEX_SPACE_CHARACTERS = /[\\t\\n\\f\\r ]/g;\n\n\t// `decode` is designed to be fully compatible with `atob` as described in the\n\t// HTML Standard. http://whatwg.org/html/webappapis.html#dom-windowbase64-atob\n\t// The optimized base64-decoding algorithm used is based on @atk’s excellent\n\t// implementation. https://gist.github.com/atk/1020396\n\tvar decode = function(input) {\n\t\tinput = String(input)\n\t\t\t.replace(REGEX_SPACE_CHARACTERS, '');\n\t\tvar length = input.length;\n\t\tif (length % 4 == 0) {\n\t\t\tinput = input.replace(/==?$/, '');\n\t\t\tlength = input.length;\n\t\t}\n\t\tif (\n\t\t\tlength % 4 == 1 ||\n\t\t\t// http://whatwg.org/C#alphanumeric-ascii-characters\n\t\t\t/[^+a-zA-Z0-9/]/.test(input)\n\t\t) {\n\t\t\terror(\n\t\t\t\t'Invalid character: the string to be decoded is not correctly encoded.'\n\t\t\t);\n\t\t}\n\t\tvar bitCounter = 0;\n\t\tvar bitStorage;\n\t\tvar buffer;\n\t\tvar output = '';\n\t\tvar position = -1;\n\t\twhile (++position < length) {\n\t\t\tbuffer = TABLE.indexOf(input.charAt(position));\n\t\t\tbitStorage = bitCounter % 4 ? bitStorage * 64 + buffer : buffer;\n\t\t\t// Unless this is the first of a group of 4 characters…\n\t\t\tif (bitCounter++ % 4) {\n\t\t\t\t// …convert the first 8 bits to a single ASCII character.\n\t\t\t\toutput += String.fromCharCode(\n\t\t\t\t\t0xFF & bitStorage >> (-2 * bitCounter & 6)\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\treturn output;\n\t};\n\n\t// `encode` is designed to be fully compatible with `btoa` as described in the\n\t// HTML Standard: http://whatwg.org/html/webappapis.html#dom-windowbase64-btoa\n\tvar encode = function(input) {\n\t\tinput = String(input);\n\t\tif (/[^\\0-\\xFF]/.test(input)) {\n\t\t\t// Note: no need to special-case astral symbols here, as surrogates are\n\t\t\t// matched, and the input is supposed to only contain ASCII anyway.\n\t\t\terror(\n\t\t\t\t'The string to be encoded contains characters outside of the ' +\n\t\t\t\t'Latin1 range.'\n\t\t\t);\n\t\t}\n\t\tvar padding = input.length % 3;\n\t\tvar output = '';\n\t\tvar position = -1;\n\t\tvar a;\n\t\tvar b;\n\t\tvar c;\n\t\tvar buffer;\n\t\t// Make sure any padding is handled outside of the loop.\n\t\tvar length = input.length - padding;\n\n\t\twhile (++position < length) {\n\t\t\t// Read three bytes, i.e. 24 bits.\n\t\t\ta = input.charCodeAt(position) << 16;\n\t\t\tb = input.charCodeAt(++position) << 8;\n\t\t\tc = input.charCodeAt(++position);\n\t\t\tbuffer = a + b + c;\n\t\t\t// Turn the 24 bits into four chunks of 6 bits each, and append the\n\t\t\t// matching character for each of them to the output.\n\t\t\toutput += (\n\t\t\t\tTABLE.charAt(buffer >> 18 & 0x3F) +\n\t\t\t\tTABLE.charAt(buffer >> 12 & 0x3F) +\n\t\t\t\tTABLE.charAt(buffer >> 6 & 0x3F) +\n\t\t\t\tTABLE.charAt(buffer & 0x3F)\n\t\t\t);\n\t\t}\n\n\t\tif (padding == 2) {\n\t\t\ta = input.charCodeAt(position) << 8;\n\t\t\tb = input.charCodeAt(++position);\n\t\t\tbuffer = a + b;\n\t\t\toutput += (\n\t\t\t\tTABLE.charAt(buffer >> 10) +\n\t\t\t\tTABLE.charAt((buffer >> 4) & 0x3F) +\n\t\t\t\tTABLE.charAt((buffer << 2) & 0x3F) +\n\t\t\t\t'='\n\t\t\t);\n\t\t} else if (padding == 1) {\n\t\t\tbuffer = input.charCodeAt(position);\n\t\t\toutput += (\n\t\t\t\tTABLE.charAt(buffer >> 2) +\n\t\t\t\tTABLE.charAt((buffer << 4) & 0x3F) +\n\t\t\t\t'=='\n\t\t\t);\n\t\t}\n\n\t\treturn output;\n\t};\n\n\tvar base64 = {\n\t\t'encode': encode,\n\t\t'decode': decode,\n\t\t'version': '1.0.0'\n\t};\n\n\t// Some AMD build optimizers, like r.js, check for specific condition patterns\n\t// like the following:\n\tif (\n\t\ttypeof define == 'function' &&\n\t\ttypeof define.amd == 'object' &&\n\t\tdefine.amd\n\t) {\n\t\tdefine(function() {\n\t\t\treturn base64;\n\t\t});\n\t}\telse if (freeExports && !freeExports.nodeType) {\n\t\tif (freeModule) { // in Node.js or RingoJS v0.8.0+\n\t\t\tfreeModule.exports = base64;\n\t\t} else { // in Narwhal or RingoJS v0.7.0-\n\t\t\tfor (var key in base64) {\n\t\t\t\tbase64.hasOwnProperty(key) && (freeExports[key] = base64[key]);\n\t\t\t}\n\t\t}\n\t} else { // in Rhino or a web browser\n\t\troot.base64 = base64;\n\t}\n\n}(this));\n","'use strict';\n\nmodule.exports = {\n BINARY_TYPES: ['nodebuffer', 'arraybuffer', 'fragments'],\n EMPTY_BUFFER: Buffer.alloc(0),\n GUID: '258EAFA5-E914-47DA-95CA-C5AB0DC85B11',\n kForOnEventAttribute: Symbol('kIsForOnEventAttribute'),\n kListener: Symbol('kListener'),\n kStatusCode: Symbol('status-code'),\n kWebSocket: Symbol('websocket'),\n NOOP: () => {}\n};\n","'use strict';\n\nconst { EMPTY_BUFFER } = require('./constants');\n\n/**\n * Merges an array of buffers into a new buffer.\n *\n * @param {Buffer[]} list The array of buffers to concat\n * @param {Number} totalLength The total length of buffers in the list\n * @return {Buffer} The resulting buffer\n * @public\n */\nfunction concat(list, totalLength) {\n if (list.length === 0) return EMPTY_BUFFER;\n if (list.length === 1) return list[0];\n\n const target = Buffer.allocUnsafe(totalLength);\n let offset = 0;\n\n for (let i = 0; i < list.length; i++) {\n const buf = list[i];\n target.set(buf, offset);\n offset += buf.length;\n }\n\n if (offset < totalLength) return target.slice(0, offset);\n\n return target;\n}\n\n/**\n * Masks a buffer using the given mask.\n *\n * @param {Buffer} source The buffer to mask\n * @param {Buffer} mask The mask to use\n * @param {Buffer} output The buffer where to store the result\n * @param {Number} offset The offset at which to start writing\n * @param {Number} length The number of bytes to mask.\n * @public\n */\nfunction _mask(source, mask, output, offset, length) {\n for (let i = 0; i < length; i++) {\n output[offset + i] = source[i] ^ mask[i & 3];\n }\n}\n\n/**\n * Unmasks a buffer using the given mask.\n *\n * @param {Buffer} buffer The buffer to unmask\n * @param {Buffer} mask The mask to use\n * @public\n */\nfunction _unmask(buffer, mask) {\n for (let i = 0; i < buffer.length; i++) {\n buffer[i] ^= mask[i & 3];\n }\n}\n\n/**\n * Converts a buffer to an `ArrayBuffer`.\n *\n * @param {Buffer} buf The buffer to convert\n * @return {ArrayBuffer} Converted buffer\n * @public\n */\nfunction toArrayBuffer(buf) {\n if (buf.byteLength === buf.buffer.byteLength) {\n return buf.buffer;\n }\n\n return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);\n}\n\n/**\n * Converts `data` to a `Buffer`.\n *\n * @param {*} data The data to convert\n * @return {Buffer} The buffer\n * @throws {TypeError}\n * @public\n */\nfunction toBuffer(data) {\n toBuffer.readOnly = true;\n\n if (Buffer.isBuffer(data)) return data;\n\n let buf;\n\n if (data instanceof ArrayBuffer) {\n buf = Buffer.from(data);\n } else if (ArrayBuffer.isView(data)) {\n buf = Buffer.from(data.buffer, data.byteOffset, data.byteLength);\n } else {\n buf = Buffer.from(data);\n toBuffer.readOnly = false;\n }\n\n return buf;\n}\n\ntry {\n const bufferUtil = require('bufferutil');\n\n module.exports = {\n concat,\n mask(source, mask, output, offset, length) {\n if (length < 48) _mask(source, mask, output, offset, length);\n else bufferUtil.mask(source, mask, output, offset, length);\n },\n toArrayBuffer,\n toBuffer,\n unmask(buffer, mask) {\n if (buffer.length < 32) _unmask(buffer, mask);\n else bufferUtil.unmask(buffer, mask);\n }\n };\n} catch (e) /* istanbul ignore next */ {\n module.exports = {\n concat,\n mask: _mask,\n toArrayBuffer,\n toBuffer,\n unmask: _unmask\n };\n}\n","'use strict';\n\nconst kDone = Symbol('kDone');\nconst kRun = Symbol('kRun');\n\n/**\n * A very simple job queue with adjustable concurrency. Adapted from\n * https://github.com/STRML/async-limiter\n */\nclass Limiter {\n /**\n * Creates a new `Limiter`.\n *\n * @param {Number} [concurrency=Infinity] The maximum number of jobs allowed\n * to run concurrently\n */\n constructor(concurrency) {\n this[kDone] = () => {\n this.pending--;\n this[kRun]();\n };\n this.concurrency = concurrency || Infinity;\n this.jobs = [];\n this.pending = 0;\n }\n\n /**\n * Adds a job to the queue.\n *\n * @param {Function} job The job to run\n * @public\n */\n add(job) {\n this.jobs.push(job);\n this[kRun]();\n }\n\n /**\n * Removes a job from the queue and runs it if possible.\n *\n * @private\n */\n [kRun]() {\n if (this.pending === this.concurrency) return;\n\n if (this.jobs.length) {\n const job = this.jobs.shift();\n\n this.pending++;\n job(this[kDone]);\n }\n }\n}\n\nmodule.exports = Limiter;\n","'use strict';\n\nconst zlib = require('zlib');\n\nconst bufferUtil = require('./buffer-util');\nconst Limiter = require('./limiter');\nconst { kStatusCode } = require('./constants');\n\nconst TRAILER = Buffer.from([0x00, 0x00, 0xff, 0xff]);\nconst kPerMessageDeflate = Symbol('permessage-deflate');\nconst kTotalLength = Symbol('total-length');\nconst kCallback = Symbol('callback');\nconst kBuffers = Symbol('buffers');\nconst kError = Symbol('error');\n\n//\n// We limit zlib concurrency, which prevents severe memory fragmentation\n// as documented in https://github.com/nodejs/node/issues/8871#issuecomment-250915913\n// and https://github.com/websockets/ws/issues/1202\n//\n// Intentionally global; it's the global thread pool that's an issue.\n//\nlet zlibLimiter;\n\n/**\n * permessage-deflate implementation.\n */\nclass PerMessageDeflate {\n /**\n * Creates a PerMessageDeflate instance.\n *\n * @param {Object} [options] Configuration options\n * @param {(Boolean|Number)} [options.clientMaxWindowBits] Advertise support\n * for, or request, a custom client window size\n * @param {Boolean} [options.clientNoContextTakeover=false] Advertise/\n * acknowledge disabling of client context takeover\n * @param {Number} [options.concurrencyLimit=10] The number of concurrent\n * calls to zlib\n * @param {(Boolean|Number)} [options.serverMaxWindowBits] Request/confirm the\n * use of a custom server window size\n * @param {Boolean} [options.serverNoContextTakeover=false] Request/accept\n * disabling of server context takeover\n * @param {Number} [options.threshold=1024] Size (in bytes) below which\n * messages should not be compressed if context takeover is disabled\n * @param {Object} [options.zlibDeflateOptions] Options to pass to zlib on\n * deflate\n * @param {Object} [options.zlibInflateOptions] Options to pass to zlib on\n * inflate\n * @param {Boolean} [isServer=false] Create the instance in either server or\n * client mode\n * @param {Number} [maxPayload=0] The maximum allowed message length\n */\n constructor(options, isServer, maxPayload) {\n this._maxPayload = maxPayload | 0;\n this._options = options || {};\n this._threshold =\n this._options.threshold !== undefined ? this._options.threshold : 1024;\n this._isServer = !!isServer;\n this._deflate = null;\n this._inflate = null;\n\n this.params = null;\n\n if (!zlibLimiter) {\n const concurrency =\n this._options.concurrencyLimit !== undefined\n ? this._options.concurrencyLimit\n : 10;\n zlibLimiter = new Limiter(concurrency);\n }\n }\n\n /**\n * @type {String}\n */\n static get extensionName() {\n return 'permessage-deflate';\n }\n\n /**\n * Create an extension negotiation offer.\n *\n * @return {Object} Extension parameters\n * @public\n */\n offer() {\n const params = {};\n\n if (this._options.serverNoContextTakeover) {\n params.server_no_context_takeover = true;\n }\n if (this._options.clientNoContextTakeover) {\n params.client_no_context_takeover = true;\n }\n if (this._options.serverMaxWindowBits) {\n params.server_max_window_bits = this._options.serverMaxWindowBits;\n }\n if (this._options.clientMaxWindowBits) {\n params.client_max_window_bits = this._options.clientMaxWindowBits;\n } else if (this._options.clientMaxWindowBits == null) {\n params.client_max_window_bits = true;\n }\n\n return params;\n }\n\n /**\n * Accept an extension negotiation offer/response.\n *\n * @param {Array} configurations The extension negotiation offers/reponse\n * @return {Object} Accepted configuration\n * @public\n */\n accept(configurations) {\n configurations = this.normalizeParams(configurations);\n\n this.params = this._isServer\n ? this.acceptAsServer(configurations)\n : this.acceptAsClient(configurations);\n\n return this.params;\n }\n\n /**\n * Releases all resources used by the extension.\n *\n * @public\n */\n cleanup() {\n if (this._inflate) {\n this._inflate.close();\n this._inflate = null;\n }\n\n if (this._deflate) {\n const callback = this._deflate[kCallback];\n\n this._deflate.close();\n this._deflate = null;\n\n if (callback) {\n callback(\n new Error(\n 'The deflate stream was closed while data was being processed'\n )\n );\n }\n }\n }\n\n /**\n * Accept an extension negotiation offer.\n *\n * @param {Array} offers The extension negotiation offers\n * @return {Object} Accepted configuration\n * @private\n */\n acceptAsServer(offers) {\n const opts = this._options;\n const accepted = offers.find((params) => {\n if (\n (opts.serverNoContextTakeover === false &&\n params.server_no_context_takeover) ||\n (params.server_max_window_bits &&\n (opts.serverMaxWindowBits === false ||\n (typeof opts.serverMaxWindowBits === 'number' &&\n opts.serverMaxWindowBits > params.server_max_window_bits))) ||\n (typeof opts.clientMaxWindowBits === 'number' &&\n !params.client_max_window_bits)\n ) {\n return false;\n }\n\n return true;\n });\n\n if (!accepted) {\n throw new Error('None of the extension offers can be accepted');\n }\n\n if (opts.serverNoContextTakeover) {\n accepted.server_no_context_takeover = true;\n }\n if (opts.clientNoContextTakeover) {\n accepted.client_no_context_takeover = true;\n }\n if (typeof opts.serverMaxWindowBits === 'number') {\n accepted.server_max_window_bits = opts.serverMaxWindowBits;\n }\n if (typeof opts.clientMaxWindowBits === 'number') {\n accepted.client_max_window_bits = opts.clientMaxWindowBits;\n } else if (\n accepted.client_max_window_bits === true ||\n opts.clientMaxWindowBits === false\n ) {\n delete accepted.client_max_window_bits;\n }\n\n return accepted;\n }\n\n /**\n * Accept the extension negotiation response.\n *\n * @param {Array} response The extension negotiation response\n * @return {Object} Accepted configuration\n * @private\n */\n acceptAsClient(response) {\n const params = response[0];\n\n if (\n this._options.clientNoContextTakeover === false &&\n params.client_no_context_takeover\n ) {\n throw new Error('Unexpected parameter \"client_no_context_takeover\"');\n }\n\n if (!params.client_max_window_bits) {\n if (typeof this._options.clientMaxWindowBits === 'number') {\n params.client_max_window_bits = this._options.clientMaxWindowBits;\n }\n } else if (\n this._options.clientMaxWindowBits === false ||\n (typeof this._options.clientMaxWindowBits === 'number' &&\n params.client_max_window_bits > this._options.clientMaxWindowBits)\n ) {\n throw new Error(\n 'Unexpected or invalid parameter \"client_max_window_bits\"'\n );\n }\n\n return params;\n }\n\n /**\n * Normalize parameters.\n *\n * @param {Array} configurations The extension negotiation offers/reponse\n * @return {Array} The offers/response with normalized parameters\n * @private\n */\n normalizeParams(configurations) {\n configurations.forEach((params) => {\n Object.keys(params).forEach((key) => {\n let value = params[key];\n\n if (value.length > 1) {\n throw new Error(`Parameter \"${key}\" must have only a single value`);\n }\n\n value = value[0];\n\n if (key === 'client_max_window_bits') {\n if (value !== true) {\n const num = +value;\n if (!Number.isInteger(num) || num < 8 || num > 15) {\n throw new TypeError(\n `Invalid value for parameter \"${key}\": ${value}`\n );\n }\n value = num;\n } else if (!this._isServer) {\n throw new TypeError(\n `Invalid value for parameter \"${key}\": ${value}`\n );\n }\n } else if (key === 'server_max_window_bits') {\n const num = +value;\n if (!Number.isInteger(num) || num < 8 || num > 15) {\n throw new TypeError(\n `Invalid value for parameter \"${key}\": ${value}`\n );\n }\n value = num;\n } else if (\n key === 'client_no_context_takeover' ||\n key === 'server_no_context_takeover'\n ) {\n if (value !== true) {\n throw new TypeError(\n `Invalid value for parameter \"${key}\": ${value}`\n );\n }\n } else {\n throw new Error(`Unknown parameter \"${key}\"`);\n }\n\n params[key] = value;\n });\n });\n\n return configurations;\n }\n\n /**\n * Decompress data. Concurrency limited.\n *\n * @param {Buffer} data Compressed data\n * @param {Boolean} fin Specifies whether or not this is the last fragment\n * @param {Function} callback Callback\n * @public\n */\n decompress(data, fin, callback) {\n zlibLimiter.add((done) => {\n this._decompress(data, fin, (err, result) => {\n done();\n callback(err, result);\n });\n });\n }\n\n /**\n * Compress data. Concurrency limited.\n *\n * @param {(Buffer|String)} data Data to compress\n * @param {Boolean} fin Specifies whether or not this is the last fragment\n * @param {Function} callback Callback\n * @public\n */\n compress(data, fin, callback) {\n zlibLimiter.add((done) => {\n this._compress(data, fin, (err, result) => {\n done();\n callback(err, result);\n });\n });\n }\n\n /**\n * Decompress data.\n *\n * @param {Buffer} data Compressed data\n * @param {Boolean} fin Specifies whether or not this is the last fragment\n * @param {Function} callback Callback\n * @private\n */\n _decompress(data, fin, callback) {\n const endpoint = this._isServer ? 'client' : 'server';\n\n if (!this._inflate) {\n const key = `${endpoint}_max_window_bits`;\n const windowBits =\n typeof this.params[key] !== 'number'\n ? zlib.Z_DEFAULT_WINDOWBITS\n : this.params[key];\n\n this._inflate = zlib.createInflateRaw({\n ...this._options.zlibInflateOptions,\n windowBits\n });\n this._inflate[kPerMessageDeflate] = this;\n this._inflate[kTotalLength] = 0;\n this._inflate[kBuffers] = [];\n this._inflate.on('error', inflateOnError);\n this._inflate.on('data', inflateOnData);\n }\n\n this._inflate[kCallback] = callback;\n\n this._inflate.write(data);\n if (fin) this._inflate.write(TRAILER);\n\n this._inflate.flush(() => {\n const err = this._inflate[kError];\n\n if (err) {\n this._inflate.close();\n this._inflate = null;\n callback(err);\n return;\n }\n\n const data = bufferUtil.concat(\n this._inflate[kBuffers],\n this._inflate[kTotalLength]\n );\n\n if (this._inflate._readableState.endEmitted) {\n this._inflate.close();\n this._inflate = null;\n } else {\n this._inflate[kTotalLength] = 0;\n this._inflate[kBuffers] = [];\n\n if (fin && this.params[`${endpoint}_no_context_takeover`]) {\n this._inflate.reset();\n }\n }\n\n callback(null, data);\n });\n }\n\n /**\n * Compress data.\n *\n * @param {(Buffer|String)} data Data to compress\n * @param {Boolean} fin Specifies whether or not this is the last fragment\n * @param {Function} callback Callback\n * @private\n */\n _compress(data, fin, callback) {\n const endpoint = this._isServer ? 'server' : 'client';\n\n if (!this._deflate) {\n const key = `${endpoint}_max_window_bits`;\n const windowBits =\n typeof this.params[key] !== 'number'\n ? zlib.Z_DEFAULT_WINDOWBITS\n : this.params[key];\n\n this._deflate = zlib.createDeflateRaw({\n ...this._options.zlibDeflateOptions,\n windowBits\n });\n\n this._deflate[kTotalLength] = 0;\n this._deflate[kBuffers] = [];\n\n this._deflate.on('data', deflateOnData);\n }\n\n this._deflate[kCallback] = callback;\n\n this._deflate.write(data);\n this._deflate.flush(zlib.Z_SYNC_FLUSH, () => {\n if (!this._deflate) {\n //\n // The deflate stream was closed while data was being processed.\n //\n return;\n }\n\n let data = bufferUtil.concat(\n this._deflate[kBuffers],\n this._deflate[kTotalLength]\n );\n\n if (fin) data = data.slice(0, data.length - 4);\n\n //\n // Ensure that the callback will not be called again in\n // `PerMessageDeflate#cleanup()`.\n //\n this._deflate[kCallback] = null;\n\n this._deflate[kTotalLength] = 0;\n this._deflate[kBuffers] = [];\n\n if (fin && this.params[`${endpoint}_no_context_takeover`]) {\n this._deflate.reset();\n }\n\n callback(null, data);\n });\n }\n}\n\nmodule.exports = PerMessageDeflate;\n\n/**\n * The listener of the `zlib.DeflateRaw` stream `'data'` event.\n *\n * @param {Buffer} chunk A chunk of data\n * @private\n */\nfunction deflateOnData(chunk) {\n this[kBuffers].push(chunk);\n this[kTotalLength] += chunk.length;\n}\n\n/**\n * The listener of the `zlib.InflateRaw` stream `'data'` event.\n *\n * @param {Buffer} chunk A chunk of data\n * @private\n */\nfunction inflateOnData(chunk) {\n this[kTotalLength] += chunk.length;\n\n if (\n this[kPerMessageDeflate]._maxPayload < 1 ||\n this[kTotalLength] <= this[kPerMessageDeflate]._maxPayload\n ) {\n this[kBuffers].push(chunk);\n return;\n }\n\n this[kError] = new RangeError('Max payload size exceeded');\n this[kError].code = 'WS_ERR_UNSUPPORTED_MESSAGE_LENGTH';\n this[kError][kStatusCode] = 1009;\n this.removeListener('data', inflateOnData);\n this.reset();\n}\n\n/**\n * The listener of the `zlib.InflateRaw` stream `'error'` event.\n *\n * @param {Error} err The emitted error\n * @private\n */\nfunction inflateOnError(err) {\n //\n // There is no need to call `Zlib#close()` as the handle is automatically\n // closed when an error is emitted.\n //\n this[kPerMessageDeflate]._inflate = null;\n err[kStatusCode] = 1007;\n this[kCallback](err);\n}\n","'use strict';\n\n//\n// Allowed token characters:\n//\n// '!', '#', '$', '%', '&', ''', '*', '+', '-',\n// '.', 0-9, A-Z, '^', '_', '`', a-z, '|', '~'\n//\n// tokenChars[32] === 0 // ' '\n// tokenChars[33] === 1 // '!'\n// tokenChars[34] === 0 // '\"'\n// ...\n//\n// prettier-ignore\nconst tokenChars = [\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0 - 15\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16 - 31\n 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, // 32 - 47\n 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, // 48 - 63\n 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 64 - 79\n 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, // 80 - 95\n 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 96 - 111\n 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0 // 112 - 127\n];\n\n/**\n * Checks if a status code is allowed in a close frame.\n *\n * @param {Number} code The status code\n * @return {Boolean} `true` if the status code is valid, else `false`\n * @public\n */\nfunction isValidStatusCode(code) {\n return (\n (code >= 1000 &&\n code <= 1014 &&\n code !== 1004 &&\n code !== 1005 &&\n code !== 1006) ||\n (code >= 3000 && code <= 4999)\n );\n}\n\n/**\n * Checks if a given buffer contains only correct UTF-8.\n * Ported from https://www.cl.cam.ac.uk/%7Emgk25/ucs/utf8_check.c by\n * Markus Kuhn.\n *\n * @param {Buffer} buf The buffer to check\n * @return {Boolean} `true` if `buf` contains only correct UTF-8, else `false`\n * @public\n */\nfunction _isValidUTF8(buf) {\n const len = buf.length;\n let i = 0;\n\n while (i < len) {\n if ((buf[i] & 0x80) === 0) {\n // 0xxxxxxx\n i++;\n } else if ((buf[i] & 0xe0) === 0xc0) {\n // 110xxxxx 10xxxxxx\n if (\n i + 1 === len ||\n (buf[i + 1] & 0xc0) !== 0x80 ||\n (buf[i] & 0xfe) === 0xc0 // Overlong\n ) {\n return false;\n }\n\n i += 2;\n } else if ((buf[i] & 0xf0) === 0xe0) {\n // 1110xxxx 10xxxxxx 10xxxxxx\n if (\n i + 2 >= len ||\n (buf[i + 1] & 0xc0) !== 0x80 ||\n (buf[i + 2] & 0xc0) !== 0x80 ||\n (buf[i] === 0xe0 && (buf[i + 1] & 0xe0) === 0x80) || // Overlong\n (buf[i] === 0xed && (buf[i + 1] & 0xe0) === 0xa0) // Surrogate (U+D800 - U+DFFF)\n ) {\n return false;\n }\n\n i += 3;\n } else if ((buf[i] & 0xf8) === 0xf0) {\n // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx\n if (\n i + 3 >= len ||\n (buf[i + 1] & 0xc0) !== 0x80 ||\n (buf[i + 2] & 0xc0) !== 0x80 ||\n (buf[i + 3] & 0xc0) !== 0x80 ||\n (buf[i] === 0xf0 && (buf[i + 1] & 0xf0) === 0x80) || // Overlong\n (buf[i] === 0xf4 && buf[i + 1] > 0x8f) ||\n buf[i] > 0xf4 // > U+10FFFF\n ) {\n return false;\n }\n\n i += 4;\n } else {\n return false;\n }\n }\n\n return true;\n}\n\ntry {\n const isValidUTF8 = require('utf-8-validate');\n\n module.exports = {\n isValidStatusCode,\n isValidUTF8(buf) {\n return buf.length < 150 ? _isValidUTF8(buf) : isValidUTF8(buf);\n },\n tokenChars\n };\n} catch (e) /* istanbul ignore next */ {\n module.exports = {\n isValidStatusCode,\n isValidUTF8: _isValidUTF8,\n tokenChars\n };\n}\n","'use strict';\n\nconst { Writable } = require('stream');\n\nconst PerMessageDeflate = require('./permessage-deflate');\nconst {\n BINARY_TYPES,\n EMPTY_BUFFER,\n kStatusCode,\n kWebSocket\n} = require('./constants');\nconst { concat, toArrayBuffer, unmask } = require('./buffer-util');\nconst { isValidStatusCode, isValidUTF8 } = require('./validation');\n\nconst GET_INFO = 0;\nconst GET_PAYLOAD_LENGTH_16 = 1;\nconst GET_PAYLOAD_LENGTH_64 = 2;\nconst GET_MASK = 3;\nconst GET_DATA = 4;\nconst INFLATING = 5;\n\n/**\n * HyBi Receiver implementation.\n *\n * @extends Writable\n */\nclass Receiver extends Writable {\n /**\n * Creates a Receiver instance.\n *\n * @param {Object} [options] Options object\n * @param {String} [options.binaryType=nodebuffer] The type for binary data\n * @param {Object} [options.extensions] An object containing the negotiated\n * extensions\n * @param {Boolean} [options.isServer=false] Specifies whether to operate in\n * client or server mode\n * @param {Number} [options.maxPayload=0] The maximum allowed message length\n * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or\n * not to skip UTF-8 validation for text and close messages\n */\n constructor(options = {}) {\n super();\n\n this._binaryType = options.binaryType || BINARY_TYPES[0];\n this._extensions = options.extensions || {};\n this._isServer = !!options.isServer;\n this._maxPayload = options.maxPayload | 0;\n this._skipUTF8Validation = !!options.skipUTF8Validation;\n this[kWebSocket] = undefined;\n\n this._bufferedBytes = 0;\n this._buffers = [];\n\n this._compressed = false;\n this._payloadLength = 0;\n this._mask = undefined;\n this._fragmented = 0;\n this._masked = false;\n this._fin = false;\n this._opcode = 0;\n\n this._totalPayloadLength = 0;\n this._messageLength = 0;\n this._fragments = [];\n\n this._state = GET_INFO;\n this._loop = false;\n }\n\n /**\n * Implements `Writable.prototype._write()`.\n *\n * @param {Buffer} chunk The chunk of data to write\n * @param {String} encoding The character encoding of `chunk`\n * @param {Function} cb Callback\n * @private\n */\n _write(chunk, encoding, cb) {\n if (this._opcode === 0x08 && this._state == GET_INFO) return cb();\n\n this._bufferedBytes += chunk.length;\n this._buffers.push(chunk);\n this.startLoop(cb);\n }\n\n /**\n * Consumes `n` bytes from the buffered data.\n *\n * @param {Number} n The number of bytes to consume\n * @return {Buffer} The consumed bytes\n * @private\n */\n consume(n) {\n this._bufferedBytes -= n;\n\n if (n === this._buffers[0].length) return this._buffers.shift();\n\n if (n < this._buffers[0].length) {\n const buf = this._buffers[0];\n this._buffers[0] = buf.slice(n);\n return buf.slice(0, n);\n }\n\n const dst = Buffer.allocUnsafe(n);\n\n do {\n const buf = this._buffers[0];\n const offset = dst.length - n;\n\n if (n >= buf.length) {\n dst.set(this._buffers.shift(), offset);\n } else {\n dst.set(new Uint8Array(buf.buffer, buf.byteOffset, n), offset);\n this._buffers[0] = buf.slice(n);\n }\n\n n -= buf.length;\n } while (n > 0);\n\n return dst;\n }\n\n /**\n * Starts the parsing loop.\n *\n * @param {Function} cb Callback\n * @private\n */\n startLoop(cb) {\n let err;\n this._loop = true;\n\n do {\n switch (this._state) {\n case GET_INFO:\n err = this.getInfo();\n break;\n case GET_PAYLOAD_LENGTH_16:\n err = this.getPayloadLength16();\n break;\n case GET_PAYLOAD_LENGTH_64:\n err = this.getPayloadLength64();\n break;\n case GET_MASK:\n this.getMask();\n break;\n case GET_DATA:\n err = this.getData(cb);\n break;\n default:\n // `INFLATING`\n this._loop = false;\n return;\n }\n } while (this._loop);\n\n cb(err);\n }\n\n /**\n * Reads the first two bytes of a frame.\n *\n * @return {(RangeError|undefined)} A possible error\n * @private\n */\n getInfo() {\n if (this._bufferedBytes < 2) {\n this._loop = false;\n return;\n }\n\n const buf = this.consume(2);\n\n if ((buf[0] & 0x30) !== 0x00) {\n this._loop = false;\n return error(\n RangeError,\n 'RSV2 and RSV3 must be clear',\n true,\n 1002,\n 'WS_ERR_UNEXPECTED_RSV_2_3'\n );\n }\n\n const compressed = (buf[0] & 0x40) === 0x40;\n\n if (compressed && !this._extensions[PerMessageDeflate.extensionName]) {\n this._loop = false;\n return error(\n RangeError,\n 'RSV1 must be clear',\n true,\n 1002,\n 'WS_ERR_UNEXPECTED_RSV_1'\n );\n }\n\n this._fin = (buf[0] & 0x80) === 0x80;\n this._opcode = buf[0] & 0x0f;\n this._payloadLength = buf[1] & 0x7f;\n\n if (this._opcode === 0x00) {\n if (compressed) {\n this._loop = false;\n return error(\n RangeError,\n 'RSV1 must be clear',\n true,\n 1002,\n 'WS_ERR_UNEXPECTED_RSV_1'\n );\n }\n\n if (!this._fragmented) {\n this._loop = false;\n return error(\n RangeError,\n 'invalid opcode 0',\n true,\n 1002,\n 'WS_ERR_INVALID_OPCODE'\n );\n }\n\n this._opcode = this._fragmented;\n } else if (this._opcode === 0x01 || this._opcode === 0x02) {\n if (this._fragmented) {\n this._loop = false;\n return error(\n RangeError,\n `invalid opcode ${this._opcode}`,\n true,\n 1002,\n 'WS_ERR_INVALID_OPCODE'\n );\n }\n\n this._compressed = compressed;\n } else if (this._opcode > 0x07 && this._opcode < 0x0b) {\n if (!this._fin) {\n this._loop = false;\n return error(\n RangeError,\n 'FIN must be set',\n true,\n 1002,\n 'WS_ERR_EXPECTED_FIN'\n );\n }\n\n if (compressed) {\n this._loop = false;\n return error(\n RangeError,\n 'RSV1 must be clear',\n true,\n 1002,\n 'WS_ERR_UNEXPECTED_RSV_1'\n );\n }\n\n if (this._payloadLength > 0x7d) {\n this._loop = false;\n return error(\n RangeError,\n `invalid payload length ${this._payloadLength}`,\n true,\n 1002,\n 'WS_ERR_INVALID_CONTROL_PAYLOAD_LENGTH'\n );\n }\n } else {\n this._loop = false;\n return error(\n RangeError,\n `invalid opcode ${this._opcode}`,\n true,\n 1002,\n 'WS_ERR_INVALID_OPCODE'\n );\n }\n\n if (!this._fin && !this._fragmented) this._fragmented = this._opcode;\n this._masked = (buf[1] & 0x80) === 0x80;\n\n if (this._isServer) {\n if (!this._masked) {\n this._loop = false;\n return error(\n RangeError,\n 'MASK must be set',\n true,\n 1002,\n 'WS_ERR_EXPECTED_MASK'\n );\n }\n } else if (this._masked) {\n this._loop = false;\n return error(\n RangeError,\n 'MASK must be clear',\n true,\n 1002,\n 'WS_ERR_UNEXPECTED_MASK'\n );\n }\n\n if (this._payloadLength === 126) this._state = GET_PAYLOAD_LENGTH_16;\n else if (this._payloadLength === 127) this._state = GET_PAYLOAD_LENGTH_64;\n else return this.haveLength();\n }\n\n /**\n * Gets extended payload length (7+16).\n *\n * @return {(RangeError|undefined)} A possible error\n * @private\n */\n getPayloadLength16() {\n if (this._bufferedBytes < 2) {\n this._loop = false;\n return;\n }\n\n this._payloadLength = this.consume(2).readUInt16BE(0);\n return this.haveLength();\n }\n\n /**\n * Gets extended payload length (7+64).\n *\n * @return {(RangeError|undefined)} A possible error\n * @private\n */\n getPayloadLength64() {\n if (this._bufferedBytes < 8) {\n this._loop = false;\n return;\n }\n\n const buf = this.consume(8);\n const num = buf.readUInt32BE(0);\n\n //\n // The maximum safe integer in JavaScript is 2^53 - 1. An error is returned\n // if payload length is greater than this number.\n //\n if (num > Math.pow(2, 53 - 32) - 1) {\n this._loop = false;\n return error(\n RangeError,\n 'Unsupported WebSocket frame: payload length > 2^53 - 1',\n false,\n 1009,\n 'WS_ERR_UNSUPPORTED_DATA_PAYLOAD_LENGTH'\n );\n }\n\n this._payloadLength = num * Math.pow(2, 32) + buf.readUInt32BE(4);\n return this.haveLength();\n }\n\n /**\n * Payload length has been read.\n *\n * @return {(RangeError|undefined)} A possible error\n * @private\n */\n haveLength() {\n if (this._payloadLength && this._opcode < 0x08) {\n this._totalPayloadLength += this._payloadLength;\n if (this._totalPayloadLength > this._maxPayload && this._maxPayload > 0) {\n this._loop = false;\n return error(\n RangeError,\n 'Max payload size exceeded',\n false,\n 1009,\n 'WS_ERR_UNSUPPORTED_MESSAGE_LENGTH'\n );\n }\n }\n\n if (this._masked) this._state = GET_MASK;\n else this._state = GET_DATA;\n }\n\n /**\n * Reads mask bytes.\n *\n * @private\n */\n getMask() {\n if (this._bufferedBytes < 4) {\n this._loop = false;\n return;\n }\n\n this._mask = this.consume(4);\n this._state = GET_DATA;\n }\n\n /**\n * Reads data bytes.\n *\n * @param {Function} cb Callback\n * @return {(Error|RangeError|undefined)} A possible error\n * @private\n */\n getData(cb) {\n let data = EMPTY_BUFFER;\n\n if (this._payloadLength) {\n if (this._bufferedBytes < this._payloadLength) {\n this._loop = false;\n return;\n }\n\n data = this.consume(this._payloadLength);\n\n if (\n this._masked &&\n (this._mask[0] | this._mask[1] | this._mask[2] | this._mask[3]) !== 0\n ) {\n unmask(data, this._mask);\n }\n }\n\n if (this._opcode > 0x07) return this.controlMessage(data);\n\n if (this._compressed) {\n this._state = INFLATING;\n this.decompress(data, cb);\n return;\n }\n\n if (data.length) {\n //\n // This message is not compressed so its length is the sum of the payload\n // length of all fragments.\n //\n this._messageLength = this._totalPayloadLength;\n this._fragments.push(data);\n }\n\n return this.dataMessage();\n }\n\n /**\n * Decompresses data.\n *\n * @param {Buffer} data Compressed data\n * @param {Function} cb Callback\n * @private\n */\n decompress(data, cb) {\n const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName];\n\n perMessageDeflate.decompress(data, this._fin, (err, buf) => {\n if (err) return cb(err);\n\n if (buf.length) {\n this._messageLength += buf.length;\n if (this._messageLength > this._maxPayload && this._maxPayload > 0) {\n return cb(\n error(\n RangeError,\n 'Max payload size exceeded',\n false,\n 1009,\n 'WS_ERR_UNSUPPORTED_MESSAGE_LENGTH'\n )\n );\n }\n\n this._fragments.push(buf);\n }\n\n const er = this.dataMessage();\n if (er) return cb(er);\n\n this.startLoop(cb);\n });\n }\n\n /**\n * Handles a data message.\n *\n * @return {(Error|undefined)} A possible error\n * @private\n */\n dataMessage() {\n if (this._fin) {\n const messageLength = this._messageLength;\n const fragments = this._fragments;\n\n this._totalPayloadLength = 0;\n this._messageLength = 0;\n this._fragmented = 0;\n this._fragments = [];\n\n if (this._opcode === 2) {\n let data;\n\n if (this._binaryType === 'nodebuffer') {\n data = concat(fragments, messageLength);\n } else if (this._binaryType === 'arraybuffer') {\n data = toArrayBuffer(concat(fragments, messageLength));\n } else {\n data = fragments;\n }\n\n this.emit('message', data, true);\n } else {\n const buf = concat(fragments, messageLength);\n\n if (!this._skipUTF8Validation && !isValidUTF8(buf)) {\n this._loop = false;\n return error(\n Error,\n 'invalid UTF-8 sequence',\n true,\n 1007,\n 'WS_ERR_INVALID_UTF8'\n );\n }\n\n this.emit('message', buf, false);\n }\n }\n\n this._state = GET_INFO;\n }\n\n /**\n * Handles a control message.\n *\n * @param {Buffer} data Data to handle\n * @return {(Error|RangeError|undefined)} A possible error\n * @private\n */\n controlMessage(data) {\n if (this._opcode === 0x08) {\n this._loop = false;\n\n if (data.length === 0) {\n this.emit('conclude', 1005, EMPTY_BUFFER);\n this.end();\n } else if (data.length === 1) {\n return error(\n RangeError,\n 'invalid payload length 1',\n true,\n 1002,\n 'WS_ERR_INVALID_CONTROL_PAYLOAD_LENGTH'\n );\n } else {\n const code = data.readUInt16BE(0);\n\n if (!isValidStatusCode(code)) {\n return error(\n RangeError,\n `invalid status code ${code}`,\n true,\n 1002,\n 'WS_ERR_INVALID_CLOSE_CODE'\n );\n }\n\n const buf = data.slice(2);\n\n if (!this._skipUTF8Validation && !isValidUTF8(buf)) {\n return error(\n Error,\n 'invalid UTF-8 sequence',\n true,\n 1007,\n 'WS_ERR_INVALID_UTF8'\n );\n }\n\n this.emit('conclude', code, buf);\n this.end();\n }\n } else if (this._opcode === 0x09) {\n this.emit('ping', data);\n } else {\n this.emit('pong', data);\n }\n\n this._state = GET_INFO;\n }\n}\n\nmodule.exports = Receiver;\n\n/**\n * Builds an error object.\n *\n * @param {function(new:Error|RangeError)} ErrorCtor The error constructor\n * @param {String} message The error message\n * @param {Boolean} prefix Specifies whether or not to add a default prefix to\n * `message`\n * @param {Number} statusCode The status code\n * @param {String} errorCode The exposed error code\n * @return {(Error|RangeError)} The error\n * @private\n */\nfunction error(ErrorCtor, message, prefix, statusCode, errorCode) {\n const err = new ErrorCtor(\n prefix ? `Invalid WebSocket frame: ${message}` : message\n );\n\n Error.captureStackTrace(err, error);\n err.code = errorCode;\n err[kStatusCode] = statusCode;\n return err;\n}\n","/* eslint no-unused-vars: [\"error\", { \"varsIgnorePattern\": \"^net|tls$\" }] */\n\n'use strict';\n\nconst net = require('net');\nconst tls = require('tls');\nconst { randomFillSync } = require('crypto');\n\nconst PerMessageDeflate = require('./permessage-deflate');\nconst { EMPTY_BUFFER } = require('./constants');\nconst { isValidStatusCode } = require('./validation');\nconst { mask: applyMask, toBuffer } = require('./buffer-util');\n\nconst kByteLength = Symbol('kByteLength');\nconst maskBuffer = Buffer.alloc(4);\n\n/**\n * HyBi Sender implementation.\n */\nclass Sender {\n /**\n * Creates a Sender instance.\n *\n * @param {(net.Socket|tls.Socket)} socket The connection socket\n * @param {Object} [extensions] An object containing the negotiated extensions\n * @param {Function} [generateMask] The function used to generate the masking\n * key\n */\n constructor(socket, extensions, generateMask) {\n this._extensions = extensions || {};\n\n if (generateMask) {\n this._generateMask = generateMask;\n this._maskBuffer = Buffer.alloc(4);\n }\n\n this._socket = socket;\n\n this._firstFragment = true;\n this._compress = false;\n\n this._bufferedBytes = 0;\n this._deflating = false;\n this._queue = [];\n }\n\n /**\n * Frames a piece of data according to the HyBi WebSocket protocol.\n *\n * @param {(Buffer|String)} data The data to frame\n * @param {Object} options Options object\n * @param {Boolean} [options.fin=false] Specifies whether or not to set the\n * FIN bit\n * @param {Function} [options.generateMask] The function used to generate the\n * masking key\n * @param {Boolean} [options.mask=false] Specifies whether or not to mask\n * `data`\n * @param {Buffer} [options.maskBuffer] The buffer used to store the masking\n * key\n * @param {Number} options.opcode The opcode\n * @param {Boolean} [options.readOnly=false] Specifies whether `data` can be\n * modified\n * @param {Boolean} [options.rsv1=false] Specifies whether or not to set the\n * RSV1 bit\n * @return {(Buffer|String)[]} The framed data\n * @public\n */\n static frame(data, options) {\n let mask;\n let merge = false;\n let offset = 2;\n let skipMasking = false;\n\n if (options.mask) {\n mask = options.maskBuffer || maskBuffer;\n\n if (options.generateMask) {\n options.generateMask(mask);\n } else {\n randomFillSync(mask, 0, 4);\n }\n\n skipMasking = (mask[0] | mask[1] | mask[2] | mask[3]) === 0;\n offset = 6;\n }\n\n let dataLength;\n\n if (typeof data === 'string') {\n if (\n (!options.mask || skipMasking) &&\n options[kByteLength] !== undefined\n ) {\n dataLength = options[kByteLength];\n } else {\n data = Buffer.from(data);\n dataLength = data.length;\n }\n } else {\n dataLength = data.length;\n merge = options.mask && options.readOnly && !skipMasking;\n }\n\n let payloadLength = dataLength;\n\n if (dataLength >= 65536) {\n offset += 8;\n payloadLength = 127;\n } else if (dataLength > 125) {\n offset += 2;\n payloadLength = 126;\n }\n\n const target = Buffer.allocUnsafe(merge ? dataLength + offset : offset);\n\n target[0] = options.fin ? options.opcode | 0x80 : options.opcode;\n if (options.rsv1) target[0] |= 0x40;\n\n target[1] = payloadLength;\n\n if (payloadLength === 126) {\n target.writeUInt16BE(dataLength, 2);\n } else if (payloadLength === 127) {\n target[2] = target[3] = 0;\n target.writeUIntBE(dataLength, 4, 6);\n }\n\n if (!options.mask) return [target, data];\n\n target[1] |= 0x80;\n target[offset - 4] = mask[0];\n target[offset - 3] = mask[1];\n target[offset - 2] = mask[2];\n target[offset - 1] = mask[3];\n\n if (skipMasking) return [target, data];\n\n if (merge) {\n applyMask(data, mask, target, offset, dataLength);\n return [target];\n }\n\n applyMask(data, mask, data, 0, dataLength);\n return [target, data];\n }\n\n /**\n * Sends a close message to the other peer.\n *\n * @param {Number} [code] The status code component of the body\n * @param {(String|Buffer)} [data] The message component of the body\n * @param {Boolean} [mask=false] Specifies whether or not to mask the message\n * @param {Function} [cb] Callback\n * @public\n */\n close(code, data, mask, cb) {\n let buf;\n\n if (code === undefined) {\n buf = EMPTY_BUFFER;\n } else if (typeof code !== 'number' || !isValidStatusCode(code)) {\n throw new TypeError('First argument must be a valid error code number');\n } else if (data === undefined || !data.length) {\n buf = Buffer.allocUnsafe(2);\n buf.writeUInt16BE(code, 0);\n } else {\n const length = Buffer.byteLength(data);\n\n if (length > 123) {\n throw new RangeError('The message must not be greater than 123 bytes');\n }\n\n buf = Buffer.allocUnsafe(2 + length);\n buf.writeUInt16BE(code, 0);\n\n if (typeof data === 'string') {\n buf.write(data, 2);\n } else {\n buf.set(data, 2);\n }\n }\n\n const options = {\n [kByteLength]: buf.length,\n fin: true,\n generateMask: this._generateMask,\n mask,\n maskBuffer: this._maskBuffer,\n opcode: 0x08,\n readOnly: false,\n rsv1: false\n };\n\n if (this._deflating) {\n this.enqueue([this.dispatch, buf, false, options, cb]);\n } else {\n this.sendFrame(Sender.frame(buf, options), cb);\n }\n }\n\n /**\n * Sends a ping message to the other peer.\n *\n * @param {*} data The message to send\n * @param {Boolean} [mask=false] Specifies whether or not to mask `data`\n * @param {Function} [cb] Callback\n * @public\n */\n ping(data, mask, cb) {\n let byteLength;\n let readOnly;\n\n if (typeof data === 'string') {\n byteLength = Buffer.byteLength(data);\n readOnly = false;\n } else {\n data = toBuffer(data);\n byteLength = data.length;\n readOnly = toBuffer.readOnly;\n }\n\n if (byteLength > 125) {\n throw new RangeError('The data size must not be greater than 125 bytes');\n }\n\n const options = {\n [kByteLength]: byteLength,\n fin: true,\n generateMask: this._generateMask,\n mask,\n maskBuffer: this._maskBuffer,\n opcode: 0x09,\n readOnly,\n rsv1: false\n };\n\n if (this._deflating) {\n this.enqueue([this.dispatch, data, false, options, cb]);\n } else {\n this.sendFrame(Sender.frame(data, options), cb);\n }\n }\n\n /**\n * Sends a pong message to the other peer.\n *\n * @param {*} data The message to send\n * @param {Boolean} [mask=false] Specifies whether or not to mask `data`\n * @param {Function} [cb] Callback\n * @public\n */\n pong(data, mask, cb) {\n let byteLength;\n let readOnly;\n\n if (typeof data === 'string') {\n byteLength = Buffer.byteLength(data);\n readOnly = false;\n } else {\n data = toBuffer(data);\n byteLength = data.length;\n readOnly = toBuffer.readOnly;\n }\n\n if (byteLength > 125) {\n throw new RangeError('The data size must not be greater than 125 bytes');\n }\n\n const options = {\n [kByteLength]: byteLength,\n fin: true,\n generateMask: this._generateMask,\n mask,\n maskBuffer: this._maskBuffer,\n opcode: 0x0a,\n readOnly,\n rsv1: false\n };\n\n if (this._deflating) {\n this.enqueue([this.dispatch, data, false, options, cb]);\n } else {\n this.sendFrame(Sender.frame(data, options), cb);\n }\n }\n\n /**\n * Sends a data message to the other peer.\n *\n * @param {*} data The message to send\n * @param {Object} options Options object\n * @param {Boolean} [options.binary=false] Specifies whether `data` is binary\n * or text\n * @param {Boolean} [options.compress=false] Specifies whether or not to\n * compress `data`\n * @param {Boolean} [options.fin=false] Specifies whether the fragment is the\n * last one\n * @param {Boolean} [options.mask=false] Specifies whether or not to mask\n * `data`\n * @param {Function} [cb] Callback\n * @public\n */\n send(data, options, cb) {\n const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName];\n let opcode = options.binary ? 2 : 1;\n let rsv1 = options.compress;\n\n let byteLength;\n let readOnly;\n\n if (typeof data === 'string') {\n byteLength = Buffer.byteLength(data);\n readOnly = false;\n } else {\n data = toBuffer(data);\n byteLength = data.length;\n readOnly = toBuffer.readOnly;\n }\n\n if (this._firstFragment) {\n this._firstFragment = false;\n if (\n rsv1 &&\n perMessageDeflate &&\n perMessageDeflate.params[\n perMessageDeflate._isServer\n ? 'server_no_context_takeover'\n : 'client_no_context_takeover'\n ]\n ) {\n rsv1 = byteLength >= perMessageDeflate._threshold;\n }\n this._compress = rsv1;\n } else {\n rsv1 = false;\n opcode = 0;\n }\n\n if (options.fin) this._firstFragment = true;\n\n if (perMessageDeflate) {\n const opts = {\n [kByteLength]: byteLength,\n fin: options.fin,\n generateMask: this._generateMask,\n mask: options.mask,\n maskBuffer: this._maskBuffer,\n opcode,\n readOnly,\n rsv1\n };\n\n if (this._deflating) {\n this.enqueue([this.dispatch, data, this._compress, opts, cb]);\n } else {\n this.dispatch(data, this._compress, opts, cb);\n }\n } else {\n this.sendFrame(\n Sender.frame(data, {\n [kByteLength]: byteLength,\n fin: options.fin,\n generateMask: this._generateMask,\n mask: options.mask,\n maskBuffer: this._maskBuffer,\n opcode,\n readOnly,\n rsv1: false\n }),\n cb\n );\n }\n }\n\n /**\n * Dispatches a message.\n *\n * @param {(Buffer|String)} data The message to send\n * @param {Boolean} [compress=false] Specifies whether or not to compress\n * `data`\n * @param {Object} options Options object\n * @param {Boolean} [options.fin=false] Specifies whether or not to set the\n * FIN bit\n * @param {Function} [options.generateMask] The function used to generate the\n * masking key\n * @param {Boolean} [options.mask=false] Specifies whether or not to mask\n * `data`\n * @param {Buffer} [options.maskBuffer] The buffer used to store the masking\n * key\n * @param {Number} options.opcode The opcode\n * @param {Boolean} [options.readOnly=false] Specifies whether `data` can be\n * modified\n * @param {Boolean} [options.rsv1=false] Specifies whether or not to set the\n * RSV1 bit\n * @param {Function} [cb] Callback\n * @private\n */\n dispatch(data, compress, options, cb) {\n if (!compress) {\n this.sendFrame(Sender.frame(data, options), cb);\n return;\n }\n\n const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName];\n\n this._bufferedBytes += options[kByteLength];\n this._deflating = true;\n perMessageDeflate.compress(data, options.fin, (_, buf) => {\n if (this._socket.destroyed) {\n const err = new Error(\n 'The socket was closed while data was being compressed'\n );\n\n if (typeof cb === 'function') cb(err);\n\n for (let i = 0; i < this._queue.length; i++) {\n const params = this._queue[i];\n const callback = params[params.length - 1];\n\n if (typeof callback === 'function') callback(err);\n }\n\n return;\n }\n\n this._bufferedBytes -= options[kByteLength];\n this._deflating = false;\n options.readOnly = false;\n this.sendFrame(Sender.frame(buf, options), cb);\n this.dequeue();\n });\n }\n\n /**\n * Executes queued send operations.\n *\n * @private\n */\n dequeue() {\n while (!this._deflating && this._queue.length) {\n const params = this._queue.shift();\n\n this._bufferedBytes -= params[3][kByteLength];\n Reflect.apply(params[0], this, params.slice(1));\n }\n }\n\n /**\n * Enqueues a send operation.\n *\n * @param {Array} params Send operation parameters.\n * @private\n */\n enqueue(params) {\n this._bufferedBytes += params[3][kByteLength];\n this._queue.push(params);\n }\n\n /**\n * Sends a frame.\n *\n * @param {Buffer[]} list The frame to send\n * @param {Function} [cb] Callback\n * @private\n */\n sendFrame(list, cb) {\n if (list.length === 2) {\n this._socket.cork();\n this._socket.write(list[0]);\n this._socket.write(list[1], cb);\n this._socket.uncork();\n } else {\n this._socket.write(list[0], cb);\n }\n }\n}\n\nmodule.exports = Sender;\n","'use strict';\n\nconst { kForOnEventAttribute, kListener } = require('./constants');\n\nconst kCode = Symbol('kCode');\nconst kData = Symbol('kData');\nconst kError = Symbol('kError');\nconst kMessage = Symbol('kMessage');\nconst kReason = Symbol('kReason');\nconst kTarget = Symbol('kTarget');\nconst kType = Symbol('kType');\nconst kWasClean = Symbol('kWasClean');\n\n/**\n * Class representing an event.\n */\nclass Event {\n /**\n * Create a new `Event`.\n *\n * @param {String} type The name of the event\n * @throws {TypeError} If the `type` argument is not specified\n */\n constructor(type) {\n this[kTarget] = null;\n this[kType] = type;\n }\n\n /**\n * @type {*}\n */\n get target() {\n return this[kTarget];\n }\n\n /**\n * @type {String}\n */\n get type() {\n return this[kType];\n }\n}\n\nObject.defineProperty(Event.prototype, 'target', { enumerable: true });\nObject.defineProperty(Event.prototype, 'type', { enumerable: true });\n\n/**\n * Class representing a close event.\n *\n * @extends Event\n */\nclass CloseEvent extends Event {\n /**\n * Create a new `CloseEvent`.\n *\n * @param {String} type The name of the event\n * @param {Object} [options] A dictionary object that allows for setting\n * attributes via object members of the same name\n * @param {Number} [options.code=0] The status code explaining why the\n * connection was closed\n * @param {String} [options.reason=''] A human-readable string explaining why\n * the connection was closed\n * @param {Boolean} [options.wasClean=false] Indicates whether or not the\n * connection was cleanly closed\n */\n constructor(type, options = {}) {\n super(type);\n\n this[kCode] = options.code === undefined ? 0 : options.code;\n this[kReason] = options.reason === undefined ? '' : options.reason;\n this[kWasClean] = options.wasClean === undefined ? false : options.wasClean;\n }\n\n /**\n * @type {Number}\n */\n get code() {\n return this[kCode];\n }\n\n /**\n * @type {String}\n */\n get reason() {\n return this[kReason];\n }\n\n /**\n * @type {Boolean}\n */\n get wasClean() {\n return this[kWasClean];\n }\n}\n\nObject.defineProperty(CloseEvent.prototype, 'code', { enumerable: true });\nObject.defineProperty(CloseEvent.prototype, 'reason', { enumerable: true });\nObject.defineProperty(CloseEvent.prototype, 'wasClean', { enumerable: true });\n\n/**\n * Class representing an error event.\n *\n * @extends Event\n */\nclass ErrorEvent extends Event {\n /**\n * Create a new `ErrorEvent`.\n *\n * @param {String} type The name of the event\n * @param {Object} [options] A dictionary object that allows for setting\n * attributes via object members of the same name\n * @param {*} [options.error=null] The error that generated this event\n * @param {String} [options.message=''] The error message\n */\n constructor(type, options = {}) {\n super(type);\n\n this[kError] = options.error === undefined ? null : options.error;\n this[kMessage] = options.message === undefined ? '' : options.message;\n }\n\n /**\n * @type {*}\n */\n get error() {\n return this[kError];\n }\n\n /**\n * @type {String}\n */\n get message() {\n return this[kMessage];\n }\n}\n\nObject.defineProperty(ErrorEvent.prototype, 'error', { enumerable: true });\nObject.defineProperty(ErrorEvent.prototype, 'message', { enumerable: true });\n\n/**\n * Class representing a message event.\n *\n * @extends Event\n */\nclass MessageEvent extends Event {\n /**\n * Create a new `MessageEvent`.\n *\n * @param {String} type The name of the event\n * @param {Object} [options] A dictionary object that allows for setting\n * attributes via object members of the same name\n * @param {*} [options.data=null] The message content\n */\n constructor(type, options = {}) {\n super(type);\n\n this[kData] = options.data === undefined ? null : options.data;\n }\n\n /**\n * @type {*}\n */\n get data() {\n return this[kData];\n }\n}\n\nObject.defineProperty(MessageEvent.prototype, 'data', { enumerable: true });\n\n/**\n * This provides methods for emulating the `EventTarget` interface. It's not\n * meant to be used directly.\n *\n * @mixin\n */\nconst EventTarget = {\n /**\n * Register an event listener.\n *\n * @param {String} type A string representing the event type to listen for\n * @param {Function} listener The listener to add\n * @param {Object} [options] An options object specifies characteristics about\n * the event listener\n * @param {Boolean} [options.once=false] A `Boolean` indicating that the\n * listener should be invoked at most once after being added. If `true`,\n * the listener would be automatically removed when invoked.\n * @public\n */\n addEventListener(type, listener, options = {}) {\n let wrapper;\n\n if (type === 'message') {\n wrapper = function onMessage(data, isBinary) {\n const event = new MessageEvent('message', {\n data: isBinary ? data : data.toString()\n });\n\n event[kTarget] = this;\n listener.call(this, event);\n };\n } else if (type === 'close') {\n wrapper = function onClose(code, message) {\n const event = new CloseEvent('close', {\n code,\n reason: message.toString(),\n wasClean: this._closeFrameReceived && this._closeFrameSent\n });\n\n event[kTarget] = this;\n listener.call(this, event);\n };\n } else if (type === 'error') {\n wrapper = function onError(error) {\n const event = new ErrorEvent('error', {\n error,\n message: error.message\n });\n\n event[kTarget] = this;\n listener.call(this, event);\n };\n } else if (type === 'open') {\n wrapper = function onOpen() {\n const event = new Event('open');\n\n event[kTarget] = this;\n listener.call(this, event);\n };\n } else {\n return;\n }\n\n wrapper[kForOnEventAttribute] = !!options[kForOnEventAttribute];\n wrapper[kListener] = listener;\n\n if (options.once) {\n this.once(type, wrapper);\n } else {\n this.on(type, wrapper);\n }\n },\n\n /**\n * Remove an event listener.\n *\n * @param {String} type A string representing the event type to remove\n * @param {Function} handler The listener to remove\n * @public\n */\n removeEventListener(type, handler) {\n for (const listener of this.listeners(type)) {\n if (listener[kListener] === handler && !listener[kForOnEventAttribute]) {\n this.removeListener(type, listener);\n break;\n }\n }\n }\n};\n\nmodule.exports = {\n CloseEvent,\n ErrorEvent,\n Event,\n EventTarget,\n MessageEvent\n};\n","'use strict';\n\nconst { tokenChars } = require('./validation');\n\n/**\n * Adds an offer to the map of extension offers or a parameter to the map of\n * parameters.\n *\n * @param {Object} dest The map of extension offers or parameters\n * @param {String} name The extension or parameter name\n * @param {(Object|Boolean|String)} elem The extension parameters or the\n * parameter value\n * @private\n */\nfunction push(dest, name, elem) {\n if (dest[name] === undefined) dest[name] = [elem];\n else dest[name].push(elem);\n}\n\n/**\n * Parses the `Sec-WebSocket-Extensions` header into an object.\n *\n * @param {String} header The field value of the header\n * @return {Object} The parsed object\n * @public\n */\nfunction parse(header) {\n const offers = Object.create(null);\n let params = Object.create(null);\n let mustUnescape = false;\n let isEscaping = false;\n let inQuotes = false;\n let extensionName;\n let paramName;\n let start = -1;\n let code = -1;\n let end = -1;\n let i = 0;\n\n for (; i < header.length; i++) {\n code = header.charCodeAt(i);\n\n if (extensionName === undefined) {\n if (end === -1 && tokenChars[code] === 1) {\n if (start === -1) start = i;\n } else if (\n i !== 0 &&\n (code === 0x20 /* ' ' */ || code === 0x09) /* '\\t' */\n ) {\n if (end === -1 && start !== -1) end = i;\n } else if (code === 0x3b /* ';' */ || code === 0x2c /* ',' */) {\n if (start === -1) {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n\n if (end === -1) end = i;\n const name = header.slice(start, end);\n if (code === 0x2c) {\n push(offers, name, params);\n params = Object.create(null);\n } else {\n extensionName = name;\n }\n\n start = end = -1;\n } else {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n } else if (paramName === undefined) {\n if (end === -1 && tokenChars[code] === 1) {\n if (start === -1) start = i;\n } else if (code === 0x20 || code === 0x09) {\n if (end === -1 && start !== -1) end = i;\n } else if (code === 0x3b || code === 0x2c) {\n if (start === -1) {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n\n if (end === -1) end = i;\n push(params, header.slice(start, end), true);\n if (code === 0x2c) {\n push(offers, extensionName, params);\n params = Object.create(null);\n extensionName = undefined;\n }\n\n start = end = -1;\n } else if (code === 0x3d /* '=' */ && start !== -1 && end === -1) {\n paramName = header.slice(start, i);\n start = end = -1;\n } else {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n } else {\n //\n // The value of a quoted-string after unescaping must conform to the\n // token ABNF, so only token characters are valid.\n // Ref: https://tools.ietf.org/html/rfc6455#section-9.1\n //\n if (isEscaping) {\n if (tokenChars[code] !== 1) {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n if (start === -1) start = i;\n else if (!mustUnescape) mustUnescape = true;\n isEscaping = false;\n } else if (inQuotes) {\n if (tokenChars[code] === 1) {\n if (start === -1) start = i;\n } else if (code === 0x22 /* '\"' */ && start !== -1) {\n inQuotes = false;\n end = i;\n } else if (code === 0x5c /* '\\' */) {\n isEscaping = true;\n } else {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n } else if (code === 0x22 && header.charCodeAt(i - 1) === 0x3d) {\n inQuotes = true;\n } else if (end === -1 && tokenChars[code] === 1) {\n if (start === -1) start = i;\n } else if (start !== -1 && (code === 0x20 || code === 0x09)) {\n if (end === -1) end = i;\n } else if (code === 0x3b || code === 0x2c) {\n if (start === -1) {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n\n if (end === -1) end = i;\n let value = header.slice(start, end);\n if (mustUnescape) {\n value = value.replace(/\\\\/g, '');\n mustUnescape = false;\n }\n push(params, paramName, value);\n if (code === 0x2c) {\n push(offers, extensionName, params);\n params = Object.create(null);\n extensionName = undefined;\n }\n\n paramName = undefined;\n start = end = -1;\n } else {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n }\n }\n\n if (start === -1 || inQuotes || code === 0x20 || code === 0x09) {\n throw new SyntaxError('Unexpected end of input');\n }\n\n if (end === -1) end = i;\n const token = header.slice(start, end);\n if (extensionName === undefined) {\n push(offers, token, params);\n } else {\n if (paramName === undefined) {\n push(params, token, true);\n } else if (mustUnescape) {\n push(params, paramName, token.replace(/\\\\/g, ''));\n } else {\n push(params, paramName, token);\n }\n push(offers, extensionName, params);\n }\n\n return offers;\n}\n\n/**\n * Builds the `Sec-WebSocket-Extensions` header field value.\n *\n * @param {Object} extensions The map of extensions and parameters to format\n * @return {String} A string representing the given object\n * @public\n */\nfunction format(extensions) {\n return Object.keys(extensions)\n .map((extension) => {\n let configurations = extensions[extension];\n if (!Array.isArray(configurations)) configurations = [configurations];\n return configurations\n .map((params) => {\n return [extension]\n .concat(\n Object.keys(params).map((k) => {\n let values = params[k];\n if (!Array.isArray(values)) values = [values];\n return values\n .map((v) => (v === true ? k : `${k}=${v}`))\n .join('; ');\n })\n )\n .join('; ');\n })\n .join(', ');\n })\n .join(', ');\n}\n\nmodule.exports = { format, parse };\n","/* eslint no-unused-vars: [\"error\", { \"varsIgnorePattern\": \"^Readable$\" }] */\n\n'use strict';\n\nconst EventEmitter = require('events');\nconst https = require('https');\nconst http = require('http');\nconst net = require('net');\nconst tls = require('tls');\nconst { randomBytes, createHash } = require('crypto');\nconst { Readable } = require('stream');\nconst { URL } = require('url');\n\nconst PerMessageDeflate = require('./permessage-deflate');\nconst Receiver = require('./receiver');\nconst Sender = require('./sender');\nconst {\n BINARY_TYPES,\n EMPTY_BUFFER,\n GUID,\n kForOnEventAttribute,\n kListener,\n kStatusCode,\n kWebSocket,\n NOOP\n} = require('./constants');\nconst {\n EventTarget: { addEventListener, removeEventListener }\n} = require('./event-target');\nconst { format, parse } = require('./extension');\nconst { toBuffer } = require('./buffer-util');\n\nconst readyStates = ['CONNECTING', 'OPEN', 'CLOSING', 'CLOSED'];\nconst subprotocolRegex = /^[!#$%&'*+\\-.0-9A-Z^_`|a-z~]+$/;\nconst protocolVersions = [8, 13];\nconst closeTimeout = 30 * 1000;\n\n/**\n * Class representing a WebSocket.\n *\n * @extends EventEmitter\n */\nclass WebSocket extends EventEmitter {\n /**\n * Create a new `WebSocket`.\n *\n * @param {(String|URL)} address The URL to which to connect\n * @param {(String|String[])} [protocols] The subprotocols\n * @param {Object} [options] Connection options\n */\n constructor(address, protocols, options) {\n super();\n\n this._binaryType = BINARY_TYPES[0];\n this._closeCode = 1006;\n this._closeFrameReceived = false;\n this._closeFrameSent = false;\n this._closeMessage = EMPTY_BUFFER;\n this._closeTimer = null;\n this._extensions = {};\n this._paused = false;\n this._protocol = '';\n this._readyState = WebSocket.CONNECTING;\n this._receiver = null;\n this._sender = null;\n this._socket = null;\n\n if (address !== null) {\n this._bufferedAmount = 0;\n this._isServer = false;\n this._redirects = 0;\n\n if (protocols === undefined) {\n protocols = [];\n } else if (!Array.isArray(protocols)) {\n if (typeof protocols === 'object' && protocols !== null) {\n options = protocols;\n protocols = [];\n } else {\n protocols = [protocols];\n }\n }\n\n initAsClient(this, address, protocols, options);\n } else {\n this._isServer = true;\n }\n }\n\n /**\n * This deviates from the WHATWG interface since ws doesn't support the\n * required default \"blob\" type (instead we define a custom \"nodebuffer\"\n * type).\n *\n * @type {String}\n */\n get binaryType() {\n return this._binaryType;\n }\n\n set binaryType(type) {\n if (!BINARY_TYPES.includes(type)) return;\n\n this._binaryType = type;\n\n //\n // Allow to change `binaryType` on the fly.\n //\n if (this._receiver) this._receiver._binaryType = type;\n }\n\n /**\n * @type {Number}\n */\n get bufferedAmount() {\n if (!this._socket) return this._bufferedAmount;\n\n return this._socket._writableState.length + this._sender._bufferedBytes;\n }\n\n /**\n * @type {String}\n */\n get extensions() {\n return Object.keys(this._extensions).join();\n }\n\n /**\n * @type {Boolean}\n */\n get isPaused() {\n return this._paused;\n }\n\n /**\n * @type {Function}\n */\n /* istanbul ignore next */\n get onclose() {\n return null;\n }\n\n /**\n * @type {Function}\n */\n /* istanbul ignore next */\n get onerror() {\n return null;\n }\n\n /**\n * @type {Function}\n */\n /* istanbul ignore next */\n get onopen() {\n return null;\n }\n\n /**\n * @type {Function}\n */\n /* istanbul ignore next */\n get onmessage() {\n return null;\n }\n\n /**\n * @type {String}\n */\n get protocol() {\n return this._protocol;\n }\n\n /**\n * @type {Number}\n */\n get readyState() {\n return this._readyState;\n }\n\n /**\n * @type {String}\n */\n get url() {\n return this._url;\n }\n\n /**\n * Set up the socket and the internal resources.\n *\n * @param {(net.Socket|tls.Socket)} socket The network socket between the\n * server and client\n * @param {Buffer} head The first packet of the upgraded stream\n * @param {Object} options Options object\n * @param {Function} [options.generateMask] The function used to generate the\n * masking key\n * @param {Number} [options.maxPayload=0] The maximum allowed message size\n * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or\n * not to skip UTF-8 validation for text and close messages\n * @private\n */\n setSocket(socket, head, options) {\n const receiver = new Receiver({\n binaryType: this.binaryType,\n extensions: this._extensions,\n isServer: this._isServer,\n maxPayload: options.maxPayload,\n skipUTF8Validation: options.skipUTF8Validation\n });\n\n this._sender = new Sender(socket, this._extensions, options.generateMask);\n this._receiver = receiver;\n this._socket = socket;\n\n receiver[kWebSocket] = this;\n socket[kWebSocket] = this;\n\n receiver.on('conclude', receiverOnConclude);\n receiver.on('drain', receiverOnDrain);\n receiver.on('error', receiverOnError);\n receiver.on('message', receiverOnMessage);\n receiver.on('ping', receiverOnPing);\n receiver.on('pong', receiverOnPong);\n\n socket.setTimeout(0);\n socket.setNoDelay();\n\n if (head.length > 0) socket.unshift(head);\n\n socket.on('close', socketOnClose);\n socket.on('data', socketOnData);\n socket.on('end', socketOnEnd);\n socket.on('error', socketOnError);\n\n this._readyState = WebSocket.OPEN;\n this.emit('open');\n }\n\n /**\n * Emit the `'close'` event.\n *\n * @private\n */\n emitClose() {\n if (!this._socket) {\n this._readyState = WebSocket.CLOSED;\n this.emit('close', this._closeCode, this._closeMessage);\n return;\n }\n\n if (this._extensions[PerMessageDeflate.extensionName]) {\n this._extensions[PerMessageDeflate.extensionName].cleanup();\n }\n\n this._receiver.removeAllListeners();\n this._readyState = WebSocket.CLOSED;\n this.emit('close', this._closeCode, this._closeMessage);\n }\n\n /**\n * Start a closing handshake.\n *\n * +----------+ +-----------+ +----------+\n * - - -|ws.close()|-->|close frame|-->|ws.close()|- - -\n * | +----------+ +-----------+ +----------+ |\n * +----------+ +-----------+ |\n * CLOSING |ws.close()|<--|close frame|<--+-----+ CLOSING\n * +----------+ +-----------+ |\n * | | | +---+ |\n * +------------------------+-->|fin| - - - -\n * | +---+ | +---+\n * - - - - -|fin|<---------------------+\n * +---+\n *\n * @param {Number} [code] Status code explaining why the connection is closing\n * @param {(String|Buffer)} [data] The reason why the connection is\n * closing\n * @public\n */\n close(code, data) {\n if (this.readyState === WebSocket.CLOSED) return;\n if (this.readyState === WebSocket.CONNECTING) {\n const msg = 'WebSocket was closed before the connection was established';\n return abortHandshake(this, this._req, msg);\n }\n\n if (this.readyState === WebSocket.CLOSING) {\n if (\n this._closeFrameSent &&\n (this._closeFrameReceived || this._receiver._writableState.errorEmitted)\n ) {\n this._socket.end();\n }\n\n return;\n }\n\n this._readyState = WebSocket.CLOSING;\n this._sender.close(code, data, !this._isServer, (err) => {\n //\n // This error is handled by the `'error'` listener on the socket. We only\n // want to know if the close frame has been sent here.\n //\n if (err) return;\n\n this._closeFrameSent = true;\n\n if (\n this._closeFrameReceived ||\n this._receiver._writableState.errorEmitted\n ) {\n this._socket.end();\n }\n });\n\n //\n // Specify a timeout for the closing handshake to complete.\n //\n this._closeTimer = setTimeout(\n this._socket.destroy.bind(this._socket),\n closeTimeout\n );\n }\n\n /**\n * Pause the socket.\n *\n * @public\n */\n pause() {\n if (\n this.readyState === WebSocket.CONNECTING ||\n this.readyState === WebSocket.CLOSED\n ) {\n return;\n }\n\n this._paused = true;\n this._socket.pause();\n }\n\n /**\n * Send a ping.\n *\n * @param {*} [data] The data to send\n * @param {Boolean} [mask] Indicates whether or not to mask `data`\n * @param {Function} [cb] Callback which is executed when the ping is sent\n * @public\n */\n ping(data, mask, cb) {\n if (this.readyState === WebSocket.CONNECTING) {\n throw new Error('WebSocket is not open: readyState 0 (CONNECTING)');\n }\n\n if (typeof data === 'function') {\n cb = data;\n data = mask = undefined;\n } else if (typeof mask === 'function') {\n cb = mask;\n mask = undefined;\n }\n\n if (typeof data === 'number') data = data.toString();\n\n if (this.readyState !== WebSocket.OPEN) {\n sendAfterClose(this, data, cb);\n return;\n }\n\n if (mask === undefined) mask = !this._isServer;\n this._sender.ping(data || EMPTY_BUFFER, mask, cb);\n }\n\n /**\n * Send a pong.\n *\n * @param {*} [data] The data to send\n * @param {Boolean} [mask] Indicates whether or not to mask `data`\n * @param {Function} [cb] Callback which is executed when the pong is sent\n * @public\n */\n pong(data, mask, cb) {\n if (this.readyState === WebSocket.CONNECTING) {\n throw new Error('WebSocket is not open: readyState 0 (CONNECTING)');\n }\n\n if (typeof data === 'function') {\n cb = data;\n data = mask = undefined;\n } else if (typeof mask === 'function') {\n cb = mask;\n mask = undefined;\n }\n\n if (typeof data === 'number') data = data.toString();\n\n if (this.readyState !== WebSocket.OPEN) {\n sendAfterClose(this, data, cb);\n return;\n }\n\n if (mask === undefined) mask = !this._isServer;\n this._sender.pong(data || EMPTY_BUFFER, mask, cb);\n }\n\n /**\n * Resume the socket.\n *\n * @public\n */\n resume() {\n if (\n this.readyState === WebSocket.CONNECTING ||\n this.readyState === WebSocket.CLOSED\n ) {\n return;\n }\n\n this._paused = false;\n if (!this._receiver._writableState.needDrain) this._socket.resume();\n }\n\n /**\n * Send a data message.\n *\n * @param {*} data The message to send\n * @param {Object} [options] Options object\n * @param {Boolean} [options.binary] Specifies whether `data` is binary or\n * text\n * @param {Boolean} [options.compress] Specifies whether or not to compress\n * `data`\n * @param {Boolean} [options.fin=true] Specifies whether the fragment is the\n * last one\n * @param {Boolean} [options.mask] Specifies whether or not to mask `data`\n * @param {Function} [cb] Callback which is executed when data is written out\n * @public\n */\n send(data, options, cb) {\n if (this.readyState === WebSocket.CONNECTING) {\n throw new Error('WebSocket is not open: readyState 0 (CONNECTING)');\n }\n\n if (typeof options === 'function') {\n cb = options;\n options = {};\n }\n\n if (typeof data === 'number') data = data.toString();\n\n if (this.readyState !== WebSocket.OPEN) {\n sendAfterClose(this, data, cb);\n return;\n }\n\n const opts = {\n binary: typeof data !== 'string',\n mask: !this._isServer,\n compress: true,\n fin: true,\n ...options\n };\n\n if (!this._extensions[PerMessageDeflate.extensionName]) {\n opts.compress = false;\n }\n\n this._sender.send(data || EMPTY_BUFFER, opts, cb);\n }\n\n /**\n * Forcibly close the connection.\n *\n * @public\n */\n terminate() {\n if (this.readyState === WebSocket.CLOSED) return;\n if (this.readyState === WebSocket.CONNECTING) {\n const msg = 'WebSocket was closed before the connection was established';\n return abortHandshake(this, this._req, msg);\n }\n\n if (this._socket) {\n this._readyState = WebSocket.CLOSING;\n this._socket.destroy();\n }\n }\n}\n\n/**\n * @constant {Number} CONNECTING\n * @memberof WebSocket\n */\nObject.defineProperty(WebSocket, 'CONNECTING', {\n enumerable: true,\n value: readyStates.indexOf('CONNECTING')\n});\n\n/**\n * @constant {Number} CONNECTING\n * @memberof WebSocket.prototype\n */\nObject.defineProperty(WebSocket.prototype, 'CONNECTING', {\n enumerable: true,\n value: readyStates.indexOf('CONNECTING')\n});\n\n/**\n * @constant {Number} OPEN\n * @memberof WebSocket\n */\nObject.defineProperty(WebSocket, 'OPEN', {\n enumerable: true,\n value: readyStates.indexOf('OPEN')\n});\n\n/**\n * @constant {Number} OPEN\n * @memberof WebSocket.prototype\n */\nObject.defineProperty(WebSocket.prototype, 'OPEN', {\n enumerable: true,\n value: readyStates.indexOf('OPEN')\n});\n\n/**\n * @constant {Number} CLOSING\n * @memberof WebSocket\n */\nObject.defineProperty(WebSocket, 'CLOSING', {\n enumerable: true,\n value: readyStates.indexOf('CLOSING')\n});\n\n/**\n * @constant {Number} CLOSING\n * @memberof WebSocket.prototype\n */\nObject.defineProperty(WebSocket.prototype, 'CLOSING', {\n enumerable: true,\n value: readyStates.indexOf('CLOSING')\n});\n\n/**\n * @constant {Number} CLOSED\n * @memberof WebSocket\n */\nObject.defineProperty(WebSocket, 'CLOSED', {\n enumerable: true,\n value: readyStates.indexOf('CLOSED')\n});\n\n/**\n * @constant {Number} CLOSED\n * @memberof WebSocket.prototype\n */\nObject.defineProperty(WebSocket.prototype, 'CLOSED', {\n enumerable: true,\n value: readyStates.indexOf('CLOSED')\n});\n\n[\n 'binaryType',\n 'bufferedAmount',\n 'extensions',\n 'isPaused',\n 'protocol',\n 'readyState',\n 'url'\n].forEach((property) => {\n Object.defineProperty(WebSocket.prototype, property, { enumerable: true });\n});\n\n//\n// Add the `onopen`, `onerror`, `onclose`, and `onmessage` attributes.\n// See https://html.spec.whatwg.org/multipage/comms.html#the-websocket-interface\n//\n['open', 'error', 'close', 'message'].forEach((method) => {\n Object.defineProperty(WebSocket.prototype, `on${method}`, {\n enumerable: true,\n get() {\n for (const listener of this.listeners(method)) {\n if (listener[kForOnEventAttribute]) return listener[kListener];\n }\n\n return null;\n },\n set(handler) {\n for (const listener of this.listeners(method)) {\n if (listener[kForOnEventAttribute]) {\n this.removeListener(method, listener);\n break;\n }\n }\n\n if (typeof handler !== 'function') return;\n\n this.addEventListener(method, handler, {\n [kForOnEventAttribute]: true\n });\n }\n });\n});\n\nWebSocket.prototype.addEventListener = addEventListener;\nWebSocket.prototype.removeEventListener = removeEventListener;\n\nmodule.exports = WebSocket;\n\n/**\n * Initialize a WebSocket client.\n *\n * @param {WebSocket} websocket The client to initialize\n * @param {(String|URL)} address The URL to which to connect\n * @param {Array} protocols The subprotocols\n * @param {Object} [options] Connection options\n * @param {Boolean} [options.followRedirects=false] Whether or not to follow\n * redirects\n * @param {Function} [options.generateMask] The function used to generate the\n * masking key\n * @param {Number} [options.handshakeTimeout] Timeout in milliseconds for the\n * handshake request\n * @param {Number} [options.maxPayload=104857600] The maximum allowed message\n * size\n * @param {Number} [options.maxRedirects=10] The maximum number of redirects\n * allowed\n * @param {String} [options.origin] Value of the `Origin` or\n * `Sec-WebSocket-Origin` header\n * @param {(Boolean|Object)} [options.perMessageDeflate=true] Enable/disable\n * permessage-deflate\n * @param {Number} [options.protocolVersion=13] Value of the\n * `Sec-WebSocket-Version` header\n * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or\n * not to skip UTF-8 validation for text and close messages\n * @private\n */\nfunction initAsClient(websocket, address, protocols, options) {\n const opts = {\n protocolVersion: protocolVersions[1],\n maxPayload: 100 * 1024 * 1024,\n skipUTF8Validation: false,\n perMessageDeflate: true,\n followRedirects: false,\n maxRedirects: 10,\n ...options,\n createConnection: undefined,\n socketPath: undefined,\n hostname: undefined,\n protocol: undefined,\n timeout: undefined,\n method: undefined,\n host: undefined,\n path: undefined,\n port: undefined\n };\n\n if (!protocolVersions.includes(opts.protocolVersion)) {\n throw new RangeError(\n `Unsupported protocol version: ${opts.protocolVersion} ` +\n `(supported versions: ${protocolVersions.join(', ')})`\n );\n }\n\n let parsedUrl;\n\n if (address instanceof URL) {\n parsedUrl = address;\n websocket._url = address.href;\n } else {\n try {\n parsedUrl = new URL(address);\n } catch (e) {\n throw new SyntaxError(`Invalid URL: ${address}`);\n }\n\n websocket._url = address;\n }\n\n const isSecure = parsedUrl.protocol === 'wss:';\n const isUnixSocket = parsedUrl.protocol === 'ws+unix:';\n let invalidURLMessage;\n\n if (parsedUrl.protocol !== 'ws:' && !isSecure && !isUnixSocket) {\n invalidURLMessage =\n 'The URL\\'s protocol must be one of \"ws:\", \"wss:\", or \"ws+unix:\"';\n } else if (isUnixSocket && !parsedUrl.pathname) {\n invalidURLMessage = \"The URL's pathname is empty\";\n } else if (parsedUrl.hash) {\n invalidURLMessage = 'The URL contains a fragment identifier';\n }\n\n if (invalidURLMessage) {\n const err = new SyntaxError(invalidURLMessage);\n\n if (websocket._redirects === 0) {\n throw err;\n } else {\n emitErrorAndClose(websocket, err);\n return;\n }\n }\n\n const defaultPort = isSecure ? 443 : 80;\n const key = randomBytes(16).toString('base64');\n const get = isSecure ? https.get : http.get;\n const protocolSet = new Set();\n let perMessageDeflate;\n\n opts.createConnection = isSecure ? tlsConnect : netConnect;\n opts.defaultPort = opts.defaultPort || defaultPort;\n opts.port = parsedUrl.port || defaultPort;\n opts.host = parsedUrl.hostname.startsWith('[')\n ? parsedUrl.hostname.slice(1, -1)\n : parsedUrl.hostname;\n opts.headers = {\n 'Sec-WebSocket-Version': opts.protocolVersion,\n 'Sec-WebSocket-Key': key,\n Connection: 'Upgrade',\n Upgrade: 'websocket',\n ...opts.headers\n };\n opts.path = parsedUrl.pathname + parsedUrl.search;\n opts.timeout = opts.handshakeTimeout;\n\n if (opts.perMessageDeflate) {\n perMessageDeflate = new PerMessageDeflate(\n opts.perMessageDeflate !== true ? opts.perMessageDeflate : {},\n false,\n opts.maxPayload\n );\n opts.headers['Sec-WebSocket-Extensions'] = format({\n [PerMessageDeflate.extensionName]: perMessageDeflate.offer()\n });\n }\n if (protocols.length) {\n for (const protocol of protocols) {\n if (\n typeof protocol !== 'string' ||\n !subprotocolRegex.test(protocol) ||\n protocolSet.has(protocol)\n ) {\n throw new SyntaxError(\n 'An invalid or duplicated subprotocol was specified'\n );\n }\n\n protocolSet.add(protocol);\n }\n\n opts.headers['Sec-WebSocket-Protocol'] = protocols.join(',');\n }\n if (opts.origin) {\n if (opts.protocolVersion < 13) {\n opts.headers['Sec-WebSocket-Origin'] = opts.origin;\n } else {\n opts.headers.Origin = opts.origin;\n }\n }\n if (parsedUrl.username || parsedUrl.password) {\n opts.auth = `${parsedUrl.username}:${parsedUrl.password}`;\n }\n\n if (isUnixSocket) {\n const parts = opts.path.split(':');\n\n opts.socketPath = parts[0];\n opts.path = parts[1];\n }\n\n if (opts.followRedirects) {\n if (websocket._redirects === 0) {\n websocket._originalHost = parsedUrl.host;\n\n const headers = options && options.headers;\n\n //\n // Shallow copy the user provided options so that headers can be changed\n // without mutating the original object.\n //\n options = { ...options, headers: {} };\n\n if (headers) {\n for (const [key, value] of Object.entries(headers)) {\n options.headers[key.toLowerCase()] = value;\n }\n }\n } else if (parsedUrl.host !== websocket._originalHost) {\n //\n // Match curl 7.77.0 behavior and drop the following headers. These\n // headers are also dropped when following a redirect to a subdomain.\n //\n delete opts.headers.authorization;\n delete opts.headers.cookie;\n delete opts.headers.host;\n opts.auth = undefined;\n }\n\n //\n // Match curl 7.77.0 behavior and make the first `Authorization` header win.\n // If the `Authorization` header is set, then there is nothing to do as it\n // will take precedence.\n //\n if (opts.auth && !options.headers.authorization) {\n options.headers.authorization =\n 'Basic ' + Buffer.from(opts.auth).toString('base64');\n }\n }\n\n let req = (websocket._req = get(opts));\n\n if (opts.timeout) {\n req.on('timeout', () => {\n abortHandshake(websocket, req, 'Opening handshake has timed out');\n });\n }\n\n req.on('error', (err) => {\n if (req === null || req.aborted) return;\n\n req = websocket._req = null;\n emitErrorAndClose(websocket, err);\n });\n\n req.on('response', (res) => {\n const location = res.headers.location;\n const statusCode = res.statusCode;\n\n if (\n location &&\n opts.followRedirects &&\n statusCode >= 300 &&\n statusCode < 400\n ) {\n if (++websocket._redirects > opts.maxRedirects) {\n abortHandshake(websocket, req, 'Maximum redirects exceeded');\n return;\n }\n\n req.abort();\n\n let addr;\n\n try {\n addr = new URL(location, address);\n } catch (e) {\n const err = new SyntaxError(`Invalid URL: ${location}`);\n emitErrorAndClose(websocket, err);\n return;\n }\n\n initAsClient(websocket, addr, protocols, options);\n } else if (!websocket.emit('unexpected-response', req, res)) {\n abortHandshake(\n websocket,\n req,\n `Unexpected server response: ${res.statusCode}`\n );\n }\n });\n\n req.on('upgrade', (res, socket, head) => {\n websocket.emit('upgrade', res);\n\n //\n // The user may have closed the connection from a listener of the `upgrade`\n // event.\n //\n if (websocket.readyState !== WebSocket.CONNECTING) return;\n\n req = websocket._req = null;\n\n const digest = createHash('sha1')\n .update(key + GUID)\n .digest('base64');\n\n if (res.headers['sec-websocket-accept'] !== digest) {\n abortHandshake(websocket, socket, 'Invalid Sec-WebSocket-Accept header');\n return;\n }\n\n const serverProt = res.headers['sec-websocket-protocol'];\n let protError;\n\n if (serverProt !== undefined) {\n if (!protocolSet.size) {\n protError = 'Server sent a subprotocol but none was requested';\n } else if (!protocolSet.has(serverProt)) {\n protError = 'Server sent an invalid subprotocol';\n }\n } else if (protocolSet.size) {\n protError = 'Server sent no subprotocol';\n }\n\n if (protError) {\n abortHandshake(websocket, socket, protError);\n return;\n }\n\n if (serverProt) websocket._protocol = serverProt;\n\n const secWebSocketExtensions = res.headers['sec-websocket-extensions'];\n\n if (secWebSocketExtensions !== undefined) {\n if (!perMessageDeflate) {\n const message =\n 'Server sent a Sec-WebSocket-Extensions header but no extension ' +\n 'was requested';\n abortHandshake(websocket, socket, message);\n return;\n }\n\n let extensions;\n\n try {\n extensions = parse(secWebSocketExtensions);\n } catch (err) {\n const message = 'Invalid Sec-WebSocket-Extensions header';\n abortHandshake(websocket, socket, message);\n return;\n }\n\n const extensionNames = Object.keys(extensions);\n\n if (\n extensionNames.length !== 1 ||\n extensionNames[0] !== PerMessageDeflate.extensionName\n ) {\n const message = 'Server indicated an extension that was not requested';\n abortHandshake(websocket, socket, message);\n return;\n }\n\n try {\n perMessageDeflate.accept(extensions[PerMessageDeflate.extensionName]);\n } catch (err) {\n const message = 'Invalid Sec-WebSocket-Extensions header';\n abortHandshake(websocket, socket, message);\n return;\n }\n\n websocket._extensions[PerMessageDeflate.extensionName] =\n perMessageDeflate;\n }\n\n websocket.setSocket(socket, head, {\n generateMask: opts.generateMask,\n maxPayload: opts.maxPayload,\n skipUTF8Validation: opts.skipUTF8Validation\n });\n });\n}\n\n/**\n * Emit the `'error'` and `'close'` event.\n *\n * @param {WebSocket} websocket The WebSocket instance\n * @param {Error} The error to emit\n * @private\n */\nfunction emitErrorAndClose(websocket, err) {\n websocket._readyState = WebSocket.CLOSING;\n websocket.emit('error', err);\n websocket.emitClose();\n}\n\n/**\n * Create a `net.Socket` and initiate a connection.\n *\n * @param {Object} options Connection options\n * @return {net.Socket} The newly created socket used to start the connection\n * @private\n */\nfunction netConnect(options) {\n options.path = options.socketPath;\n return net.connect(options);\n}\n\n/**\n * Create a `tls.TLSSocket` and initiate a connection.\n *\n * @param {Object} options Connection options\n * @return {tls.TLSSocket} The newly created socket used to start the connection\n * @private\n */\nfunction tlsConnect(options) {\n options.path = undefined;\n\n if (!options.servername && options.servername !== '') {\n options.servername = net.isIP(options.host) ? '' : options.host;\n }\n\n return tls.connect(options);\n}\n\n/**\n * Abort the handshake and emit an error.\n *\n * @param {WebSocket} websocket The WebSocket instance\n * @param {(http.ClientRequest|net.Socket|tls.Socket)} stream The request to\n * abort or the socket to destroy\n * @param {String} message The error message\n * @private\n */\nfunction abortHandshake(websocket, stream, message) {\n websocket._readyState = WebSocket.CLOSING;\n\n const err = new Error(message);\n Error.captureStackTrace(err, abortHandshake);\n\n if (stream.setHeader) {\n stream.abort();\n\n if (stream.socket && !stream.socket.destroyed) {\n //\n // On Node.js >= 14.3.0 `request.abort()` does not destroy the socket if\n // called after the request completed. See\n // https://github.com/websockets/ws/issues/1869.\n //\n stream.socket.destroy();\n }\n\n stream.once('abort', websocket.emitClose.bind(websocket));\n websocket.emit('error', err);\n } else {\n stream.destroy(err);\n stream.once('error', websocket.emit.bind(websocket, 'error'));\n stream.once('close', websocket.emitClose.bind(websocket));\n }\n}\n\n/**\n * Handle cases where the `ping()`, `pong()`, or `send()` methods are called\n * when the `readyState` attribute is `CLOSING` or `CLOSED`.\n *\n * @param {WebSocket} websocket The WebSocket instance\n * @param {*} [data] The data to send\n * @param {Function} [cb] Callback\n * @private\n */\nfunction sendAfterClose(websocket, data, cb) {\n if (data) {\n const length = toBuffer(data).length;\n\n //\n // The `_bufferedAmount` property is used only when the peer is a client and\n // the opening handshake fails. Under these circumstances, in fact, the\n // `setSocket()` method is not called, so the `_socket` and `_sender`\n // properties are set to `null`.\n //\n if (websocket._socket) websocket._sender._bufferedBytes += length;\n else websocket._bufferedAmount += length;\n }\n\n if (cb) {\n const err = new Error(\n `WebSocket is not open: readyState ${websocket.readyState} ` +\n `(${readyStates[websocket.readyState]})`\n );\n cb(err);\n }\n}\n\n/**\n * The listener of the `Receiver` `'conclude'` event.\n *\n * @param {Number} code The status code\n * @param {Buffer} reason The reason for closing\n * @private\n */\nfunction receiverOnConclude(code, reason) {\n const websocket = this[kWebSocket];\n\n websocket._closeFrameReceived = true;\n websocket._closeMessage = reason;\n websocket._closeCode = code;\n\n if (websocket._socket[kWebSocket] === undefined) return;\n\n websocket._socket.removeListener('data', socketOnData);\n process.nextTick(resume, websocket._socket);\n\n if (code === 1005) websocket.close();\n else websocket.close(code, reason);\n}\n\n/**\n * The listener of the `Receiver` `'drain'` event.\n *\n * @private\n */\nfunction receiverOnDrain() {\n const websocket = this[kWebSocket];\n\n if (!websocket.isPaused) websocket._socket.resume();\n}\n\n/**\n * The listener of the `Receiver` `'error'` event.\n *\n * @param {(RangeError|Error)} err The emitted error\n * @private\n */\nfunction receiverOnError(err) {\n const websocket = this[kWebSocket];\n\n if (websocket._socket[kWebSocket] !== undefined) {\n websocket._socket.removeListener('data', socketOnData);\n\n //\n // On Node.js < 14.0.0 the `'error'` event is emitted synchronously. See\n // https://github.com/websockets/ws/issues/1940.\n //\n process.nextTick(resume, websocket._socket);\n\n websocket.close(err[kStatusCode]);\n }\n\n websocket.emit('error', err);\n}\n\n/**\n * The listener of the `Receiver` `'finish'` event.\n *\n * @private\n */\nfunction receiverOnFinish() {\n this[kWebSocket].emitClose();\n}\n\n/**\n * The listener of the `Receiver` `'message'` event.\n *\n * @param {Buffer|ArrayBuffer|Buffer[])} data The message\n * @param {Boolean} isBinary Specifies whether the message is binary or not\n * @private\n */\nfunction receiverOnMessage(data, isBinary) {\n this[kWebSocket].emit('message', data, isBinary);\n}\n\n/**\n * The listener of the `Receiver` `'ping'` event.\n *\n * @param {Buffer} data The data included in the ping frame\n * @private\n */\nfunction receiverOnPing(data) {\n const websocket = this[kWebSocket];\n\n websocket.pong(data, !websocket._isServer, NOOP);\n websocket.emit('ping', data);\n}\n\n/**\n * The listener of the `Receiver` `'pong'` event.\n *\n * @param {Buffer} data The data included in the pong frame\n * @private\n */\nfunction receiverOnPong(data) {\n this[kWebSocket].emit('pong', data);\n}\n\n/**\n * Resume a readable stream\n *\n * @param {Readable} stream The readable stream\n * @private\n */\nfunction resume(stream) {\n stream.resume();\n}\n\n/**\n * The listener of the `net.Socket` `'close'` event.\n *\n * @private\n */\nfunction socketOnClose() {\n const websocket = this[kWebSocket];\n\n this.removeListener('close', socketOnClose);\n this.removeListener('data', socketOnData);\n this.removeListener('end', socketOnEnd);\n\n websocket._readyState = WebSocket.CLOSING;\n\n let chunk;\n\n //\n // The close frame might not have been received or the `'end'` event emitted,\n // for example, if the socket was destroyed due to an error. Ensure that the\n // `receiver` stream is closed after writing any remaining buffered data to\n // it. If the readable side of the socket is in flowing mode then there is no\n // buffered data as everything has been already written and `readable.read()`\n // will return `null`. If instead, the socket is paused, any possible buffered\n // data will be read as a single chunk.\n //\n if (\n !this._readableState.endEmitted &&\n !websocket._closeFrameReceived &&\n !websocket._receiver._writableState.errorEmitted &&\n (chunk = websocket._socket.read()) !== null\n ) {\n websocket._receiver.write(chunk);\n }\n\n websocket._receiver.end();\n\n this[kWebSocket] = undefined;\n\n clearTimeout(websocket._closeTimer);\n\n if (\n websocket._receiver._writableState.finished ||\n websocket._receiver._writableState.errorEmitted\n ) {\n websocket.emitClose();\n } else {\n websocket._receiver.on('error', receiverOnFinish);\n websocket._receiver.on('finish', receiverOnFinish);\n }\n}\n\n/**\n * The listener of the `net.Socket` `'data'` event.\n *\n * @param {Buffer} chunk A chunk of data\n * @private\n */\nfunction socketOnData(chunk) {\n if (!this[kWebSocket]._receiver.write(chunk)) {\n this.pause();\n }\n}\n\n/**\n * The listener of the `net.Socket` `'end'` event.\n *\n * @private\n */\nfunction socketOnEnd() {\n const websocket = this[kWebSocket];\n\n websocket._readyState = WebSocket.CLOSING;\n websocket._receiver.end();\n this.end();\n}\n\n/**\n * The listener of the `net.Socket` `'error'` event.\n *\n * @private\n */\nfunction socketOnError() {\n const websocket = this[kWebSocket];\n\n this.removeListener('error', socketOnError);\n this.on('error', NOOP);\n\n if (websocket) {\n websocket._readyState = WebSocket.CLOSING;\n this.destroy();\n }\n}\n","'use strict';\n\nconst { Duplex } = require('stream');\n\n/**\n * Emits the `'close'` event on a stream.\n *\n * @param {Duplex} stream The stream.\n * @private\n */\nfunction emitClose(stream) {\n stream.emit('close');\n}\n\n/**\n * The listener of the `'end'` event.\n *\n * @private\n */\nfunction duplexOnEnd() {\n if (!this.destroyed && this._writableState.finished) {\n this.destroy();\n }\n}\n\n/**\n * The listener of the `'error'` event.\n *\n * @param {Error} err The error\n * @private\n */\nfunction duplexOnError(err) {\n this.removeListener('error', duplexOnError);\n this.destroy();\n if (this.listenerCount('error') === 0) {\n // Do not suppress the throwing behavior.\n this.emit('error', err);\n }\n}\n\n/**\n * Wraps a `WebSocket` in a duplex stream.\n *\n * @param {WebSocket} ws The `WebSocket` to wrap\n * @param {Object} [options] The options for the `Duplex` constructor\n * @return {Duplex} The duplex stream\n * @public\n */\nfunction createWebSocketStream(ws, options) {\n let terminateOnDestroy = true;\n\n const duplex = new Duplex({\n ...options,\n autoDestroy: false,\n emitClose: false,\n objectMode: false,\n writableObjectMode: false\n });\n\n ws.on('message', function message(msg, isBinary) {\n const data =\n !isBinary && duplex._readableState.objectMode ? msg.toString() : msg;\n\n if (!duplex.push(data)) ws.pause();\n });\n\n ws.once('error', function error(err) {\n if (duplex.destroyed) return;\n\n // Prevent `ws.terminate()` from being called by `duplex._destroy()`.\n //\n // - If the `'error'` event is emitted before the `'open'` event, then\n // `ws.terminate()` is a noop as no socket is assigned.\n // - Otherwise, the error is re-emitted by the listener of the `'error'`\n // event of the `Receiver` object. The listener already closes the\n // connection by calling `ws.close()`. This allows a close frame to be\n // sent to the other peer. If `ws.terminate()` is called right after this,\n // then the close frame might not be sent.\n terminateOnDestroy = false;\n duplex.destroy(err);\n });\n\n ws.once('close', function close() {\n if (duplex.destroyed) return;\n\n duplex.push(null);\n });\n\n duplex._destroy = function (err, callback) {\n if (ws.readyState === ws.CLOSED) {\n callback(err);\n process.nextTick(emitClose, duplex);\n return;\n }\n\n let called = false;\n\n ws.once('error', function error(err) {\n called = true;\n callback(err);\n });\n\n ws.once('close', function close() {\n if (!called) callback(err);\n process.nextTick(emitClose, duplex);\n });\n\n if (terminateOnDestroy) ws.terminate();\n };\n\n duplex._final = function (callback) {\n if (ws.readyState === ws.CONNECTING) {\n ws.once('open', function open() {\n duplex._final(callback);\n });\n return;\n }\n\n // If the value of the `_socket` property is `null` it means that `ws` is a\n // client websocket and the handshake failed. In fact, when this happens, a\n // socket is never assigned to the websocket. Wait for the `'error'` event\n // that will be emitted by the websocket.\n if (ws._socket === null) return;\n\n if (ws._socket._writableState.finished) {\n callback();\n if (duplex._readableState.endEmitted) duplex.destroy();\n } else {\n ws._socket.once('finish', function finish() {\n // `duplex` is not destroyed here because the `'end'` event will be\n // emitted on `duplex` after this `'finish'` event. The EOF signaling\n // `null` chunk is, in fact, pushed when the websocket emits `'close'`.\n callback();\n });\n ws.close();\n }\n };\n\n duplex._read = function () {\n if (ws.isPaused) ws.resume();\n };\n\n duplex._write = function (chunk, encoding, callback) {\n if (ws.readyState === ws.CONNECTING) {\n ws.once('open', function open() {\n duplex._write(chunk, encoding, callback);\n });\n return;\n }\n\n ws.send(chunk, callback);\n };\n\n duplex.on('end', duplexOnEnd);\n duplex.on('error', duplexOnError);\n return duplex;\n}\n\nmodule.exports = createWebSocketStream;\n","'use strict';\n\nconst { tokenChars } = require('./validation');\n\n/**\n * Parses the `Sec-WebSocket-Protocol` header into a set of subprotocol names.\n *\n * @param {String} header The field value of the header\n * @return {Set} The subprotocol names\n * @public\n */\nfunction parse(header) {\n const protocols = new Set();\n let start = -1;\n let end = -1;\n let i = 0;\n\n for (i; i < header.length; i++) {\n const code = header.charCodeAt(i);\n\n if (end === -1 && tokenChars[code] === 1) {\n if (start === -1) start = i;\n } else if (\n i !== 0 &&\n (code === 0x20 /* ' ' */ || code === 0x09) /* '\\t' */\n ) {\n if (end === -1 && start !== -1) end = i;\n } else if (code === 0x2c /* ',' */) {\n if (start === -1) {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n\n if (end === -1) end = i;\n\n const protocol = header.slice(start, end);\n\n if (protocols.has(protocol)) {\n throw new SyntaxError(`The \"${protocol}\" subprotocol is duplicated`);\n }\n\n protocols.add(protocol);\n start = end = -1;\n } else {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n }\n\n if (start === -1 || end !== -1) {\n throw new SyntaxError('Unexpected end of input');\n }\n\n const protocol = header.slice(start, i);\n\n if (protocols.has(protocol)) {\n throw new SyntaxError(`The \"${protocol}\" subprotocol is duplicated`);\n }\n\n protocols.add(protocol);\n return protocols;\n}\n\nmodule.exports = { parse };\n","/* eslint no-unused-vars: [\"error\", { \"varsIgnorePattern\": \"^net|tls|https$\" }] */\n\n'use strict';\n\nconst EventEmitter = require('events');\nconst http = require('http');\nconst https = require('https');\nconst net = require('net');\nconst tls = require('tls');\nconst { createHash } = require('crypto');\n\nconst extension = require('./extension');\nconst PerMessageDeflate = require('./permessage-deflate');\nconst subprotocol = require('./subprotocol');\nconst WebSocket = require('./websocket');\nconst { GUID, kWebSocket } = require('./constants');\n\nconst keyRegex = /^[+/0-9A-Za-z]{22}==$/;\n\nconst RUNNING = 0;\nconst CLOSING = 1;\nconst CLOSED = 2;\n\n/**\n * Class representing a WebSocket server.\n *\n * @extends EventEmitter\n */\nclass WebSocketServer extends EventEmitter {\n /**\n * Create a `WebSocketServer` instance.\n *\n * @param {Object} options Configuration options\n * @param {Number} [options.backlog=511] The maximum length of the queue of\n * pending connections\n * @param {Boolean} [options.clientTracking=true] Specifies whether or not to\n * track clients\n * @param {Function} [options.handleProtocols] A hook to handle protocols\n * @param {String} [options.host] The hostname where to bind the server\n * @param {Number} [options.maxPayload=104857600] The maximum allowed message\n * size\n * @param {Boolean} [options.noServer=false] Enable no server mode\n * @param {String} [options.path] Accept only connections matching this path\n * @param {(Boolean|Object)} [options.perMessageDeflate=false] Enable/disable\n * permessage-deflate\n * @param {Number} [options.port] The port where to bind the server\n * @param {(http.Server|https.Server)} [options.server] A pre-created HTTP/S\n * server to use\n * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or\n * not to skip UTF-8 validation for text and close messages\n * @param {Function} [options.verifyClient] A hook to reject connections\n * @param {Function} [options.WebSocket=WebSocket] Specifies the `WebSocket`\n * class to use. It must be the `WebSocket` class or class that extends it\n * @param {Function} [callback] A listener for the `listening` event\n */\n constructor(options, callback) {\n super();\n\n options = {\n maxPayload: 100 * 1024 * 1024,\n skipUTF8Validation: false,\n perMessageDeflate: false,\n handleProtocols: null,\n clientTracking: true,\n verifyClient: null,\n noServer: false,\n backlog: null, // use default (511 as implemented in net.js)\n server: null,\n host: null,\n path: null,\n port: null,\n WebSocket,\n ...options\n };\n\n if (\n (options.port == null && !options.server && !options.noServer) ||\n (options.port != null && (options.server || options.noServer)) ||\n (options.server && options.noServer)\n ) {\n throw new TypeError(\n 'One and only one of the \"port\", \"server\", or \"noServer\" options ' +\n 'must be specified'\n );\n }\n\n if (options.port != null) {\n this._server = http.createServer((req, res) => {\n const body = http.STATUS_CODES[426];\n\n res.writeHead(426, {\n 'Content-Length': body.length,\n 'Content-Type': 'text/plain'\n });\n res.end(body);\n });\n this._server.listen(\n options.port,\n options.host,\n options.backlog,\n callback\n );\n } else if (options.server) {\n this._server = options.server;\n }\n\n if (this._server) {\n const emitConnection = this.emit.bind(this, 'connection');\n\n this._removeListeners = addListeners(this._server, {\n listening: this.emit.bind(this, 'listening'),\n error: this.emit.bind(this, 'error'),\n upgrade: (req, socket, head) => {\n this.handleUpgrade(req, socket, head, emitConnection);\n }\n });\n }\n\n if (options.perMessageDeflate === true) options.perMessageDeflate = {};\n if (options.clientTracking) {\n this.clients = new Set();\n this._shouldEmitClose = false;\n }\n\n this.options = options;\n this._state = RUNNING;\n }\n\n /**\n * Returns the bound address, the address family name, and port of the server\n * as reported by the operating system if listening on an IP socket.\n * If the server is listening on a pipe or UNIX domain socket, the name is\n * returned as a string.\n *\n * @return {(Object|String|null)} The address of the server\n * @public\n */\n address() {\n if (this.options.noServer) {\n throw new Error('The server is operating in \"noServer\" mode');\n }\n\n if (!this._server) return null;\n return this._server.address();\n }\n\n /**\n * Stop the server from accepting new connections and emit the `'close'` event\n * when all existing connections are closed.\n *\n * @param {Function} [cb] A one-time listener for the `'close'` event\n * @public\n */\n close(cb) {\n if (this._state === CLOSED) {\n if (cb) {\n this.once('close', () => {\n cb(new Error('The server is not running'));\n });\n }\n\n process.nextTick(emitClose, this);\n return;\n }\n\n if (cb) this.once('close', cb);\n\n if (this._state === CLOSING) return;\n this._state = CLOSING;\n\n if (this.options.noServer || this.options.server) {\n if (this._server) {\n this._removeListeners();\n this._removeListeners = this._server = null;\n }\n\n if (this.clients) {\n if (!this.clients.size) {\n process.nextTick(emitClose, this);\n } else {\n this._shouldEmitClose = true;\n }\n } else {\n process.nextTick(emitClose, this);\n }\n } else {\n const server = this._server;\n\n this._removeListeners();\n this._removeListeners = this._server = null;\n\n //\n // The HTTP/S server was created internally. Close it, and rely on its\n // `'close'` event.\n //\n server.close(() => {\n emitClose(this);\n });\n }\n }\n\n /**\n * See if a given request should be handled by this server instance.\n *\n * @param {http.IncomingMessage} req Request object to inspect\n * @return {Boolean} `true` if the request is valid, else `false`\n * @public\n */\n shouldHandle(req) {\n if (this.options.path) {\n const index = req.url.indexOf('?');\n const pathname = index !== -1 ? req.url.slice(0, index) : req.url;\n\n if (pathname !== this.options.path) return false;\n }\n\n return true;\n }\n\n /**\n * Handle a HTTP Upgrade request.\n *\n * @param {http.IncomingMessage} req The request object\n * @param {(net.Socket|tls.Socket)} socket The network socket between the\n * server and client\n * @param {Buffer} head The first packet of the upgraded stream\n * @param {Function} cb Callback\n * @public\n */\n handleUpgrade(req, socket, head, cb) {\n socket.on('error', socketOnError);\n\n const key =\n req.headers['sec-websocket-key'] !== undefined\n ? req.headers['sec-websocket-key']\n : false;\n const version = +req.headers['sec-websocket-version'];\n\n if (\n req.method !== 'GET' ||\n req.headers.upgrade.toLowerCase() !== 'websocket' ||\n !key ||\n !keyRegex.test(key) ||\n (version !== 8 && version !== 13) ||\n !this.shouldHandle(req)\n ) {\n return abortHandshake(socket, 400);\n }\n\n const secWebSocketProtocol = req.headers['sec-websocket-protocol'];\n let protocols = new Set();\n\n if (secWebSocketProtocol !== undefined) {\n try {\n protocols = subprotocol.parse(secWebSocketProtocol);\n } catch (err) {\n return abortHandshake(socket, 400);\n }\n }\n\n const secWebSocketExtensions = req.headers['sec-websocket-extensions'];\n const extensions = {};\n\n if (\n this.options.perMessageDeflate &&\n secWebSocketExtensions !== undefined\n ) {\n const perMessageDeflate = new PerMessageDeflate(\n this.options.perMessageDeflate,\n true,\n this.options.maxPayload\n );\n\n try {\n const offers = extension.parse(secWebSocketExtensions);\n\n if (offers[PerMessageDeflate.extensionName]) {\n perMessageDeflate.accept(offers[PerMessageDeflate.extensionName]);\n extensions[PerMessageDeflate.extensionName] = perMessageDeflate;\n }\n } catch (err) {\n return abortHandshake(socket, 400);\n }\n }\n\n //\n // Optionally call external client verification handler.\n //\n if (this.options.verifyClient) {\n const info = {\n origin:\n req.headers[`${version === 8 ? 'sec-websocket-origin' : 'origin'}`],\n secure: !!(req.socket.authorized || req.socket.encrypted),\n req\n };\n\n if (this.options.verifyClient.length === 2) {\n this.options.verifyClient(info, (verified, code, message, headers) => {\n if (!verified) {\n return abortHandshake(socket, code || 401, message, headers);\n }\n\n this.completeUpgrade(\n extensions,\n key,\n protocols,\n req,\n socket,\n head,\n cb\n );\n });\n return;\n }\n\n if (!this.options.verifyClient(info)) return abortHandshake(socket, 401);\n }\n\n this.completeUpgrade(extensions, key, protocols, req, socket, head, cb);\n }\n\n /**\n * Upgrade the connection to WebSocket.\n *\n * @param {Object} extensions The accepted extensions\n * @param {String} key The value of the `Sec-WebSocket-Key` header\n * @param {Set} protocols The subprotocols\n * @param {http.IncomingMessage} req The request object\n * @param {(net.Socket|tls.Socket)} socket The network socket between the\n * server and client\n * @param {Buffer} head The first packet of the upgraded stream\n * @param {Function} cb Callback\n * @throws {Error} If called more than once with the same socket\n * @private\n */\n completeUpgrade(extensions, key, protocols, req, socket, head, cb) {\n //\n // Destroy the socket if the client has already sent a FIN packet.\n //\n if (!socket.readable || !socket.writable) return socket.destroy();\n\n if (socket[kWebSocket]) {\n throw new Error(\n 'server.handleUpgrade() was called more than once with the same ' +\n 'socket, possibly due to a misconfiguration'\n );\n }\n\n if (this._state > RUNNING) return abortHandshake(socket, 503);\n\n const digest = createHash('sha1')\n .update(key + GUID)\n .digest('base64');\n\n const headers = [\n 'HTTP/1.1 101 Switching Protocols',\n 'Upgrade: websocket',\n 'Connection: Upgrade',\n `Sec-WebSocket-Accept: ${digest}`\n ];\n\n const ws = new this.options.WebSocket(null);\n\n if (protocols.size) {\n //\n // Optionally call external protocol selection handler.\n //\n const protocol = this.options.handleProtocols\n ? this.options.handleProtocols(protocols, req)\n : protocols.values().next().value;\n\n if (protocol) {\n headers.push(`Sec-WebSocket-Protocol: ${protocol}`);\n ws._protocol = protocol;\n }\n }\n\n if (extensions[PerMessageDeflate.extensionName]) {\n const params = extensions[PerMessageDeflate.extensionName].params;\n const value = extension.format({\n [PerMessageDeflate.extensionName]: [params]\n });\n headers.push(`Sec-WebSocket-Extensions: ${value}`);\n ws._extensions = extensions;\n }\n\n //\n // Allow external modification/inspection of handshake headers.\n //\n this.emit('headers', headers, req);\n\n socket.write(headers.concat('\\r\\n').join('\\r\\n'));\n socket.removeListener('error', socketOnError);\n\n ws.setSocket(socket, head, {\n maxPayload: this.options.maxPayload,\n skipUTF8Validation: this.options.skipUTF8Validation\n });\n\n if (this.clients) {\n this.clients.add(ws);\n ws.on('close', () => {\n this.clients.delete(ws);\n\n if (this._shouldEmitClose && !this.clients.size) {\n process.nextTick(emitClose, this);\n }\n });\n }\n\n cb(ws, req);\n }\n}\n\nmodule.exports = WebSocketServer;\n\n/**\n * Add event listeners on an `EventEmitter` using a map of <event, listener>\n * pairs.\n *\n * @param {EventEmitter} server The event emitter\n * @param {Object.<String, Function>} map The listeners to add\n * @return {Function} A function that will remove the added listeners when\n * called\n * @private\n */\nfunction addListeners(server, map) {\n for (const event of Object.keys(map)) server.on(event, map[event]);\n\n return function removeListeners() {\n for (const event of Object.keys(map)) {\n server.removeListener(event, map[event]);\n }\n };\n}\n\n/**\n * Emit a `'close'` event on an `EventEmitter`.\n *\n * @param {EventEmitter} server The event emitter\n * @private\n */\nfunction emitClose(server) {\n server._state = CLOSED;\n server.emit('close');\n}\n\n/**\n * Handle premature socket errors.\n *\n * @private\n */\nfunction socketOnError() {\n this.destroy();\n}\n\n/**\n * Close the connection when preconditions are not fulfilled.\n *\n * @param {(net.Socket|tls.Socket)} socket The socket of the upgrade request\n * @param {Number} code The HTTP response status code\n * @param {String} [message] The HTTP response body\n * @param {Object} [headers] Additional HTTP response headers\n * @private\n */\nfunction abortHandshake(socket, code, message, headers) {\n if (socket.writable) {\n message = message || http.STATUS_CODES[code];\n headers = {\n Connection: 'close',\n 'Content-Type': 'text/html',\n 'Content-Length': Buffer.byteLength(message),\n ...headers\n };\n\n socket.write(\n `HTTP/1.1 ${code} ${http.STATUS_CODES[code]}\\r\\n` +\n Object.keys(headers)\n .map((h) => `${h}: ${headers[h]}`)\n .join('\\r\\n') +\n '\\r\\n\\r\\n' +\n message\n );\n }\n\n socket.removeListener('error', socketOnError);\n socket.destroy();\n}\n","'use strict';\n\nconst WebSocket = require('./lib/websocket');\n\nWebSocket.createWebSocketStream = require('./lib/stream');\nWebSocket.Server = require('./lib/websocket-server');\nWebSocket.Receiver = require('./lib/receiver');\nWebSocket.Sender = require('./lib/sender');\n\nWebSocket.WebSocket = WebSocket;\nWebSocket.WebSocketServer = WebSocket.Server;\n\nmodule.exports = WebSocket;\n","/*!\n * name: main.js\n * desc: 为了将rtsp2web发布为一个 npm 包。\n * 由于resource.js中require了一些第三方node包,在使用rollup打包时,\n * 不符合模块打包的规范(import是符合模块打包规范的)\n * main.js就是将resource.js进行轻微的改动;以及精简(为了打包产物最小化)\n * 这样可以使用rollup进行打包处理,以及做一些压缩和babel的处理\n * 在npm项目中使用rtsp2web,使用方法可以参考example目录的示例\n * (c) begin with 2022 by NeverYu\n * Released under the ISC License.\n */\nconst child = require('child_process')\nimport http from 'http'\nimport https from 'https'\n// import { createServer } from 'https'\nimport fs from 'fs'\nimport pem from 'pem'\nconst events = require('events')\nconst url = require('url')\nimport { decode } from 'base-64'\nimport { Server } from 'ws'\nconst WebSocketServer = Server\n\n// 默认的ffmpeg路径(一般正常安装的ffmpeg,名称(路径)是:ffmpeg)\nconst FFmpegPath = 'ffmpeg'\n// 默认的端口\nconst defaultPort = 9999\n// 默认的视频视口框架大小\nlet videoSize = '1920x1080'\n// 视频场景比例缩放\nlet videoScale = '-1:-1'\n// 视频的码率(默认不传)\nlet videoBit = '2000k'\n// 视频的解码器\nlet vcodecValue = 'mpeg1video'\n// watermate 内容加密\nlet wmContent =\n 'JUU1JThFJUJCJUU5JTk5JUE0JUU2JUIwJUI0JUU1JThEJUIwUVElRUYlQkMlOUE0MjEzNTQ1MzI='\n// 默认的filter参数\nlet vfValue =\n 'drawtext=x=w-tw-100:y=100:fontcolor=white:fontsize=36:text=' +\n decodeURIComponent(decode(wmContent)) +\n ':box=1:boxcolor=black,scale=-1:-1,eq='\nlet noWMvfValue = 'scale=-1:-1,eq='\n\n/**\n * 配置vcodec时,可传入的参数形式包含:\n * vcodec, c:v, -c:v, codec:v\n */\nconst config_vcodec = ['vcodec', 'c:v', '-c:v', 'codec:v']\n\n/**\n * 支持的可配置参数\n */\nconst isConfigKey = [\n '-s',\n '-b:v',\n 'scale',\n 'contrast',\n 'brightness',\n 'saturation',\n 'gamma',\n ...config_vcodec\n]\n// -vf 的配置参数\nconst isVFConfigKey = ['scale', 'contrast', 'brightness', 'saturation', 'gamma']\n\n/**\n * 对应的参数校验规则\n */\nconst validValueRules = (key, value) => {\n switch (key) {\n case '-s':\n if (value.includes('x')) {\n if (\n value.split('x')[0] &&\n value.split('x')[0] > 0 &&\n value.split('x')[1] &&\n value.split('x')[1] > 0\n ) {\n return true\n }\n }\n break\n case 'vcodec':\n case 'c:v':\n case '-c:v':\n case 'codec:v':\n if (value) {\n return true\n }\n break\n case '-b:v':\n if (value.endsWith('k')) {\n return true\n }\n break\n case 'scale':\n if (value.includes(':')) {\n if (value.split(':')[0] && value.split(':')[1]) {\n return true\n }\n }\n break\n case 'contrast':\n if (value) {\n return true\n }\n break\n case 'brightness':\n if (value) {\n return true\n }\n break\n case 'saturation':\n if (value) {\n return true\n }\n break\n case 'gamma':\n if (value) {\n return true\n }\n break\n }\n}\n\n/**\n * configFreeTime:空闲时间;单位:秒(s)\n * 一个已启动的视频通道,如果在一段时间(configFreeTime)内没有被使用,则销毁该视频通道\n * 建议:值为10的倍数,取值范围60-120\n */\nlet configFreeTime = 60\n/**\n * intervalTime:定时器循环时间;单位:秒(s)\n * 用于计时,来定时检测当前是否有空闲的视频通道(执行的是RTSP2web类中的checkFree方法)\n * 建议:值为5的倍数,取值范围5-20\n */\nlet intervalTime = 10\n\n/**\n * 用于创建一个新的视频转码流类\n */\nclass Mpeg2Muxer extends events.EventEmitter {\n exitCode = undefined\n // 额外的 ffmpeg 参数\n additionalFlags = []\n stream = null\n inputStreamStarted = false\n constructor(options) {\n super()\n this.options = options\n this.ffmpegPath = options.ffmpegPath || FFmpegPath\n this.url = options.url\n this.ffmpegOptions = options.ffmpegOptions\n this.initMpeg2Muxer()\n }\n initMpeg2Muxer() {\n // ffmpeg参数解析\n if (this.ffmpegOptions) {\n for (let key in this.ffmpegOptions) {\n this.additionalFlags.push(key)\n if (String(this.ffmpegOptions[key]) !== '') {\n this.additionalFlags.push(String(this.ffmpegOptions[key]))\n }\n }\n }\n // 参数整合拼接\n this.spawnOptions = [\n '-rtsp_transport',\n 'tcp',\n '-thread_queue_size',\n '256',\n '-i',\n this.url,\n '-f',\n 'mpegts',\n // '-codec:a',\n // 'mp2',\n // '-vf',\n // 'scale=-1:-1,eq=brightness=0.2:saturation=2.8:',\n // additional ffmpeg options go here\n ...this.additionalFlags,\n '-nostats',\n // '-b:v',\n // '2000k',\n // '-b:a',\n // '128k',\n '-r',\n '29.97',\n '-'\n ]\n // 创建一个命令行子进程\n this.stream = child.spawn(this.ffmpegPath, this.spawnOptions, {\n detached: false\n })\n\n this.stream.on('error', (code, signal) => {\n console.error(\n '启动ffmpeg时出错,请确保你安装了ffmpeg,然后检查路径或者命令参数'\n )\n })\n this.stream.on('close', (code, signal) => {\n console.log('ffmpeg关闭,code:', code)\n return this.emit('ffmpegClosed')\n })\n this.stream.on('exit', (code, signal) => {\n if (code === 1) {\n console.error(\n '***由于ffmpeg退出,ffmpeg启动不成功,请检查ffmpeg参数或相关情况或联系作者***'\n )\n this.exitCode = 1\n return this.emit('exitWithError')\n }\n })\n\n this.inputStreamStarted = true\n this.stream.stdout.on('data', (data) => {\n return this.emit('mpeg2data', data)\n })\n this.stream.stderr.on('data', (data) => {\n return this.emit('ffmpegStderr', data)\n })\n }\n}\n\n/**\n * 一个视频通道可能对应多个客户端(也就是多个ws句柄)\n * 为什么呢\n * 因为一个rtsp视频流可能有多个客户端(多台电脑)在同时播放的情况\n * 视频转码(依赖ffmpeg)是需要消耗运行电脑cpu的\n * 为了避免资源的浪费,同一个rtsp视频流只开启一个转码程序,也就是一个视频通道\n * 多个ws句柄可以共用一个视频通道\n */\nclass Channel {\n /**\n * freeTime: 用于记录该视频通道空闲的时间\n * 如果这个视频通道的空闲时间超过一个设定值\n * 我们就可以关闭这个视频通道了,停掉转码服务,释放电脑资源\n * @type {Number}\n */\n freeTime = 0\n /* 视频通道是否正在封装码流 */\n isStreamWrap = false\n clients = []\n mpeg2Muxer = {\n instance: null,\n stream: null,\n data: null\n }\n\n constructor(config) {\n // 前端传过来的参数\n this.config = config\n this.url = config.url\n }\n // 创建一个rtsp的视频转码\n createStream() {\n if (this.isStreamWrap) {\n return\n }\n console.log('创建一个新的ffmpeg子进程')\n this.isStreamWrap = true\n this.mpeg2Muxer.instance = new Mpeg2Muxer({\n ffmpegOptions: this.formatParams(this.config),\n url: this.url,\n ffmpegPath: 'ffmpeg'\n })\n this.mpeg2Muxer.stream = this.mpeg2Muxer.instance.stream\n /**\n * 监听到子进程发送过来的数据\n */\n this.mpeg2Muxer.instance.on('mpeg2data', (data) => {\n /**\n * 【广播数据】\n * rtsp视频流实时转帧之后,当前视频流通道实时进行广播\n * 将图像数据广播给它的所有client(也就是它的每个ws句柄)\n */\n this.broadcast(data)\n // this.mpeg2Muxer.data = data\n })\n\n /**\n * 监听到创建的子进程ffmpeg由于error退出了\n */\n this.mpeg2Muxer.instance.on('exitWithError', () => {\n // console.log('监听到有一个ffmpeg进程退出了!')\n })\n\n /**\n * 监听到创建的子进程ffmpeg关闭了\n * 该视频通道的子进程ffmpeg都关闭了,那么要注销掉该视频通道\n * 以及和该视频通道关联的ws句柄\n */\n this.mpeg2Muxer.instance.on('ffmpegClosed', () => {\n // console.log('监听到有一个ffmpeg进程关闭了!')\n this.destroy()\n })\n }\n formatParams(params) {\n // 是否有视频过滤的参数配置(包括eq,scale)\n let result = {\n '-codec:v': vcodecValue,\n '-vf': vfValue\n }\n for (let [key, value] of Object.entries(params)) {\n if (key === 'wm' && value === '0') {\n result['-vf'] = noWMvfValue\n }\n // 是支持的可配置的参数\n if (isConfigKey.includes(key)) {\n // 是配置vf相关的参数\n if (isVFConfigKey.includes(key)) {\n // todo: 加validValueRules验证\n if (key === 'scale') {\n result['-vf'] = result['-vf'].replace(\n /scale=[x0-9\\:\\-]*/g,\n `scale=${value}`\n )\n } else {\n result['-vf'] += `${key}=${value}:`\n }\n } else if (config_vcodec.includes(key)) {\n // 修改指定的视频解码器\n result['-codec:v'] = value\n } else {\n // 值校验\n if (validValueRules(key, value)) {\n result[key] = value\n }\n }\n }\n }\n return result\n }\n destroy() {\n this.mpeg2Muxer.stream?.kill()\n this.mpeg2Muxer.stream = null\n this.mpeg2Muxer.instance?.removeAllListeners()\n this.mpeg2Muxer.instance = null\n this.isStreamWrap = false\n this.dropAllClient()\n }\n broadcast(data) {\n for (let client of this.clients) {\n if (client.isSegment) {\n client.send(data)\n }\n }\n }\n // client就是每个ws连接成功后的句柄\n addClient(client) {\n /**\n * 当用户关闭客户端页面时,或者当客户端页面关闭视频播放窗口时\n */\n client.once('close', () => {\n this.dropClient(client)\n })\n this.clients.push(client)\n if (!this.isStreamWrap) {\n this.createStream()\n }\n // isSegment是一个标志位,标识这个ws句柄正在使用中\n client.isSegment = true\n }\n /**\n * 销毁一个ws句柄\n * @param {ws} client\n */\n dropClient(client) {\n let index = this.clients.indexOf(client)\n client.isSegment = false\n // 强制关闭连接;客户端、服务端实例都可调用\n client.terminate()\n client = null\n console.log('视频关闭,销毁一个client(ws句柄)')\n if (index > -1) {\n this.clients.splice(index, 1)\n }\n }\n dropAllClient() {\n for (let client of this.clients) {\n client.isSegment = false\n // 强制关闭连接;客户端、服务端实例都可调用\n client.terminate()\n }\n this.clients = []\n }\n}\n\nimport { version } from './package.json'\n\n/**\n * 入口类\n */\nclass RTSP2web {\n static version = version\n // 视频实例列表(以rtsp_url作为唯一区分)\n channels = []\n /**\n * 实例化一个流媒体服务器对象\n * @param http HTTP服务\n */\n constructor(config) {\n /**\n * 创建RTSP2web时,配置全局参数\n */\n if (config && typeof config.wm === 'boolean' && !config.wm) {\n vfValue = noWMvfValue\n }\n\n /**\n * 创建rtsp2web实例时,配置视频解码器\n */\n if (\n config &&\n typeof config.vcodec === 'string' &&\n config.vcodec.length > 0\n ) {\n vcodecValue = config.vcodec\n }\n\n /**\n * RTSP2web是入口类,在入口类中起一个定时器,对所有的视频通道进行空闲检测\n */\n setInterval(() => this.checkFree(), intervalTime * 1000)\n\n let httpServer = http.createServer()\n /**\n * wss协议\n */\n if (config && typeof config.wss === 'object') {\n console.log('wss启动中....')\n if (config.wss.hasOwnProperty('pfx')) {\n if (!config.wss.hasOwnProperty('passphrase')) {\n console.error(\n '【wss启动失败;请传入正确的pfx文件指定密码:passphrase】'\n )\n } else {\n try {\n const options = {\n pfx: fs.readFileSync(config.wss.pfx),\n passphrase: config.wss.passphrase\n }\n pem.readPkcs12(\n options.pfx,\n { p12Password: options.passphrase },\n (err, resp) => {\n httpServer = https.createServer({\n cert: resp.cert,\n key: resp.key\n })\n }\n )\n } catch (err) {\n console.error(\n '--【读取pfx安全证书文件出错,wss启动失败,退回到ws;错误信息如下,有问题请联系我】--'\n )\n console.log(err)\n }\n }\n } else {\n if (!config.wss.hasOwnProperty('cert')) {\n console.error('【wss启动失败;请传入正确的安全证书公钥:cert】')\n } else if (!config.wss.hasOwnProperty('key')) {\n console.error('【wss启动失败;请传入正确的安全证书私钥:key】')\n } else {\n try {\n httpServer = https.createServer({\n // certPath\n cert: fs.readFileSync(config.wss.cert),\n // keyPath\n key: fs.readFileSync(config.wss.key)\n })\n } catch (err) {\n console.error(\n '--【读取cert安全证书文件出错,wss启动失败,退回到ws;错误信息如下,有问题请联系我】--'\n )\n console.log(err)\n }\n }\n }\n }\n\n // 创建websocket服务\n this.wss = new WebSocketServer({\n server: httpServer\n })\n\n /**\n * Event: 'connection'成功握手连接时触发\n * [socket] {WebSocket} socket连接句柄(解释:每一个成功连接到这个websocket服务器的链接就是一个句柄,句柄之间是独立的)\n * [request] {http.IncomingMessage}\n */\n this.wss.on('connection', (ws, request) => {\n // 通过 ws 对象,就可以获取到客户端发送过来的信息和主动推送信息给客户端\n // 1、解析url\n const params = url.parse(request.url, true)\n // console.log(params.query.url)\n\n // 2、每一个新的长连接连接成功以后,给它注册一下(其实就是记录一下)\n if (params.query.url) {\n // 因为我定义的是,前端的rtsp_url用btoa处理后以参数的形式传入,所有这里需要解析一下\n const url = decode(params.query.url.toString())\n params.query.url = url\n // console.log(url)\n this.registeClient(ws, {\n url,\n options: params.query\n })\n }\n console.log('一个新的client(ws句柄)连接成功')\n })\n\n httpServer.listen(config ? config.port || defaultPort : defaultPort)\n }\n\n registeClient(ws, data) {\n let channel = this.getChannel(data.url)\n if (!channel) {\n channel = this.createChannel(data.options, ws)\n }\n channel.addClient(ws)\n }\n\n getChannel(url) {\n for (let channel of this.channels) {\n if (channel.url === url) {\n return channel\n }\n }\n return null\n }\n\n /**\n * 创建一个视频通道\n * @Author Author\n * @DateTime 2022-05-06T14:40:28+0800\n * @param {[type]} data [description]\n * @param {[type]} ws [description]\n * @return {[type]} [description]\n */\n createChannel(data, ws) {\n // 一个channel就是一个视频通道\n const channel = new Channel(data, ws)\n this.channels.push(channel)\n return channel\n }\n\n /**\n * 空闲检测,视频通道空间超过1分钟,则移除对应的视频通道\n * @Author Author\n * @DateTime 2022-02-15T14:25:47+0800\n * @return {[type]} [description]\n */\n checkFree() {\n for (let channel of this.channels) {\n if (channel.clients.length > 0) {\n channel.freeTime = 0\n } else {\n channel.freeTime += intervalTime\n }\n if (channel.freeTime >= configFreeTime) {\n this.destroyedChannel(channel)\n }\n }\n }\n\n /**\n * 销毁/停掉一个视频通道\n * @Author Author\n * @DateTime 2022-02-15T14:29:35+0800\n * @param {[type]} channel [description]\n * @return {[type]} [description]\n */\n destroyedChannel(channel) {\n let index = this.channels.indexOf(channel)\n if (index > -1) {\n this.channels.splice(index, 1)\n channel.destroy()\n }\n }\n}\n\nmodule.exports = RTSP2web\n"],"names":["Object","defineProperty","promisify_1","value","promisify","original","TypeError","argumentNames","ES6Promise","Promise","Error","_this","this","_len","arguments","length","args","Array","_key","resolve","reject","push","err","_len2","values","_key2","o","forEach","index","name","apply","undefined","isWindows","process","platform","trailingSlashRe","osTmpdir","path","env","TEMP","TMP","SystemRoot","windir","TMPDIR","test","slice","pathlib","require$$0","fs","require$$1","crypto","require$$2","require$$3","tempDir","PEMJS_TMPDIR","module","exports","isNumber","str","isArray","isHex","hex","toHex","i","charCodeAt","toString","ciphers","createPasswordFile","options","params","PasswordFileArray","prototype","hasOwnProperty","call","passType","PasswordFile","join","randomBytes","password","trim","mustPass","cipher","indexOf","writeFileSync","deleteTempFiles","files","callback","rmFiles","deleteSeries","list","finalCallback","file","shift","unlink","code","windows","isexe","sync","checkStat","statSync","stat","isSymbolicLink","isFile","pathext","pathExt","PATHEXT","split","p","toLowerCase","substr","checkPathExt","cb","er","mode","core","mod","uid","gid","myUid","getuid","myGid","getgid","u","parseInt","g","ug","checkMode","global","TESTING_WINDOWS","isexe_1","is","ignoreErrors","OSTYPE","COLON","getNotFoundError","cmd","assign","getPathInfo","opt","colon","pathEnv","match","cwd","PATH","pathExtExe","unshift","which","found","step","all","ppRaw","pathPart","pCmd","subStep","ii","ext","then","res","which_1","j","cur","ex","nothrow","helper","cpspawn","spawn","require$$4","require$$5","require$$6","settings","set","option","get","binary","pathBin","OPENSSL_BIN","error","testOpenSSLPath","openssl","stderr","stdout","Buffer","alloc","on","data","concat","needed","finished","done","ret","from","spawnWrapper","tmpfiles","fpath","delTempPWFiles","contents","fsErr","tmp","String","toUpperCase","exec","searchStr","start","end","RegExp","substring","execBinary","convert","PEM2DER","pathIN","pathOUT","type","DER2PEM","PEM2P7B","pathBundleIN","cert","ca","P7B2PEM","PEM2PFX","key","PFX2PEM","P7B2PFX","tmpfile","replace","net","pem","createPrivateKey","createDhparam","createEcparam","createCSR","createCertificate","readCertificateInfo","getPublicKey","getFingerprint","getModulus","getDhparamInfo","createPkcs12","readPkcs12","verifySigningChain","checkCertificate","checkPkcs12","config","keys","k","keyBitsize","Number","sslErr","dhparam","keyName","paramEnc","noOut","searchString","ecparam","commonName","isIPv4","isIPv6","altNames","clientKey","hash","csrConfigFile","csrData","C","country","ST","state","L","locality","O","organization","OU","organizationUnit","CN","DC","dc","emailAddress","map","tmpStr","generateCSRSubject","altNamesRep","isIP","clientKeyPassword","csr","keyData","serviceKey","selfSigned","error2","data2","days","serviceCertificate","serial","startsWith","serialFile","serviceKeyPassword","extFile","san","dns","i2","ip","i3","email","response","certificate","publicKey","certData","subject","issuer","ky","certValues","validity","matchAll","sort","t","n","e","r","pregMatchAll","Date","parse","signatureAlgorithm","publicKeySize","publicKeyAlgorithm","fetchCertificateData","isBuffer","modulus","require","dh","result","size","prime","line","fingerprint","certFiles","pkcs12","bufferOrPath","p12Password","keybundle","message","certs","readFromString","pop","passphrase","regexp","matches","arr","extras","splice","input","regex","haystack","nonGlobalRegex","nonGlobalMatch","globalRegex","globalMatch","matchArray","string","output","offset","endOffset","promisified","root","freeExports","freeModule","freeGlobal","window","InvalidCharacterError","TABLE","REGEX_SPACE_CHARACTERS","base64","encode","a","b","c","buffer","padding","position","charAt","decode","bitStorage","bitCounter","fromCharCode","version","nodeType","constants","BINARY_TYPES","EMPTY_BUFFER","GUID","kForOnEventAttribute","Symbol","kListener","kStatusCode","kWebSocket","NOOP","totalLength","target","allocUnsafe","buf","_mask","source","mask","_unmask","toArrayBuffer","byteLength","byteOffset","toBuffer","readOnly","ArrayBuffer","isView","bufferUtil","bufferUtilModule","unmask","kDone","kRun","limiter","constructor","concurrency","pending","Infinity","jobs","add","job","zlib","Limiter","TRAILER","kPerMessageDeflate","kTotalLength","kCallback","kBuffers","kError","zlibLimiter","permessageDeflate","isServer","maxPayload","_maxPayload","_options","_threshold","threshold","_isServer","_deflate","_inflate","concurrencyLimit","extensionName","offer","serverNoContextTakeover","server_no_context_takeover","clientNoContextTakeover","client_no_context_takeover","serverMaxWindowBits","server_max_window_bits","clientMaxWindowBits","client_max_window_bits","accept","configurations","normalizeParams","acceptAsServer","acceptAsClient","cleanup","close","offers","opts","accepted","find","num","isInteger","decompress","fin","_decompress","compress","_compress","endpoint","windowBits","Z_DEFAULT_WINDOWBITS","createInflateRaw","zlibInflateOptions","inflateOnError","inflateOnData","write","flush","_readableState","endEmitted","reset","createDeflateRaw","zlibDeflateOptions","deflateOnData","Z_SYNC_FLUSH","chunk","RangeError","removeListener","tokenChars","isValidStatusCode","_isValidUTF8","len","isValidUTF8","validationModule","Writable","PerMessageDeflate","receiver","super","_binaryType","binaryType","_extensions","extensions","_skipUTF8Validation","skipUTF8Validation","_bufferedBytes","_buffers","_compressed","_payloadLength","_fragmented","_masked","_fin","_opcode","_totalPayloadLength","_messageLength","_fragments","_state","_loop","_write","encoding","startLoop","consume","dst","Uint8Array","getInfo","getPayloadLength16","getPayloadLength64","getMask","getData","compressed","haveLength","readUInt16BE","readUInt32BE","Math","pow","controlMessage","dataMessage","messageLength","fragments","emit","ErrorCtor","prefix","statusCode","errorCode","captureStackTrace","randomFillSync","applyMask","kByteLength","maskBuffer","Sender","socket","generateMask","_generateMask","_maskBuffer","_socket","_firstFragment","_deflating","_queue","static","dataLength","merge","skipMasking","payloadLength","opcode","rsv1","writeUInt16BE","writeUIntBE","enqueue","dispatch","sendFrame","frame","ping","pong","send","perMessageDeflate","_","destroyed","dequeue","Reflect","cork","uncork","sender","kCode","kData","kMessage","kReason","kTarget","kType","kWasClean","Event","enumerable","CloseEvent","reason","wasClean","ErrorEvent","MessageEvent","EventTarget","addEventListener","listener","wrapper","isBinary","event","_closeFrameReceived","_closeFrameSent","once","removeEventListener","handler","listeners","eventTarget","dest","elem","extension","format","v","header","create","paramName","mustUnescape","isEscaping","inQuotes","SyntaxError","token","EventEmitter","https","http","tls","createHash","URL","require$$7","require$$8","Receiver","require$$9","require$$10","require$$11","require$$12","require$$13","require$$14","readyStates","subprotocolRegex","protocolVersions","WebSocket","address","protocols","_closeCode","_closeMessage","_closeTimer","_paused","_protocol","_readyState","CONNECTING","_receiver","_sender","_bufferedAmount","_redirects","initAsClient","includes","bufferedAmount","_writableState","isPaused","onclose","onerror","onopen","onmessage","protocol","readyState","url","_url","setSocket","head","receiverOnConclude","receiverOnDrain","receiverOnError","receiverOnMessage","receiverOnPing","receiverOnPong","setTimeout","setNoDelay","socketOnClose","socketOnData","socketOnEnd","socketOnError","OPEN","emitClose","CLOSED","removeAllListeners","msg","abortHandshake","_req","CLOSING","errorEmitted","destroy","bind","pause","sendAfterClose","resume","needDrain","terminate","property","method","websocket","protocolVersion","followRedirects","maxRedirects","createConnection","socketPath","hostname","timeout","host","port","parsedUrl","href","isSecure","isUnixSocket","invalidURLMessage","pathname","emitErrorAndClose","defaultPort","protocolSet","Set","tlsConnect","netConnect","headers","Connection","Upgrade","search","handshakeTimeout","has","origin","Origin","username","auth","parts","_originalHost","entries","authorization","cookie","req","aborted","location","addr","abort","digest","update","serverProt","protError","secWebSocketExtensions","extensionNames","connect","servername","stream","setHeader","nextTick","receiverOnFinish","read","clearTimeout","Duplex","duplexOnEnd","duplexOnError","listenerCount","ws","terminateOnDestroy","duplex","autoDestroy","objectMode","writableObjectMode","_destroy","called","_final","_read","subprotocol","keyRegex","websocketServer","handleProtocols","clientTracking","verifyClient","noServer","backlog","server","_server","createServer","body","STATUS_CODES","writeHead","listen","emitConnection","_removeListeners","addListeners","listening","upgrade","handleUpgrade","clients","_shouldEmitClose","shouldHandle","secWebSocketProtocol","info","secure","authorized","encrypted","verified","completeUpgrade","readable","writable","next","delete","h","createWebSocketStream","Server","WebSocketServer","child","events","vcodecValue","vfValue","decodeURIComponent","config_vcodec","isConfigKey","isVFConfigKey","validValueRules","endsWith","Mpeg2Muxer","_classCallCheck","_defineProperty","_assertThisInitialized","_super","ffmpegPath","ffmpegOptions","initMpeg2Muxer","_this2","additionalFlags","spawnOptions","detached","signal","console","log","exitCode","inputStreamStarted","Channel","instance","_this3","isStreamWrap","mpeg2Muxer","formatParams","broadcast","_i","_Object$entries","_Object$entries$_i","_slicedToArray","_this$mpeg2Muxer$stre","_this$mpeg2Muxer$inst","kill","dropAllClient","_step","_iterator","_createForOfIteratorHelper","s","client","isSegment","f","_this4","dropClient","createStream","_step2","_iterator2","RTSP2web","_this5","wm","vcodec","setInterval","checkFree","intervalTime","httpServer","_typeof","wss","pfx","readFileSync","resp","request","query","registeClient","channel","getChannel","createChannel","addClient","_step3","_iterator3","channels","_step4","_iterator4","freeTime","destroyedChannel"],"mappings":"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"}