This commit is contained in:
tatianamac
2019-11-26 14:50:43 -08:00
parent 8a55660ed0
commit 6d5445ecc5
13894 changed files with 2233957 additions and 0 deletions

53
node_modules/engine.io-client/lib/transports/index.js generated vendored Executable file
View File

@ -0,0 +1,53 @@
/**
* Module dependencies
*/
var XMLHttpRequest = require('xmlhttprequest-ssl');
var XHR = require('./polling-xhr');
var JSONP = require('./polling-jsonp');
var websocket = require('./websocket');
/**
* Export transports.
*/
exports.polling = polling;
exports.websocket = websocket;
/**
* Polling transport polymorphic constructor.
* Decides on xhr vs jsonp based on feature detection.
*
* @api private
*/
function polling (opts) {
var xhr;
var xd = false;
var xs = false;
var jsonp = false !== opts.jsonp;
if (typeof location !== 'undefined') {
var isSSL = 'https:' === location.protocol;
var port = location.port;
// some user agents have empty `location.port`
if (!port) {
port = isSSL ? 443 : 80;
}
xd = opts.hostname !== location.hostname || port !== opts.port;
xs = opts.secure !== isSSL;
}
opts.xdomain = xd;
opts.xscheme = xs;
xhr = new XMLHttpRequest(opts);
if ('open' in xhr && !opts.forceJSONP) {
return new XHR(opts);
} else {
if (!jsonp) throw new Error('JSONP disabled');
return new JSONP(opts);
}
}

View File

@ -0,0 +1,239 @@
/**
* Module requirements.
*/
var Polling = require('./polling');
var inherit = require('component-inherit');
/**
* Module exports.
*/
module.exports = JSONPPolling;
/**
* Cached regular expressions.
*/
var rNewline = /\n/g;
var rEscapedNewline = /\\n/g;
/**
* Global JSONP callbacks.
*/
var callbacks;
/**
* Noop.
*/
function empty () { }
/**
* Until https://github.com/tc39/proposal-global is shipped.
*/
function glob () {
return typeof self !== 'undefined' ? self
: typeof window !== 'undefined' ? window
: typeof global !== 'undefined' ? global : {};
}
/**
* JSONP Polling constructor.
*
* @param {Object} opts.
* @api public
*/
function JSONPPolling (opts) {
Polling.call(this, opts);
this.query = this.query || {};
// define global callbacks array if not present
// we do this here (lazily) to avoid unneeded global pollution
if (!callbacks) {
// we need to consider multiple engines in the same page
var global = glob();
callbacks = global.___eio = (global.___eio || []);
}
// callback identifier
this.index = callbacks.length;
// add callback to jsonp global
var self = this;
callbacks.push(function (msg) {
self.onData(msg);
});
// append to query string
this.query.j = this.index;
// prevent spurious errors from being emitted when the window is unloaded
if (typeof addEventListener === 'function') {
addEventListener('beforeunload', function () {
if (self.script) self.script.onerror = empty;
}, false);
}
}
/**
* Inherits from Polling.
*/
inherit(JSONPPolling, Polling);
/*
* JSONP only supports binary as base64 encoded strings
*/
JSONPPolling.prototype.supportsBinary = false;
/**
* Closes the socket.
*
* @api private
*/
JSONPPolling.prototype.doClose = function () {
if (this.script) {
this.script.parentNode.removeChild(this.script);
this.script = null;
}
if (this.form) {
this.form.parentNode.removeChild(this.form);
this.form = null;
this.iframe = null;
}
Polling.prototype.doClose.call(this);
};
/**
* Starts a poll cycle.
*
* @api private
*/
JSONPPolling.prototype.doPoll = function () {
var self = this;
var script = document.createElement('script');
if (this.script) {
this.script.parentNode.removeChild(this.script);
this.script = null;
}
script.async = true;
script.src = this.uri();
script.onerror = function (e) {
self.onError('jsonp poll error', e);
};
var insertAt = document.getElementsByTagName('script')[0];
if (insertAt) {
insertAt.parentNode.insertBefore(script, insertAt);
} else {
(document.head || document.body).appendChild(script);
}
this.script = script;
var isUAgecko = 'undefined' !== typeof navigator && /gecko/i.test(navigator.userAgent);
if (isUAgecko) {
setTimeout(function () {
var iframe = document.createElement('iframe');
document.body.appendChild(iframe);
document.body.removeChild(iframe);
}, 100);
}
};
/**
* Writes with a hidden iframe.
*
* @param {String} data to send
* @param {Function} called upon flush.
* @api private
*/
JSONPPolling.prototype.doWrite = function (data, fn) {
var self = this;
if (!this.form) {
var form = document.createElement('form');
var area = document.createElement('textarea');
var id = this.iframeId = 'eio_iframe_' + this.index;
var iframe;
form.className = 'socketio';
form.style.position = 'absolute';
form.style.top = '-1000px';
form.style.left = '-1000px';
form.target = id;
form.method = 'POST';
form.setAttribute('accept-charset', 'utf-8');
area.name = 'd';
form.appendChild(area);
document.body.appendChild(form);
this.form = form;
this.area = area;
}
this.form.action = this.uri();
function complete () {
initIframe();
fn();
}
function initIframe () {
if (self.iframe) {
try {
self.form.removeChild(self.iframe);
} catch (e) {
self.onError('jsonp polling iframe removal error', e);
}
}
try {
// ie6 dynamic iframes with target="" support (thanks Chris Lambacher)
var html = '<iframe src="javascript:0" name="' + self.iframeId + '">';
iframe = document.createElement(html);
} catch (e) {
iframe = document.createElement('iframe');
iframe.name = self.iframeId;
iframe.src = 'javascript:0';
}
iframe.id = self.iframeId;
self.form.appendChild(iframe);
self.iframe = iframe;
}
initIframe();
// escape \n to prevent it from being converted into \r\n by some UAs
// double escaping is required for escaped new lines because unescaping of new lines can be done safely on server-side
data = data.replace(rEscapedNewline, '\\\n');
this.area.value = data.replace(rNewline, '\\n');
try {
this.form.submit();
} catch (e) {}
if (this.iframe.attachEvent) {
this.iframe.onreadystatechange = function () {
if (self.iframe.readyState === 'complete') {
complete();
}
};
} else {
this.iframe.onload = complete;
}
};

