aboutsummaryrefslogtreecommitdiffhomepage
path: root/node_modules/socket.io/lib
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/socket.io/lib
downloadspanish-checkers-67fdec20726e48ba3a934cb25bb30d47ec4a4f29.tar.gz
spanish-checkers-67fdec20726e48ba3a934cb25bb30d47ec4a4f29.zip
Initial commit, version 0.5.3
Diffstat (limited to 'node_modules/socket.io/lib')
-rw-r--r--node_modules/socket.io/lib/client.js252
-rw-r--r--node_modules/socket.io/lib/index.js474
-rw-r--r--node_modules/socket.io/lib/namespace.js279
-rw-r--r--node_modules/socket.io/lib/socket.js557
4 files changed, 1562 insertions, 0 deletions
diff --git a/node_modules/socket.io/lib/client.js b/node_modules/socket.io/lib/client.js
new file mode 100644
index 0000000..0b5f044
--- /dev/null
+++ b/node_modules/socket.io/lib/client.js
@@ -0,0 +1,252 @@
+
+/**
+ * Module dependencies.
+ */
+
+var parser = require('socket.io-parser');
+var debug = require('debug')('socket.io:client');
+var url = require('url');
+
+/**
+ * Module exports.
+ */
+
+module.exports = Client;
+
+/**
+ * Client constructor.
+ *
+ * @param {Server} server instance
+ * @param {Socket} conn
+ * @api private
+ */
+
+function Client(server, conn){
+ this.server = server;
+ this.conn = conn;
+ this.encoder = server.encoder;
+ this.decoder = new server.parser.Decoder();
+ this.id = conn.id;
+ this.request = conn.request;
+ this.setup();
+ this.sockets = {};
+ this.nsps = {};
+ this.connectBuffer = [];
+}
+
+/**
+ * Sets up event listeners.
+ *
+ * @api private
+ */
+
+Client.prototype.setup = function(){
+ this.onclose = this.onclose.bind(this);
+ this.ondata = this.ondata.bind(this);
+ this.onerror = this.onerror.bind(this);
+ this.ondecoded = this.ondecoded.bind(this);
+
+ this.decoder.on('decoded', this.ondecoded);
+ this.conn.on('data', this.ondata);
+ this.conn.on('error', this.onerror);
+ this.conn.on('close', this.onclose);
+};
+
+/**
+ * Connects a client to a namespace.
+ *
+ * @param {String} name namespace
+ * @api private
+ */
+
+Client.prototype.connect = function(name, query){
+ debug('connecting to namespace %s', name);
+ var nsp = this.server.nsps[name];
+ if (!nsp) {
+ this.packet({ type: parser.ERROR, nsp: name, data : 'Invalid namespace'});
+ return;
+ }
+
+ if ('/' != name && !this.nsps['/']) {
+ this.connectBuffer.push(name);
+ return;
+ }
+
+ var self = this;
+ var socket = nsp.add(this, query, function(){
+ self.sockets[socket.id] = socket;
+ self.nsps[nsp.name] = socket;
+
+ if ('/' == nsp.name && self.connectBuffer.length > 0) {
+ self.connectBuffer.forEach(self.connect, self);
+ self.connectBuffer = [];
+ }
+ });
+};
+
+/**
+ * Disconnects from all namespaces and closes transport.
+ *
+ * @api private
+ */
+
+Client.prototype.disconnect = function(){
+ for (var id in this.sockets) {
+ if (this.sockets.hasOwnProperty(id)) {
+ this.sockets[id].disconnect();
+ }
+ }
+ this.sockets = {};
+ this.close();
+};
+
+/**
+ * Removes a socket. Called by each `Socket`.
+ *
+ * @api private
+ */
+
+Client.prototype.remove = function(socket){
+ if (this.sockets.hasOwnProperty(socket.id)) {
+ var nsp = this.sockets[socket.id].nsp.name;
+ delete this.sockets[socket.id];
+ delete this.nsps[nsp];
+ } else {
+ debug('ignoring remove for %s', socket.id);
+ }
+};
+
+/**
+ * Closes the underlying connection.
+ *
+ * @api private
+ */
+
+Client.prototype.close = function(){
+ if ('open' == this.conn.readyState) {
+ debug('forcing transport close');
+ this.conn.close();
+ this.onclose('forced server close');
+ }
+};
+
+/**
+ * Writes a packet to the transport.
+ *
+ * @param {Object} packet object
+ * @param {Object} opts
+ * @api private
+ */
+
+Client.prototype.packet = function(packet, opts){
+ opts = opts || {};
+ var self = this;
+
+ // this writes to the actual connection
+ function writeToEngine(encodedPackets) {
+ if (opts.volatile && !self.conn.transport.writable) return;
+ for (var i = 0; i < encodedPackets.length; i++) {
+ self.conn.write(encodedPackets[i], { compress: opts.compress });
+ }
+ }
+
+ if ('open' == this.conn.readyState) {
+ debug('writing packet %j', packet);
+ if (!opts.preEncoded) { // not broadcasting, need to encode
+ this.encoder.encode(packet, writeToEngine); // encode, then write results to engine
+ } else { // a broadcast pre-encodes a packet
+ writeToEngine(packet);
+ }
+ } else {
+ debug('ignoring packet write %j', packet);
+ }
+};
+
+/**
+ * Called with incoming transport data.
+ *
+ * @api private
+ */
+
+Client.prototype.ondata = function(data){
+ // try/catch is needed for protocol violations (GH-1880)
+ try {
+ this.decoder.add(data);
+ } catch(e) {
+ this.onerror(e);
+ }
+};
+
+/**
+ * Called when parser fully decodes a packet.
+ *
+ * @api private
+ */
+
+Client.prototype.ondecoded = function(packet) {
+ if (parser.CONNECT == packet.type) {
+ this.connect(url.parse(packet.nsp).pathname, url.parse(packet.nsp, true).query);
+ } else {
+ var socket = this.nsps[packet.nsp];
+ if (socket) {
+ process.nextTick(function() {
+ socket.onpacket(packet);
+ });
+ } else {
+ debug('no socket for namespace %s', packet.nsp);
+ }
+ }
+};
+
+/**
+ * Handles an error.
+ *
+ * @param {Object} err object
+ * @api private
+ */
+
+Client.prototype.onerror = function(err){
+ for (var id in this.sockets) {
+ if (this.sockets.hasOwnProperty(id)) {
+ this.sockets[id].onerror(err);
+ }
+ }
+ this.conn.close();
+};
+
+/**
+ * Called upon transport close.
+ *
+ * @param {String} reason
+ * @api private
+ */
+
+Client.prototype.onclose = function(reason){
+ debug('client close with reason %s', reason);
+
+ // ignore a potential subsequent `close` event
+ this.destroy();
+
+ // `nsps` and `sockets` are cleaned up seamlessly
+ for (var id in this.sockets) {
+ if (this.sockets.hasOwnProperty(id)) {
+ this.sockets[id].onclose(reason);
+ }
+ }
+ this.sockets = {};
+
+ this.decoder.destroy(); // clean up decoder
+};
+
+/**
+ * Cleans up event listeners.
+ *
+ * @api private
+ */
+
+Client.prototype.destroy = function(){
+ this.conn.removeListener('data', this.ondata);
+ this.conn.removeListener('error', this.onerror);
+ this.conn.removeListener('close', this.onclose);
+ this.decoder.removeListener('decoded', this.ondecoded);
+};
diff --git a/node_modules/socket.io/lib/index.js b/node_modules/socket.io/lib/index.js
new file mode 100644
index 0000000..e16133a
--- /dev/null
+++ b/node_modules/socket.io/lib/index.js
@@ -0,0 +1,474 @@
+
+/**
+ * Module dependencies.
+ */
+
+var http = require('http');
+var read = require('fs').readFileSync;
+var path = require('path');
+var exists = require('fs').existsSync;
+var engine = require('engine.io');
+var clientVersion = require('socket.io-client/package.json').version;
+var Client = require('./client');
+var Emitter = require('events').EventEmitter;
+var Namespace = require('./namespace');
+var Adapter = require('socket.io-adapter');
+var parser = require('socket.io-parser');
+var debug = require('debug')('socket.io:server');
+var url = require('url');
+
+/**
+ * Module exports.
+ */
+
+module.exports = Server;
+
+/**
+ * Socket.IO client source.
+ */
+
+var clientSource = undefined;
+var clientSourceMap = undefined;
+
+/**
+ * Server constructor.
+ *
+ * @param {http.Server|Number|Object} srv http server, port or options
+ * @param {Object} [opts]
+ * @api public
+ */
+
+function Server(srv, opts){
+ if (!(this instanceof Server)) return new Server(srv, opts);
+ if ('object' == typeof srv && srv instanceof Object && !srv.listen) {
+ opts = srv;
+ srv = null;
+ }
+ opts = opts || {};
+ this.nsps = {};
+ this.path(opts.path || '/socket.io');
+ this.serveClient(false !== opts.serveClient);
+ this.parser = opts.parser || parser;
+ this.encoder = new this.parser.Encoder();
+ this.adapter(opts.adapter || Adapter);
+ this.origins(opts.origins || '*:*');
+ this.sockets = this.of('/');
+ if (srv) this.attach(srv, opts);
+}
+
+/**
+ * Server request verification function, that checks for allowed origins
+ *
+ * @param {http.IncomingMessage} req request
+ * @param {Function} fn callback to be called with the result: `fn(err, success)`
+ */
+
+Server.prototype.checkRequest = function(req, fn) {
+ var origin = req.headers.origin || req.headers.referer;
+
+ // file:// URLs produce a null Origin which can't be authorized via echo-back
+ if ('null' == origin || null == origin) origin = '*';
+
+ if (!!origin && typeof(this._origins) == 'function') return this._origins(origin, fn);
+ if (this._origins.indexOf('*:*') !== -1) return fn(null, true);
+ if (origin) {
+ try {
+ var parts = url.parse(origin);
+ var defaultPort = 'https:' == parts.protocol ? 443 : 80;
+ parts.port = parts.port != null
+ ? parts.port
+ : defaultPort;
+ var ok =
+ ~this._origins.indexOf(parts.hostname + ':' + parts.port) ||
+ ~this._origins.indexOf(parts.hostname + ':*') ||
+ ~this._origins.indexOf('*:' + parts.port);
+ return fn(null, !!ok);
+ } catch (ex) {
+ }
+ }
+ fn(null, false);
+};
+
+/**
+ * Sets/gets whether client code is being served.
+ *
+ * @param {Boolean} v whether to serve client code
+ * @return {Server|Boolean} self when setting or value when getting
+ * @api public
+ */
+
+Server.prototype.serveClient = function(v){
+ if (!arguments.length) return this._serveClient;
+ this._serveClient = v;
+ var resolvePath = function(file){
+ var filepath = path.resolve(__dirname, './../../', file);
+ if (exists(filepath)) {
+ return filepath;
+ }
+ return require.resolve(file);
+ };
+ if (v && !clientSource) {
+ clientSource = read(resolvePath( 'socket.io-client/dist/socket.io.js'), 'utf-8');
+ try {
+ clientSourceMap = read(resolvePath( 'socket.io-client/dist/socket.io.js.map'), 'utf-8');
+ } catch(err) {
+ debug('could not load sourcemap file');
+ }
+ }
+ return this;
+};
+
+/**
+ * Old settings for backwards compatibility
+ */
+
+var oldSettings = {
+ "transports": "transports",
+ "heartbeat timeout": "pingTimeout",
+ "heartbeat interval": "pingInterval",
+ "destroy buffer size": "maxHttpBufferSize"
+};
+
+/**
+ * Backwards compatibility.
+ *
+ * @api public
+ */
+
+Server.prototype.set = function(key, val){
+ if ('authorization' == key && val) {
+ this.use(function(socket, next) {
+ val(socket.request, function(err, authorized) {
+ if (err) return next(new Error(err));
+ if (!authorized) return next(new Error('Not authorized'));
+ next();
+ });
+ });
+ } else if ('origins' == key && val) {
+ this.origins(val);
+ } else if ('resource' == key) {
+ this.path(val);
+ } else if (oldSettings[key] && this.eio[oldSettings[key]]) {
+ this.eio[oldSettings[key]] = val;
+ } else {
+ console.error('Option %s is not valid. Please refer to the README.', key);
+ }
+
+ return this;
+};
+
+/**
+ * Sets the client serving path.
+ *
+ * @param {String} v pathname
+ * @return {Server|String} self when setting or value when getting
+ * @api public
+ */
+
+Server.prototype.path = function(v){
+ if (!arguments.length) return this._path;
+ this._path = v.replace(/\/$/, '');
+ return this;
+};
+
+/**
+ * Sets the adapter for rooms.
+ *
+ * @param {Adapter} v pathname
+ * @return {Server|Adapter} self when setting or value when getting
+ * @api public
+ */
+
+Server.prototype.adapter = function(v){
+ if (!arguments.length) return this._adapter;
+ this._adapter = v;
+ for (var i in this.nsps) {
+ if (this.nsps.hasOwnProperty(i)) {
+ this.nsps[i].initAdapter();
+ }
+ }
+ return this;
+};
+
+/**
+ * Sets the allowed origins for requests.
+ *
+ * @param {String} v origins
+ * @return {Server|Adapter} self when setting or value when getting
+ * @api public
+ */
+
+Server.prototype.origins = function(v){
+ if (!arguments.length) return this._origins;
+
+ this._origins = v;
+ return this;
+};
+
+/**
+ * Attaches socket.io to a server or port.
+ *
+ * @param {http.Server|Number} server or port
+ * @param {Object} options passed to engine.io
+ * @return {Server} self
+ * @api public
+ */
+
+Server.prototype.listen =
+Server.prototype.attach = function(srv, opts){
+ if ('function' == typeof srv) {
+ var msg = 'You are trying to attach socket.io to an express ' +
+ 'request handler function. Please pass a http.Server instance.';
+ throw new Error(msg);
+ }
+
+ // handle a port as a string
+ if (Number(srv) == srv) {
+ srv = Number(srv);
+ }
+
+ if ('number' == typeof srv) {
+ debug('creating http server and binding to %d', srv);
+ var port = srv;
+ srv = http.Server(function(req, res){
+ res.writeHead(404);
+ res.end();
+ });
+ srv.listen(port);
+
+ }
+
+ // set engine.io path to `/socket.io`
+ opts = opts || {};
+ opts.path = opts.path || this.path();
+ // set origins verification
+ opts.allowRequest = opts.allowRequest || this.checkRequest.bind(this);
+
+ if (this.sockets.fns.length > 0) {
+ this.initEngine(srv, opts);
+ return this;
+ }
+
+ var self = this;
+ var connectPacket = { type: parser.CONNECT, nsp: '/' };
+ this.encoder.encode(connectPacket, function (encodedPacket){
+ // the CONNECT packet will be merged with Engine.IO handshake,
+ // to reduce the number of round trips
+ opts.initialPacket = encodedPacket;
+
+ self.initEngine(srv, opts);
+ });
+ return this;
+};
+
+/**
+ * Initialize engine
+ *
+ * @param {Object} options passed to engine.io
+ * @api private
+ */
+
+Server.prototype.initEngine = function(srv, opts){
+ // initialize engine
+ debug('creating engine.io instance with opts %j', opts);
+ this.eio = engine.attach(srv, opts);
+
+ // attach static file serving
+ if (this._serveClient) this.attachServe(srv);
+
+ // Export http server
+ this.httpServer = srv;
+
+ // bind to engine events
+ this.bind(this.eio);
+};
+
+/**
+ * Attaches the static file serving.
+ *
+ * @param {Function|http.Server} srv http server
+ * @api private
+ */
+
+Server.prototype.attachServe = function(srv){
+ debug('attaching client serving req handler');
+ var url = this._path + '/socket.io.js';
+ var urlMap = this._path + '/socket.io.js.map';
+ var evs = srv.listeners('request').slice(0);
+ var self = this;
+ srv.removeAllListeners('request');
+ srv.on('request', function(req, res) {
+ if (0 === req.url.indexOf(urlMap)) {
+ self.serveMap(req, res);
+ } else if (0 === req.url.indexOf(url)) {
+ self.serve(req, res);
+ } else {
+ for (var i = 0; i < evs.length; i++) {
+ evs[i].call(srv, req, res);
+ }
+ }
+ });
+};
+
+/**
+ * Handles a request serving `/socket.io.js`
+ *
+ * @param {http.Request} req
+ * @param {http.Response} res
+ * @api private
+ */
+
+Server.prototype.serve = function(req, res){
+ // Per the standard, ETags must be quoted:
+ // https://tools.ietf.org/html/rfc7232#section-2.3
+ var expectedEtag = '"' + clientVersion + '"';
+
+ var etag = req.headers['if-none-match'];
+ if (etag) {
+ if (expectedEtag == etag) {
+ debug('serve client 304');
+ res.writeHead(304);
+ res.end();
+ return;
+ }
+ }
+
+ debug('serve client source');
+ res.setHeader('Content-Type', 'application/javascript');
+ res.setHeader('ETag', expectedEtag);
+ res.writeHead(200);
+ res.end(clientSource);
+};
+
+/**
+ * Handles a request serving `/socket.io.js.map`
+ *
+ * @param {http.Request} req
+ * @param {http.Response} res
+ * @api private
+ */
+
+Server.prototype.serveMap = function(req, res){
+ // Per the standard, ETags must be quoted:
+ // https://tools.ietf.org/html/rfc7232#section-2.3
+ var expectedEtag = '"' + clientVersion + '"';
+
+ var etag = req.headers['if-none-match'];
+ if (etag) {
+ if (expectedEtag == etag) {
+ debug('serve client 304');
+ res.writeHead(304);
+ res.end();
+ return;
+ }
+ }
+
+ debug('serve client sourcemap');
+ res.setHeader('Content-Type', 'application/json');
+ res.setHeader('ETag', expectedEtag);
+ res.writeHead(200);
+ res.end(clientSourceMap);
+};
+
+/**
+ * Binds socket.io to an engine.io instance.
+ *
+ * @param {engine.Server} engine engine.io (or compatible) server
+ * @return {Server} self
+ * @api public
+ */
+
+Server.prototype.bind = function(engine){
+ this.engine = engine;
+ this.engine.on('connection', this.onconnection.bind(this));
+ return this;
+};
+
+/**
+ * Called with each incoming transport connection.
+ *
+ * @param {engine.Socket} conn
+ * @return {Server} self
+ * @api public
+ */
+
+Server.prototype.onconnection = function(conn){
+ debug('incoming connection with id %s', conn.id);
+ var client = new Client(this, conn);
+ client.connect('/');
+ return this;
+};
+
+/**
+ * Looks up a namespace.
+ *
+ * @param {String} name nsp name
+ * @param {Function} [fn] optional, nsp `connection` ev handler
+ * @api public
+ */
+
+Server.prototype.of = function(name, fn){
+ if (String(name)[0] !== '/') name = '/' + name;
+
+ var nsp = this.nsps[name];
+ if (!nsp) {
+ debug('initializing namespace %s', name);
+ nsp = new Namespace(this, name);
+ this.nsps[name] = nsp;
+ }
+ if (fn) nsp.on('connect', fn);
+ return nsp;
+};
+
+/**
+ * Closes server connection
+ *
+ * @param {Function} [fn] optional, called as `fn([err])` on error OR all conns closed
+ * @api public
+ */
+
+Server.prototype.close = function(fn){
+ for (var id in this.nsps['/'].sockets) {
+ if (this.nsps['/'].sockets.hasOwnProperty(id)) {
+ this.nsps['/'].sockets[id].onclose();
+ }
+ }
+
+ this.engine.close();
+
+ if (this.httpServer) {
+ this.httpServer.close(fn);
+ } else {
+ fn && fn();
+ }
+};
+
+/**
+ * Expose main namespace (/).
+ */
+
+var emitterMethods = Object.keys(Emitter.prototype).filter(function(key){
+ return typeof Emitter.prototype[key] === 'function';
+});
+
+emitterMethods.concat(['to', 'in', 'use', 'send', 'write', 'clients', 'compress']).forEach(function(fn){
+ Server.prototype[fn] = function(){
+ return this.sockets[fn].apply(this.sockets, arguments);
+ };
+});
+
+Namespace.flags.forEach(function(flag){
+ Object.defineProperty(Server.prototype, flag, {
+ get: function() {
+ this.sockets.flags = this.sockets.flags || {};
+ this.sockets.flags[flag] = true;
+ return this;
+ }
+ });
+});
+
+/**
+ * BC with `io.listen`
+ */
+
+Server.listen = Server;
diff --git a/node_modules/socket.io/lib/namespace.js b/node_modules/socket.io/lib/namespace.js
new file mode 100644
index 0000000..0b0657b
--- /dev/null
+++ b/node_modules/socket.io/lib/namespace.js
@@ -0,0 +1,279 @@
+
+/**
+ * Module dependencies.
+ */
+
+var Socket = require('./socket');
+var Emitter = require('events').EventEmitter;
+var parser = require('socket.io-parser');
+var debug = require('debug')('socket.io:namespace');
+
+/**
+ * Module exports.
+ */
+
+module.exports = exports = Namespace;
+
+/**
+ * Blacklisted events.
+ */
+
+exports.events = [
+ 'connect', // for symmetry with client
+ 'connection',
+ 'newListener'
+];
+
+/**
+ * Flags.
+ */
+
+exports.flags = [
+ 'json',
+ 'volatile',
+ 'local'
+];
+
+/**
+ * `EventEmitter#emit` reference.
+ */
+
+var emit = Emitter.prototype.emit;
+
+/**
+ * Namespace constructor.
+ *
+ * @param {Server} server instance
+ * @param {Socket} name
+ * @api private
+ */
+
+function Namespace(server, name){
+ this.name = name;
+ this.server = server;
+ this.sockets = {};
+ this.connected = {};
+ this.fns = [];
+ this.ids = 0;
+ this.rooms = [];
+ this.flags = {};
+ this.initAdapter();
+}
+
+/**
+ * Inherits from `EventEmitter`.
+ */
+
+Namespace.prototype.__proto__ = Emitter.prototype;
+
+/**
+ * Apply flags from `Socket`.
+ */
+
+exports.flags.forEach(function(flag){
+ Object.defineProperty(Namespace.prototype, flag, {
+ get: function() {
+ this.flags[flag] = true;
+ return this;
+ }
+ });
+});
+
+/**
+ * Initializes the `Adapter` for this nsp.
+ * Run upon changing adapter by `Server#adapter`
+ * in addition to the constructor.
+ *
+ * @api private
+ */
+
+Namespace.prototype.initAdapter = function(){
+ this.adapter = new (this.server.adapter())(this);
+};
+
+/**
+ * Sets up namespace middleware.
+ *
+ * @return {Namespace} self
+ * @api public
+ */
+
+Namespace.prototype.use = function(fn){
+ if (this.server.eio) {
+ debug('removing initial packet');
+ delete this.server.eio.initialPacket;
+ }
+ this.fns.push(fn);
+ return this;
+};
+
+/**
+ * Executes the middleware for an incoming client.
+ *
+ * @param {Socket} socket that will get added
+ * @param {Function} fn last fn call in the middleware
+ * @api private
+ */
+
+Namespace.prototype.run = function(socket, fn){
+ var fns = this.fns.slice(0);
+ if (!fns.length) return fn(null);
+
+ function run(i){
+ fns[i](socket, function(err){
+ // upon error, short-circuit
+ if (err) return fn(err);
+
+ // if no middleware left, summon callback
+ if (!fns[i + 1]) return fn(null);
+
+ // go on to next
+ run(i + 1);
+ });
+ }
+
+ run(0);
+};
+
+/**
+ * Targets a room when emitting.
+ *
+ * @param {String} name
+ * @return {Namespace} self
+ * @api public
+ */
+
+Namespace.prototype.to =
+Namespace.prototype.in = function(name){
+ if (!~this.rooms.indexOf(name)) this.rooms.push(name);
+ return this;
+};
+
+/**
+ * Adds a new client.
+ *
+ * @return {Socket}
+ * @api private
+ */
+
+Namespace.prototype.add = function(client, query, fn){
+ debug('adding socket to nsp %s', this.name);
+ var socket = new Socket(this, client, query);
+ var self = this;
+ this.run(socket, function(err){
+ process.nextTick(function(){
+ if ('open' == client.conn.readyState) {
+ if (err) return socket.error(err.data || err.message);
+
+ // track socket
+ self.sockets[socket.id] = socket;
+
+ // it's paramount that the internal `onconnect` logic
+ // fires before user-set events to prevent state order
+ // violations (such as a disconnection before the connection
+ // logic is complete)
+ socket.onconnect();
+ if (fn) fn();
+
+ // fire user-set events
+ self.emit('connect', socket);
+ self.emit('connection', socket);
+ } else {
+ debug('next called after client was closed - ignoring socket');
+ }
+ });
+ });
+ return socket;
+};
+
+/**
+ * Removes a client. Called by each `Socket`.
+ *
+ * @api private
+ */
+
+Namespace.prototype.remove = function(socket){
+ if (this.sockets.hasOwnProperty(socket.id)) {
+ delete this.sockets[socket.id];
+ } else {
+ debug('ignoring remove for %s', socket.id);
+ }
+};
+
+/**
+ * Emits to all clients.
+ *
+ * @return {Namespace} self
+ * @api public
+ */
+
+Namespace.prototype.emit = function(ev){
+ if (~exports.events.indexOf(ev)) {
+ emit.apply(this, arguments);
+ return this;
+ }
+ // set up packet object
+ var args = Array.prototype.slice.call(arguments);
+ var packet = { type: parser.EVENT, data: args };
+
+ if ('function' == typeof args[args.length - 1]) {
+ throw new Error('Callbacks are not supported when broadcasting');
+ }
+
+ var rooms = this.rooms.slice(0);
+ var flags = Object.assign({}, this.flags);
+
+ // reset flags
+ this.rooms = [];
+ this.flags = {};
+
+ this.adapter.broadcast(packet, {
+ rooms: rooms,
+ flags: flags
+ });
+
+ return this;
+};
+
+/**
+ * Sends a `message` event to all clients.
+ *
+ * @return {Namespace} self
+ * @api public
+ */
+
+Namespace.prototype.send =
+Namespace.prototype.write = function(){
+ var args = Array.prototype.slice.call(arguments);
+ args.unshift('message');
+ this.emit.apply(this, args);
+ return this;
+};
+
+/**
+ * Gets a list of clients.
+ *
+ * @return {Namespace} self
+ * @api public
+ */
+
+Namespace.prototype.clients = function(fn){
+ this.adapter.clients(this.rooms, fn);
+ // reset rooms for scenario:
+ // .in('room').clients() (GH-1978)
+ this.rooms = [];
+ return this;
+};
+
+/**
+ * Sets the compress flag.
+ *
+ * @param {Boolean} compress if `true`, compresses the sending data
+ * @return {Socket} self
+ * @api public
+ */
+
+Namespace.prototype.compress = function(compress){
+ this.flags.compress = compress;
+ return this;
+};
diff --git a/node_modules/socket.io/lib/socket.js b/node_modules/socket.io/lib/socket.js
new file mode 100644
index 0000000..6c6bcde
--- /dev/null
+++ b/node_modules/socket.io/lib/socket.js
@@ -0,0 +1,557 @@
+
+/**
+ * Module dependencies.
+ */
+
+var Emitter = require('events').EventEmitter;
+var parser = require('socket.io-parser');
+var url = require('url');
+var debug = require('debug')('socket.io:socket');
+
+/**
+ * Module exports.
+ */
+
+module.exports = exports = Socket;
+
+/**
+ * Blacklisted events.
+ *
+ * @api public
+ */
+
+exports.events = [
+ 'error',
+ 'connect',
+ 'disconnect',
+ 'disconnecting',
+ 'newListener',
+ 'removeListener'
+];
+
+/**
+ * Flags.
+ *
+ * @api private
+ */
+
+var flags = [
+ 'json',
+ 'volatile',
+ 'broadcast'
+];
+
+/**
+ * `EventEmitter#emit` reference.
+ */
+
+var emit = Emitter.prototype.emit;
+
+/**
+ * Interface to a `Client` for a given `Namespace`.
+ *
+ * @param {Namespace} nsp
+ * @param {Client} client
+ * @api public
+ */
+
+function Socket(nsp, client, query){
+ this.nsp = nsp;
+ this.server = nsp.server;
+ this.adapter = this.nsp.adapter;
+ this.id = nsp.name !== '/' ? nsp.name + '#' + client.id : client.id;
+ this.client = client;
+ this.conn = client.conn;
+ this.rooms = {};
+ this.acks = {};
+ this.connected = true;
+ this.disconnected = false;
+ this.handshake = this.buildHandshake(query);
+ this.fns = [];
+ this.flags = {};
+ this._rooms = [];
+}
+
+/**
+ * Inherits from `EventEmitter`.
+ */
+
+Socket.prototype.__proto__ = Emitter.prototype;
+
+/**
+ * Apply flags from `Socket`.
+ */
+
+flags.forEach(function(flag){
+ Object.defineProperty(Socket.prototype, flag, {
+ get: function() {
+ this.flags[flag] = true;
+ return this;
+ }
+ });
+});
+
+/**
+ * `request` engine.io shortcut.
+ *
+ * @api public
+ */
+
+Object.defineProperty(Socket.prototype, 'request', {
+ get: function() {
+ return this.conn.request;
+ }
+});
+
+/**
+ * Builds the `handshake` BC object
+ *
+ * @api private
+ */
+
+Socket.prototype.buildHandshake = function(query){
+ var self = this;
+ function buildQuery(){
+ var requestQuery = url.parse(self.request.url, true).query;
+ //if socket-specific query exist, replace query strings in requestQuery
+ return Object.assign({}, query, requestQuery);
+ }
+ return {
+ headers: this.request.headers,
+ time: (new Date) + '',
+ address: this.conn.remoteAddress,
+ xdomain: !!this.request.headers.origin,
+ secure: !!this.request.connection.encrypted,
+ issued: +(new Date),
+ url: this.request.url,
+ query: buildQuery()
+ };
+};
+
+/**
+ * Emits to this client.
+ *
+ * @return {Socket} self
+ * @api public
+ */
+
+Socket.prototype.emit = function(ev){
+ if (~exports.events.indexOf(ev)) {
+ emit.apply(this, arguments);
+ return this;
+ }
+
+ var args = Array.prototype.slice.call(arguments);
+ var packet = {
+ type: parser.EVENT,
+ data: args
+ };
+
+ // access last argument to see if it's an ACK callback
+ if (typeof args[args.length - 1] === 'function') {
+ if (this._rooms.length || this.flags.broadcast) {
+ throw new Error('Callbacks are not supported when broadcasting');
+ }
+
+ debug('emitting packet with ack id %d', this.nsp.ids);
+ this.acks[this.nsp.ids] = args.pop();
+ packet.id = this.nsp.ids++;
+ }
+
+ var rooms = this._rooms.slice(0);
+ var flags = Object.assign({}, this.flags);
+
+ // reset flags
+ this._rooms = [];
+ this.flags = {};
+
+ if (rooms.length || flags.broadcast) {
+ this.adapter.broadcast(packet, {
+ except: [this.id],
+ rooms: rooms,
+ flags: flags
+ });
+ } else {
+ // dispatch packet
+ this.packet(packet, flags);
+ }
+ return this;
+};
+
+/**
+ * Targets a room when broadcasting.
+ *
+ * @param {String} name
+ * @return {Socket} self
+ * @api public
+ */
+
+Socket.prototype.to =
+Socket.prototype.in = function(name){
+ if (!~this._rooms.indexOf(name)) this._rooms.push(name);
+ return this;
+};
+
+/**
+ * Sends a `message` event.
+ *
+ * @return {Socket} self
+ * @api public
+ */
+
+Socket.prototype.send =
+Socket.prototype.write = function(){
+ var args = Array.prototype.slice.call(arguments);
+ args.unshift('message');
+ this.emit.apply(this, args);
+ return this;
+};
+
+/**
+ * Writes a packet.
+ *
+ * @param {Object} packet object
+ * @param {Object} opts options
+ * @api private
+ */
+
+Socket.prototype.packet = function(packet, opts){
+ packet.nsp = this.nsp.name;
+ opts = opts || {};
+ opts.compress = false !== opts.compress;
+ this.client.packet(packet, opts);
+};
+
+/**
+ * Joins a room.
+ *
+ * @param {String|Array} room or array of rooms
+ * @param {Function} fn optional, callback
+ * @return {Socket} self
+ * @api private
+ */
+
+Socket.prototype.join = function(rooms, fn){
+ debug('joining room %s', rooms);
+ var self = this;
+ if (!Array.isArray(rooms)) {
+ rooms = [rooms];
+ }
+ rooms = rooms.filter(function (room) {
+ return !self.rooms.hasOwnProperty(room);
+ });
+ if (!rooms.length) {
+ fn && fn(null);
+ return this;
+ }
+ this.adapter.addAll(this.id, rooms, function(err){
+ if (err) return fn && fn(err);
+ debug('joined room %s', rooms);
+ rooms.forEach(function (room) {
+ self.rooms[room] = room;
+ });
+ fn && fn(null);
+ });
+ return this;
+};
+
+/**
+ * Leaves a room.
+ *
+ * @param {String} room
+ * @param {Function} fn optional, callback
+ * @return {Socket} self
+ * @api private
+ */
+
+Socket.prototype.leave = function(room, fn){
+ debug('leave room %s', room);
+ var self = this;
+ this.adapter.del(this.id, room, function(err){
+ if (err) return fn && fn(err);
+ debug('left room %s', room);
+ delete self.rooms[room];
+ fn && fn(null);
+ });
+ return this;
+};
+
+/**
+ * Leave all rooms.
+ *
+ * @api private
+ */
+
+Socket.prototype.leaveAll = function(){
+ this.adapter.delAll(this.id);
+ this.rooms = {};
+};
+
+/**
+ * Called by `Namespace` upon successful
+ * middleware execution (ie: authorization).
+ * Socket is added to namespace array before
+ * call to join, so adapters can access it.
+ *
+ * @api private
+ */
+
+Socket.prototype.onconnect = function(){
+ debug('socket connected - writing packet');
+ this.nsp.connected[this.id] = this;
+ this.join(this.id);
+ var skip = this.nsp.name === '/' && this.nsp.fns.length === 0;
+ if (skip) {
+ debug('packet already sent in initial handshake');
+ } else {
+ this.packet({ type: parser.CONNECT });
+ }
+};
+
+/**
+ * Called with each packet. Called by `Client`.
+ *
+ * @param {Object} packet
+ * @api private
+ */
+
+Socket.prototype.onpacket = function(packet){
+ debug('got packet %j', packet);
+ switch (packet.type) {
+ case parser.EVENT:
+ this.onevent(packet);
+ break;
+
+ case parser.BINARY_EVENT:
+ this.onevent(packet);
+ break;
+
+ case parser.ACK:
+ this.onack(packet);
+ break;
+
+ case parser.BINARY_ACK:
+ this.onack(packet);
+ break;
+
+ case parser.DISCONNECT:
+ this.ondisconnect();
+ break;
+
+ case parser.ERROR:
+ this.onerror(new Error(packet.data));
+ }
+};
+
+/**
+ * Called upon event packet.
+ *
+ * @param {Object} packet object
+ * @api private
+ */
+
+Socket.prototype.onevent = function(packet){
+ var args = packet.data || [];
+ debug('emitting event %j', args);
+
+ if (null != packet.id) {
+ debug('attaching ack callback to event');
+ args.push(this.ack(packet.id));
+ }
+
+ this.dispatch(args);
+};
+
+/**
+ * Produces an ack callback to emit with an event.
+ *
+ * @param {Number} id packet id
+ * @api private
+ */
+
+Socket.prototype.ack = function(id){
+ var self = this;
+ var sent = false;
+ return function(){
+ // prevent double callbacks
+ if (sent) return;
+ var args = Array.prototype.slice.call(arguments);
+ debug('sending ack %j', args);
+
+ self.packet({
+ id: id,
+ type: parser.ACK,
+ data: args
+ });
+
+ sent = true;
+ };
+};
+
+/**
+ * Called upon ack packet.
+ *
+ * @api private
+ */
+
+Socket.prototype.onack = function(packet){
+ var ack = this.acks[packet.id];
+ if ('function' == typeof ack) {
+ debug('calling ack %s with %j', packet.id, packet.data);
+ ack.apply(this, packet.data);
+ delete this.acks[packet.id];
+ } else {
+ debug('bad ack %s', packet.id);
+ }
+};
+
+/**
+ * Called upon client disconnect packet.
+ *
+ * @api private
+ */
+
+Socket.prototype.ondisconnect = function(){
+ debug('got disconnect packet');
+ this.onclose('client namespace disconnect');
+};
+
+/**
+ * Handles a client error.
+ *
+ * @api private
+ */
+
+Socket.prototype.onerror = function(err){
+ if (this.listeners('error').length) {
+ this.emit('error', err);
+ } else {
+ console.error('Missing error handler on `socket`.');
+ console.error(err.stack);
+ }
+};
+
+/**
+ * Called upon closing. Called by `Client`.
+ *
+ * @param {String} reason
+ * @throw {Error} optional error object
+ * @api private
+ */
+
+Socket.prototype.onclose = function(reason){
+ if (!this.connected) return this;
+ debug('closing socket - reason %s', reason);
+ this.emit('disconnecting', reason);
+ this.leaveAll();
+ this.nsp.remove(this);
+ this.client.remove(this);
+ this.connected = false;
+ this.disconnected = true;
+ delete this.nsp.connected[this.id];
+ this.emit('disconnect', reason);
+};
+
+/**
+ * Produces an `error` packet.
+ *
+ * @param {Object} err error object
+ * @api private
+ */
+
+Socket.prototype.error = function(err){
+ this.packet({ type: parser.ERROR, data: err });
+};
+
+/**
+ * Disconnects this client.
+ *
+ * @param {Boolean} close if `true`, closes the underlying connection
+ * @return {Socket} self
+ * @api public
+ */
+
+Socket.prototype.disconnect = function(close){
+ if (!this.connected) return this;
+ if (close) {
+ this.client.disconnect();
+ } else {
+ this.packet({ type: parser.DISCONNECT });
+ this.onclose('server namespace disconnect');
+ }
+ return this;
+};
+
+/**
+ * Sets the compress flag.
+ *
+ * @param {Boolean} compress if `true`, compresses the sending data
+ * @return {Socket} self
+ * @api public
+ */
+
+Socket.prototype.compress = function(compress){
+ this.flags.compress = compress;
+ return this;
+};
+
+/**
+ * Dispatch incoming event to socket listeners.
+ *
+ * @param {Array} event that will get emitted
+ * @api private
+ */
+
+Socket.prototype.dispatch = function(event){
+ debug('dispatching an event %j', event);
+ var self = this;
+ function dispatchSocket(err) {
+ process.nextTick(function(){
+ if (err) {
+ return self.error(err.data || err.message);
+ }
+ emit.apply(self, event);
+ });
+ }
+ this.run(event, dispatchSocket);
+};
+
+/**
+ * Sets up socket middleware.
+ *
+ * @param {Function} middleware function (event, next)
+ * @return {Socket} self
+ * @api public
+ */
+
+Socket.prototype.use = function(fn){
+ this.fns.push(fn);
+ return this;
+};
+
+/**
+ * Executes the middleware for an incoming event.
+ *
+ * @param {Array} event that will get emitted
+ * @param {Function} last fn call in the middleware
+ * @api private
+ */
+Socket.prototype.run = function(event, fn){
+ var fns = this.fns.slice(0);
+ if (!fns.length) return fn(null);
+
+ function run(i){
+ fns[i](event, function(err){
+ // upon error, short-circuit
+ if (err) return fn(err);
+
+ // if no middleware left, summon callback
+ if (!fns[i + 1]) return fn(null);
+
+ // go on to next
+ run(i + 1);
+ });
+ }
+
+ run(0);
+};