aboutsummaryrefslogtreecommitdiffhomepage
path: root/node_modules/engine.io/lib/transports
diff options
context:
space:
mode:
authorYaroslav De La Peña Smirnov <yaros.rus_89@live.com.mx>2017-11-29 11:44:34 +0300
committerYaroslav De La Peña Smirnov <yaros.rus_89@live.com.mx>2017-11-29 11:44:34 +0300
commit67fdec20726e48ba3a934cb25bb30d47ec4a4f29 (patch)
tree37fd9f4f0b0c20103e1646fc83021e4765de3680 /node_modules/engine.io/lib/transports
downloadspanish-checkers-67fdec20726e48ba3a934cb25bb30d47ec4a4f29.tar.gz
spanish-checkers-67fdec20726e48ba3a934cb25bb30d47ec4a4f29.zip
Initial commit, version 0.5.3
Diffstat (limited to 'node_modules/engine.io/lib/transports')
-rw-r--r--node_modules/engine.io/lib/transports/index.js36
-rw-r--r--node_modules/engine.io/lib/transports/polling-jsonp.js75
-rw-r--r--node_modules/engine.io/lib/transports/polling-xhr.js69
-rw-r--r--node_modules/engine.io/lib/transports/polling.js407
-rw-r--r--node_modules/engine.io/lib/transports/websocket.js134
5 files changed, 721 insertions, 0 deletions
diff --git a/node_modules/engine.io/lib/transports/index.js b/node_modules/engine.io/lib/transports/index.js
new file mode 100644
index 0000000..fcff322
--- /dev/null
+++ b/node_modules/engine.io/lib/transports/index.js
@@ -0,0 +1,36 @@
+
+/**
+ * Module dependencies.
+ */
+
+var XHR = require('./polling-xhr');
+var JSONP = require('./polling-jsonp');
+
+/**
+ * Export transports.
+ */
+
+module.exports = exports = {
+ polling: polling,
+ websocket: require('./websocket')
+};
+
+/**
+ * Export upgrades map.
+ */
+
+exports.polling.upgradesTo = ['websocket'];
+
+/**
+ * Polling polymorphic constructor.
+ *
+ * @api private
+ */
+
+function polling (req) {
+ if ('string' === typeof req._query.j) {
+ return new JSONP(req);
+ } else {
+ return new XHR(req);
+ }
+}
diff --git a/node_modules/engine.io/lib/transports/polling-jsonp.js b/node_modules/engine.io/lib/transports/polling-jsonp.js
new file mode 100644
index 0000000..62e66e7
--- /dev/null
+++ b/node_modules/engine.io/lib/transports/polling-jsonp.js
@@ -0,0 +1,75 @@
+
+/**
+ * Module dependencies.
+ */
+
+var Polling = require('./polling');
+var qs = require('querystring');
+var rDoubleSlashes = /\\\\n/g;
+var rSlashes = /(\\)?\\n/g;
+var util = require('util');
+
+/**
+ * Module exports.
+ */
+
+module.exports = JSONP;
+
+/**
+ * JSON-P polling transport.
+ *
+ * @api public
+ */
+
+function JSONP (req) {
+ Polling.call(this, req);
+
+ this.head = '___eio[' + (req._query.j || '').replace(/[^0-9]/g, '') + '](';
+ this.foot = ');';
+}
+
+/**
+ * Inherits from Polling.
+ */
+
+util.inherits(JSONP, Polling);
+
+/**
+ * Handles incoming data.
+ * Due to a bug in \n handling by browsers, we expect a escaped string.
+ *
+ * @api private
+ */
+
+JSONP.prototype.onData = function (data) {
+ // we leverage the qs module so that we get built-in DoS protection
+ // and the fast alternative to decodeURIComponent
+ data = qs.parse(data).d;
+ if ('string' === typeof data) {
+ // client will send already escaped newlines as \\\\n and newlines as \\n
+ // \\n must be replaced with \n and \\\\n with \\n
+ data = data.replace(rSlashes, function (match, slashes) {
+ return slashes ? match : '\n';
+ });
+ Polling.prototype.onData.call(this, data.replace(rDoubleSlashes, '\\n'));
+ }
+};
+
+/**
+ * Performs the write.
+ *
+ * @api private
+ */
+
+JSONP.prototype.doWrite = function (data, options, callback) {
+ // we must output valid javascript, not valid json
+ // see: http://timelessrepo.com/json-isnt-a-javascript-subset
+ var js = JSON.stringify(data)
+ .replace(/\u2028/g, '\\u2028')
+ .replace(/\u2029/g, '\\u2029');
+
+ // prepare response
+ data = this.head + js + this.foot;
+
+ Polling.prototype.doWrite.call(this, data, options, callback);
+};
diff --git a/node_modules/engine.io/lib/transports/polling-xhr.js b/node_modules/engine.io/lib/transports/polling-xhr.js
new file mode 100644
index 0000000..3562524
--- /dev/null
+++ b/node_modules/engine.io/lib/transports/polling-xhr.js
@@ -0,0 +1,69 @@
+
+/**
+ * Module dependencies.
+ */
+
+var Polling = require('./polling');
+var util = require('util');
+
+/**
+ * Module exports.
+ */
+
+module.exports = XHR;
+
+/**
+ * Ajax polling transport.
+ *
+ * @api public
+ */
+
+function XHR (req) {
+ Polling.call(this, req);
+}
+
+/**
+ * Inherits from Polling.
+ */
+
+util.inherits(XHR, Polling);
+
+/**
+ * Overrides `onRequest` to handle `OPTIONS`..
+ *
+ * @param {http.IncomingMessage}
+ * @api private
+ */
+
+XHR.prototype.onRequest = function (req) {
+ if ('OPTIONS' === req.method) {
+ var res = req.res;
+ var headers = this.headers(req);
+ headers['Access-Control-Allow-Headers'] = 'Content-Type';
+ res.writeHead(200, headers);
+ res.end();
+ } else {
+ Polling.prototype.onRequest.call(this, req);
+ }
+};
+
+/**
+ * Returns headers for a response.
+ *
+ * @param {http.IncomingMessage} request
+ * @param {Object} extra headers
+ * @api private
+ */
+
+XHR.prototype.headers = function (req, headers) {
+ headers = headers || {};
+
+ if (req.headers.origin) {
+ headers['Access-Control-Allow-Credentials'] = 'true';
+ headers['Access-Control-Allow-Origin'] = req.headers.origin;
+ } else {
+ headers['Access-Control-Allow-Origin'] = '*';
+ }
+
+ return Polling.prototype.headers.call(this, req, headers);
+};
diff --git a/node_modules/engine.io/lib/transports/polling.js b/node_modules/engine.io/lib/transports/polling.js
new file mode 100644
index 0000000..6c5c0cc
--- /dev/null
+++ b/node_modules/engine.io/lib/transports/polling.js
@@ -0,0 +1,407 @@
+
+/**
+ * Module requirements.
+ */
+
+var Transport = require('../transport');
+var parser = require('engine.io-parser');
+var zlib = require('zlib');
+var accepts = require('accepts');
+var util = require('util');
+var debug = require('debug')('engine:polling');
+
+var compressionMethods = {
+ gzip: zlib.createGzip,
+ deflate: zlib.createDeflate
+};
+
+/**
+ * Exports the constructor.
+ */
+
+module.exports = Polling;
+
+/**
+ * HTTP polling constructor.
+ *
+ * @api public.
+ */
+
+function Polling (req) {
+ Transport.call(this, req);
+
+ this.closeTimeout = 30 * 1000;
+ this.maxHttpBufferSize = null;
+ this.httpCompression = null;
+}
+
+/**
+ * Inherits from Transport.
+ *
+ * @api public.
+ */
+
+util.inherits(Polling, Transport);
+
+/**
+ * Transport name
+ *
+ * @api public
+ */
+
+Polling.prototype.name = 'polling';
+
+/**
+ * Overrides onRequest.
+ *
+ * @param {http.IncomingMessage}
+ * @api private
+ */
+
+Polling.prototype.onRequest = function (req) {
+ var res = req.res;
+
+ if ('GET' === req.method) {
+ this.onPollRequest(req, res);
+ } else if ('POST' === req.method) {
+ this.onDataRequest(req, res);
+ } else {
+ res.writeHead(500);
+ res.end();
+ }
+};
+
+/**
+ * The client sends a request awaiting for us to send data.
+ *
+ * @api private
+ */
+
+Polling.prototype.onPollRequest = function (req, res) {
+ if (this.req) {
+ debug('request overlap');
+ // assert: this.res, '.req and .res should be (un)set together'
+ this.onError('overlap from client');
+ res.writeHead(500);
+ res.end();
+ return;
+ }
+
+ debug('setting request');
+
+ this.req = req;
+ this.res = res;
+
+ var self = this;
+
+ function onClose () {
+ self.onError('poll connection closed prematurely');
+ }
+
+ function cleanup () {
+ req.removeListener('close', onClose);
+ self.req = self.res = null;
+ }
+
+ req.cleanup = cleanup;
+ req.on('close', onClose);
+
+ this.writable = true;
+ this.emit('drain');
+
+ // if we're still writable but had a pending close, trigger an empty send
+ if (this.writable && this.shouldClose) {
+ debug('triggering empty send to append close packet');
+ this.send([{ type: 'noop' }]);
+ }
+};
+
+/**
+ * The client sends a request with data.
+ *
+ * @api private
+ */
+
+Polling.prototype.onDataRequest = function (req, res) {
+ if (this.dataReq) {
+ // assert: this.dataRes, '.dataReq and .dataRes should be (un)set together'
+ this.onError('data request overlap from client');
+ res.writeHead(500);
+ res.end();
+ return;
+ }
+
+ var isBinary = 'application/octet-stream' === req.headers['content-type'];
+
+ this.dataReq = req;
+ this.dataRes = res;
+
+ var chunks = isBinary ? new Buffer(0) : ''; // eslint-disable-line node/no-deprecated-api
+ var self = this;
+
+ function cleanup () {
+ req.removeListener('data', onData);
+ req.removeListener('end', onEnd);
+ req.removeListener('close', onClose);
+ self.dataReq = self.dataRes = chunks = null;
+ }
+
+ function onClose () {
+ cleanup();
+ self.onError('data request connection closed prematurely');
+ }
+
+ function onData (data) {
+ var contentLength;
+ if (isBinary) {
+ chunks = Buffer.concat([chunks, data]);
+ contentLength = chunks.length;
+ } else {
+ chunks += data;
+ contentLength = Buffer.byteLength(chunks);
+ }
+
+ if (contentLength > self.maxHttpBufferSize) {
+ chunks = isBinary ? new Buffer(0) : ''; // eslint-disable-line node/no-deprecated-api
+ req.connection.destroy();
+ }
+ }
+
+ function onEnd () {
+ self.onData(chunks);
+
+ var headers = {
+ // text/html is required instead of text/plain to avoid an
+ // unwanted download dialog on certain user-agents (GH-43)
+ 'Content-Type': 'text/html',
+ 'Content-Length': 2
+ };
+
+ res.writeHead(200, self.headers(req, headers));
+ res.end('ok');
+ cleanup();
+ }
+
+ req.on('close', onClose);
+ if (!isBinary) req.setEncoding('utf8');
+ req.on('data', onData);
+ req.on('end', onEnd);
+};
+
+/**
+ * Processes the incoming data payload.
+ *
+ * @param {String} encoded payload
+ * @api private
+ */
+
+Polling.prototype.onData = function (data) {
+ debug('received "%s"', data);
+ var self = this;
+ var callback = function (packet) {
+ if ('close' === packet.type) {
+ debug('got xhr close packet');
+ self.onClose();
+ return false;
+ }
+
+ self.onPacket(packet);
+ };
+
+ parser.decodePayload(data, callback);
+};
+
+/**
+ * Overrides onClose.
+ *
+ * @api private
+ */
+
+Polling.prototype.onClose = function () {
+ if (this.writable) {
+ // close pending poll request
+ this.send([{ type: 'noop' }]);
+ }
+ Transport.prototype.onClose.call(this);
+};
+
+/**
+ * Writes a packet payload.
+ *
+ * @param {Object} packet
+ * @api private
+ */
+
+Polling.prototype.send = function (packets) {
+ this.writable = false;
+
+ if (this.shouldClose) {
+ debug('appending close packet to payload');
+ packets.push({ type: 'close' });
+ this.shouldClose();
+ this.shouldClose = null;
+ }
+
+ var self = this;
+ parser.encodePayload(packets, this.supportsBinary, function (data) {
+ var compress = packets.some(function (packet) {
+ return packet.options && packet.options.compress;
+ });
+ self.write(data, { compress: compress });
+ });
+};
+
+/**
+ * Writes data as response to poll request.
+ *
+ * @param {String} data
+ * @param {Object} options
+ * @api private
+ */
+
+Polling.prototype.write = function (data, options) {
+ debug('writing "%s"', data);
+ var self = this;
+ this.doWrite(data, options, function () {
+ self.req.cleanup();
+ });
+};
+
+/**
+ * Performs the write.
+ *
+ * @api private
+ */
+
+Polling.prototype.doWrite = function (data, options, callback) {
+ var self = this;
+
+ // explicit UTF-8 is required for pages not served under utf
+ var isString = typeof data === 'string';
+ var contentType = isString
+ ? 'text/plain; charset=UTF-8'
+ : 'application/octet-stream';
+
+ var headers = {
+ 'Content-Type': contentType
+ };
+
+ if (!this.httpCompression || !options.compress) {
+ respond(data);
+ return;
+ }
+
+ var len = isString ? Buffer.byteLength(data) : data.length;
+ if (len < this.httpCompression.threshold) {
+ respond(data);
+ return;
+ }
+
+ var encoding = accepts(this.req).encodings(['gzip', 'deflate']);
+ if (!encoding) {
+ respond(data);
+ return;
+ }
+
+ this.compress(data, encoding, function (err, data) {
+ if (err) {
+ self.res.writeHead(500);
+ self.res.end();
+ callback(err);
+ return;
+ }
+
+ headers['Content-Encoding'] = encoding;
+ respond(data);
+ });
+
+ function respond (data) {
+ headers['Content-Length'] = 'string' === typeof data ? Buffer.byteLength(data) : data.length;
+ self.res.writeHead(200, self.headers(self.req, headers));
+ self.res.end(data);
+ callback();
+ }
+};
+
+/**
+ * Compresses data.
+ *
+ * @api private
+ */
+
+Polling.prototype.compress = function (data, encoding, callback) {
+ debug('compressing');
+
+ var buffers = [];
+ var nread = 0;
+
+ compressionMethods[encoding](this.httpCompression)
+ .on('error', callback)
+ .on('data', function (chunk) {
+ buffers.push(chunk);
+ nread += chunk.length;
+ })
+ .on('end', function () {
+ callback(null, Buffer.concat(buffers, nread));
+ })
+ .end(data);
+};
+
+/**
+ * Closes the transport.
+ *
+ * @api private
+ */
+
+Polling.prototype.doClose = function (fn) {
+ debug('closing');
+
+ var self = this;
+ var closeTimeoutTimer;
+
+ if (this.dataReq) {
+ debug('aborting ongoing data request');
+ this.dataReq.destroy();
+ }
+
+ if (this.writable) {
+ debug('transport writable - closing right away');
+ this.send([{ type: 'close' }]);
+ onClose();
+ } else if (this.discarded) {
+ debug('transport discarded - closing right away');
+ onClose();
+ } else {
+ debug('transport not writable - buffering orderly close');
+ this.shouldClose = onClose;
+ closeTimeoutTimer = setTimeout(onClose, this.closeTimeout);
+ }
+
+ function onClose () {
+ clearTimeout(closeTimeoutTimer);
+ fn();
+ self.onClose();
+ }
+};
+
+/**
+ * Returns headers for a response.
+ *
+ * @param {http.IncomingMessage} request
+ * @param {Object} extra headers
+ * @api private
+ */
+
+Polling.prototype.headers = function (req, headers) {
+ headers = headers || {};
+
+ // prevent XSS warnings on IE
+ // https://github.com/LearnBoost/socket.io/pull/1333
+ var ua = req.headers['user-agent'];
+ if (ua && (~ua.indexOf(';MSIE') || ~ua.indexOf('Trident/'))) {
+ headers['X-XSS-Protection'] = '0';
+ }
+
+ this.emit('headers', headers);
+ return headers;
+};
diff --git a/node_modules/engine.io/lib/transports/websocket.js b/node_modules/engine.io/lib/transports/websocket.js
new file mode 100644
index 0000000..7d5511b
--- /dev/null
+++ b/node_modules/engine.io/lib/transports/websocket.js
@@ -0,0 +1,134 @@
+
+/**
+ * Module dependencies.
+ */
+
+var Transport = require('../transport');
+var parser = require('engine.io-parser');
+var util = require('util');
+var debug = require('debug')('engine:ws');
+
+/**
+ * Export the constructor.
+ */
+
+module.exports = WebSocket;
+
+/**
+ * WebSocket transport
+ *
+ * @param {http.IncomingMessage}
+ * @api public
+ */
+
+function WebSocket (req) {
+ Transport.call(this, req);
+ var self = this;
+ this.socket = req.websocket;
+ this.socket.on('message', this.onData.bind(this));
+ this.socket.once('close', this.onClose.bind(this));
+ this.socket.on('error', this.onError.bind(this));
+ this.socket.on('headers', onHeaders);
+ this.writable = true;
+ this.perMessageDeflate = null;
+
+ function onHeaders (headers) {
+ self.emit('headers', headers);
+ }
+}
+
+/**
+ * Inherits from Transport.
+ */
+
+util.inherits(WebSocket, Transport);
+
+/**
+ * Transport name
+ *
+ * @api public
+ */
+
+WebSocket.prototype.name = 'websocket';
+
+/**
+ * Advertise upgrade support.
+ *
+ * @api public
+ */
+
+WebSocket.prototype.handlesUpgrades = true;
+
+/**
+ * Advertise framing support.
+ *
+ * @api public
+ */
+
+WebSocket.prototype.supportsFraming = true;
+
+/**
+ * Processes the incoming data.
+ *
+ * @param {String} encoded packet
+ * @api private
+ */
+
+WebSocket.prototype.onData = function (data) {
+ debug('received "%s"', data);
+ Transport.prototype.onData.call(this, data);
+};
+
+/**
+ * Writes a packet payload.
+ *
+ * @param {Array} packets
+ * @api private
+ */
+
+WebSocket.prototype.send = function (packets) {
+ var self = this;
+
+ for (var i = 0; i < packets.length; i++) {
+ var packet = packets[i];
+ parser.encodePacket(packet, self.supportsBinary, send);
+ }
+
+ function send (data) {
+ debug('writing "%s"', data);
+
+ // always creates a new object since ws modifies it
+ 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;
+ }
+ }
+
+ self.writable = false;
+ self.socket.send(data, opts, onEnd);
+ }
+
+ function onEnd (err) {
+ if (err) return self.onError('write error', err.stack);
+ self.writable = true;
+ self.emit('drain');
+ }
+};
+
+/**
+ * Closes the transport.
+ *
+ * @api private
+ */
+
+WebSocket.prototype.doClose = function (fn) {
+ debug('closing');
+ this.socket.close();
+ fn && fn();
+};