417
node_modules/engine.io-client/lib/transports/polling-xhr.js generated vendored Executable file
View File

@ -0,0 +1,417 @@
/* global attachEvent */
/**
* Module requirements.
*/
var XMLHttpRequest = require('xmlhttprequest-ssl');
var Polling = require('./polling');
var Emitter = require('component-emitter');
var inherit = require('component-inherit');
var debug = require('debug')('engine.io-client:polling-xhr');
/**
* Module exports.
*/
module.exports = XHR;
module.exports.Request = Request;
/**
* Empty function
*/
function empty () {}
/**
* XHR Polling constructor.
*
* @param {Object} opts
* @api public
*/
function XHR (opts) {
Polling.call(this, opts);
this.requestTimeout = opts.requestTimeout;
this.extraHeaders = opts.extraHeaders;
if (typeof location !== 'undefined') {
var isSSL = 'https:' === location.protocol;
var port = location.port;
// some user agents have empty `location.port`
if (!port) {
port = isSSL ? 443 : 80;
}
this.xd = (typeof location !== 'undefined' && opts.hostname !== location.hostname) ||
port !== opts.port;
this.xs = opts.secure !== isSSL;
}
}
/**
* Inherits from Polling.
*/
inherit(XHR, Polling);
/**
* XHR supports binary
*/
XHR.prototype.supportsBinary = true;
/**
* Creates a request.
*
* @param {String} method
* @api private
*/
XHR.prototype.request = function (opts) {
opts = opts || {};
opts.uri = this.uri();
opts.xd = this.xd;
opts.xs = this.xs;
opts.agent = this.agent || false;
opts.supportsBinary = this.supportsBinary;
opts.enablesXDR = this.enablesXDR;
opts.withCredentials = this.withCredentials;
// SSL options for Node.js client
opts.pfx = this.pfx;
opts.key = this.key;
opts.passphrase = this.passphrase;
opts.cert = this.cert;
opts.ca = this.ca;
opts.ciphers = this.ciphers;
opts.rejectUnauthorized = this.rejectUnauthorized;
opts.requestTimeout = this.requestTimeout;
// other options for Node.js client
opts.extraHeaders = this.extraHeaders;
return new Request(opts);
};
/**
* Sends data.
*
* @param {String} data to send.
* @param {Function} called upon flush.
* @api private
*/
XHR.prototype.doWrite = function (data, fn) {
var isBinary = typeof data !== 'string' && data !== undefined;
var req = this.request({ method: 'POST', data: data, isBinary: isBinary });
var self = this;
req.on('success', fn);
req.on('error', function (err) {
self.onError('xhr post error', err);
});
this.sendXhr = req;
};
/**
* Starts a poll cycle.
*
* @api private
*/
XHR.prototype.doPoll = function () {
debug('xhr poll');
var req = this.request();
var self = this;
req.on('data', function (data) {
self.onData(data);
});
req.on('error', function (err) {
self.onError('xhr poll error', err);
});
this.pollXhr = req;
};
/**
* Request constructor
*
* @param {Object} options
* @api public
*/
function Request (opts) {
this.method = opts.method || 'GET';
this.uri = opts.uri;
this.xd = !!opts.xd;
this.xs = !!opts.xs;
this.async = false !== opts.async;
this.data = undefined !== opts.data ? opts.data : null;
this.agent = opts.agent;
this.isBinary = opts.isBinary;
this.supportsBinary = opts.supportsBinary;
this.enablesXDR = opts.enablesXDR;
this.withCredentials = opts.withCredentials;
this.requestTimeout = opts.requestTimeout;
// SSL options for Node.js client
this.pfx = opts.pfx;
this.key = opts.key;
this.passphrase = opts.passphrase;
this.cert = opts.cert;
this.ca = opts.ca;
this.ciphers = opts.ciphers;
this.rejectUnauthorized = opts.rejectUnauthorized;
// other options for Node.js client
this.extraHeaders = opts.extraHeaders;
this.create();
}
/**
* Mix in `Emitter`.
*/
Emitter(Request.prototype);
/**
* Creates the XHR object and sends the request.
*
* @api private
*/
Request.prototype.create = function () {
var opts = { agent: this.agent, xdomain: this.xd, xscheme: this.xs, enablesXDR: this.enablesXDR };
// SSL options for Node.js client
opts.pfx = this.pfx;
opts.key = this.key;
opts.passphrase = this.passphrase;
opts.cert = this.cert;
opts.ca = this.ca;
opts.ciphers = this.ciphers;
opts.rejectUnauthorized = this.rejectUnauthorized;
var xhr = this.xhr = new XMLHttpRequest(opts);
var self = this;
try {
debug('xhr open %s: %s', this.method, this.uri);
xhr.open(this.method, this.uri, this.async);
try {
if (this.extraHeaders) {
xhr.setDisableHeaderCheck && xhr.setDisableHeaderCheck(true);
for (var i in this.extraHeaders) {
if (this.extraHeaders.hasOwnProperty(i)) {
xhr.setRequestHeader(i, this.extraHeaders[i]);
}
}
}
} catch (e) {}
if ('POST' === this.method) {
try {
if (this.isBinary) {
xhr.setRequestHeader('Content-type', 'application/octet-stream');
} else {
xhr.setRequestHeader('Content-type', 'text/plain;charset=UTF-8');
}
} catch (e) {}
}
try {
xhr.setRequestHeader('Accept', '*/*');
} catch (e) {}
// ie6 check
if ('withCredentials' in xhr) {
xhr.withCredentials = this.withCredentials;
}
if (this.requestTimeout) {
xhr.timeout = this.requestTimeout;
}
if (this.hasXDR()) {
xhr.onload = function () {
self.onLoad();
};
xhr.onerror = function () {
self.onError(xhr.responseText);
};
} else {
xhr.onreadystatechange = function () {
if (xhr.readyState === 2) {
try {
var contentType = xhr.getResponseHeader('Content-Type');
if (self.supportsBinary && contentType === 'application/octet-stream' || contentType === 'application/octet-stream; charset=UTF-8') {
xhr.responseType = 'arraybuffer';
}
} catch (e) {}
}
if (4 !== xhr.readyState) return;
if (200 === xhr.status || 1223 === xhr.status) {
self.onLoad();
} else {
// make sure the `error` event handler that's user-set
// does not throw in the same tick and gets caught here
setTimeout(function () {
self.onError(typeof xhr.status === 'number' ? xhr.status : 0);
}, 0);
}
};
}
debug('xhr data %s', this.data);
xhr.send(this.data);
} catch (e) {
// Need to defer since .create() is called directly fhrom the constructor
// and thus the 'error' event can only be only bound *after* this exception
// occurs. Therefore, also, we cannot throw here at all.
setTimeout(function () {
self.onError(e);
}, 0);
return;
}
if (typeof document !== 'undefined') {
this.index = Request.requestsCount++;
Request.requests[this.index] = this;
}
};
/**
* Called upon successful response.
*
* @api private
*/
Request.prototype.onSuccess = function () {
this.emit('success');
this.cleanup();
};
/**
* Called if we have data.
*
* @api private
*/
Request.prototype.onData = function (data) {
this.emit('data', data);
this.onSuccess();
};
/**
* Called upon error.
*
* @api private
*/
Request.prototype.onError = function (err) {
this.emit('error', err);
this.cleanup(true);
};
/**
* Cleans up house.
*
* @api private
*/
Request.prototype.cleanup = function (fromError) {
if ('undefined' === typeof this.xhr || null === this.xhr) {
return;
}
// xmlhttprequest
if (this.hasXDR()) {
this.xhr.onload = this.xhr.onerror = empty;
} else {
this.xhr.onreadystatechange = empty;
}
if (fromError) {
try {
this.xhr.abort();
} catch (e) {}
}
if (typeof document !== 'undefined') {
delete Request.requests[this.index];
}
this.xhr = null;
};
/**
* Called upon load.
*
* @api private
*/
Request.prototype.onLoad = function () {
var data;
try {
var contentType;
try {
contentType = this.xhr.getResponseHeader('Content-Type');
} catch (e) {}
if (contentType === 'application/octet-stream' || contentType === 'application/octet-stream; charset=UTF-8') {
data = this.xhr.response || this.xhr.responseText;
} else {
data = this.xhr.responseText;
}
} catch (e) {
this.onError(e);
}
if (null != data) {
this.onData(data);
}
};
/**
* Check if it has XDomainRequest.
*
* @api private
*/
Request.prototype.hasXDR = function () {
return typeof XDomainRequest !== 'undefined' && !this.xs && this.enablesXDR;
};
/**
* Aborts the request.
*
* @api public
*/
Request.prototype.abort = function () {
this.cleanup();
};
/**
* Aborts pending requests when unloading the window. This is needed to prevent
* memory leaks (e.g. when using IE) and to ensure that no spurious error is
* emitted.
*/
Request.requestsCount = 0;
Request.requests = {};
if (typeof document !== 'undefined') {
if (typeof attachEvent === 'function') {
attachEvent('onunload', unloadHandler);
} else if (typeof addEventListener === 'function') {
var terminationEvent = 'onpagehide' in self ? 'pagehide' : 'unload';
addEventListener(terminationEvent, unloadHandler, false);
}
}
function unloadHandler () {
for (var i in Request.requests) {
if (Request.requests.hasOwnProperty(i)) {
Request.requests[i].abort();
}
}
}

