UNPKG

pusher-js

Version:

Pusher Channels JavaScript library for browsers, React Native, NodeJS and web workers

1,747 lines (1,433 loc) 320 kB
/*! * Pusher JavaScript Library v7.0.5 * https://pusher.com/ * * Copyright 2020, Pusher * Released under the MIT licence. */ module.exports = /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); /******/ } /******/ }; /******/ /******/ // define __esModule on exports /******/ __webpack_require__.r = function(exports) { /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); /******/ } /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ }; /******/ /******/ // create a fake namespace object /******/ // mode & 1: value is a module id, require it /******/ // mode & 2: merge all properties of value into the ns /******/ // mode & 4: return value when already ns object /******/ // mode & 8|1: behave like require /******/ __webpack_require__.t = function(value, mode) { /******/ if(mode & 1) value = __webpack_require__(value); /******/ if(mode & 8) return value; /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; /******/ var ns = Object.create(null); /******/ __webpack_require__.r(ns); /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); /******/ return ns; /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = 21); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (function(module, exports) { module.exports = require("util"); /***/ }), /* 1 */ /***/ (function(module, exports, __webpack_require__) { /* eslint-disable node/no-deprecated-api */ var buffer = __webpack_require__(22) var Buffer = buffer.Buffer // alternative to using Object.keys for old browsers function copyProps (src, dst) { for (var key in src) { dst[key] = src[key] } } if (Buffer.from && Buffer.alloc && Buffer.allocUnsafe && Buffer.allocUnsafeSlow) { module.exports = buffer } else { // Copy properties from require('buffer') copyProps(buffer, exports) exports.Buffer = SafeBuffer } function SafeBuffer (arg, encodingOrOffset, length) { return Buffer(arg, encodingOrOffset, length) } // Copy static methods from Buffer copyProps(Buffer, SafeBuffer) SafeBuffer.from = function (arg, encodingOrOffset, length) { if (typeof arg === 'number') { throw new TypeError('Argument must not be a number') } return Buffer(arg, encodingOrOffset, length) } SafeBuffer.alloc = function (size, fill, encoding) { if (typeof size !== 'number') { throw new TypeError('Argument must be a number') } var buf = Buffer(size) if (fill !== undefined) { if (typeof encoding === 'string') { buf.fill(fill, encoding) } else { buf.fill(fill) } } else { buf.fill(0) } return buf } SafeBuffer.allocUnsafe = function (size) { if (typeof size !== 'number') { throw new TypeError('Argument must be a number') } return Buffer(size) } SafeBuffer.allocUnsafeSlow = function (size) { if (typeof size !== 'number') { throw new TypeError('Argument must be a number') } return buffer.SlowBuffer(size) } /***/ }), /* 2 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var Buffer = __webpack_require__(1).Buffer, Emitter = __webpack_require__(23).EventEmitter, util = __webpack_require__(0), streams = __webpack_require__(24), Headers = __webpack_require__(9), Reader = __webpack_require__(25); var Base = function(request, url, options) { Emitter.call(this); Base.validateOptions(options || {}, ['maxLength', 'masking', 'requireMasking', 'protocols']); this._request = request; this._reader = new Reader(); this._options = options || {}; this._maxLength = this._options.maxLength || this.MAX_LENGTH; this._headers = new Headers(); this.__queue = []; this.readyState = 0; this.url = url; this.io = new streams.IO(this); this.messages = new streams.Messages(this); this._bindEventListeners(); }; util.inherits(Base, Emitter); Base.isWebSocket = function(request) { var connection = request.headers.connection || '', upgrade = request.headers.upgrade || ''; return request.method === 'GET' && connection.toLowerCase().split(/ *, */).indexOf('upgrade') >= 0 && upgrade.toLowerCase() === 'websocket'; }; Base.validateOptions = function(options, validKeys) { for (var key in options) { if (validKeys.indexOf(key) < 0) throw new Error('Unrecognized option: ' + key); } }; var instance = { // This is 64MB, small enough for an average VPS to handle without // crashing from process out of memory MAX_LENGTH: 0x3ffffff, STATES: ['connecting', 'open', 'closing', 'closed'], _bindEventListeners: function() { var self = this; // Protocol errors are informational and do not have to be handled this.messages.on('error', function() {}); this.on('message', function(event) { var messages = self.messages; if (messages.readable) messages.emit('data', event.data); }); this.on('error', function(error) { var messages = self.messages; if (messages.readable) messages.emit('error', error); }); this.on('close', function() { var messages = self.messages; if (!messages.readable) return; messages.readable = messages.writable = false; messages.emit('end'); }); }, getState: function() { return this.STATES[this.readyState] || null; }, addExtension: function(extension) { return false; }, setHeader: function(name, value) { if (this.readyState > 0) return false; this._headers.set(name, value); return true; }, start: function() { if (this.readyState !== 0) return false; if (!Base.isWebSocket(this._request)) return this._failHandshake(new Error('Not a WebSocket request')); var response; try { response = this._handshakeResponse(); } catch (error) { return this._failHandshake(error); } this._write(response); if (this._stage !== -1) this._open(); return true; }, _failHandshake: function(error) { var headers = new Headers(); headers.set('Content-Type', 'text/plain'); headers.set('Content-Length', Buffer.byteLength(error.message, 'utf8')); headers = ['HTTP/1.1 400 Bad Request', headers.toString(), error.message]; this._write(Buffer.from(headers.join('\r\n'), 'utf8')); this._fail('protocol_error', error.message); return false; }, text: function(message) { return this.frame(message); }, binary: function(message) { return false; }, ping: function() { return false; }, pong: function() { return false; }, close: function(reason, code) { if (this.readyState !== 1) return false; this.readyState = 3; this.emit('close', new Base.CloseEvent(null, null)); return true; }, _open: function() { this.readyState = 1; this.__queue.forEach(function(args) { this.frame.apply(this, args) }, this); this.__queue = []; this.emit('open', new Base.OpenEvent()); }, _queue: function(message) { this.__queue.push(message); return true; }, _write: function(chunk) { var io = this.io; if (io.readable) io.emit('data', chunk); }, _fail: function(type, message) { this.readyState = 2; this.emit('error', new Error(message)); this.close(); } }; for (var key in instance) Base.prototype[key] = instance[key]; Base.ConnectEvent = function() {}; Base.OpenEvent = function() {}; Base.CloseEvent = function(code, reason) { this.code = code; this.reason = reason; }; Base.MessageEvent = function(data) { this.data = data; }; Base.PingEvent = function(data) { this.data = data; }; Base.PongEvent = function(data) { this.data = data; }; module.exports = Base; /***/ }), /* 3 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; // Protocol references: // // * http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-75 // * http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-76 // * http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-17 var Base = __webpack_require__(2), Client = __webpack_require__(26), Server = __webpack_require__(37); var Driver = { client: function(url, options) { options = options || {}; if (options.masking === undefined) options.masking = true; return new Client(url, options); }, server: function(options) { options = options || {}; if (options.requireMasking === undefined) options.requireMasking = true; return new Server(options); }, http: function() { return Server.http.apply(Server, arguments); }, isSecureRequest: function(request) { return Server.isSecureRequest(request); }, isWebSocket: function(request) { return Base.isWebSocket(request); }, validateOptions: function(options, validKeys) { Base.validateOptions(options, validKeys); } }; module.exports = Driver; /***/ }), /* 4 */ /***/ (function(module, exports) { module.exports = require("stream"); /***/ }), /* 5 */ /***/ (function(module, exports) { module.exports = require("crypto"); /***/ }), /* 6 */ /***/ (function(module, exports) { module.exports = require("url"); /***/ }), /* 7 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var Event = function(eventType, options) { this.type = eventType; for (var key in options) this[key] = options[key]; }; Event.prototype.initEvent = function(eventType, canBubble, cancelable) { this.type = eventType; this.bubbles = canBubble; this.cancelable = cancelable; }; Event.prototype.stopPropagation = function() {}; Event.prototype.preventDefault = function() {}; Event.CAPTURING_PHASE = 1; Event.AT_TARGET = 2; Event.BUBBLING_PHASE = 3; module.exports = Event; /***/ }), /* 8 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; // Copyright (C) 2016 Dmitry Chestnykh // MIT License. See LICENSE file for details. var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); Object.defineProperty(exports, "__esModule", { value: true }); /** * Package base64 implements Base64 encoding and decoding. */ // Invalid character used in decoding to indicate // that the character to decode is out of range of // alphabet and cannot be decoded. var INVALID_BYTE = 256; /** * Implements standard Base64 encoding. * * Operates in constant time. */ var Coder = /** @class */ (function () { // TODO(dchest): methods to encode chunk-by-chunk. function Coder(_paddingCharacter) { if (_paddingCharacter === void 0) { _paddingCharacter = "="; } this._paddingCharacter = _paddingCharacter; } Coder.prototype.encodedLength = function (length) { if (!this._paddingCharacter) { return (length * 8 + 5) / 6 | 0; } return (length + 2) / 3 * 4 | 0; }; Coder.prototype.encode = function (data) { var out = ""; var i = 0; for (; i < data.length - 2; i += 3) { var c = (data[i] << 16) | (data[i + 1] << 8) | (data[i + 2]); out += this._encodeByte((c >>> 3 * 6) & 63); out += this._encodeByte((c >>> 2 * 6) & 63); out += this._encodeByte((c >>> 1 * 6) & 63); out += this._encodeByte((c >>> 0 * 6) & 63); } var left = data.length - i; if (left > 0) { var c = (data[i] << 16) | (left === 2 ? data[i + 1] << 8 : 0); out += this._encodeByte((c >>> 3 * 6) & 63); out += this._encodeByte((c >>> 2 * 6) & 63); if (left === 2) { out += this._encodeByte((c >>> 1 * 6) & 63); } else { out += this._paddingCharacter || ""; } out += this._paddingCharacter || ""; } return out; }; Coder.prototype.maxDecodedLength = function (length) { if (!this._paddingCharacter) { return (length * 6 + 7) / 8 | 0; } return length / 4 * 3 | 0; }; Coder.prototype.decodedLength = function (s) { return this.maxDecodedLength(s.length - this._getPaddingLength(s)); }; Coder.prototype.decode = function (s) { if (s.length === 0) { return new Uint8Array(0); } var paddingLength = this._getPaddingLength(s); var length = s.length - paddingLength; var out = new Uint8Array(this.maxDecodedLength(length)); var op = 0; var i = 0; var haveBad = 0; var v0 = 0, v1 = 0, v2 = 0, v3 = 0; for (; i < length - 4; i += 4) { v0 = this._decodeChar(s.charCodeAt(i + 0)); v1 = this._decodeChar(s.charCodeAt(i + 1)); v2 = this._decodeChar(s.charCodeAt(i + 2)); v3 = this._decodeChar(s.charCodeAt(i + 3)); out[op++] = (v0 << 2) | (v1 >>> 4); out[op++] = (v1 << 4) | (v2 >>> 2); out[op++] = (v2 << 6) | v3; haveBad |= v0 & INVALID_BYTE; haveBad |= v1 & INVALID_BYTE; haveBad |= v2 & INVALID_BYTE; haveBad |= v3 & INVALID_BYTE; } if (i < length - 1) { v0 = this._decodeChar(s.charCodeAt(i)); v1 = this._decodeChar(s.charCodeAt(i + 1)); out[op++] = (v0 << 2) | (v1 >>> 4); haveBad |= v0 & INVALID_BYTE; haveBad |= v1 & INVALID_BYTE; } if (i < length - 2) { v2 = this._decodeChar(s.charCodeAt(i + 2)); out[op++] = (v1 << 4) | (v2 >>> 2); haveBad |= v2 & INVALID_BYTE; } if (i < length - 3) { v3 = this._decodeChar(s.charCodeAt(i + 3)); out[op++] = (v2 << 6) | v3; haveBad |= v3 & INVALID_BYTE; } if (haveBad !== 0) { throw new Error("Base64Coder: incorrect characters for decoding"); } return out; }; // Standard encoding have the following encoded/decoded ranges, // which we need to convert between. // // ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 0123456789 + / // Index: 0 - 25 26 - 51 52 - 61 62 63 // ASCII: 65 - 90 97 - 122 48 - 57 43 47 // // Encode 6 bits in b into a new character. Coder.prototype._encodeByte = function (b) { // Encoding uses constant time operations as follows: // // 1. Define comparison of A with B using (A - B) >>> 8: // if A > B, then result is positive integer // if A <= B, then result is 0 // // 2. Define selection of C or 0 using bitwise AND: X & C: // if X == 0, then result is 0 // if X != 0, then result is C // // 3. Start with the smallest comparison (b >= 0), which is always // true, so set the result to the starting ASCII value (65). // // 4. Continue comparing b to higher ASCII values, and selecting // zero if comparison isn't true, otherwise selecting a value // to add to result, which: // // a) undoes the previous addition // b) provides new value to add // var result = b; // b >= 0 result += 65; // b > 25 result += ((25 - b) >>> 8) & ((0 - 65) - 26 + 97); // b > 51 result += ((51 - b) >>> 8) & ((26 - 97) - 52 + 48); // b > 61 result += ((61 - b) >>> 8) & ((52 - 48) - 62 + 43); // b > 62 result += ((62 - b) >>> 8) & ((62 - 43) - 63 + 47); return String.fromCharCode(result); }; // Decode a character code into a byte. // Must return 256 if character is out of alphabet range. Coder.prototype._decodeChar = function (c) { // Decoding works similar to encoding: using the same comparison // function, but now it works on ranges: result is always incremented // by value, but this value becomes zero if the range is not // satisfied. // // Decoding starts with invalid value, 256, which is then // subtracted when the range is satisfied. If none of the ranges // apply, the function returns 256, which is then checked by // the caller to throw error. var result = INVALID_BYTE; // start with invalid character // c == 43 (c > 42 and c < 44) result += (((42 - c) & (c - 44)) >>> 8) & (-INVALID_BYTE + c - 43 + 62); // c == 47 (c > 46 and c < 48) result += (((46 - c) & (c - 48)) >>> 8) & (-INVALID_BYTE + c - 47 + 63); // c > 47 and c < 58 result += (((47 - c) & (c - 58)) >>> 8) & (-INVALID_BYTE + c - 48 + 52); // c > 64 and c < 91 result += (((64 - c) & (c - 91)) >>> 8) & (-INVALID_BYTE + c - 65 + 0); // c > 96 and c < 123 result += (((96 - c) & (c - 123)) >>> 8) & (-INVALID_BYTE + c - 97 + 26); return result; }; Coder.prototype._getPaddingLength = function (s) { var paddingLength = 0; if (this._paddingCharacter) { for (var i = s.length - 1; i >= 0; i--) { if (s[i] !== this._paddingCharacter) { break; } paddingLength++; } if (s.length < 4 || paddingLength > 2) { throw new Error("Base64Coder: incorrect padding"); } } return paddingLength; }; return Coder; }()); exports.Coder = Coder; var stdCoder = new Coder(); function encode(data) { return stdCoder.encode(data); } exports.encode = encode; function decode(s) { return stdCoder.decode(s); } exports.decode = decode; /** * Implements URL-safe Base64 encoding. * (Same as Base64, but '+' is replaced with '-', and '/' with '_'). * * Operates in constant time. */ var URLSafeCoder = /** @class */ (function (_super) { __extends(URLSafeCoder, _super); function URLSafeCoder() { return _super !== null && _super.apply(this, arguments) || this; } // URL-safe encoding have the following encoded/decoded ranges: // // ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 0123456789 - _ // Index: 0 - 25 26 - 51 52 - 61 62 63 // ASCII: 65 - 90 97 - 122 48 - 57 45 95 // URLSafeCoder.prototype._encodeByte = function (b) { var result = b; // b >= 0 result += 65; // b > 25 result += ((25 - b) >>> 8) & ((0 - 65) - 26 + 97); // b > 51 result += ((51 - b) >>> 8) & ((26 - 97) - 52 + 48); // b > 61 result += ((61 - b) >>> 8) & ((52 - 48) - 62 + 45); // b > 62 result += ((62 - b) >>> 8) & ((62 - 45) - 63 + 95); return String.fromCharCode(result); }; URLSafeCoder.prototype._decodeChar = function (c) { var result = INVALID_BYTE; // c == 45 (c > 44 and c < 46) result += (((44 - c) & (c - 46)) >>> 8) & (-INVALID_BYTE + c - 45 + 62); // c == 95 (c > 94 and c < 96) result += (((94 - c) & (c - 96)) >>> 8) & (-INVALID_BYTE + c - 95 + 63); // c > 47 and c < 58 result += (((47 - c) & (c - 58)) >>> 8) & (-INVALID_BYTE + c - 48 + 52); // c > 64 and c < 91 result += (((64 - c) & (c - 91)) >>> 8) & (-INVALID_BYTE + c - 65 + 0); // c > 96 and c < 123 result += (((96 - c) & (c - 123)) >>> 8) & (-INVALID_BYTE + c - 97 + 26); return result; }; return URLSafeCoder; }(Coder)); exports.URLSafeCoder = URLSafeCoder; var urlSafeCoder = new URLSafeCoder(); function encodeURLSafe(data) { return urlSafeCoder.encode(data); } exports.encodeURLSafe = encodeURLSafe; function decodeURLSafe(s) { return urlSafeCoder.decode(s); } exports.decodeURLSafe = decodeURLSafe; exports.encodedLength = function (length) { return stdCoder.encodedLength(length); }; exports.maxDecodedLength = function (length) { return stdCoder.maxDecodedLength(length); }; exports.decodedLength = function (s) { return stdCoder.decodedLength(s); }; /***/ }), /* 9 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var Headers = function() { this.clear(); }; Headers.prototype.ALLOWED_DUPLICATES = ['set-cookie', 'set-cookie2', 'warning', 'www-authenticate']; Headers.prototype.clear = function() { this._sent = {}; this._lines = []; }; Headers.prototype.set = function(name, value) { if (value === undefined) return; name = this._strip(name); value = this._strip(value); var key = name.toLowerCase(); if (!this._sent.hasOwnProperty(key) || this.ALLOWED_DUPLICATES.indexOf(key) >= 0) { this._sent[key] = true; this._lines.push(name + ': ' + value + '\r\n'); } }; Headers.prototype.toString = function() { return this._lines.join(''); }; Headers.prototype._strip = function(string) { return string.toString().replace(/^ */, '').replace(/ *$/, ''); }; module.exports = Headers; /***/ }), /* 10 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var NodeHTTPParser = __webpack_require__(27).HTTPParser, Buffer = __webpack_require__(1).Buffer; var TYPES = { request: NodeHTTPParser.REQUEST || 'request', response: NodeHTTPParser.RESPONSE || 'response' }; var HttpParser = function(type) { this._type = type; this._parser = new NodeHTTPParser(TYPES[type]); this._complete = false; this.headers = {}; var current = null, self = this; this._parser.onHeaderField = function(b, start, length) { current = b.toString('utf8', start, start + length).toLowerCase(); }; this._parser.onHeaderValue = function(b, start, length) { var value = b.toString('utf8', start, start + length); if (self.headers.hasOwnProperty(current)) self.headers[current] += ', ' + value; else self.headers[current] = value; }; this._parser.onHeadersComplete = this._parser[NodeHTTPParser.kOnHeadersComplete] = function(majorVersion, minorVersion, headers, method, pathname, statusCode) { var info = arguments[0]; if (typeof info === 'object') { method = info.method; pathname = info.url; statusCode = info.statusCode; headers = info.headers; } self.method = (typeof method === 'number') ? HttpParser.METHODS[method] : method; self.statusCode = statusCode; self.url = pathname; if (!headers) return; for (var i = 0, n = headers.length, key, value; i < n; i += 2) { key = headers[i].toLowerCase(); value = headers[i+1]; if (self.headers.hasOwnProperty(key)) self.headers[key] += ', ' + value; else self.headers[key] = value; } self._complete = true; }; }; HttpParser.METHODS = { 0: 'DELETE', 1: 'GET', 2: 'HEAD', 3: 'POST', 4: 'PUT', 5: 'CONNECT', 6: 'OPTIONS', 7: 'TRACE', 8: 'COPY', 9: 'LOCK', 10: 'MKCOL', 11: 'MOVE', 12: 'PROPFIND', 13: 'PROPPATCH', 14: 'SEARCH', 15: 'UNLOCK', 16: 'BIND', 17: 'REBIND', 18: 'UNBIND', 19: 'ACL', 20: 'REPORT', 21: 'MKACTIVITY', 22: 'CHECKOUT', 23: 'MERGE', 24: 'M-SEARCH', 25: 'NOTIFY', 26: 'SUBSCRIBE', 27: 'UNSUBSCRIBE', 28: 'PATCH', 29: 'PURGE', 30: 'MKCALENDAR', 31: 'LINK', 32: 'UNLINK' }; var VERSION = (process.version || '') .match(/[0-9]+/g) .map(function(n) { return parseInt(n, 10) }); if (VERSION[0] === 0 && VERSION[1] === 12) { HttpParser.METHODS[16] = 'REPORT'; HttpParser.METHODS[17] = 'MKACTIVITY'; HttpParser.METHODS[18] = 'CHECKOUT'; HttpParser.METHODS[19] = 'MERGE'; HttpParser.METHODS[20] = 'M-SEARCH'; HttpParser.METHODS[21] = 'NOTIFY'; HttpParser.METHODS[22] = 'SUBSCRIBE'; HttpParser.METHODS[23] = 'UNSUBSCRIBE'; HttpParser.METHODS[24] = 'PATCH'; HttpParser.METHODS[25] = 'PURGE'; } HttpParser.prototype.isComplete = function() { return this._complete; }; HttpParser.prototype.parse = function(chunk) { var consumed = this._parser.execute(chunk, 0, chunk.length); if (typeof consumed !== 'number') { this.error = consumed; this._complete = true; return; } if (this._complete) this.body = (consumed < chunk.length) ? chunk.slice(consumed) : Buffer.alloc(0); }; module.exports = HttpParser; /***/ }), /* 11 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var Stream = __webpack_require__(4).Stream, util = __webpack_require__(0), driver = __webpack_require__(3), EventTarget = __webpack_require__(16), Event = __webpack_require__(7); var API = function(options) { options = options || {}; driver.validateOptions(options, ['headers', 'extensions', 'maxLength', 'ping', 'proxy', 'tls', 'ca']); this.readable = this.writable = true; var headers = options.headers; if (headers) { for (var name in headers) this._driver.setHeader(name, headers[name]); } var extensions = options.extensions; if (extensions) { [].concat(extensions).forEach(this._driver.addExtension, this._driver); } this._ping = options.ping; this._pingId = 0; this.readyState = API.CONNECTING; this.bufferedAmount = 0; this.protocol = ''; this.url = this._driver.url; this.version = this._driver.version; var self = this; this._driver.on('open', function(e) { self._open() }); this._driver.on('message', function(e) { self._receiveMessage(e.data) }); this._driver.on('close', function(e) { self._beginClose(e.reason, e.code) }); this._driver.on('error', function(error) { self._emitError(error.message); }); this.on('error', function() {}); this._driver.messages.on('drain', function() { self.emit('drain'); }); if (this._ping) this._pingTimer = setInterval(function() { self._pingId += 1; self.ping(self._pingId.toString()); }, this._ping * 1000); this._configureStream(); if (!this._proxy) { this._stream.pipe(this._driver.io); this._driver.io.pipe(this._stream); } }; util.inherits(API, Stream); API.CONNECTING = 0; API.OPEN = 1; API.CLOSING = 2; API.CLOSED = 3; API.CLOSE_TIMEOUT = 30000; var instance = { write: function(data) { return this.send(data); }, end: function(data) { if (data !== undefined) this.send(data); this.close(); }, pause: function() { return this._driver.messages.pause(); }, resume: function() { return this._driver.messages.resume(); }, send: function(data) { if (this.readyState > API.OPEN) return false; if (!(data instanceof Buffer)) data = String(data); return this._driver.messages.write(data); }, ping: function(message, callback) { if (this.readyState > API.OPEN) return false; return this._driver.ping(message, callback); }, close: function(code, reason) { if (code === undefined) code = 1000; if (reason === undefined) reason = ''; if (code !== 1000 && (code < 3000 || code > 4999)) throw new Error("Failed to execute 'close' on WebSocket: " + "The code must be either 1000, or between 3000 and 4999. " + code + " is neither."); if (this.readyState !== API.CLOSED) this.readyState = API.CLOSING; var self = this; this._closeTimer = setTimeout(function() { self._beginClose('', 1006); }, API.CLOSE_TIMEOUT); this._driver.close(reason, code); }, _configureStream: function() { var self = this; this._stream.setTimeout(0); this._stream.setNoDelay(true); ['close', 'end'].forEach(function(event) { this._stream.on(event, function() { self._finalizeClose() }); }, this); this._stream.on('error', function(error) { self._emitError('Network error: ' + self.url + ': ' + error.message); self._finalizeClose(); }); }, _open: function() { if (this.readyState !== API.CONNECTING) return; this.readyState = API.OPEN; this.protocol = this._driver.protocol || ''; var event = new Event('open'); event.initEvent('open', false, false); this.dispatchEvent(event); }, _receiveMessage: function(data) { if (this.readyState > API.OPEN) return false; if (this.readable) this.emit('data', data); var event = new Event('message', {data: data}); event.initEvent('message', false, false); this.dispatchEvent(event); }, _emitError: function(message) { if (this.readyState >= API.CLOSING) return; var event = new Event('error', {message: message}); event.initEvent('error', false, false); this.dispatchEvent(event); }, _beginClose: function(reason, code) { if (this.readyState === API.CLOSED) return; this.readyState = API.CLOSING; this._closeParams = [reason, code]; if (this._stream) { this._stream.destroy(); if (!this._stream.readable) this._finalizeClose(); } }, _finalizeClose: function() { if (this.readyState === API.CLOSED) return; this.readyState = API.CLOSED; if (this._closeTimer) clearTimeout(this._closeTimer); if (this._pingTimer) clearInterval(this._pingTimer); if (this._stream) this._stream.end(); if (this.readable) this.emit('end'); this.readable = this.writable = false; var reason = this._closeParams ? this._closeParams[0] : '', code = this._closeParams ? this._closeParams[1] : 1006; var event = new Event('close', {code: code, reason: reason}); event.initEvent('close', false, false); this.dispatchEvent(event); } }; for (var method in instance) API.prototype[method] = instance[method]; for (var key in EventTarget) API.prototype[key] = EventTarget[key]; module.exports = API; /***/ }), /* 12 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var Buffer = __webpack_require__(1).Buffer, crypto = __webpack_require__(5), util = __webpack_require__(0), Extensions = __webpack_require__(29), Base = __webpack_require__(2), Frame = __webpack_require__(34), Message = __webpack_require__(35); var Hybi = function(request, url, options) { Base.apply(this, arguments); this._extensions = new Extensions(); this._stage = 0; this._masking = this._options.masking; this._protocols = this._options.protocols || []; this._requireMasking = this._options.requireMasking; this._pingCallbacks = {}; if (typeof this._protocols === 'string') this._protocols = this._protocols.split(/ *, */); if (!this._request) return; var protos = this._request.headers['sec-websocket-protocol'], supported = this._protocols; if (protos !== undefined) { if (typeof protos === 'string') protos = protos.split(/ *, */); this.protocol = protos.filter(function(p) { return supported.indexOf(p) >= 0 })[0]; } this.version = 'hybi-' + Hybi.VERSION; }; util.inherits(Hybi, Base); Hybi.VERSION = '13'; Hybi.mask = function(payload, mask, offset) { if (!mask || mask.length === 0) return payload; offset = offset || 0; for (var i = 0, n = payload.length - offset; i < n; i++) { payload[offset + i] = payload[offset + i] ^ mask[i % 4]; } return payload; }; Hybi.generateAccept = function(key) { var sha1 = crypto.createHash('sha1'); sha1.update(key + Hybi.GUID); return sha1.digest('base64'); }; Hybi.GUID = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'; var instance = { FIN: 0x80, MASK: 0x80, RSV1: 0x40, RSV2: 0x20, RSV3: 0x10, OPCODE: 0x0F, LENGTH: 0x7F, OPCODES: { continuation: 0, text: 1, binary: 2, close: 8, ping: 9, pong: 10 }, OPCODE_CODES: [0, 1, 2, 8, 9, 10], MESSAGE_OPCODES: [0, 1, 2], OPENING_OPCODES: [1, 2], ERRORS: { normal_closure: 1000, going_away: 1001, protocol_error: 1002, unacceptable: 1003, encoding_error: 1007, policy_violation: 1008, too_large: 1009, extension_error: 1010, unexpected_condition: 1011 }, ERROR_CODES: [1000, 1001, 1002, 1003, 1007, 1008, 1009, 1010, 1011], DEFAULT_ERROR_CODE: 1000, MIN_RESERVED_ERROR: 3000, MAX_RESERVED_ERROR: 4999, // http://www.w3.org/International/questions/qa-forms-utf-8.en.php UTF8_MATCH: /^([\x00-\x7F]|[\xC2-\xDF][\x80-\xBF]|\xE0[\xA0-\xBF][\x80-\xBF]|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}|\xED[\x80-\x9F][\x80-\xBF]|\xF0[\x90-\xBF][\x80-\xBF]{2}|[\xF1-\xF3][\x80-\xBF]{3}|\xF4[\x80-\x8F][\x80-\xBF]{2})*$/, addExtension: function(extension) { this._extensions.add(extension); return true; }, parse: function(chunk) { this._reader.put(chunk); var buffer = true; while (buffer) { switch (this._stage) { case 0: buffer = this._reader.read(1); if (buffer) this._parseOpcode(buffer[0]); break; case 1: buffer = this._reader.read(1); if (buffer) this._parseLength(buffer[0]); break; case 2: buffer = this._reader.read(this._frame.lengthBytes); if (buffer) this._parseExtendedLength(buffer); break; case 3: buffer = this._reader.read(4); if (buffer) { this._stage = 4; this._frame.maskingKey = buffer; } break; case 4: buffer = this._reader.read(this._frame.length); if (buffer) { this._stage = 0; this._emitFrame(buffer); } break; default: buffer = null; } } }, text: function(message) { if (this.readyState > 1) return false; return this.frame(message, 'text'); }, binary: function(message) { if (this.readyState > 1) return false; return this.frame(message, 'binary'); }, ping: function(message, callback) { if (this.readyState > 1) return false; message = message || ''; if (callback) this._pingCallbacks[message] = callback; return this.frame(message, 'ping'); }, pong: function(message) { if (this.readyState > 1) return false; message = message ||''; return this.frame(message, 'pong'); }, close: function(reason, code) { reason = reason || ''; code = code || this.ERRORS.normal_closure; if (this.readyState <= 0) { this.readyState = 3; this.emit('close', new Base.CloseEvent(code, reason)); return true; } else if (this.readyState === 1) { this.readyState = 2; this._extensions.close(function() { this.frame(reason, 'close', code) }, this); return true; } else { return false; } }, frame: function(buffer, type, code) { if (this.readyState <= 0) return this._queue([buffer, type, code]); if (this.readyState > 2) return false; if (buffer instanceof Array) buffer = Buffer.from(buffer); if (typeof buffer === 'number') buffer = buffer.toString(); var message = new Message(), isText = (typeof buffer === 'string'), payload, copy; message.rsv1 = message.rsv2 = message.rsv3 = false; message.opcode = this.OPCODES[type || (isText ? 'text' : 'binary')]; payload = isText ? Buffer.from(buffer, 'utf8') : buffer; if (code) { copy = payload; payload = Buffer.allocUnsafe(2 + copy.length); payload.writeUInt16BE(code, 0); copy.copy(payload, 2); } message.data = payload; var onMessageReady = function(message) { var frame = new Frame(); frame.final = true; frame.rsv1 = message.rsv1; frame.rsv2 = message.rsv2; frame.rsv3 = message.rsv3; frame.opcode = message.opcode; frame.masked = !!this._masking; frame.length = message.data.length; frame.payload = message.data; if (frame.masked) frame.maskingKey = crypto.randomBytes(4); this._sendFrame(frame); }; if (this.MESSAGE_OPCODES.indexOf(message.opcode) >= 0) this._extensions.processOutgoingMessage(message, function(error, message) { if (error) return this._fail('extension_error', error.message); onMessageReady.call(this, message); }, this); else onMessageReady.call(this, message); return true; }, _sendFrame: function(frame) { var length = frame.length, header = (length <= 125) ? 2 : (length <= 65535 ? 4 : 10), offset = header + (frame.masked ? 4 : 0), buffer = Buffer.allocUnsafe(offset + length), masked = frame.masked ? this.MASK : 0; buffer[0] = (frame.final ? this.FIN : 0) | (frame.rsv1 ? this.RSV1 : 0) | (frame.rsv2 ? this.RSV2 : 0) | (frame.rsv3 ? this.RSV3 : 0) | frame.opcode; if (length <= 125) { buffer[1] = masked | length; } else if (length <= 65535) { buffer[1] = masked | 126; buffer.writeUInt16BE(length, 2); } else { buffer[1] = masked | 127; buffer.writeUInt32BE(Math.floor(length / 0x100000000), 2); buffer.writeUInt32BE(length % 0x100000000, 6); } frame.payload.copy(buffer, offset); if (frame.masked) { frame.maskingKey.copy(buffer, header); Hybi.mask(buffer, frame.maskingKey, offset); } this._write(buffer); }, _handshakeResponse: function() { var secKey = this._request.headers['sec-websocket-key'], version = this._request.headers['sec-websocket-version']; if (version !== Hybi.VERSION) throw new Error('Unsupported WebSocket version: ' + version); if (typeof secKey !== 'string') throw new Error('Missing handshake request header: Sec-WebSocket-Key'); this._headers.set('Upgrade', 'websocket'); this._headers.set('Connection', 'Upgrade'); this._headers.set('Sec-WebSocket-Accept', Hybi.generateAccept(secKey)); if (this.protocol) this._headers.set('Sec-WebSocket-Protocol', this.protocol); var extensions = this._extensions.generateResponse(this._request.headers['sec-websocket-extensions']); if (extensions) this._headers.set('Sec-WebSocket-Extensions', extensions); var start = 'HTTP/1.1 101 Switching Protocols', headers = [start, this._headers.toString(), '']; return Buffer.from(headers.join('\r\n'), 'utf8'); }, _shutdown: function(code, reason, error) { delete this._frame; delete this._message; this._stage = 5; var sendCloseFrame = (this.readyState === 1); this.readyState = 2; this._extensions.close(function() { if (sendCloseFrame) this.frame(reason, 'close', code); this.readyState = 3; if (error) this.emit('error', new Error(reason)); this.emit('close', new Base.CloseEvent(code, reason)); }, this); }, _fail: function(type, message) { if (this.readyState > 1) return; this._shutdown(this.ERRORS[type], message, true); }, _parseOpcode: function(octet) { var rsvs = [this.RSV1, this.RSV2, this.RSV3].map(function(rsv) { return (octet & rsv) === rsv; }); var frame = this._frame = new Frame(); frame.final = (octet & this.FIN) === this.FIN; frame.rsv1 = rsvs[0]; frame.rsv2 = rsvs[1]; frame.rsv3 = rsvs[2]; frame.opcode = (octet & this.OPCODE); this._stage = 1; if (!this._extensions.validFrameRsv(frame)) return this._fail('protocol_error', 'One or more reserved bits are on: reserved1 = ' + (frame.rsv1 ? 1 : 0) + ', reserved2 = ' + (frame.rsv2 ? 1 : 0) + ', reserved3 = ' + (frame.rsv3 ? 1 : 0)); if (this.OPCODE_CODES.indexOf(frame.opcode) < 0) return this._fail('protocol_error', 'Unrecognized frame opcode: ' + frame.opcode); if (this.MESSAGE_OPCODES.indexOf(frame.opcode) < 0 && !frame.final) return this._fail('protocol_error', 'Received fragmented control frame: opcode = ' + frame.opcode); if (this._message && this.OPENING_OPCODES.indexOf(frame.opcode) >= 0) return this._fail('protocol_error', 'Received new data frame but previous continuous frame is unfinished'); }, _parseLength: function(octet) { var frame = this._frame; frame.masked = (octet & this.MASK) === this.MASK; frame.length = (octet & this.LENGTH); if (frame.length >= 0 && frame.length <= 125) { this._stage = frame.masked ? 3 : 4; if (!this._checkFrameLength()) return; } else { this._stage = 2; frame.lengthBytes = (frame.length === 126 ? 2 : 8); } if (this._requireMasking && !frame.masked) return this._fail('unacceptable', 'Received unmasked frame but masking is required'); }, _parseExtendedLength: function(buffer) { var frame = this._frame; frame.length = this._readUInt(buffer); this._stage = frame.masked ? 3 : 4; if (this.MESSAGE_OPCODES.indexOf(frame.opcode) < 0 && frame.length > 125) return this._fail('protocol_error', 'Received control frame having too long payload: ' + frame.length); if (!this._checkFrameLength()) return; }, _checkFrameLength: function() { var length = this._message ? this._message.length : 0; if (length + this._frame.length > this._maxLength) { this._fail('too_large', 'WebSocket frame length too large'); return false; } else { return true; } }, _emitFrame: function(buffer) { var frame = this._frame, payload = frame.payload = Hybi.mask(buffer, frame.maskingKey), opcode = frame.opcode, message, code, reason, callbacks, callback; delete this._frame; if (opcode === this.OPCODES.continuation) { if (!this._message) return this._fail('protocol_error', 'Received unexpected continuation frame'); this._message.pushFrame(frame); } if (opcode === this.OPCODES.text || opcode === this.OPCODES.binary) { this._message = new Message(); this._message.pushFrame(frame); } if (frame.final && this.MESSAGE_OPCODES.indexOf(opcode) >= 0) return this._emitMessage(this._message); if (opcode === this.OPCODES.close) { code = (payload.length >= 2) ? payload.readUInt16BE(0) : null; reason = (payload.length > 2) ? this._encode(payload.slice(2)) : null; if (!(payload.length === 0) && !(code !== null && code >= this.MIN_RESERVED_ERROR && code <= this.MAX_RESERVED_ERROR) && this.ERROR_CODES.indexOf(code) < 0) code = this.ERRORS.protocol_error; if (payload.length > 125 || (payload.length > 2 && !reason)) code = this.ERRORS.protocol_error; this._shutdown(code || this.DEFAULT_ERROR_CODE, reason || ''); } if (opcode === this.OPCODES.ping) { this.frame(payload, 'pong'); this.emit('ping', new Base.PingEvent(payload.toString())) } if (opcode === this.OPCODES.pong) { callbacks = this._pingCallbacks; message = this._encode(payload); callback = callbacks[message]; delete callbacks[message]; if (callback) callback() this.emit('pong', new Base.PongEvent(payload.toString())) } }, _emitMessage: function(message) { var message = this._message; message.read(); delete this._message; this._extensions.processIncomingMessage(message, function(error, message) { if (error) return this._fail('extension_error', error.message); var payload = message.data; if (message.opcode === this.OPCODES.text) payload = this._encode(payload); if (payload === null) return this._fail('encoding_error', 'Could not decode a text frame as UTF-8'); else this.emit('message', new Base.MessageEvent(payload)); }, this); }, _encode: function(buffer) { try { var string = buffer.toString('binary', 0, buffer.length); if (!this.UTF8_MATCH.test(string)) return null; } catch (e) {} return buffer.toString('utf8', 0, buffer.length); }, _readUInt: function(buffer) { if (buffer.length === 2) return buffer.readUInt16BE(0); return buffer.readUInt32BE(0) * 0x100000000 + buffer.readUInt32BE(4); } }; for (var key in instance) Hybi.prototype[key] = instance[key]; module.exports = Hybi; /***/ }), /* 13 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var RingBuffer = function(bufferSize) { this._bufferSize = bufferSize; this.clear(); }; RingBuffer.prototype.clear = function() { this._buffer = new Array(this._bufferSize); this._ringOffset = 0; this._ringSize = this._bufferSize; this._head = 0; this._tail = 0; this.length = 0; }; RingBuffer.prototype.push = function(value) { var expandBuffer = false, expandRing = false; if (this._ringSize < this._bufferSize) { expandBuffer = (this._tail === 0); } else if (this._ringOffset === this._ringSize) { expandBuffer = true; expandRing = (this._tail === 0); } if (expandBuffer) { this._tail = this._bufferSize; this._buffer = this._buffer.concat(new Array(this._bufferSize)); this._bufferSize = this._buffer.length; if (expandRing) this._ringSize = this._bufferSize; } this._buffer[this._tail] = value; this.length += 1; if (this._tail < this._ringSize) this._ringOffset += 1; this._tail = (this._tail + 1) % this._bufferSize; }; RingBuffer.prototype.peek = function() { if (this.length === 0) return void 0; return this._buffer[this._head]; }; RingBuffer.prototype.shift = function() { if (this.length === 0) return void 0; var value = this._buffer[this._head]; this._buffer[this._head] = void 0; this.length -= 1; this._ringOffset -= 1; if (this._ringOffset === 0 && this.length > 0) { this._head = this._ringSize; this._ringOffset = this.length; this._ringSize = this._bufferSize; } else { this._head = (this._head + 1) % this._ringSize; } return value; }; module.exports = RingBuffer; /***/ }), /* 14 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var RingBuffer = __webpack_require__(13); var Pledge = function() { this._complete = false; this._callbacks = new RingBuffer(Pledge.QUEUE_SIZE); }; Pledge.QUEUE_SIZE = 4; Pledge.all = function(list) { var pledge = new Pledge(), pending = list.length, n = pending; if (pending === 0) pledge.done(); while (n--) list[n].then(function() { pending -= 1; if (pending === 0) pledge.done(); }); return pledge; }; Pledge.prototype.then = function(callback) { if (this._complete) callback(); else this._callbacks.push(callback); }; Pledge.prototype.done = function() { this._complete = true; var callbacks = this._callbacks, callback; while (callback = callbacks.shift()) callback(); }; module.exports = Pledg