245
node_modules/engine.io-client/lib/transports/polling.js generated vendored Normal file
View File

@ -0,0 +1,245 @@
/**
* Module dependencies.
*/
var Transport = require('../transport');
var parseqs = require('parseqs');
var parser = require('engine.io-parser');
var inherit = require('component-inherit');
var yeast = require('yeast');
var debug = require('debug')('engine.io-client:polling');
/**
* Module exports.
*/
module.exports = Polling;
/**
* Is XHR2 supported?
*/
var hasXHR2 = (function () {
var XMLHttpRequest = require('xmlhttprequest-ssl');
var xhr = new XMLHttpRequest({ xdomain: false });
return null != xhr.responseType;
})();
/**
* Polling interface.
*
* @param {Object} opts
* @api private
*/
function Polling (opts) {
var forceBase64 = (opts && opts.forceBase64);
if (!hasXHR2 || forceBase64) {
this.supportsBinary = false;
}
Transport.call(this, opts);
}
/**
* Inherits from Transport.
*/
inherit(Polling, Transport);
/**
* Transport name.
*/
Polling.prototype.name = 'polling';
/**
* Opens the socket (triggers polling). We write a PING message to determine
* when the transport is open.
*
* @api private
*/
Polling.prototype.doOpen = function () {
this.poll();
};
/**
* Pauses polling.
*
* @param {Function} callback upon buffers are flushed and transport is paused
* @api private
*/
Polling.prototype.pause = function (onPause) {
var self = this;
this.readyState = 'pausing';
function pause () {
debug('paused');
self.readyState = 'paused';
onPause();
}
if (this.polling || !this.writable) {
var total = 0;
if (this.polling) {
debug('we are currently polling - waiting to pause');
total++;
this.once('pollComplete', function () {
debug('pre-pause polling complete');
--total || pause();
});
}
if (!this.writable) {
debug('we are currently writing - waiting to pause');
total++;
this.once('drain', function () {
debug('pre-pause writing complete');
--total || pause();
});
}
} else {
pause();
}
};
/**
* Starts polling cycle.
*
* @api public
*/
Polling.prototype.poll = function () {
debug('polling');
this.polling = true;
this.doPoll();
this.emit('poll');
};
/**
* Overloads onData to detect payloads.
*
* @api private
*/
Polling.prototype.onData = function (data) {
var self = this;
debug('polling got data %s', data);
var callback = function (packet, index, total) {
// if its the first message we consider the transport open
if ('opening' === self.readyState) {
self.onOpen();
}
// if its a close packet, we close the ongoing requests
if ('close' === packet.type) {
self.onClose();
return false;
}
// otherwise bypass onData and handle the message
self.onPacket(packet);
};
// decode payload
parser.decodePayload(data, this.socket.binaryType, callback);
// if an event did not trigger closing
if ('closed' !== this.readyState) {
// if we got data we're not polling
this.polling = false;
this.emit('pollComplete');
if ('open' === this.readyState) {
this.poll();
} else {
debug('ignoring poll - transport state "%s"', this.readyState);
}
}
};
/**
* For polling, send a close packet.
*
* @api private
*/
Polling.prototype.doClose = function () {
var self = this;
function close () {
debug('writing close packet');
self.write([{ type: 'close' }]);
}
if ('open' === this.readyState) {
debug('transport open - closing');
close();
} else {
// in case we're trying to close while
// handshaking is in progress (GH-164)
debug('transport not open - deferring close');
this.once('open', close);
}
};
/**
* Writes a packets payload.
*
* @param {Array} data packets
* @param {Function} drain callback
* @api private
*/
Polling.prototype.write = function (packets) {
var self = this;
this.writable = false;
var callbackfn = function () {
self.writable = true;
self.emit('drain');
};
parser.encodePayload(packets, this.supportsBinary, function (data) {
self.doWrite(data, callbackfn);
});
};
/**
* Generates uri for connection.
*
* @api private
*/
Polling.prototype.uri = function () {
var query = this.query || {};
var schema = this.secure ? 'https' : 'http';
var port = '';
// cache busting is forced
if (false !== this.timestampRequests) {
query[this.timestampParam] = yeast();
}
if (!this.supportsBinary && !query.sid) {
query.b64 = 1;
}
query = parseqs.encode(query);
// avoid port if default for schema
if (this.port && (('https' === schema && Number(this.port) !== 443) ||
('http' === schema && Number(this.port) !== 80))) {
port = ':' + this.port;
}
// prepend ? to query
if (query.length) {
query = '?' + query;
}
var ipv6 = this.hostname.indexOf(':') !== -1;
return schema + '://' + (ipv6 ? '[' + this.hostname + ']' : this.hostname) + port + this.path + query;
};

View File

@ -0,0 +1,295 @@
/**
* Module dependencies.
*/
var Transport = require('../transport');
var parser = require('engine.io-parser');
var parseqs = require('parseqs');
var inherit = require('component-inherit');
var yeast = require('yeast');
var debug = require('debug')('engine.io-client:websocket');
var BrowserWebSocket, NodeWebSocket;
if (typeof WebSocket !== 'undefined') {
BrowserWebSocket = WebSocket;
} else if (typeof self !== 'undefined') {
BrowserWebSocket = self.WebSocket || self.MozWebSocket;
}
if (typeof window === 'undefined') {
try {
NodeWebSocket = require('ws');
} catch (e) { }
}
/**
* Get either the `WebSocket` or `MozWebSocket` globals
* in the browser or try to resolve WebSocket-compatible
* interface exposed by `ws` for Node-like environment.
*/
var WebSocketImpl = BrowserWebSocket || NodeWebSocket;
/**
* Module exports.
*/
module.exports = WS;
/**
* WebSocket transport constructor.
*
* @api {Object} connection options
* @api public
*/
function WS (opts) {
var forceBase64 = (opts && opts.forceBase64);
if (forceBase64) {
this.supportsBinary = false;
}
this.perMessageDeflate = opts.perMessageDeflate;
this.usingBrowserWebSocket = BrowserWebSocket && !opts.forceNode;
this.protocols = opts.protocols;
if (!this.usingBrowserWebSocket) {
WebSocketImpl = NodeWebSocket;
}
Transport.call(this, opts);
}
/**
* Inherits from Transport.
*/
inherit(WS, Transport);
/**
* Transport name.
*
* @api public
*/
WS.prototype.name = 'websocket';
/*
* WebSockets support binary
*/
WS.prototype.supportsBinary = true;
/**
* Opens socket.
*
* @api private
*/
WS.prototype.doOpen = function () {
if (!this.check()) {
// let probe timeout
return;
}
var uri = this.uri();
var protocols = this.protocols;
var opts = {
agent: this.agent,
perMessageDeflate: this.perMessageDeflate
};
// SSL options for Node.js client
opts.pfx = this.pfx;
opts.key = this.key;
opts.passphrase = this.passphrase;
opts.cert = this.cert;
opts.ca = this.ca;
opts.ciphers = this.ciphers;
opts.rejectUnauthorized = this.rejectUnauthorized;
if (this.extraHeaders) {
opts.headers = this.extraHeaders;
}
if (this.localAddress) {
opts.localAddress = this.localAddress;
}
try {
this.ws =
this.usingBrowserWebSocket && !this.isReactNative
? protocols
? new WebSocketImpl(uri, protocols)
: new WebSocketImpl(uri)
: new WebSocketImpl(uri, protocols, opts);
} catch (err) {
return this.emit('error', err);
}
if (this.ws.binaryType === undefined) {
this.supportsBinary = false;
}
if (this.ws.supports && this.ws.supports.binary) {
this.supportsBinary = true;
this.ws.binaryType = 'nodebuffer';
} else {
this.ws.binaryType = 'arraybuffer';
}
this.addEventListeners();
};
/**
* Adds event listeners to the socket
*
* @api private
*/
WS.prototype.addEventListeners = function () {
var self = this;
this.ws.onopen = function () {
self.onOpen();
};
this.ws.onclose = function () {
self.onClose();
};
this.ws.onmessage = function (ev) {
self.onData(ev.data);
};
this.ws.onerror = function (e) {
self.onError('websocket error', e);
};
};
/**
* Writes data to socket.
*
* @param {Array} array of packets.
* @api private
*/
WS.prototype.write = function (packets) {
var self = this;
this.writable = false;
// encodePacket efficient as it uses WS framing
// no need for encodePayload
var total = packets.length;
for (var i = 0, l = total; i < l; i++) {
(function (packet) {
parser.encodePacket(packet, self.supportsBinary, function (data) {
if (!self.usingBrowserWebSocket) {
// always create a new object (GH-437)
var opts = {};
if (packet.options) {
opts.compress = packet.options.compress;
}
if (self.perMessageDeflate) {
var len = 'string' === typeof data ? Buffer.byteLength(data) : data.length;
if (len < self.perMessageDeflate.threshold) {
opts.compress = false;
}
}
}
// Sometimes the websocket has already been closed but the browser didn't
// have a chance of informing us about it yet, in that case send will
// throw an error
try {
if (self.usingBrowserWebSocket) {
// TypeError is thrown when passing the second argument on Safari
self.ws.send(data);
} else {
self.ws.send(data, opts);
}
} catch (e) {
debug('websocket closed before onclose event');
}
--total || done();
});
})(packets[i]);
}
function done () {
self.emit('flush');
// fake drain
// defer to next tick to allow Socket to clear writeBuffer
setTimeout(function () {
self.writable = true;
self.emit('drain');
}, 0);
}
};
/**
* Called upon close
*
* @api private
*/
WS.prototype.onClose = function () {
Transport.prototype.onClose.call(this);
};
/**
* Closes socket.
*
* @api private
*/
WS.prototype.doClose = function () {
if (typeof this.ws !== 'undefined') {
this.ws.close();
}
};
/**
* Generates uri for connection.
*
* @api private
*/
WS.prototype.uri = function () {
var query = this.query || {};
var schema = this.secure ? 'wss' : 'ws';
var port = '';
// avoid port if default for schema
if (this.port && (('wss' === schema && Number(this.port) !== 443) ||
('ws' === schema && Number(this.port) !== 80))) {
port = ':' + this.port;
}
// append timestamp to URI
if (this.timestampRequests) {
query[this.timestampParam] = yeast();
}
// communicate binary support capabilities
if (!this.supportsBinary) {
query.b64 = 1;
}
query = parseqs.encode(query);
// prepend ? to query
if (query.length) {
query = '?' + query;
}
var ipv6 = this.hostname.indexOf(':') !== -1;
return schema + '://' + (ipv6 ? '[' + this.hostname + ']' : this.hostname) + port + this.path + query;
};
/**
* Feature detection for WebSocket.
*
* @return {Boolean} whether this transport is available.
* @api public
*/
WS.prototype.check = function () {
return !!WebSocketImpl && !('__initialize' in WebSocketImpl && this.name === WS.prototype.name);
};