diff --git a/.eslintrc.json b/.eslintrc.json index 6d3c020b6..082c0cb59 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,10 +1,4 @@ { - "extends": "standard", - "parser": "babel-eslint", - "rules": { - "yoda": 0, - "semi": [2, "always"], - "no-extra-semi": 2, - "semi-spacing": [2, { "before": false, "after": true }] - } + "extends": "prettier", + "parser": "babel-eslint" } diff --git a/lib/engine.io.js b/lib/engine.io.js index 6fe013880..2c1ce9d10 100644 --- a/lib/engine.io.js +++ b/lib/engine.io.js @@ -2,8 +2,8 @@ * Module dependencies. */ -const http = require('http'); -const Server = require('./server'); +const http = require("http"); +const Server = require("./server"); /** * Invoking the library as a function delegates to attach if the first argument @@ -18,7 +18,7 @@ const Server = require('./server'); * @api public */ -exports = module.exports = function () { +exports = module.exports = function() { // backwards compatible use as `.attach` // if first argument is an http server if (arguments.length && arguments[0] instanceof http.Server) { @@ -51,7 +51,7 @@ exports.Server = Server; * @api public */ -exports.Socket = require('./socket'); +exports.Socket = require("./socket"); /** * Expose Transport constructor. @@ -59,7 +59,7 @@ exports.Socket = require('./socket'); * @api public */ -exports.Transport = require('./transport'); +exports.Transport = require("./transport"); /** * Expose mutable list of available transports. @@ -67,7 +67,7 @@ exports.Transport = require('./transport'); * @api public */ -exports.transports = require('./transports'); +exports.transports = require("./transports"); /** * Exports parser. @@ -75,7 +75,7 @@ exports.transports = require('./transports'); * @api public */ -exports.parser = require('engine.io-parser'); +exports.parser = require("engine.io-parser"); /** * Creates an http.Server exclusively used for WS upgrades. @@ -89,15 +89,15 @@ exports.parser = require('engine.io-parser'); exports.listen = listen; -function listen (port, options, fn) { - if ('function' === typeof options) { +function listen(port, options, fn) { + if ("function" === typeof options) { fn = options; options = {}; } - const server = http.createServer(function (req, res) { + const server = http.createServer(function(req, res) { res.writeHead(501); - res.end('Not Implemented'); + res.end("Not Implemented"); }); // create engine server @@ -120,7 +120,7 @@ function listen (port, options, fn) { exports.attach = attach; -function attach (server, options) { +function attach(server, options) { const engine = new Server(options); engine.attach(server, options); return engine; diff --git a/lib/server.js b/lib/server.js index 2922c6323..89eaf606d 100644 --- a/lib/server.js +++ b/lib/server.js @@ -1,11 +1,11 @@ -const qs = require('querystring'); -const parse = require('url').parse; -const base64id = require('base64id'); -const transports = require('./transports'); -const EventEmitter = require('events').EventEmitter; -const Socket = require('./socket'); -const debug = require('debug')('engine'); -const cookieMod = require('cookie'); +const qs = require("querystring"); +const parse = require("url").parse; +const base64id = require("base64id"); +const transports = require("./transports"); +const EventEmitter = require("events").EventEmitter; +const Socket = require("./socket"); +const debug = require("debug")("engine"); +const cookieMod = require("cookie"); class Server extends EventEmitter { /** @@ -14,7 +14,7 @@ class Server extends EventEmitter { * @param {Object} options * @api public */ - constructor (opts) { + constructor(opts) { super(); this.clients = {}; @@ -22,23 +22,26 @@ class Server extends EventEmitter { opts = opts || {}; - this.wsEngine = opts.wsEngine || process.env.EIO_WS_ENGINE || 'ws'; + this.wsEngine = opts.wsEngine || process.env.EIO_WS_ENGINE || "ws"; this.pingTimeout = opts.pingTimeout || 5000; this.pingInterval = opts.pingInterval || 25000; this.upgradeTimeout = opts.upgradeTimeout || 10000; - this.maxHttpBufferSize = opts.maxHttpBufferSize || 10E7; + this.maxHttpBufferSize = opts.maxHttpBufferSize || 10e7; this.transports = opts.transports || Object.keys(transports); this.allowUpgrades = false !== opts.allowUpgrades; this.allowRequest = opts.allowRequest; - this.cookie = false !== opts.cookie ? (opts.cookie || 'io') : false; - this.cookiePath = false !== opts.cookiePath ? (opts.cookiePath || '/') : false; + this.cookie = false !== opts.cookie ? opts.cookie || "io" : false; + this.cookiePath = + false !== opts.cookiePath ? opts.cookiePath || "/" : false; this.cookieHttpOnly = false !== opts.cookieHttpOnly; - this.perMessageDeflate = false !== opts.perMessageDeflate ? (opts.perMessageDeflate || true) : false; - this.httpCompression = false !== opts.httpCompression ? (opts.httpCompression || {}) : false; + this.perMessageDeflate = + false !== opts.perMessageDeflate ? opts.perMessageDeflate || true : false; + this.httpCompression = + false !== opts.httpCompression ? opts.httpCompression || {} : false; this.initialPacket = opts.initialPacket; // initialize compression options - ['perMessageDeflate', 'httpCompression'].forEach((type) => { + ["perMessageDeflate", "httpCompression"].forEach(type => { let compression = this[type]; if (true === compression) this[type] = compression = {}; if (compression && null == compression.threshold) { @@ -54,16 +57,21 @@ class Server extends EventEmitter { * * @api private */ - init () { - if (!~this.transports.indexOf('websocket')) return; + init() { + if (!~this.transports.indexOf("websocket")) return; if (this.ws) this.ws.close(); let wsModule; switch (this.wsEngine) { - case 'uws': wsModule = require('uws'); break; - case 'ws': wsModule = require('ws'); break; - default: throw new Error('unknown wsEngine'); + case "uws": + wsModule = require("uws"); + break; + case "ws": + wsModule = require("ws"); + break; + default: + throw new Error("unknown wsEngine"); } this.ws = new wsModule.Server({ noServer: true, @@ -79,7 +87,7 @@ class Server extends EventEmitter { * @return {Array} * @api public */ - upgrades (transport) { + upgrades(transport) { if (!this.allowUpgrades) return []; return transports[transport].upgradesTo || []; } @@ -91,7 +99,7 @@ class Server extends EventEmitter { * @return {Boolean} whether the request is valid * @api private */ - verify (req, upgrade, fn) { + verify(req, upgrade, fn) { // transport check const transport = req._query.transport; if (!~this.transports.indexOf(transport)) { @@ -103,7 +111,7 @@ class Server extends EventEmitter { const isOriginInvalid = checkInvalidHeaderChar(req.headers.origin); if (isOriginInvalid) { req.headers.origin = null; - debug('origin header invalid'); + debug("origin header invalid"); return fn(Server.errors.BAD_REQUEST, false); } @@ -115,12 +123,13 @@ class Server extends EventEmitter { return fn(Server.errors.UNKNOWN_SID, false); } if (!upgrade && this.clients[sid].transport.name !== transport) { - debug('bad request: unexpected transport without upgrade'); + debug("bad request: unexpected transport without upgrade"); return fn(Server.errors.BAD_REQUEST, false); } } else { // handshake is GET only - if ('GET' !== req.method) return fn(Server.errors.BAD_HANDSHAKE_METHOD, false); + if ("GET" !== req.method) + return fn(Server.errors.BAD_HANDSHAKE_METHOD, false); if (!this.allowRequest) return fn(null, true); return this.allowRequest(req, fn); } @@ -133,10 +142,10 @@ class Server extends EventEmitter { * * @api private */ - prepare (req) { + prepare(req) { // try to leverage pre-existing `req._query` (e.g: from connect) if (!req._query) { - req._query = ~req.url.indexOf('?') ? qs.parse(parse(req.url).query) : {}; + req._query = ~req.url.indexOf("?") ? qs.parse(parse(req.url).query) : {}; } } @@ -145,15 +154,15 @@ class Server extends EventEmitter { * * @api public */ - close () { - debug('closing all open clients'); + close() { + debug("closing all open clients"); for (let i in this.clients) { if (this.clients.hasOwnProperty(i)) { this.clients[i].close(true); } } if (this.ws) { - debug('closing webSocketServer'); + debug("closing webSocketServer"); this.ws.close(); // don't delete this.ws because it can be used again if the http server starts listening again } @@ -167,20 +176,20 @@ class Server extends EventEmitter { * @param {http.ServerResponse|http.OutgoingMessage} response * @api public */ - handleRequest (req, res) { + handleRequest(req, res) { debug('handling "%s" http request "%s"', req.method, req.url); this.prepare(req); req.res = res; const self = this; - this.verify(req, false, function (err, success) { + this.verify(req, false, function(err, success) { if (!success) { sendErrorMessage(req, res, err); return; } if (req._query.sid) { - debug('setting new request for existing client'); + debug("setting new request for existing client"); self.clients[req._query.sid].transport.onRequest(req); } else { self.handshake(req._query.transport, req); @@ -195,7 +204,7 @@ class Server extends EventEmitter { * @param {Object} request object * @api public */ - generateId (req) { + generateId(req) { return base64id.generateId(); } @@ -206,17 +215,17 @@ class Server extends EventEmitter { * @param {Object} request object * @api private */ - handshake (transportName, req) { + handshake(transportName, req) { const id = this.generateId(req); debug('handshaking client "%s"', id); try { var transport = new transports[transportName](req); - if ('polling' === transportName) { + if ("polling" === transportName) { transport.maxHttpBufferSize = this.maxHttpBufferSize; transport.httpCompression = this.httpCompression; - } else if ('websocket' === transportName) { + } else if ("websocket" === transportName) { transport.perMessageDeflate = this.perMessageDeflate; } @@ -234,12 +243,11 @@ class Server extends EventEmitter { const self = this; if (false !== this.cookie) { - transport.on('headers', function (headers) { - headers['Set-Cookie'] = cookieMod.serialize(self.cookie, id, - { - path: self.cookiePath, - httpOnly: self.cookiePath ? self.cookieHttpOnly : false - }); + transport.on("headers", function(headers) { + headers["Set-Cookie"] = cookieMod.serialize(self.cookie, id, { + path: self.cookiePath, + httpOnly: self.cookiePath ? self.cookieHttpOnly : false + }); }); } @@ -248,12 +256,12 @@ class Server extends EventEmitter { this.clients[id] = socket; this.clientsCount++; - socket.once('close', function () { + socket.once("close", function() { delete self.clients[id]; self.clientsCount--; }); - this.emit('connection', socket); + this.emit("connection", socket); } /** @@ -261,11 +269,11 @@ class Server extends EventEmitter { * * @api public */ - handleUpgrade (req, socket, upgradeHead) { + handleUpgrade(req, socket, upgradeHead) { this.prepare(req); const self = this; - this.verify(req, true, function (err, success) { + this.verify(req, true, function(err, success) { if (!success) { abortConnection(socket, err); return; @@ -275,7 +283,7 @@ class Server extends EventEmitter { upgradeHead = null; // delegate to ws - self.ws.handleUpgrade(req, socket, head, function (conn) { + self.ws.handleUpgrade(req, socket, head, function(conn) { self.onWebSocket(req, conn); }); }); @@ -287,11 +295,14 @@ class Server extends EventEmitter { * @param {ws.Socket} websocket * @api private */ - onWebSocket (req, socket) { - socket.on('error', onUpgradeError); - - if (transports[req._query.transport] !== undefined && !transports[req._query.transport].prototype.handlesUpgrades) { - debug('transport doesnt handle upgraded requests'); + onWebSocket(req, socket) { + socket.on("error", onUpgradeError); + + if ( + transports[req._query.transport] !== undefined && + !transports[req._query.transport].prototype.handlesUpgrades + ) { + debug("transport doesnt handle upgraded requests"); socket.close(); return; } @@ -305,19 +316,19 @@ class Server extends EventEmitter { if (id) { const client = this.clients[id]; if (!client) { - debug('upgrade attempt for closed client'); + debug("upgrade attempt for closed client"); socket.close(); } else if (client.upgrading) { - debug('transport has already been trying to upgrade'); + debug("transport has already been trying to upgrade"); socket.close(); } else if (client.upgraded) { - debug('transport had already been upgraded'); + debug("transport had already been upgraded"); socket.close(); } else { - debug('upgrading existing transport'); + debug("upgrading existing transport"); // transport error handling takes over - socket.removeListener('error', onUpgradeError); + socket.removeListener("error", onUpgradeError); const transport = new transports[req._query.transport](req); if (req._query && req._query.b64) { @@ -330,13 +341,13 @@ class Server extends EventEmitter { } } else { // transport error handling takes over - socket.removeListener('error', onUpgradeError); + socket.removeListener("error", onUpgradeError); this.handshake(req._query.transport, req); } - function onUpgradeError () { - debug('websocket error before upgrade'); + function onUpgradeError() { + debug("websocket error before upgrade"); // socket.close() not needed } } @@ -348,34 +359,40 @@ class Server extends EventEmitter { * @param {Object} options * @api public */ - attach (server, options) { + attach(server, options) { const self = this; options = options || {}; - let path = (options.path || '/engine.io').replace(/\/$/, ''); + let path = (options.path || "/engine.io").replace(/\/$/, ""); const destroyUpgradeTimeout = options.destroyUpgradeTimeout || 1000; // normalize path - path += '/'; + path += "/"; - function check (req) { - if ('OPTIONS' === req.method && false === options.handlePreflightRequest) { + function check(req) { + if ( + "OPTIONS" === req.method && + false === options.handlePreflightRequest + ) { return false; } return path === req.url.substr(0, path.length); } // cache and clean up listeners - const listeners = server.listeners('request').slice(0); - server.removeAllListeners('request'); - server.on('close', self.close.bind(self)); - server.on('listening', self.init.bind(self)); + const listeners = server.listeners("request").slice(0); + server.removeAllListeners("request"); + server.on("close", self.close.bind(self)); + server.on("listening", self.init.bind(self)); // add request handler - server.on('request', function (req, res) { + server.on("request", function(req, res) { if (check(req)) { debug('intercepting request for path "%s"', path); - if ('OPTIONS' === req.method && 'function' === typeof options.handlePreflightRequest) { + if ( + "OPTIONS" === req.method && + "function" === typeof options.handlePreflightRequest + ) { options.handlePreflightRequest.call(server, req, res); } else { self.handleRequest(req, res); @@ -389,8 +406,8 @@ class Server extends EventEmitter { } }); - if (~self.transports.indexOf('websocket')) { - server.on('upgrade', function (req, socket, head) { + if (~self.transports.indexOf("websocket")) { + server.on("upgrade", function(req, socket, head) { if (check(req)) { self.handleUpgrade(req, socket, head); } else if (false !== options.destroyUpgrade) { @@ -398,7 +415,7 @@ class Server extends EventEmitter { // but by adding a handler, we prevent that // and if no eio thing handles the upgrade // then the socket needs to die! - setTimeout(function () { + setTimeout(function() { if (socket.writable && socket.bytesWritten <= 0) { return socket.end(); } @@ -422,11 +439,11 @@ Server.errors = { }; Server.errorMessages = { - 0: 'Transport unknown', - 1: 'Session ID unknown', - 2: 'Bad handshake method', - 3: 'Bad request', - 4: 'Forbidden' + 0: "Transport unknown", + 1: "Session ID unknown", + 2: "Bad handshake method", + 3: "Bad request", + 4: "Forbidden" }; /** @@ -437,30 +454,34 @@ Server.errorMessages = { * @api private */ -function sendErrorMessage (req, res, code) { - const headers = {'Content-Type': 'application/json'}; +function sendErrorMessage(req, res, code) { + const headers = { "Content-Type": "application/json" }; const isForbidden = !Server.errorMessages.hasOwnProperty(code); if (isForbidden) { res.writeHead(403, headers); - res.end(JSON.stringify({ - code: Server.errors.FORBIDDEN, - message: code || Server.errorMessages[Server.errors.FORBIDDEN] - })); + res.end( + JSON.stringify({ + code: Server.errors.FORBIDDEN, + message: code || Server.errorMessages[Server.errors.FORBIDDEN] + }) + ); return; } if (req.headers.origin) { - headers['Access-Control-Allow-Credentials'] = 'true'; - headers['Access-Control-Allow-Origin'] = req.headers.origin; + headers["Access-Control-Allow-Credentials"] = "true"; + headers["Access-Control-Allow-Origin"] = req.headers.origin; } else { - headers['Access-Control-Allow-Origin'] = '*'; + headers["Access-Control-Allow-Origin"] = "*"; } if (res !== undefined) { res.writeHead(400, headers); - res.end(JSON.stringify({ - code: code, - message: Server.errorMessages[code] - })); + res.end( + JSON.stringify({ + code: code, + message: Server.errorMessages[code] + }) + ); } } @@ -472,17 +493,21 @@ function sendErrorMessage (req, res, code) { * @api private */ -function abortConnection (socket, code) { +function abortConnection(socket, code) { if (socket.writable) { - const message = Server.errorMessages.hasOwnProperty(code) ? Server.errorMessages[code] : String(code || ''); + const message = Server.errorMessages.hasOwnProperty(code) + ? Server.errorMessages[code] + : String(code || ""); const length = Buffer.byteLength(message); socket.write( - 'HTTP/1.1 400 Bad Request\r\n' + - 'Connection: close\r\n' + - 'Content-type: text/html\r\n' + - 'Content-Length: ' + length + '\r\n' + - '\r\n' + - message + "HTTP/1.1 400 Bad Request\r\n" + + "Connection: close\r\n" + + "Content-type: text/html\r\n" + + "Content-Length: " + + length + + "\r\n" + + "\r\n" + + message ); } socket.destroy(); @@ -504,6 +529,7 @@ module.exports = Server; * so take care when making changes to the implementation so that the source * code size does not exceed v8's default max_inlined_source_size setting. **/ +// prettier-ignore const validHdrChars = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, // 0 - 15 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16 - 31 @@ -524,27 +550,23 @@ const validHdrChars = [ ] function checkInvalidHeaderChar(val) { - val += ''; - if (val.length < 1) - return false; + val += ""; + if (val.length < 1) return false; if (!validHdrChars[val.charCodeAt(0)]) { debug('invalid header, index 0, char "%s"', val.charCodeAt(0)); return true; } - if (val.length < 2) - return false; + if (val.length < 2) return false; if (!validHdrChars[val.charCodeAt(1)]) { debug('invalid header, index 1, char "%s"', val.charCodeAt(1)); return true; } - if (val.length < 3) - return false; + if (val.length < 3) return false; if (!validHdrChars[val.charCodeAt(2)]) { debug('invalid header, index 2, char "%s"', val.charCodeAt(2)); return true; } - if (val.length < 4) - return false; + if (val.length < 4) return false; if (!validHdrChars[val.charCodeAt(3)]) { debug('invalid header, index 3, char "%s"', val.charCodeAt(3)); return true; diff --git a/lib/socket.js b/lib/socket.js index 415a65a1d..97de8b6df 100644 --- a/lib/socket.js +++ b/lib/socket.js @@ -1,5 +1,5 @@ -const EventEmitter = require('events'); -const debug = require('debug')('engine:socket'); +const EventEmitter = require("events"); +const debug = require("debug")("engine:socket"); class Socket extends EventEmitter { /** @@ -7,13 +7,13 @@ class Socket extends EventEmitter { * * @api private */ - constructor (id, server, transport, req) { + constructor(id, server, transport, req) { super(); this.id = id; this.server = server; this.upgrading = false; this.upgraded = false; - this.readyState = 'opening'; + this.readyState = "opening"; this.writeBuffer = []; this.packetsFn = []; this.sentCallbackFn = []; @@ -40,23 +40,26 @@ class Socket extends EventEmitter { * * @api private */ - onOpen () { - this.readyState = 'open'; + onOpen() { + this.readyState = "open"; // sends an `open` packet this.transport.sid = this.id; - this.sendPacket('open', JSON.stringify({ - sid: this.id, - upgrades: this.getAvailableUpgrades(), - pingInterval: this.server.pingInterval, - pingTimeout: this.server.pingTimeout - })); + this.sendPacket( + "open", + JSON.stringify({ + sid: this.id, + upgrades: this.getAvailableUpgrades(), + pingInterval: this.server.pingInterval, + pingTimeout: this.server.pingTimeout + }) + ); if (this.server.initialPacket) { - this.sendPacket('message', this.server.initialPacket); + this.sendPacket("message", this.server.initialPacket); } - this.emit('open'); + this.emit("open"); this.setPingTimeout(); } @@ -66,34 +69,34 @@ class Socket extends EventEmitter { * @param {Object} packet * @api private */ - onPacket (packet) { - if ('open' === this.readyState) { + onPacket(packet) { + if ("open" === this.readyState) { // export packet event - debug('packet'); - this.emit('packet', packet); + debug("packet"); + this.emit("packet", packet); // Reset ping timeout on any packet, incoming data is a good sign of // other side's liveness this.setPingTimeout(); switch (packet.type) { - case 'ping': - debug('got ping'); - this.sendPacket('pong'); - this.emit('heartbeat'); + case "ping": + debug("got ping"); + this.sendPacket("pong"); + this.emit("heartbeat"); break; - case 'error': - this.onClose('parse error'); + case "error": + this.onClose("parse error"); break; - case 'message': - this.emit('data', packet.data); - this.emit('message', packet.data); + case "message": + this.emit("data", packet.data); + this.emit("message", packet.data); break; } } else { - debug('packet received with closed socket'); + debug("packet received with closed socket"); } } @@ -103,9 +106,9 @@ class Socket extends EventEmitter { * @param {Error} error object * @api private */ - onError (err) { - debug('transport error'); - this.onClose('transport error', err); + onError(err) { + debug("transport error"); + this.onClose("transport error", err); } /** @@ -113,10 +116,10 @@ class Socket extends EventEmitter { * * @api private */ - setPingTimeout () { + setPingTimeout() { clearTimeout(this.pingTimeoutTimer); this.pingTimeoutTimer = setTimeout(() => { - this.onClose('ping timeout'); + this.onClose("ping timeout"); }, this.server.pingInterval + this.server.pingTimeout); } @@ -126,25 +129,25 @@ class Socket extends EventEmitter { * @param {Transport} transport * @api private */ - setTransport (transport) { + setTransport(transport) { const onError = this.onError.bind(this); const onPacket = this.onPacket.bind(this); const flush = this.flush.bind(this); - const onClose = this.onClose.bind(this, 'transport close'); + const onClose = this.onClose.bind(this, "transport close"); this.transport = transport; - this.transport.once('error', onError); - this.transport.on('packet', onPacket); - this.transport.on('drain', flush); - this.transport.once('close', onClose); + this.transport.once("error", onError); + this.transport.on("packet", onPacket); + this.transport.on("drain", flush); + this.transport.once("close", onClose); // this function will manage packet events (also message callbacks) this.setupSendCallback(); - this.cleanupFn.push(function () { - transport.removeListener('error', onError); - transport.removeListener('packet', onPacket); - transport.removeListener('drain', flush); - transport.removeListener('close', onClose); + this.cleanupFn.push(function() { + transport.removeListener("error", onError); + transport.removeListener("packet", onPacket); + transport.removeListener("drain", flush); + transport.removeListener("close", onClose); }); } @@ -154,42 +157,45 @@ class Socket extends EventEmitter { * @param {Transport} transport * @api private */ - maybeUpgrade (transport) { - debug('might upgrade socket transport from "%s" to "%s"' - , this.transport.name, transport.name); + maybeUpgrade(transport) { + debug( + 'might upgrade socket transport from "%s" to "%s"', + this.transport.name, + transport.name + ); this.upgrading = true; const self = this; // set transport upgrade timer - self.upgradeTimeoutTimer = setTimeout(function () { - debug('client did not complete upgrade - closing transport'); + self.upgradeTimeoutTimer = setTimeout(function() { + debug("client did not complete upgrade - closing transport"); cleanup(); - if ('open' === transport.readyState) { + if ("open" === transport.readyState) { transport.close(); } }, this.server.upgradeTimeout); - function onPacket (packet) { - if ('ping' === packet.type && 'probe' === packet.data) { - transport.send([{ type: 'pong', data: 'probe' }]); - self.emit('upgrading', transport); + function onPacket(packet) { + if ("ping" === packet.type && "probe" === packet.data) { + transport.send([{ type: "pong", data: "probe" }]); + self.emit("upgrading", transport); clearInterval(self.checkIntervalTimer); self.checkIntervalTimer = setInterval(check, 100); - } else if ('upgrade' === packet.type && self.readyState !== 'closed') { - debug('got upgrade packet - upgrading'); + } else if ("upgrade" === packet.type && self.readyState !== "closed") { + debug("got upgrade packet - upgrading"); cleanup(); self.transport.discard(); self.upgraded = true; self.clearTransport(); self.setTransport(transport); - self.emit('upgrade', transport); + self.emit("upgrade", transport); self.setPingTimeout(); self.flush(); - if (self.readyState === 'closing') { - transport.close(function () { - self.onClose('forced close'); + if (self.readyState === "closing") { + transport.close(function() { + self.onClose("forced close"); }); } } else { @@ -199,14 +205,14 @@ class Socket extends EventEmitter { } // we force a polling cycle to ensure a fast upgrade - function check () { - if ('polling' === self.transport.name && self.transport.writable) { - debug('writing a noop packet to polling for fast upgrade'); - self.transport.send([{ type: 'noop' }]); + function check() { + if ("polling" === self.transport.name && self.transport.writable) { + debug("writing a noop packet to polling for fast upgrade"); + self.transport.send([{ type: "noop" }]); } } - function cleanup () { + function cleanup() { self.upgrading = false; clearInterval(self.checkIntervalTimer); @@ -215,32 +221,32 @@ class Socket extends EventEmitter { clearTimeout(self.upgradeTimeoutTimer); self.upgradeTimeoutTimer = null; - transport.removeListener('packet', onPacket); - transport.removeListener('close', onTransportClose); - transport.removeListener('error', onError); - self.removeListener('close', onClose); + transport.removeListener("packet", onPacket); + transport.removeListener("close", onTransportClose); + transport.removeListener("error", onError); + self.removeListener("close", onClose); } - function onError (err) { - debug('client did not complete upgrade - %s', err); + function onError(err) { + debug("client did not complete upgrade - %s", err); cleanup(); transport.close(); transport = null; } - function onTransportClose () { - onError('transport closed'); + function onTransportClose() { + onError("transport closed"); } - function onClose () { - onError('socket closed'); + function onClose() { + onError("socket closed"); } - transport.on('packet', onPacket); - transport.once('close', onTransportClose); - transport.once('error', onError); + transport.on("packet", onPacket); + transport.once("close", onTransportClose); + transport.once("error", onError); - self.once('close', onClose); + self.once("close", onClose); } /** @@ -248,7 +254,7 @@ class Socket extends EventEmitter { * * @api private */ - clearTransport () { + clearTransport() { let cleanup; const toCleanUp = this.cleanupFn.length; @@ -259,8 +265,8 @@ class Socket extends EventEmitter { } // silence further transport errors and prevent uncaught exceptions - this.transport.on('error', function () { - debug('error triggered by discarded transport'); + this.transport.on("error", function() { + debug("error triggered by discarded transport"); }); // ensure transport won't stay open @@ -274,9 +280,9 @@ class Socket extends EventEmitter { * Possible reasons: `ping timeout`, `client error`, `parse error`, * `transport error`, `server close`, `transport close` */ - onClose (reason, description) { - if ('closed' !== this.readyState) { - this.readyState = 'closed'; + onClose(reason, description) { + if ("closed" !== this.readyState) { + this.readyState = "closed"; clearTimeout(this.pingTimeoutTimer); clearInterval(this.checkIntervalTimer); this.checkIntervalTimer = null; @@ -284,13 +290,13 @@ class Socket extends EventEmitter { const self = this; // clean writeBuffer in next tick, so developers can still // grab the writeBuffer on 'close' event - process.nextTick(function () { + process.nextTick(function() { self.writeBuffer = []; }); this.packetsFn = []; this.sentCallbackFn = []; this.clearTransport(); - this.emit('close', reason, description); + this.emit("close", reason, description); } } @@ -299,27 +305,27 @@ class Socket extends EventEmitter { * * @api private */ - setupSendCallback () { + setupSendCallback() { const self = this; - this.transport.on('drain', onDrain); + this.transport.on("drain", onDrain); - this.cleanupFn.push(function () { - self.transport.removeListener('drain', onDrain); + this.cleanupFn.push(function() { + self.transport.removeListener("drain", onDrain); }); // the message was sent successfully, execute the callback - function onDrain () { + function onDrain() { if (self.sentCallbackFn.length > 0) { const seqFn = self.sentCallbackFn.splice(0, 1)[0]; - if ('function' === typeof seqFn) { - debug('executing send callback'); + if ("function" === typeof seqFn) { + debug("executing send callback"); seqFn(self.transport); } else if (Array.isArray(seqFn)) { - debug('executing batch send callback'); + debug("executing batch send callback"); const l = seqFn.length; let i = 0; for (; i < l; i++) { - if ('function' === typeof seqFn[i]) { + if ("function" === typeof seqFn[i]) { seqFn[i](self.transport); } } @@ -337,13 +343,13 @@ class Socket extends EventEmitter { * @return {Socket} for chaining * @api public */ - send (data, options, callback) { - this.sendPacket('message', data, options, callback); + send(data, options, callback) { + this.sendPacket("message", data, options, callback); return this; } - write (data, options, callback) { - this.sendPacket('message', data, options, callback); + write(data, options, callback) { + this.sendPacket("message", data, options, callback); return this; } @@ -355,8 +361,8 @@ class Socket extends EventEmitter { * @param {Object} options * @api private */ - sendPacket (type, data, options, callback) { - if ('function' === typeof options) { + sendPacket(type, data, options, callback) { + if ("function" === typeof options) { callback = options; options = null; } @@ -364,7 +370,7 @@ class Socket extends EventEmitter { options = options || {}; options.compress = false !== options.compress; - if ('closing' !== this.readyState && 'closed' !== this.readyState) { + if ("closing" !== this.readyState && "closed" !== this.readyState) { debug('sending packet "%s" (%s)', type, data); const packet = { @@ -374,7 +380,7 @@ class Socket extends EventEmitter { if (data) packet.data = data; // exports packetCreate event - this.emit('packetCreate', packet); + this.emit("packetCreate", packet); this.writeBuffer.push(packet); @@ -390,13 +396,15 @@ class Socket extends EventEmitter { * * @api private */ - flush () { - if ('closed' !== this.readyState && + flush() { + if ( + "closed" !== this.readyState && this.transport.writable && - this.writeBuffer.length) { - debug('flushing buffer to transport'); - this.emit('flush', this.writeBuffer); - this.server.emit('flush', this, this.writeBuffer); + this.writeBuffer.length + ) { + debug("flushing buffer to transport"); + this.emit("flush", this.writeBuffer); + this.server.emit("flush", this, this.writeBuffer); const wbuf = this.writeBuffer; this.writeBuffer = []; if (!this.transport.supportsFraming) { @@ -406,8 +414,8 @@ class Socket extends EventEmitter { } this.packetsFn = []; this.transport.send(wbuf); - this.emit('drain'); - this.server.emit('drain', this); + this.emit("drain"); + this.server.emit("drain", this); } } @@ -416,7 +424,7 @@ class Socket extends EventEmitter { * * @api private */ - getAvailableUpgrades () { + getAvailableUpgrades() { const availableUpgrades = []; const allUpgrades = this.server.upgrades(this.transport.name); let i = 0; @@ -437,13 +445,13 @@ class Socket extends EventEmitter { * @return {Socket} for chaining * @api public */ - close (discard) { - if ('open' !== this.readyState) return; + close(discard) { + if ("open" !== this.readyState) return; - this.readyState = 'closing'; + this.readyState = "closing"; if (this.writeBuffer.length) { - this.once('drain', this.closeTransport.bind(this, discard)); + this.once("drain", this.closeTransport.bind(this, discard)); return; } @@ -456,9 +464,9 @@ class Socket extends EventEmitter { * @param {Boolean} discard * @api private */ - closeTransport (discard) { + closeTransport(discard) { if (discard) this.transport.discard(); - this.transport.close(this.onClose.bind(this, 'forced close')); + this.transport.close(this.onClose.bind(this, "forced close")); } } diff --git a/lib/transport.js b/lib/transport.js index 0beed0a04..f45c5911b 100644 --- a/lib/transport.js +++ b/lib/transport.js @@ -1,6 +1,6 @@ -const EventEmitter = require('events'); -const parser = require('engine.io-parser'); -const debug = require('debug')('engine:transport'); +const EventEmitter = require("events"); +const parser = require("engine.io-parser"); +const debug = require("debug")("engine:transport"); /** * Noop function. @@ -8,7 +8,7 @@ const debug = require('debug')('engine:transport'); * @api private */ -function noop () {} +function noop() {} class Transport extends EventEmitter { /** @@ -17,9 +17,9 @@ class Transport extends EventEmitter { * @param {http.IncomingMessage} request * @api public */ - constructor (req) { + constructor(req) { super(); - this.readyState = 'open'; + this.readyState = "open"; this.discarded = false; } @@ -28,7 +28,7 @@ class Transport extends EventEmitter { * * @api private */ - discard () { + discard() { this.discarded = true; } @@ -38,8 +38,8 @@ class Transport extends EventEmitter { * @param {http.IncomingMessage} request * @api private */ - onRequest (req) { - debug('setting request'); + onRequest(req) { + debug("setting request"); this.req = req; } @@ -48,10 +48,10 @@ class Transport extends EventEmitter { * * @api private */ - close (fn) { - if ('closed' === this.readyState || 'closing' === this.readyState) return; + close(fn) { + if ("closed" === this.readyState || "closing" === this.readyState) return; - this.readyState = 'closing'; + this.readyState = "closing"; this.doClose(fn || noop); } @@ -62,14 +62,14 @@ class Transport extends EventEmitter { * @param {Object} error description * @api private */ - onError (msg, desc) { - if (this.listeners('error').length) { + onError(msg, desc) { + if (this.listeners("error").length) { const err = new Error(msg); - err.type = 'TransportError'; + err.type = "TransportError"; err.description = desc; - this.emit('error', err); + this.emit("error", err); } else { - debug('ignored transport error %s (%s)', msg, desc); + debug("ignored transport error %s (%s)", msg, desc); } } @@ -79,8 +79,8 @@ class Transport extends EventEmitter { * @param {Object} packet * @api private */ - onPacket (packet) { - this.emit('packet', packet); + onPacket(packet) { + this.emit("packet", packet); } /** @@ -89,7 +89,7 @@ class Transport extends EventEmitter { * @param {String} data * @api private */ - onData (data) { + onData(data) { this.onPacket(parser.decodePacket(data)); } @@ -98,9 +98,9 @@ class Transport extends EventEmitter { * * @api private */ - onClose () { - this.readyState = 'closed'; - this.emit('close'); + onClose() { + this.readyState = "closed"; + this.emit("close"); } } diff --git a/lib/transports/index.js b/lib/transports/index.js index 0b6a40b42..ea106551e 100644 --- a/lib/transports/index.js +++ b/lib/transports/index.js @@ -1,5 +1,5 @@ -const XHR = require('./polling-xhr'); -const JSONP = require('./polling-jsonp'); +const XHR = require("./polling-xhr"); +const JSONP = require("./polling-jsonp"); /** * Export transports. @@ -7,14 +7,14 @@ const JSONP = require('./polling-jsonp'); module.exports = exports = { polling: polling, - websocket: require('./websocket') + websocket: require("./websocket") }; /** * Export upgrades map. */ -exports.polling.upgradesTo = ['websocket']; +exports.polling.upgradesTo = ["websocket"]; /** * Polling polymorphic constructor. @@ -22,8 +22,8 @@ exports.polling.upgradesTo = ['websocket']; * @api private */ -function polling (req) { - if ('string' === typeof req._query.j) { +function polling(req) { + if ("string" === typeof req._query.j) { return new JSONP(req); } else { return new XHR(req); diff --git a/lib/transports/polling-jsonp.js b/lib/transports/polling-jsonp.js index de3de36e7..bb07ce857 100644 --- a/lib/transports/polling-jsonp.js +++ b/lib/transports/polling-jsonp.js @@ -1,5 +1,5 @@ -const Polling = require('./polling'); -const qs = require('querystring'); +const Polling = require("./polling"); +const qs = require("querystring"); const rDoubleSlashes = /\\\\n/g; const rSlashes = /(\\)?\\n/g; @@ -9,11 +9,11 @@ class JSONP extends Polling { * * @api public */ - constructor (req) { + constructor(req) { super(req); - this.head = '___eio[' + (req._query.j || '').replace(/[^0-9]/g, '') + ']('; - this.foot = ');'; + this.head = "___eio[" + (req._query.j || "").replace(/[^0-9]/g, "") + "]("; + this.foot = ");"; } /** @@ -22,17 +22,17 @@ class JSONP extends Polling { * * @api private */ - onData (data) { + onData(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) { + 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'; + data = data.replace(rSlashes, function(match, slashes) { + return slashes ? match : "\n"; }); - super.onData(data.replace(rDoubleSlashes, '\\n')); + super.onData(data.replace(rDoubleSlashes, "\\n")); } } @@ -41,12 +41,12 @@ class JSONP extends Polling { * * @api private */ - doWrite (data, options, callback) { + doWrite(data, options, callback) { // we must output valid javascript, not valid json // see: http://timelessrepo.com/json-isnt-a-javascript-subset const js = JSON.stringify(data) - .replace(/\u2028/g, '\\u2028') - .replace(/\u2029/g, '\\u2029'); + .replace(/\u2028/g, "\\u2028") + .replace(/\u2029/g, "\\u2029"); // prepare response data = this.head + js + this.foot; diff --git a/lib/transports/polling-xhr.js b/lib/transports/polling-xhr.js index 977e3c16d..c4a63e26b 100644 --- a/lib/transports/polling-xhr.js +++ b/lib/transports/polling-xhr.js @@ -1,4 +1,4 @@ -const Polling = require('./polling'); +const Polling = require("./polling"); class XHR extends Polling { /** @@ -7,11 +7,11 @@ class XHR extends Polling { * @param {http.IncomingMessage} * @api private */ - onRequest (req) { - if ('OPTIONS' === req.method) { + onRequest(req) { + if ("OPTIONS" === req.method) { const res = req.res; const headers = this.headers(req); - headers['Access-Control-Allow-Headers'] = 'Content-Type'; + headers["Access-Control-Allow-Headers"] = "Content-Type"; res.writeHead(200, headers); res.end(); } else { @@ -26,14 +26,14 @@ class XHR extends Polling { * @param {Object} extra headers * @api private */ - headers (req, headers) { + headers(req, headers) { headers = headers || {}; if (req.headers.origin) { - headers['Access-Control-Allow-Credentials'] = 'true'; - headers['Access-Control-Allow-Origin'] = req.headers.origin; + headers["Access-Control-Allow-Credentials"] = "true"; + headers["Access-Control-Allow-Origin"] = req.headers.origin; } else { - headers['Access-Control-Allow-Origin'] = '*'; + headers["Access-Control-Allow-Origin"] = "*"; } return super.headers(req, headers); diff --git a/lib/transports/polling.js b/lib/transports/polling.js index 063360aaf..680f8642c 100644 --- a/lib/transports/polling.js +++ b/lib/transports/polling.js @@ -1,8 +1,8 @@ -const Transport = require('../transport'); -const parser = require('engine.io-parser'); -const zlib = require('zlib'); -const accepts = require('accepts'); -const debug = require('debug')('engine:polling'); +const Transport = require("../transport"); +const parser = require("engine.io-parser"); +const zlib = require("zlib"); +const accepts = require("accepts"); +const debug = require("debug")("engine:polling"); const compressionMethods = { gzip: zlib.createGzip, @@ -15,7 +15,7 @@ class Polling extends Transport { * * @api public. */ - constructor (req) { + constructor(req) { super(req); this.closeTimeout = 30 * 1000; @@ -28,8 +28,8 @@ class Polling extends Transport { * * @api public */ - get name () { - return 'polling'; + get name() { + return "polling"; } /** @@ -38,12 +38,12 @@ class Polling extends Transport { * @param {http.IncomingMessage} * @api private */ - onRequest (req) { + onRequest(req) { const res = req.res; - if ('GET' === req.method) { + if ("GET" === req.method) { this.onPollRequest(req, res); - } else if ('POST' === req.method) { + } else if ("POST" === req.method) { this.onDataRequest(req, res); } else { res.writeHead(500); @@ -56,42 +56,42 @@ class Polling extends Transport { * * @api private */ - onPollRequest (req, res) { + onPollRequest(req, res) { if (this.req) { - debug('request overlap'); + debug("request overlap"); // assert: this.res, '.req and .res should be (un)set together' - this.onError('overlap from client'); + this.onError("overlap from client"); res.writeHead(500); res.end(); return; } - debug('setting request'); + debug("setting request"); this.req = req; this.res = res; const self = this; - function onClose () { - self.onError('poll connection closed prematurely'); + function onClose() { + self.onError("poll connection closed prematurely"); } - function cleanup () { - req.removeListener('close', onClose); + function cleanup() { + req.removeListener("close", onClose); self.req = self.res = null; } req.cleanup = cleanup; - req.on('close', onClose); + req.on("close", onClose); this.writable = true; - this.emit('drain'); + 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' }]); + debug("triggering empty send to append close packet"); + this.send([{ type: "noop" }]); } } @@ -100,36 +100,36 @@ class Polling extends Transport { * * @api private */ - onDataRequest (req, res) { + onDataRequest(req, res) { if (this.dataReq) { // assert: this.dataRes, '.dataReq and .dataRes should be (un)set together' - this.onError('data request overlap from client'); + this.onError("data request overlap from client"); res.writeHead(500); res.end(); return; } - const isBinary = 'application/octet-stream' === req.headers['content-type']; + const isBinary = "application/octet-stream" === req.headers["content-type"]; this.dataReq = req; this.dataRes = res; - let chunks = isBinary ? Buffer.concat([]) : ''; + let chunks = isBinary ? Buffer.concat([]) : ""; const self = this; - function cleanup () { - req.removeListener('data', onData); - req.removeListener('end', onEnd); - req.removeListener('close', onClose); + function cleanup() { + req.removeListener("data", onData); + req.removeListener("end", onEnd); + req.removeListener("close", onClose); self.dataReq = self.dataRes = chunks = null; } - function onClose () { + function onClose() { cleanup(); - self.onError('data request connection closed prematurely'); + self.onError("data request connection closed prematurely"); } - function onData (data) { + function onData(data) { let contentLength; if (isBinary) { chunks = Buffer.concat([chunks, data]); @@ -140,30 +140,30 @@ class Polling extends Transport { } if (contentLength > self.maxHttpBufferSize) { - chunks = isBinary ? Buffer.concat([]) : ''; + chunks = isBinary ? Buffer.concat([]) : ""; req.connection.destroy(); } } - function onEnd () { + function onEnd() { self.onData(chunks); const 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 + "Content-Type": "text/html", + "Content-Length": 2 }; res.writeHead(200, self.headers(req, headers)); - res.end('ok'); + res.end("ok"); cleanup(); } - req.on('close', onClose); - if (!isBinary) req.setEncoding('utf8'); - req.on('data', onData); - req.on('end', onEnd); + req.on("close", onClose); + if (!isBinary) req.setEncoding("utf8"); + req.on("data", onData); + req.on("end", onEnd); } /** @@ -172,12 +172,12 @@ class Polling extends Transport { * @param {String} encoded payload * @api private */ - onData (data) { + onData(data) { debug('received "%s"', data); const self = this; - const callback = function (packet) { - if ('close' === packet.type) { - debug('got xhr close packet'); + const callback = function(packet) { + if ("close" === packet.type) { + debug("got xhr close packet"); self.onClose(); return false; } @@ -193,10 +193,10 @@ class Polling extends Transport { * * @api private */ - onClose () { + onClose() { if (this.writable) { // close pending poll request - this.send([{ type: 'noop' }]); + this.send([{ type: "noop" }]); } super.onClose(); } @@ -207,19 +207,19 @@ class Polling extends Transport { * @param {Object} packet * @api private */ - send (packets) { + send(packets) { this.writable = false; if (this.shouldClose) { - debug('appending close packet to payload'); - packets.push({ type: 'close' }); + debug("appending close packet to payload"); + packets.push({ type: "close" }); this.shouldClose(); this.shouldClose = null; } const self = this; - parser.encodePayload(packets, this.supportsBinary, function (data) { - const compress = packets.some(function (packet) { + parser.encodePayload(packets, this.supportsBinary, function(data) { + const compress = packets.some(function(packet) { return packet.options && packet.options.compress; }); self.write(data, { compress: compress }); @@ -233,10 +233,10 @@ class Polling extends Transport { * @param {Object} options * @api private */ - write (data, options) { + write(data, options) { debug('writing "%s"', data); const self = this; - this.doWrite(data, options, function () { + this.doWrite(data, options, function() { self.req.cleanup(); }); } @@ -246,17 +246,17 @@ class Polling extends Transport { * * @api private */ - doWrite (data, options, callback) { + doWrite(data, options, callback) { const self = this; // explicit UTF-8 is required for pages not served under utf - const isString = typeof data === 'string'; + const isString = typeof data === "string"; const contentType = isString - ? 'text/plain; charset=UTF-8' - : 'application/octet-stream'; + ? "text/plain; charset=UTF-8" + : "application/octet-stream"; const headers = { - 'Content-Type': contentType + "Content-Type": contentType }; if (!this.httpCompression || !options.compress) { @@ -270,13 +270,13 @@ class Polling extends Transport { return; } - const encoding = accepts(this.req).encodings(['gzip', 'deflate']); + const encoding = accepts(this.req).encodings(["gzip", "deflate"]); if (!encoding) { respond(data); return; } - this.compress(data, encoding, function (err, data) { + this.compress(data, encoding, function(err, data) { if (err) { self.res.writeHead(500); self.res.end(); @@ -284,12 +284,13 @@ class Polling extends Transport { return; } - headers['Content-Encoding'] = encoding; + headers["Content-Encoding"] = encoding; respond(data); }); - function respond (data) { - headers['Content-Length'] = 'string' === typeof data ? Buffer.byteLength(data) : data.length; + 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(); @@ -301,19 +302,19 @@ class Polling extends Transport { * * @api private */ - compress (data, encoding, callback) { - debug('compressing'); + compress(data, encoding, callback) { + debug("compressing"); const buffers = []; let nread = 0; compressionMethods[encoding](this.httpCompression) - .on('error', callback) - .on('data', function (chunk) { + .on("error", callback) + .on("data", function(chunk) { buffers.push(chunk); nread += chunk.length; }) - .on('end', function () { + .on("end", function() { callback(null, Buffer.concat(buffers, nread)); }) .end(data); @@ -324,31 +325,31 @@ class Polling extends Transport { * * @api private */ - doClose (fn) { - debug('closing'); + doClose(fn) { + debug("closing"); const self = this; let closeTimeoutTimer; if (this.dataReq) { - debug('aborting ongoing data request'); + debug("aborting ongoing data request"); this.dataReq.destroy(); } if (this.writable) { - debug('transport writable - closing right away'); - this.send([{ type: 'close' }]); + debug("transport writable - closing right away"); + this.send([{ type: "close" }]); onClose(); } else if (this.discarded) { - debug('transport discarded - closing right away'); + debug("transport discarded - closing right away"); onClose(); } else { - debug('transport not writable - buffering orderly close'); + debug("transport not writable - buffering orderly close"); this.shouldClose = onClose; closeTimeoutTimer = setTimeout(onClose, this.closeTimeout); } - function onClose () { + function onClose() { clearTimeout(closeTimeoutTimer); fn(); self.onClose(); @@ -362,17 +363,17 @@ class Polling extends Transport { * @param {Object} extra headers * @api private */ - headers (req, headers) { + headers(req, headers) { headers = headers || {}; // prevent XSS warnings on IE // https://github.com/LearnBoost/socket.io/pull/1333 - const ua = req.headers['user-agent']; - if (ua && (~ua.indexOf(';MSIE') || ~ua.indexOf('Trident/'))) { - headers['X-XSS-Protection'] = '0'; + const ua = req.headers["user-agent"]; + if (ua && (~ua.indexOf(";MSIE") || ~ua.indexOf("Trident/"))) { + headers["X-XSS-Protection"] = "0"; } - this.emit('headers', headers); + this.emit("headers", headers); return headers; } } diff --git a/lib/transports/websocket.js b/lib/transports/websocket.js index ee228e9ee..7f0f0cb0d 100644 --- a/lib/transports/websocket.js +++ b/lib/transports/websocket.js @@ -1,6 +1,6 @@ -const Transport = require('../transport'); -const parser = require('engine.io-parser'); -const debug = require('debug')('engine:ws'); +const Transport = require("../transport"); +const parser = require("engine.io-parser"); +const debug = require("debug")("engine:ws"); class WebSocket extends Transport { /** @@ -9,14 +9,14 @@ class WebSocket extends Transport { * @param {http.IncomingMessage} * @api public */ - constructor (req) { + constructor(req) { super(req); 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', (headers) => { - this.emit('headers', headers); + 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", headers => { + this.emit("headers", headers); }); this.writable = true; this.perMessageDeflate = null; @@ -27,8 +27,8 @@ class WebSocket extends Transport { * * @api public */ - get name () { - return 'websocket'; + get name() { + return "websocket"; } /** @@ -36,7 +36,7 @@ class WebSocket extends Transport { * * @api public */ - get handlesUpgrades () { + get handlesUpgrades() { return true; } @@ -45,7 +45,7 @@ class WebSocket extends Transport { * * @api public */ - get supportsFraming () { + get supportsFraming() { return true; } @@ -55,7 +55,7 @@ class WebSocket extends Transport { * @param {String} encoded packet * @api private */ - onData (data) { + onData(data) { debug('received "%s"', data); super.onData(data); } @@ -66,7 +66,7 @@ class WebSocket extends Transport { * @param {Array} packets * @api private */ - send (packets) { + send(packets) { var self = this; for (var i = 0; i < packets.length; i++) { @@ -74,7 +74,7 @@ class WebSocket extends Transport { parser.encodePacket(packet, self.supportsBinary, send); } - function send (data) { + function send(data) { debug('writing "%s"', data); // always creates a new object since ws modifies it @@ -84,7 +84,8 @@ class WebSocket extends Transport { } if (self.perMessageDeflate) { - var len = 'string' === typeof data ? Buffer.byteLength(data) : data.length; + var len = + "string" === typeof data ? Buffer.byteLength(data) : data.length; if (len < self.perMessageDeflate.threshold) { opts.compress = false; } @@ -94,10 +95,10 @@ class WebSocket extends Transport { self.socket.send(data, opts, onEnd); } - function onEnd (err) { - if (err) return self.onError('write error', err.stack); + function onEnd(err) { + if (err) return self.onError("write error", err.stack); self.writable = true; - self.emit('drain'); + self.emit("drain"); } } @@ -106,8 +107,8 @@ class WebSocket extends Transport { * * @api private */ - doClose (fn) { - debug('closing'); + doClose(fn) { + debug("closing"); this.socket.close(); fn && fn(); } diff --git a/package-lock.json b/package-lock.json index 542c3b12f..58d3b9dd4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -203,27 +203,6 @@ "sprintf-js": "~1.0.2" } }, - "array-includes": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz", - "integrity": "sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0", - "is-string": "^1.0.5" - } - }, - "array.prototype.flat": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz", - "integrity": "sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - } - }, "arraybuffer.slice": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", @@ -292,498 +271,6 @@ "eslint-visitor-keys": "^1.0.0" } }, - "babel-helper-call-delegate": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", - "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=", - "dev": true, - "requires": { - "babel-helper-hoist-variables": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helper-define-map": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz", - "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=", - "dev": true, - "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" - } - }, - "babel-helper-function-name": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", - "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", - "dev": true, - "requires": { - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helper-get-function-arity": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", - "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-helper-hoist-variables": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz", - "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-helper-optimise-call-expression": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz", - "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-helper-regex": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz", - "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" - } - }, - "babel-helper-replace-supers": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz", - "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=", - "dev": true, - "requires": { - "babel-helper-optimise-call-expression": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-messages": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", - "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-check-es2015-constants": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", - "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-arrow-functions": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", - "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-block-scoped-functions": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", - "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-block-scoping": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz", - "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" - } - }, - "babel-plugin-transform-es2015-classes": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", - "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=", - "dev": true, - "requires": { - "babel-helper-define-map": "^6.24.1", - "babel-helper-function-name": "^6.24.1", - "babel-helper-optimise-call-expression": "^6.24.1", - "babel-helper-replace-supers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-computed-properties": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", - "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-destructuring": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", - "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-duplicate-keys": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz", - "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-for-of": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", - "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-function-name": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", - "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", - "dev": true, - "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-literals": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", - "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-modules-amd": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz", - "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", - "dev": true, - "requires": { - "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-modules-commonjs": { - "version": "6.26.2", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz", - "integrity": "sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==", - "dev": true, - "requires": { - "babel-plugin-transform-strict-mode": "^6.24.1", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-types": "^6.26.0" - } - }, - "babel-plugin-transform-es2015-modules-systemjs": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz", - "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=", - "dev": true, - "requires": { - "babel-helper-hoist-variables": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-modules-umd": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz", - "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=", - "dev": true, - "requires": { - "babel-plugin-transform-es2015-modules-amd": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-object-super": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz", - "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=", - "dev": true, - "requires": { - "babel-helper-replace-supers": "^6.24.1", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-parameters": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", - "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=", - "dev": true, - "requires": { - "babel-helper-call-delegate": "^6.24.1", - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-shorthand-properties": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", - "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-spread": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", - "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-sticky-regex": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", - "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=", - "dev": true, - "requires": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-template-literals": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", - "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-typeof-symbol": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", - "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-unicode-regex": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", - "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=", - "dev": true, - "requires": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "regexpu-core": "^2.0.0" - } - }, - "babel-plugin-transform-regenerator": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz", - "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=", - "dev": true, - "requires": { - "regenerator-transform": "^0.10.0" - } - }, - "babel-plugin-transform-strict-mode": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", - "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-preset-es2015": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz", - "integrity": "sha1-1EBQ1rwsn+6nAqrzjXJ6AhBTiTk=", - "dev": true, - "requires": { - "babel-plugin-check-es2015-constants": "^6.22.0", - "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoping": "^6.24.1", - "babel-plugin-transform-es2015-classes": "^6.24.1", - "babel-plugin-transform-es2015-computed-properties": "^6.24.1", - "babel-plugin-transform-es2015-destructuring": "^6.22.0", - "babel-plugin-transform-es2015-duplicate-keys": "^6.24.1", - "babel-plugin-transform-es2015-for-of": "^6.22.0", - "babel-plugin-transform-es2015-function-name": "^6.24.1", - "babel-plugin-transform-es2015-literals": "^6.22.0", - "babel-plugin-transform-es2015-modules-amd": "^6.24.1", - "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", - "babel-plugin-transform-es2015-modules-systemjs": "^6.24.1", - "babel-plugin-transform-es2015-modules-umd": "^6.24.1", - "babel-plugin-transform-es2015-object-super": "^6.24.1", - "babel-plugin-transform-es2015-parameters": "^6.24.1", - "babel-plugin-transform-es2015-shorthand-properties": "^6.24.1", - "babel-plugin-transform-es2015-spread": "^6.22.0", - "babel-plugin-transform-es2015-sticky-regex": "^6.24.1", - "babel-plugin-transform-es2015-template-literals": "^6.22.0", - "babel-plugin-transform-es2015-typeof-symbol": "^6.22.0", - "babel-plugin-transform-es2015-unicode-regex": "^6.24.1", - "babel-plugin-transform-regenerator": "^6.24.1" - } - }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "dev": true, - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "babel-template": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", - "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "lodash": "^4.17.4" - }, - "dependencies": { - "babylon": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", - "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", - "dev": true - } - } - }, - "babel-traverse": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", - "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", - "dev": true, - "requires": { - "babel-code-frame": "^6.26.0", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "debug": "^2.6.8", - "globals": "^9.18.0", - "invariant": "^2.2.2", - "lodash": "^4.17.4" - }, - "dependencies": { - "babylon": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", - "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", - "dev": true - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "globals": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", - "dev": true - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "babel-types": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", - "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "esutils": "^2.0.2", - "lodash": "^4.17.4", - "to-fast-properties": "^1.0.3" - }, - "dependencies": { - "to-fast-properties": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", - "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", - "dev": true - } - } - }, "babylon": { "version": "7.0.0-beta.44", "resolved": "https://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.44.tgz", @@ -967,12 +454,6 @@ "typedarray": "^0.0.6" } }, - "contains-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", - "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", - "dev": true - }, "cookie": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", @@ -984,12 +465,6 @@ "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==", "dev": true }, - "core-js": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", - "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", - "dev": true - }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", @@ -1021,15 +496,6 @@ "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", "dev": true }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -1093,45 +559,6 @@ "has-binary2": "~1.0.2" } }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es-abstract": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.0.tgz", - "integrity": "sha512-yYkE07YF+6SIBmg1MsJ9dlub5L48Ek7X0qz+c/CPCHS9EBXfESorzng4cJQjJW5/pB6vDF41u7F8vUhLVDqIug==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.1.5", - "is-regex": "^1.0.5", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimleft": "^2.1.1", - "string.prototype.trimright": "^2.1.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", @@ -1210,151 +637,15 @@ } } }, - "eslint-config-standard": { - "version": "10.2.1", - "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-10.2.1.tgz", - "integrity": "sha1-wGHk0GbzedwXzVYsZOgZtN1FRZE=", - "dev": true - }, - "eslint-import-resolver-node": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.3.tgz", - "integrity": "sha512-b8crLDo0M5RSe5YG8Pu2DYBj71tSB6OvXkfzwbJU2w7y8P4/yo0MyF8jU26IEuEuHF2K5/gcAJE3LhQGqBBbVg==", - "dev": true, - "requires": { - "debug": "^2.6.9", - "resolve": "^1.13.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "eslint-module-utils": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.5.1.tgz", - "integrity": "sha512-GcNwsYv8MfoEBSbAmV+PSVn2RlhpCShbLImtNviAYa/LE0PgNqxH5tLi1Ld9yeFwdjHsarXK+7G9vsyddmB6dw==", - "dev": true, - "requires": { - "debug": "^2.6.9", - "pkg-dir": "^2.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "eslint-plugin-import": { - "version": "2.20.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.20.0.tgz", - "integrity": "sha512-NK42oA0mUc8Ngn4kONOPsPB1XhbUvNHqF+g307dPV28aknPoiNnKLFd9em4nkswwepdF5ouieqv5Th/63U7YJQ==", - "dev": true, - "requires": { - "array-includes": "^3.0.3", - "array.prototype.flat": "^1.2.1", - "contains-path": "^0.1.0", - "debug": "^2.6.9", - "doctrine": "1.5.0", - "eslint-import-resolver-node": "^0.3.2", - "eslint-module-utils": "^2.4.1", - "has": "^1.0.3", - "minimatch": "^3.0.4", - "object.values": "^1.1.0", - "read-pkg-up": "^2.0.0", - "resolve": "^1.12.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "doctrine": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", - "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", - "dev": true, - "requires": { - "esutils": "^2.0.2", - "isarray": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "eslint-plugin-node": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-5.2.1.tgz", - "integrity": "sha512-xhPXrh0Vl/b7870uEbaumb2Q+LxaEcOQ3kS1jtIXanBAwpMre1l5q/l2l/hESYJGEFKuI78bp6Uw50hlpr7B+g==", + "eslint-config-prettier": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.9.0.tgz", + "integrity": "sha512-k4E14HBtcLv0uqThaI6I/n1LEqROp8XaPu6SO9Z32u5NlGRC07Enu1Bh2KEFw4FNHbekH8yzbIU9kUGxbiGmCA==", "dev": true, "requires": { - "ignore": "^3.3.6", - "minimatch": "^3.0.4", - "resolve": "^1.3.3", - "semver": "5.3.0" - }, - "dependencies": { - "semver": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", - "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", - "dev": true - } + "get-stdin": "^6.0.0" } }, - "eslint-plugin-promise": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-3.8.0.tgz", - "integrity": "sha512-JiFL9UFR15NKpHyGii1ZcvmtIqa3UTwiDAGb8atSffe43qJ3+1czVGN6UtkklpcJ2DVnqvTMzEKRaJdBkAL2aQ==", - "dev": true - }, - "eslint-plugin-standard": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-3.1.0.tgz", - "integrity": "sha512-fVcdyuKRr0EZ4fjWl3c+gp1BANFJD1+RaWa2UPYfMZ6jCtp5RG00kSaXnK/dE5sYzt4kaWJ9qdxqUfc0d9kX0w==", - "dev": true - }, "eslint-scope": { "version": "3.7.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz", @@ -1477,15 +768,6 @@ "object-assign": "^4.0.1" } }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, "flat-cache": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz", @@ -1521,18 +803,18 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, "functional-red-black-tree": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", "dev": true }, + "get-stdin": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", + "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", + "dev": true + }, "glob": { "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", @@ -1565,15 +847,6 @@ "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", "dev": true }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, "has-ansi": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", @@ -1603,24 +876,12 @@ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true - }, "he": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", "dev": true }, - "hosted-git-info": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.5.tgz", - "integrity": "sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg==", - "dev": true - }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -1712,24 +973,6 @@ "loose-envify": "^1.0.0" } }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, - "is-callable": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", - "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", - "dev": true - }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "dev": true - }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", @@ -1742,36 +985,12 @@ "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", "dev": true }, - "is-regex": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", - "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, "is-resolvable": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", "dev": true }, - "is-string": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", - "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", - "dev": true - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, "isarray": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", @@ -1827,28 +1046,6 @@ "type-check": "~0.3.2" } }, - "load-json-file": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "strip-bom": "^3.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, "lodash": { "version": "4.17.15", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", @@ -2015,60 +1212,12 @@ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", "dev": true }, - "object-inspect": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", - "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.values": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", - "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1", - "function-bind": "^1.1.1", - "has": "^1.0.3" - } - }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -2107,39 +1256,6 @@ "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "dev": true }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true, - "requires": { - "error-ex": "^1.2.0" - } - }, "parseqs": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", @@ -2158,12 +1274,6 @@ "better-assert": "~1.0.0" } }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", @@ -2176,36 +1286,6 @@ "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", "dev": true }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "path-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", - "dev": true, - "requires": { - "pify": "^2.0.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", - "dev": true, - "requires": { - "find-up": "^2.1.0" - } - }, "pluralize": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", @@ -2218,10 +1298,10 @@ "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", "dev": true }, - "private": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", - "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", + "prettier": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", + "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", "dev": true }, "process-nextick-args": { @@ -2248,27 +1328,6 @@ "integrity": "sha512-Cxm7/SS/y/Z3MHWSxXb8lIFqgqBowP5JMlTUFyJN88y0SGQhVmZnqFK/PeuMX9LzUyWsqqhNxIyg0jlzq946yA==", "dev": true }, - "read-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", - "dev": true, - "requires": { - "load-json-file": "^2.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^2.0.0" - } - }, - "read-pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", - "dev": true, - "requires": { - "find-up": "^2.0.0", - "read-pkg": "^2.0.0" - } - }, "readable-stream": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", @@ -2292,69 +1351,12 @@ } } }, - "regenerate": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", - "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==", - "dev": true - }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true - }, - "regenerator-transform": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz", - "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==", - "dev": true, - "requires": { - "babel-runtime": "^6.18.0", - "babel-types": "^6.19.0", - "private": "^0.1.6" - } - }, "regexpp": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-1.1.0.tgz", "integrity": "sha512-LOPw8FpgdQF9etWMaAfG/WRthIdXJGYp4mJ2Jgn/2lpkbod9jPn0t9UqN7AxBOKNfzRbYyVfgc7Vk4t/MpnXgw==", "dev": true }, - "regexpu-core": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", - "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", - "dev": true, - "requires": { - "regenerate": "^1.2.1", - "regjsgen": "^0.2.0", - "regjsparser": "^0.1.4" - } - }, - "regjsgen": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", - "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=", - "dev": true - }, - "regjsparser": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", - "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", - "dev": true, - "requires": { - "jsesc": "~0.5.0" - }, - "dependencies": { - "jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", - "dev": true - } - } - }, "require-uncached": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", @@ -2365,15 +1367,6 @@ "resolve-from": "^1.0.0" } }, - "resolve": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.13.1.tgz", - "integrity": "sha512-CxqObCX8K8YtAhOBRg+lrcdn+LK+WYOS8tSjqSFbjtrI5PnS63QPhZl4+yKfrU9tdsbMu9Anr/amegT87M9Z6w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, "resolve-from": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", @@ -2483,38 +1476,6 @@ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true }, - "spdx-correct": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", - "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", - "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", - "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", - "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", - "dev": true - }, "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", @@ -2548,26 +1509,6 @@ } } }, - "string.prototype.trimleft": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz", - "integrity": "sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "function-bind": "^1.1.1" - } - }, - "string.prototype.trimright": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz", - "integrity": "sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "function-bind": "^1.1.1" - } - }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -2586,12 +1527,6 @@ "ansi-regex": "^2.0.0" } }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - }, "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", @@ -2710,16 +1645,6 @@ "integrity": "sha512-HNMztPP5A1sKuVFmdZ6BPVpBQd5bUjNC8EFMFiICK+oho/OQsAJy5hnIx4btMHiOk8j04f/DbIlqnEZ9d72dqg==", "dev": true }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", diff --git a/package.json b/package.json index d99b2c31b..73d87a85b 100644 --- a/package.json +++ b/package.json @@ -34,23 +34,21 @@ }, "devDependencies": { "babel-eslint": "^8.0.2", - "babel-preset-es2015": "^6.24.0", "engine.io-client": "3.4.0", - "eslint": "^4.5.0", - "eslint-config-standard": "^10.2.1", - "eslint-plugin-import": "^2.7.0", - "eslint-plugin-node": "^5.1.1", - "eslint-plugin-promise": "^3.5.0", - "eslint-plugin-standard": "^3.0.1", + "eslint": "^4.19.1", + "eslint-config-prettier": "^6.9.0", "expect.js": "^0.3.1", "mocha": "^4.0.1", + "prettier": "^1.19.1", "s": "0.1.1", "superagent": "^3.8.1", "uws": "~9.14.0" }, "scripts": { "lint": "eslint lib/ test/ *.js", - "test": "npm run lint && mocha && EIO_WS_ENGINE=uws mocha" + "test": "npm run lint && npm run format:check && mocha && EIO_WS_ENGINE=uws mocha", + "format:check": "prettier --check 'lib/**/*.js' 'test/**/*.js'", + "format:fix": "prettier --write 'lib/**/*.js' 'test/**/*.js'" }, "repository": { "type": "git", diff --git a/test/common.js b/test/common.js index 1f7244445..14845c7ff 100644 --- a/test/common.js +++ b/test/common.js @@ -1,21 +1,20 @@ - /** * Module dependencies. */ -var eio = require('..'); +var eio = require(".."); /** * Listen shortcut that fires a callback on an ephemeral port. */ -exports.listen = function (opts, fn) { - if ('function' === typeof opts) { +exports.listen = function(opts, fn) { + if ("function" === typeof opts) { fn = opts; opts = {}; } - var e = eio.listen(0, opts, function () { + var e = eio.listen(0, opts, function() { fn(e.httpServer.address().port); }); @@ -26,4 +25,4 @@ exports.listen = function (opts, fn) { * Sprintf util. */ -require('s').extend(); +require("s").extend(); diff --git a/test/engine.io.js b/test/engine.io.js index 9387094c9..95f0449a1 100644 --- a/test/engine.io.js +++ b/test/engine.io.js @@ -1,41 +1,40 @@ - /** * Test dependencies. */ -var net = require('net'); -var eio = require('..'); -var listen = require('./common').listen; -var expect = require('expect.js'); -var request = require('superagent'); -var http = require('http'); +var net = require("net"); +var eio = require(".."); +var listen = require("./common").listen; +var expect = require("expect.js"); +var request = require("superagent"); +var http = require("http"); /** * Tests. */ -describe('engine', function () { - it('should expose protocol number', function () { - expect(eio.protocol).to.be.a('number'); +describe("engine", function() { + it("should expose protocol number", function() { + expect(eio.protocol).to.be.a("number"); }); - it('should be the same version as client', function () { - var version = require('../package').version; - expect(version).to.be(require('engine.io-client/package').version); + it("should be the same version as client", function() { + var version = require("../package").version; + expect(version).to.be(require("engine.io-client/package").version); }); - describe('engine()', function () { - it('should create a Server when require called with no arguments', function () { + describe("engine()", function() { + it("should create a Server when require called with no arguments", function() { var engine = eio(); expect(engine).to.be.an(eio.Server); expect(engine.ws).to.be.ok(); }); }); - describe('listen', function () { - it('should open a http server that returns 501', function (done) { - listen(function (port) { - request.get('http://localhost:%d/'.s(port), function (err, res) { + describe("listen", function() { + it("should open a http server that returns 501", function(done) { + listen(function(port) { + request.get("http://localhost:%d/".s(port), function(err, res) { expect(err).to.be.an(Error); expect(res.status).to.be(501); done(); @@ -44,189 +43,205 @@ describe('engine', function () { }); }); - describe('attach()', function () { - it('should work from require()', function () { + describe("attach()", function() { + it("should work from require()", function() { var server = http.createServer(); var engine = eio(server); expect(engine).to.be.an(eio.Server); }); - it('should return an engine.Server', function () { + it("should return an engine.Server", function() { var server = http.createServer(); var engine = eio.attach(server); expect(engine).to.be.an(eio.Server); }); - it('should attach engine to an http server', function (done) { + it("should attach engine to an http server", function(done) { var server = http.createServer(); eio.attach(server); - server.listen(function () { - var uri = 'http://localhost:%d/engine.io/default/'.s(server.address().port); - request.get(uri, function (err, res) { + server.listen(function() { + var uri = "http://localhost:%d/engine.io/default/".s( + server.address().port + ); + request.get(uri, function(err, res) { expect(err).to.be.an(Error); expect(res.status).to.be(400); expect(res.body.code).to.be(0); - expect(res.body.message).to.be('Transport unknown'); - server.once('close', done); + expect(res.body.message).to.be("Transport unknown"); + server.once("close", done); server.close(); }); }); }); - it('should destroy upgrades not handled by engine', function (done) { + it("should destroy upgrades not handled by engine", function(done) { var server = http.createServer(); eio.attach(server, { destroyUpgradeTimeout: 50 }); - server.listen(function () { + server.listen(function() { var client = net.createConnection(server.address().port); - client.setEncoding('ascii'); - client.write([ - 'GET / HTTP/1.1', - 'Connection: Upgrade', - 'Upgrade: IRC/6.9', - '', '' - ].join('\r\n')); - - var check = setTimeout(function () { - done(new Error('Client should have ended')); + client.setEncoding("ascii"); + client.write( + [ + "GET / HTTP/1.1", + "Connection: Upgrade", + "Upgrade: IRC/6.9", + "", + "" + ].join("\r\n") + ); + + var check = setTimeout(function() { + done(new Error("Client should have ended")); }, 100); - client.on('end', function () { + client.on("end", function() { clearTimeout(check); done(); }); }); }); - it('should not destroy unhandled upgrades with destroyUpgrade:false', function (done) { + it("should not destroy unhandled upgrades with destroyUpgrade:false", function(done) { var server = http.createServer(); eio.attach(server, { destroyUpgrade: false, destroyUpgradeTimeout: 50 }); - server.listen(function () { + server.listen(function() { var client = net.createConnection(server.address().port); - client.on('connect', function () { - client.setEncoding('ascii'); - client.write([ - 'GET / HTTP/1.1', - 'Connection: Upgrade', - 'Upgrade: IRC/6.9', - '', '' - ].join('\r\n')); - - setTimeout(function () { - client.removeListener('end', onEnd); + client.on("connect", function() { + client.setEncoding("ascii"); + client.write( + [ + "GET / HTTP/1.1", + "Connection: Upgrade", + "Upgrade: IRC/6.9", + "", + "" + ].join("\r\n") + ); + + setTimeout(function() { + client.removeListener("end", onEnd); done(); }, 100); - function onEnd () { - done(new Error('Client should not end')); + function onEnd() { + done(new Error("Client should not end")); } - client.on('end', onEnd); + client.on("end", onEnd); }); }); }); - it('should destroy unhandled upgrades with after a timeout', function (done) { + it("should destroy unhandled upgrades with after a timeout", function(done) { var server = http.createServer(); eio.attach(server, { destroyUpgradeTimeout: 200 }); - server.listen(function () { + server.listen(function() { var client = net.createConnection(server.address().port); - client.on('connect', function () { - client.setEncoding('ascii'); - client.write([ - 'GET / HTTP/1.1', - 'Connection: Upgrade', - 'Upgrade: IRC/6.9', - '', '' - ].join('\r\n')); + client.on("connect", function() { + client.setEncoding("ascii"); + client.write( + [ + "GET / HTTP/1.1", + "Connection: Upgrade", + "Upgrade: IRC/6.9", + "", + "" + ].join("\r\n") + ); // send from client to server // tests that socket is still alive // this will not keep the socket open as the server does not handle it - setTimeout(function () { - client.write('foo'); + setTimeout(function() { + client.write("foo"); }, 100); - function onEnd () { + function onEnd() { done(); } - client.on('end', onEnd); + client.on("end", onEnd); }); }); }); - it('should not destroy handled upgrades with after a timeout', function (done) { + it("should not destroy handled upgrades with after a timeout", function(done) { var server = http.createServer(); eio.attach(server, { destroyUpgradeTimeout: 100 }); // write to the socket to keep engine.io from closing it by writing before the timeout - server.on('upgrade', function (req, socket) { - socket.write('foo'); - socket.on('data', function (chunk) { - expect(chunk.toString()).to.be('foo'); + server.on("upgrade", function(req, socket) { + socket.write("foo"); + socket.on("data", function(chunk) { + expect(chunk.toString()).to.be("foo"); socket.end(); }); }); - server.listen(function () { + server.listen(function() { var client = net.createConnection(server.address().port); - client.on('connect', function () { - client.setEncoding('ascii'); - client.write([ - 'GET / HTTP/1.1', - 'Connection: Upgrade', - 'Upgrade: IRC/6.9', - '', '' - ].join('\r\n')); + client.on("connect", function() { + client.setEncoding("ascii"); + client.write( + [ + "GET / HTTP/1.1", + "Connection: Upgrade", + "Upgrade: IRC/6.9", + "", + "" + ].join("\r\n") + ); // test that socket is still open by writing after the timeout period - setTimeout(function () { - client.write('foo'); + setTimeout(function() { + client.write("foo"); }, 200); - client.on('data', function (data) { - }); + client.on("data", function(data) {}); - client.on('end', done); + client.on("end", done); }); }); }); - it('should preserve original request listeners', function (done) { + it("should preserve original request listeners", function(done) { var listeners = 0; - var server = http.createServer(function (req, res) { + var server = http.createServer(function(req, res) { expect(req && res).to.be.ok(); listeners++; }); - server.on('request', function (req, res) { + server.on("request", function(req, res) { expect(req && res).to.be.ok(); res.writeHead(200); - res.end(''); + res.end(""); listeners++; }); eio.attach(server); - server.listen(function () { + server.listen(function() { var port = server.address().port; - request.get('http://localhost:%d/engine.io/default/'.s(port), function (err, res) { + request.get("http://localhost:%d/engine.io/default/".s(port), function( + err, + res + ) { expect(err).to.be.an(Error); expect(res.status).to.be(400); expect(res.body.code).to.be(0); - expect(res.body.message).to.be('Transport unknown'); - request.get('http://localhost:%d/test'.s(port), function (err, res) { + expect(res.body.message).to.be("Transport unknown"); + request.get("http://localhost:%d/test".s(port), function(err, res) { expect(err).to.be(null); expect(res.status).to.be(200); expect(listeners).to.eql(2); - server.once('close', done); + server.once("close", done); server.close(); }); }); diff --git a/test/fixtures/server-close-upgraded.js b/test/fixtures/server-close-upgraded.js index dc608d30b..df773cd28 100644 --- a/test/fixtures/server-close-upgraded.js +++ b/test/fixtures/server-close-upgraded.js @@ -1,9 +1,9 @@ -var eioc = require('engine.io-client'); -var listen = require('../common').listen; +var eioc = require("engine.io-client"); +var listen = require("../common").listen; -var engine = listen(function (port) { - var socket = new eioc.Socket('ws://localhost:' + port); - socket.on('upgrade', function () { +var engine = listen(function(port) { + var socket = new eioc.Socket("ws://localhost:" + port); + socket.on("upgrade", function() { engine.httpServer.close(); engine.close(); }); diff --git a/test/fixtures/server-close-upgrading.js b/test/fixtures/server-close-upgrading.js index 4ebfcc52b..f47cfba6a 100644 --- a/test/fixtures/server-close-upgrading.js +++ b/test/fixtures/server-close-upgrading.js @@ -1,9 +1,9 @@ -var eioc = require('engine.io-client'); -var listen = require('../common').listen; +var eioc = require("engine.io-client"); +var listen = require("../common").listen; -var engine = listen(function (port) { - var socket = new eioc.Socket('ws://localhost:' + port); - socket.on('upgrading', function () { +var engine = listen(function(port) { + var socket = new eioc.Socket("ws://localhost:" + port); + socket.on("upgrading", function() { engine.httpServer.close(); engine.close(); }); diff --git a/test/fixtures/server-close.js b/test/fixtures/server-close.js index 07c312094..c1fd4537f 100644 --- a/test/fixtures/server-close.js +++ b/test/fixtures/server-close.js @@ -1,9 +1,9 @@ -var eioc = require('engine.io-client'); -var listen = require('../common').listen; +var eioc = require("engine.io-client"); +var listen = require("../common").listen; -var engine = listen(function (port) { - var socket = new eioc.Socket('ws://localhost:' + port); - socket.on('open', function () { +var engine = listen(function(port) { + var socket = new eioc.Socket("ws://localhost:" + port); + socket.on("open", function() { engine.httpServer.close(); engine.close(); }); diff --git a/test/jsonp.js b/test/jsonp.js index 776582818..39407cd32 100644 --- a/test/jsonp.js +++ b/test/jsonp.js @@ -1,68 +1,68 @@ - /** * Module dependencies. */ -var eioc = require('engine.io-client'); -var listen = require('./common').listen; -var expect = require('expect.js'); -var request = require('superagent'); +var eioc = require("engine.io-client"); +var listen = require("./common").listen; +var expect = require("expect.js"); +var request = require("superagent"); -describe('JSONP', function () { - before(function () { +describe("JSONP", function() { + before(function() { // we have to override the browser's functionality for JSONP - document = { // eslint-disable-line no-global-assign + document = { + // eslint-disable-line no-global-assign body: { - appendChild: function () {}, - removeChild: function () {} + appendChild: function() {}, + removeChild: function() {} } }; - document.createElement = function (name) { + document.createElement = function(name) { var self = this; - if ('script' === name) { + if ("script" === name) { var script = {}; - script.__defineGetter__('parentNode', function () { + script.__defineGetter__("parentNode", function() { return document.body; }); - script.__defineSetter__('src', function (uri) { - request.get(uri).end(function (err, res) { + script.__defineSetter__("src", function(uri) { + request.get(uri).end(function(err, res) { expect(err).to.be(null); eval(res.text); // eslint-disable-line no-eval }); }); return script; - } else if ('form' === name) { + } else if ("form" === name) { var form = { style: {}, - action: '', - parentNode: { removeChild: function () {} }, - removeChild: function () {}, - setAttribute: function () {}, - appendChild: function () {}, - submit: function () { + action: "", + parentNode: { removeChild: function() {} }, + removeChild: function() {}, + setAttribute: function() {}, + appendChild: function() {}, + submit: function() { request .post(this.action) - .type('form') + .type("form") .send({ d: self.areaValue }) - .end(function () {}); + .end(function() {}); } }; return form; - } else if ('textarea' === name) { + } else if ("textarea" === name) { var textarea = {}; // a hack to be able to access the area data when form is sent - textarea.__defineSetter__('value', function (data) { + textarea.__defineSetter__("value", function(data) { self.areaValue = data; }); return textarea; - } else if (~name.indexOf('iframe')) { + } else if (~name.indexOf("iframe")) { var iframe = {}; - setTimeout(function () { + setTimeout(function() { if (iframe.onload) iframe.onload(); }, 0); @@ -72,102 +72,116 @@ describe('JSONP', function () { } }; - document.getElementsByTagName = function (name) { - return [{ - parentNode: { - insertBefore: function () {} + document.getElementsByTagName = function(name) { + return [ + { + parentNode: { + insertBefore: function() {} + } } - }]; + ]; }; }); - after(function () { + after(function() { delete document.getElementsByTagName; delete document.createElement; delete global.document; }); - describe('handshake', function () { - it('should open with polling JSONP when requested', function (done) { - var engine = listen({ allowUpgrades: false, transports: ['polling'] }, function (port) { - eioc('ws://localhost:' + port, - { transports: ['polling'], forceJSONP: true, upgrade: false }); - engine.on('connection', function (socket) { - expect(socket.transport.name).to.be('polling'); - expect(socket.transport.head).to.be('___eio[0]('); - done(); - }); - }); + describe("handshake", function() { + it("should open with polling JSONP when requested", function(done) { + var engine = listen( + { allowUpgrades: false, transports: ["polling"] }, + function(port) { + eioc("ws://localhost:" + port, { + transports: ["polling"], + forceJSONP: true, + upgrade: false + }); + engine.on("connection", function(socket) { + expect(socket.transport.name).to.be("polling"); + expect(socket.transport.head).to.be("___eio[0]("); + done(); + }); + } + ); }); }); - describe('messages', function () { + describe("messages", function() { var engine, port, socket; - beforeEach(function (done) { - engine = listen({ allowUpgrades: false, transports: ['polling'] }, function (p) { - port = p; + beforeEach(function(done) { + engine = listen( + { allowUpgrades: false, transports: ["polling"] }, + function(p) { + port = p; - socket = new eioc.Socket('ws://localhost:' + port - , { transports: ['polling'], forceJSONP: true, upgrade: false }); + socket = new eioc.Socket("ws://localhost:" + port, { + transports: ["polling"], + forceJSONP: true, + upgrade: false + }); - done(); - }); + done(); + } + ); }); - it('should arrive from client to server and back (pollingJSONP)', function (done) { - engine.on('connection', function (conn) { - conn.on('message', function (msg) { - conn.send('a'); + it("should arrive from client to server and back (pollingJSONP)", function(done) { + engine.on("connection", function(conn) { + conn.on("message", function(msg) { + conn.send("a"); }); }); - socket.on('open', function () { - socket.send('a'); - socket.on('message', function (msg) { + socket.on("open", function() { + socket.send("a"); + socket.on("message", function(msg) { expect(socket.transport.query.j).to.not.be(undefined); - expect(msg).to.be('a'); + expect(msg).to.be("a"); done(); }); }); }); - it('should not fail JSON.parse for stringified messages', function (done) { - engine.on('connection', function (conn) { - conn.on('message', function (message) { - expect(JSON.parse(message)).to.be.eql({test: 'a\r\nb\n\n\n\nc'}); + it("should not fail JSON.parse for stringified messages", function(done) { + engine.on("connection", function(conn) { + conn.on("message", function(message) { + expect(JSON.parse(message)).to.be.eql({ test: "a\r\nb\n\n\n\nc" }); done(); }); }); - socket.on('open', function () { - socket.send(JSON.stringify({test: 'a\r\nb\n\n\n\nc'})); + socket.on("open", function() { + socket.send(JSON.stringify({ test: "a\r\nb\n\n\n\nc" })); }); }); - it('should parse newlines in message correctly', function (done) { - engine.on('connection', function (conn) { - conn.on('message', function (message) { - expect(message).to.be.equal('a\r\nb\n\n\n\nc'); + it("should parse newlines in message correctly", function(done) { + engine.on("connection", function(conn) { + conn.on("message", function(message) { + expect(message).to.be.equal("a\r\nb\n\n\n\nc"); done(); }); }); - socket.on('open', function () { - socket.send('a\r\nb\n\n\n\nc'); + socket.on("open", function() { + socket.send("a\r\nb\n\n\n\nc"); }); }); - it('should arrive from server to client and back with binary data (pollingJSONP)', function (done) { + it("should arrive from server to client and back with binary data (pollingJSONP)", function(done) { var binaryData = Buffer.allocUnsafe(5); for (var i = 0; i < 5; i++) binaryData[i] = i; - engine.on('connection', function (conn) { - conn.on('message', function (msg) { + engine.on("connection", function(conn) { + conn.on("message", function(msg) { conn.send(msg); }); }); - socket.on('open', function () { + socket.on("open", function() { socket.send(binaryData); - socket.on('message', function (msg) { + socket.on("message", function(msg) { for (var i = 0; i < msg.length; i++) expect(msg[i]).to.be(i); done(); }); @@ -175,57 +189,69 @@ describe('JSONP', function () { }); }); - describe('close', function () { - it('should trigger when server closes a client', function (done) { - var engine = listen({ allowUpgrades: false, transports: ['polling'] }, function (port) { - var socket = new eioc.Socket('ws://localhost:' + port, - { transports: ['polling'], forceJSONP: true, upgrade: false }); - var total = 2; - - engine.on('connection', function (conn) { - conn.on('close', function (reason) { - expect(reason).to.be('forced close'); - --total || done(); + describe("close", function() { + it("should trigger when server closes a client", function(done) { + var engine = listen( + { allowUpgrades: false, transports: ["polling"] }, + function(port) { + var socket = new eioc.Socket("ws://localhost:" + port, { + transports: ["polling"], + forceJSONP: true, + upgrade: false }); - setTimeout(function () { - conn.close(); - }, 10); - }); + var total = 2; - socket.on('open', function () { - socket.on('close', function (reason) { - expect(reason).to.be('transport close'); - --total || done(); + engine.on("connection", function(conn) { + conn.on("close", function(reason) { + expect(reason).to.be("forced close"); + --total || done(); + }); + setTimeout(function() { + conn.close(); + }, 10); }); - }); - }); - }); - it('should trigger when client closes', function (done) { - var engine = listen({ allowUpgrades: false, transports: ['polling'] }, function (port) { - var socket = new eioc.Socket('ws://localhost:' + port - , { transports: ['polling'], forceJSONP: true, upgrade: false }); - var total = 2; + socket.on("open", function() { + socket.on("close", function(reason) { + expect(reason).to.be("transport close"); + --total || done(); + }); + }); + } + ); + }); - engine.on('connection', function (conn) { - conn.on('close', function (reason) { - expect(reason).to.be('transport close'); - --total || done(); + it("should trigger when client closes", function(done) { + var engine = listen( + { allowUpgrades: false, transports: ["polling"] }, + function(port) { + var socket = new eioc.Socket("ws://localhost:" + port, { + transports: ["polling"], + forceJSONP: true, + upgrade: false }); - }); + var total = 2; - socket.on('open', function () { - socket.send('a'); - socket.on('close', function (reason) { - expect(reason).to.be('forced close'); - --total || done(); + engine.on("connection", function(conn) { + conn.on("close", function(reason) { + expect(reason).to.be("transport close"); + --total || done(); + }); }); - setTimeout(function () { - socket.close(); - }, 10); - }); - }); + socket.on("open", function() { + socket.send("a"); + socket.on("close", function(reason) { + expect(reason).to.be("forced close"); + --total || done(); + }); + + setTimeout(function() { + socket.close(); + }, 10); + }); + } + ); }); }); }); diff --git a/test/server.js b/test/server.js index 9da4d109b..0f4c6352f 100644 --- a/test/server.js +++ b/test/server.js @@ -4,235 +4,288 @@ * Tests dependencies. */ -var http = require('http'); -var https = require('https'); -var fs = require('fs'); -var path = require('path'); -var exec = require('child_process').exec; -var zlib = require('zlib'); -var eio = require('..'); -var eioc = require('engine.io-client'); -var listen = require('./common').listen; -var expect = require('expect.js'); -var request = require('superagent'); -var cookieMod = require('cookie'); +var http = require("http"); +var https = require("https"); +var fs = require("fs"); +var path = require("path"); +var exec = require("child_process").exec; +var zlib = require("zlib"); +var eio = require(".."); +var eioc = require("engine.io-client"); +var listen = require("./common").listen; +var expect = require("expect.js"); +var request = require("superagent"); +var cookieMod = require("cookie"); // are we running on node < 4.4.3 ? -var NODE_LT_443 = (function () { - var parts = process.versions.node.split('.'); - return (parts[0] < 4 || parts[1] < 4 || parts[2] < 3); +var NODE_LT_443 = (function() { + var parts = process.versions.node.split("."); + return parts[0] < 4 || parts[1] < 4 || parts[2] < 3; })(); // are we running uws wsEngine ? -var UWS_ENGINE = process.env.EIO_WS_ENGINE === 'uws'; +var UWS_ENGINE = process.env.EIO_WS_ENGINE === "uws"; /** * Tests. */ -describe('server', function () { - describe('verification', function () { - it('should disallow non-existent transports', function (done) { - listen(function (port) { - request.get('http://localhost:%d/engine.io/default/'.s(port)) - .query({ transport: 'tobi' }) // no tobi transport - outrageous - .end(function (err, res) { +describe("server", function() { + describe("verification", function() { + it("should disallow non-existent transports", function(done) { + listen(function(port) { + request + .get("http://localhost:%d/engine.io/default/".s(port)) + .query({ transport: "tobi" }) // no tobi transport - outrageous + .end(function(err, res) { expect(err).to.be.an(Error); expect(res.status).to.be(400); expect(res.body.code).to.be(0); - expect(res.body.message).to.be('Transport unknown'); - expect(res.header['access-control-allow-origin']).to.be('*'); + expect(res.body.message).to.be("Transport unknown"); + expect(res.header["access-control-allow-origin"]).to.be("*"); done(); }); }); }); - it('should disallow `constructor` as transports', function (done) { + it("should disallow `constructor` as transports", function(done) { // make sure we check for actual properties - not those present on every {} - listen(function (port) { - request.get('http://localhost:%d/engine.io/default/'.s(port)) - .set('Origin', 'http://engine.io') - .query({ transport: 'constructor' }) - .end(function (err, res) { + listen(function(port) { + request + .get("http://localhost:%d/engine.io/default/".s(port)) + .set("Origin", "http://engine.io") + .query({ transport: "constructor" }) + .end(function(err, res) { expect(err).to.be.an(Error); expect(res.status).to.be(400); expect(res.body.code).to.be(0); - expect(res.body.message).to.be('Transport unknown'); - expect(res.header['access-control-allow-credentials']).to.be('true'); - expect(res.header['access-control-allow-origin']).to.be('http://engine.io'); + expect(res.body.message).to.be("Transport unknown"); + expect(res.header["access-control-allow-credentials"]).to.be( + "true" + ); + expect(res.header["access-control-allow-origin"]).to.be( + "http://engine.io" + ); done(); }); }); }); - it('should disallow non-existent sids', function (done) { - listen(function (port) { - request.get('http://localhost:%d/engine.io/default/'.s(port)) - .set('Origin', 'http://engine.io') - .query({ transport: 'polling', sid: 'test' }) - .end(function (err, res) { + it("should disallow non-existent sids", function(done) { + listen(function(port) { + request + .get("http://localhost:%d/engine.io/default/".s(port)) + .set("Origin", "http://engine.io") + .query({ transport: "polling", sid: "test" }) + .end(function(err, res) { expect(err).to.be.an(Error); expect(res.status).to.be(400); expect(res.body.code).to.be(1); - expect(res.body.message).to.be('Session ID unknown'); - expect(res.header['access-control-allow-credentials']).to.be('true'); - expect(res.header['access-control-allow-origin']).to.be('http://engine.io'); + expect(res.body.message).to.be("Session ID unknown"); + expect(res.header["access-control-allow-credentials"]).to.be( + "true" + ); + expect(res.header["access-control-allow-origin"]).to.be( + "http://engine.io" + ); done(); }); }); }); - it('should disallow requests that are rejected by `allowRequest`', function (done) { - listen({ allowRequest: function (req, fn) { fn('Thou shall not pass', false); } }, function (port) { - request.get('http://localhost:%d/engine.io/default/'.s(port)) - .set('Origin', 'http://engine.io') - .query({ transport: 'polling' }) - .end(function (err, res) { - expect(err).to.be.an(Error); - expect(res.status).to.be(403); - expect(res.body.code).to.be(4); - expect(res.body.message).to.be('Thou shall not pass'); - expect(res.header['access-control-allow-credentials']).to.be(undefined); - expect(res.header['access-control-allow-origin']).to.be(undefined); - done(); - }); - }); + it("should disallow requests that are rejected by `allowRequest`", function(done) { + listen( + { + allowRequest: function(req, fn) { + fn("Thou shall not pass", false); + } + }, + function(port) { + request + .get("http://localhost:%d/engine.io/default/".s(port)) + .set("Origin", "http://engine.io") + .query({ transport: "polling" }) + .end(function(err, res) { + expect(err).to.be.an(Error); + expect(res.status).to.be(403); + expect(res.body.code).to.be(4); + expect(res.body.message).to.be("Thou shall not pass"); + expect(res.header["access-control-allow-credentials"]).to.be( + undefined + ); + expect(res.header["access-control-allow-origin"]).to.be( + undefined + ); + done(); + }); + } + ); }); - it('should disallow connection that are rejected by `allowRequest`', function (done) { - listen({ allowRequest: function (req, fn) { fn(null, false); } }, function (port) { - var client = eioc('ws://localhost:%d'.s(port), { transports: ['websocket'] }); - client.on('error', function () { - done(); - }); - }); + it("should disallow connection that are rejected by `allowRequest`", function(done) { + listen( + { + allowRequest: function(req, fn) { + fn(null, false); + } + }, + function(port) { + var client = eioc("ws://localhost:%d".s(port), { + transports: ["websocket"] + }); + client.on("error", function() { + done(); + }); + } + ); }); }); - describe('handshake', function () { - it('should send the io cookie', function (done) { - listen(function (port) { - request.get('http://localhost:%d/engine.io/default/'.s(port)) - .query({ transport: 'polling', b64: 1 }) - .end(function (err, res) { + describe("handshake", function() { + it("should send the io cookie", function(done) { + listen(function(port) { + request + .get("http://localhost:%d/engine.io/default/".s(port)) + .query({ transport: "polling", b64: 1 }) + .end(function(err, res) { expect(err).to.be(null); // hack-obtain sid var sid = res.text.match(/"sid":"([^"]+)"/)[1]; - expect(res.headers['set-cookie'][0]).to.be('io=' + sid + '; Path=/; HttpOnly'); + expect(res.headers["set-cookie"][0]).to.be( + "io=" + sid + "; Path=/; HttpOnly" + ); done(); }); }); }); - it('should send the io cookie custom name', function (done) { - listen({ cookie: 'woot' }, function (port) { - request.get('http://localhost:%d/engine.io/default/'.s(port)) - .query({ transport: 'polling', b64: 1 }) - .end(function (err, res) { + it("should send the io cookie custom name", function(done) { + listen({ cookie: "woot" }, function(port) { + request + .get("http://localhost:%d/engine.io/default/".s(port)) + .query({ transport: "polling", b64: 1 }) + .end(function(err, res) { expect(err).to.be(null); var sid = res.text.match(/"sid":"([^"]+)"/)[1]; - expect(res.headers['set-cookie'][0]).to.be('woot=' + sid + '; Path=/; HttpOnly'); + expect(res.headers["set-cookie"][0]).to.be( + "woot=" + sid + "; Path=/; HttpOnly" + ); done(); }); }); }); - it('should send the cookie with custom path', function (done) { - listen({ cookiePath: '/custom' }, function (port) { - request.get('http://localhost:%d/engine.io/default/'.s(port)) - .query({ transport: 'polling', b64: 1 }) - .end(function (err, res) { + it("should send the cookie with custom path", function(done) { + listen({ cookiePath: "/custom" }, function(port) { + request + .get("http://localhost:%d/engine.io/default/".s(port)) + .query({ transport: "polling", b64: 1 }) + .end(function(err, res) { expect(err).to.be(null); var sid = res.text.match(/"sid":"([^"]+)"/)[1]; - expect(res.headers['set-cookie'][0]).to.be('io=' + sid + '; Path=/custom; HttpOnly'); + expect(res.headers["set-cookie"][0]).to.be( + "io=" + sid + "; Path=/custom; HttpOnly" + ); done(); }); }); }); - it('should send the cookie with path=false', function (done) { - listen({ cookiePath: false }, function (port) { - request.get('http://localhost:%d/engine.io/default/'.s(port)) - .query({ transport: 'polling', b64: 1 }) - .end(function (err, res) { + it("should send the cookie with path=false", function(done) { + listen({ cookiePath: false }, function(port) { + request + .get("http://localhost:%d/engine.io/default/".s(port)) + .query({ transport: "polling", b64: 1 }) + .end(function(err, res) { expect(err).to.be(null); var sid = res.text.match(/"sid":"([^"]+)"/)[1]; - expect(res.headers['set-cookie'][0]).to.be('io=' + sid); + expect(res.headers["set-cookie"][0]).to.be("io=" + sid); done(); }); }); }); - it('should send the io cookie with httpOnly=true', function (done) { - listen({ cookieHttpOnly: true }, function (port) { - request.get('http://localhost:%d/engine.io/default/'.s(port)) - .query({ transport: 'polling', b64: 1 }) - .end(function (err, res) { + it("should send the io cookie with httpOnly=true", function(done) { + listen({ cookieHttpOnly: true }, function(port) { + request + .get("http://localhost:%d/engine.io/default/".s(port)) + .query({ transport: "polling", b64: 1 }) + .end(function(err, res) { expect(err).to.be(null); var sid = res.text.match(/"sid":"([^"]+)"/)[1]; - expect(res.headers['set-cookie'][0]).to.be('io=' + sid + '; Path=/; HttpOnly'); + expect(res.headers["set-cookie"][0]).to.be( + "io=" + sid + "; Path=/; HttpOnly" + ); done(); }); }); }); - it('should send the io cookie with httpOnly=true and path=false', function (done) { - listen({ cookieHttpOnly: true, cookiePath: false }, function (port) { - request.get('http://localhost:%d/engine.io/default/'.s(port)) - .query({ transport: 'polling', b64: 1 }) - .end(function (err, res) { + it("should send the io cookie with httpOnly=true and path=false", function(done) { + listen({ cookieHttpOnly: true, cookiePath: false }, function(port) { + request + .get("http://localhost:%d/engine.io/default/".s(port)) + .query({ transport: "polling", b64: 1 }) + .end(function(err, res) { expect(err).to.be(null); var sid = res.text.match(/"sid":"([^"]+)"/)[1]; - expect(res.headers['set-cookie'][0]).to.be('io=' + sid); + expect(res.headers["set-cookie"][0]).to.be("io=" + sid); done(); }); }); }); - it('should send the io cookie with httpOnly=false', function (done) { - listen({ cookieHttpOnly: false }, function (port) { - request.get('http://localhost:%d/engine.io/default/'.s(port)) - .query({ transport: 'polling', b64: 1 }) - .end(function (err, res) { + it("should send the io cookie with httpOnly=false", function(done) { + listen({ cookieHttpOnly: false }, function(port) { + request + .get("http://localhost:%d/engine.io/default/".s(port)) + .query({ transport: "polling", b64: 1 }) + .end(function(err, res) { expect(err).to.be(null); var sid = res.text.match(/"sid":"([^"]+)"/)[1]; - expect(res.headers['set-cookie'][0]).to.be('io=' + sid + '; Path=/'); + expect(res.headers["set-cookie"][0]).to.be( + "io=" + sid + "; Path=/" + ); done(); }); }); }); - it('should send the io cookie with httpOnly not boolean', function (done) { - listen({ cookieHttpOnly: 'no' }, function (port) { - request.get('http://localhost:%d/engine.io/default/'.s(port)) - .query({ transport: 'polling', b64: 1 }) - .end(function (err, res) { + it("should send the io cookie with httpOnly not boolean", function(done) { + listen({ cookieHttpOnly: "no" }, function(port) { + request + .get("http://localhost:%d/engine.io/default/".s(port)) + .query({ transport: "polling", b64: 1 }) + .end(function(err, res) { expect(err).to.be(null); var sid = res.text.match(/"sid":"([^"]+)"/)[1]; - expect(res.headers['set-cookie'][0]).to.be('io=' + sid + '; Path=/; HttpOnly'); + expect(res.headers["set-cookie"][0]).to.be( + "io=" + sid + "; Path=/; HttpOnly" + ); done(); }); }); }); - it('should not send the io cookie', function (done) { - listen({ cookie: false }, function (port) { - request.get('http://localhost:%d/engine.io/default/'.s(port)) - .query({ transport: 'polling' }) - .end(function (err, res) { + it("should not send the io cookie", function(done) { + listen({ cookie: false }, function(port) { + request + .get("http://localhost:%d/engine.io/default/".s(port)) + .query({ transport: "polling" }) + .end(function(err, res) { expect(err).to.be(null); - expect(res.headers['set-cookie']).to.be(undefined); + expect(res.headers["set-cookie"]).to.be(undefined); done(); }); }); }); - it('should register a new client', function (done) { - var engine = listen({ allowUpgrades: false }, function (port) { + it("should register a new client", function(done) { + var engine = listen({ allowUpgrades: false }, function(port) { expect(Object.keys(engine.clients)).to.have.length(0); expect(engine.clientsCount).to.be(0); - var socket = new eioc.Socket('ws://localhost:%d'.s(port)); - socket.on('open', function () { + var socket = new eioc.Socket("ws://localhost:%d".s(port)); + socket.on("open", function() { expect(Object.keys(engine.clients)).to.have.length(1); expect(engine.clientsCount).to.be(1); done(); @@ -240,19 +293,19 @@ describe('server', function () { }); }); - it('should register a new client with custom id', function (done) { - var engine = listen({ allowUpgrades: false }, function (port) { + it("should register a new client with custom id", function(done) { + var engine = listen({ allowUpgrades: false }, function(port) { expect(Object.keys(engine.clients)).to.have.length(0); expect(engine.clientsCount).to.be(0); - var customId = 'CustomId' + Date.now(); + var customId = "CustomId" + Date.now(); - engine.generateId = function (req) { + engine.generateId = function(req) { return customId; }; - var socket = new eioc.Socket('ws://localhost:%d'.s(port)); - socket.once('open', function () { + var socket = new eioc.Socket("ws://localhost:%d".s(port)); + socket.once("open", function() { expect(Object.keys(engine.clients)).to.have.length(1); expect(engine.clientsCount).to.be(1); expect(socket.id).to.be(customId); @@ -262,119 +315,122 @@ describe('server', function () { }); }); - it('should exchange handshake data', function (done) { - listen({ allowUpgrades: false }, function (port) { - var socket = new eioc.Socket('ws://localhost:%d'.s(port)); - socket.on('handshake', function (obj) { - expect(obj.sid).to.be.a('string'); - expect(obj.pingTimeout).to.be.a('number'); - expect(obj.upgrades).to.be.an('array'); + it("should exchange handshake data", function(done) { + listen({ allowUpgrades: false }, function(port) { + var socket = new eioc.Socket("ws://localhost:%d".s(port)); + socket.on("handshake", function(obj) { + expect(obj.sid).to.be.a("string"); + expect(obj.pingTimeout).to.be.a("number"); + expect(obj.upgrades).to.be.an("array"); done(); }); }); }); - it('should allow custom ping timeouts', function (done) { - listen({ allowUpgrades: false, pingTimeout: 123 }, function (port) { - var socket = new eioc.Socket('http://localhost:%d'.s(port)); - socket.on('handshake', function (obj) { + it("should allow custom ping timeouts", function(done) { + listen({ allowUpgrades: false, pingTimeout: 123 }, function(port) { + var socket = new eioc.Socket("http://localhost:%d".s(port)); + socket.on("handshake", function(obj) { expect(obj.pingTimeout).to.be(123); done(); }); }); }); - it('should trigger a connection event with a Socket', function (done) { - var engine = listen({ allowUpgrades: false }, function (port) { - eioc('ws://localhost:%d'.s(port)); - engine.on('connection', function (socket) { + it("should trigger a connection event with a Socket", function(done) { + var engine = listen({ allowUpgrades: false }, function(port) { + eioc("ws://localhost:%d".s(port)); + engine.on("connection", function(socket) { expect(socket).to.be.an(eio.Socket); done(); }); }); }); - it('should open with polling by default', function (done) { - var engine = listen({ allowUpgrades: false }, function (port) { - eioc('ws://localhost:%d'.s(port)); - engine.on('connection', function (socket) { - expect(socket.transport.name).to.be('polling'); + it("should open with polling by default", function(done) { + var engine = listen({ allowUpgrades: false }, function(port) { + eioc("ws://localhost:%d".s(port)); + engine.on("connection", function(socket) { + expect(socket.transport.name).to.be("polling"); done(); }); }); }); - it('should be able to open with ws directly', function (done) { - var engine = listen({ transports: ['websocket'] }, function (port) { - eioc('ws://localhost:%d'.s(port), { transports: ['websocket'] }); - engine.on('connection', function (socket) { - expect(socket.transport.name).to.be('websocket'); + it("should be able to open with ws directly", function(done) { + var engine = listen({ transports: ["websocket"] }, function(port) { + eioc("ws://localhost:%d".s(port), { transports: ["websocket"] }); + engine.on("connection", function(socket) { + expect(socket.transport.name).to.be("websocket"); done(); }); }); }); - it('should not suggest any upgrades for websocket', function (done) { - listen({ transports: ['websocket'] }, function (port) { - var socket = new eioc.Socket('ws://localhost:%d'.s(port), { transports: ['websocket'] }); - socket.on('handshake', function (obj) { + it("should not suggest any upgrades for websocket", function(done) { + listen({ transports: ["websocket"] }, function(port) { + var socket = new eioc.Socket("ws://localhost:%d".s(port), { + transports: ["websocket"] + }); + socket.on("handshake", function(obj) { expect(obj.upgrades).to.have.length(0); done(); }); }); }); - it('should not suggest upgrades when none are availble', function (done) { - listen({ transports: ['polling'] }, function (port) { - var socket = new eioc.Socket('ws://localhost:%d'.s(port), { }); - socket.on('handshake', function (obj) { + it("should not suggest upgrades when none are availble", function(done) { + listen({ transports: ["polling"] }, function(port) { + var socket = new eioc.Socket("ws://localhost:%d".s(port), {}); + socket.on("handshake", function(obj) { expect(obj.upgrades).to.have.length(0); done(); }); }); }); - it('should only suggest available upgrades', function (done) { - listen({ transports: ['polling'] }, function (port) { - var socket = new eioc.Socket('ws://localhost:%d'.s(port), { }); - socket.on('handshake', function (obj) { + it("should only suggest available upgrades", function(done) { + listen({ transports: ["polling"] }, function(port) { + var socket = new eioc.Socket("ws://localhost:%d".s(port), {}); + socket.on("handshake", function(obj) { expect(obj.upgrades).to.have.length(0); done(); }); }); }); - it('should suggest all upgrades when no transports are disabled', function (done) { - listen({}, function (port) { - var socket = new eioc.Socket('ws://localhost:%d'.s(port), { }); - socket.on('handshake', function (obj) { + it("should suggest all upgrades when no transports are disabled", function(done) { + listen({}, function(port) { + var socket = new eioc.Socket("ws://localhost:%d".s(port), {}); + socket.on("handshake", function(obj) { expect(obj.upgrades).to.have.length(1); - expect(obj.upgrades).to.have.contain('websocket'); + expect(obj.upgrades).to.have.contain("websocket"); done(); }); }); }); - it('default to polling when proxy doesn\'t support websocket', function (done) { - var engine = listen({ allowUpgrades: false }, function (port) { - engine.on('connection', function (socket) { - socket.on('message', function (msg) { - if ('echo' === msg) socket.send(msg); + it("default to polling when proxy doesn't support websocket", function(done) { + var engine = listen({ allowUpgrades: false }, function(port) { + engine.on("connection", function(socket) { + socket.on("message", function(msg) { + if ("echo" === msg) socket.send(msg); }); }); - var socket = new eioc.Socket('ws://localhost:%d'.s(port)); - socket.on('open', function () { - request.get('http://localhost:%d/engine.io/'.s(port)) - .set({ connection: 'close' }) - .query({ transport: 'websocket', sid: socket.id }) - .end(function (err, res) { + var socket = new eioc.Socket("ws://localhost:%d".s(port)); + socket.on("open", function() { + request + .get("http://localhost:%d/engine.io/".s(port)) + .set({ connection: "close" }) + .query({ transport: "websocket", sid: socket.id }) + .end(function(err, res) { expect(err).to.be.an(Error); expect(res.status).to.be(400); expect(res.body.code).to.be(3); - socket.send('echo'); - socket.on('message', function (msg) { - expect(msg).to.be('echo'); + socket.send("echo"); + socket.on("message", function(msg) { + expect(msg).to.be("echo"); done(); }); }); @@ -382,52 +438,57 @@ describe('server', function () { }); }); - it('should allow arbitrary data through query string', function (done) { - var engine = listen({ allowUpgrades: false }, function (port) { - eioc('ws://localhost:%d'.s(port), { query: { a: 'b' } }); - engine.on('connection', function (conn) { - expect(conn.request._query).to.have.keys('transport', 'a'); - expect(conn.request._query.a).to.be('b'); + it("should allow arbitrary data through query string", function(done) { + var engine = listen({ allowUpgrades: false }, function(port) { + eioc("ws://localhost:%d".s(port), { query: { a: "b" } }); + engine.on("connection", function(conn) { + expect(conn.request._query).to.have.keys("transport", "a"); + expect(conn.request._query.a).to.be("b"); done(); }); }); }); - it('should allow data through query string in uri', function (done) { - var engine = listen({ allowUpgrades: false }, function (port) { - eioc('ws://localhost:%d?a=b&c=d'.s(port)); - engine.on('connection', function (conn) { - expect(conn.request._query.EIO).to.be.a('string'); - expect(conn.request._query.a).to.be('b'); - expect(conn.request._query.c).to.be('d'); + it("should allow data through query string in uri", function(done) { + var engine = listen({ allowUpgrades: false }, function(port) { + eioc("ws://localhost:%d?a=b&c=d".s(port)); + engine.on("connection", function(conn) { + expect(conn.request._query.EIO).to.be.a("string"); + expect(conn.request._query.a).to.be("b"); + expect(conn.request._query.c).to.be("d"); done(); }); }); }); - it('should disallow bad requests', function (done) { - listen(function (port) { - request.get('http://localhost:%d/engine.io/default/'.s(port)) - .set('Origin', 'http://engine.io') - .query({ transport: 'websocket' }) - .end(function (err, res) { + it("should disallow bad requests", function(done) { + listen(function(port) { + request + .get("http://localhost:%d/engine.io/default/".s(port)) + .set("Origin", "http://engine.io") + .query({ transport: "websocket" }) + .end(function(err, res) { expect(err).to.be.an(Error); expect(res.status).to.be(400); expect(res.body.code).to.be(3); - expect(res.body.message).to.be('Bad request'); - expect(res.header['access-control-allow-credentials']).to.be('true'); - expect(res.header['access-control-allow-origin']).to.be('http://engine.io'); + expect(res.body.message).to.be("Bad request"); + expect(res.header["access-control-allow-credentials"]).to.be( + "true" + ); + expect(res.header["access-control-allow-origin"]).to.be( + "http://engine.io" + ); done(); }); }); }); - it('should send a packet along with the handshake', function (done) { - listen({ initialPacket: 'faster!' }, function (port) { - var socket = new eioc.Socket('ws://localhost:%d'.s(port)); - socket.on('open', function () { - socket.on('message', function (msg) { - expect(msg).to.be('faster!'); + it("should send a packet along with the handshake", function(done) { + listen({ initialPacket: "faster!" }, function(port) { + var socket = new eioc.Socket("ws://localhost:%d".s(port)); + socket.on("open", function() { + socket.on("message", function(msg) { + expect(msg).to.be("faster!"); done(); }); }); @@ -435,68 +496,68 @@ describe('server', function () { }); }); - describe('close', function () { - it('should be able to access non-empty writeBuffer at closing (server)', function (done) { - var opts = {allowUpgrades: false}; - var engine = listen(opts, function (port) { - eioc('http://localhost:%d'.s(port)); - engine.on('connection', function (conn) { - conn.on('close', function (reason) { + describe("close", function() { + it("should be able to access non-empty writeBuffer at closing (server)", function(done) { + var opts = { allowUpgrades: false }; + var engine = listen(opts, function(port) { + eioc("http://localhost:%d".s(port)); + engine.on("connection", function(conn) { + conn.on("close", function(reason) { expect(conn.writeBuffer.length).to.be(1); - setTimeout(function () { + setTimeout(function() { expect(conn.writeBuffer.length).to.be(0); // writeBuffer has been cleared }, 10); done(); }); - conn.writeBuffer.push({ type: 'message', data: 'foo' }); - conn.onError(''); + conn.writeBuffer.push({ type: "message", data: "foo" }); + conn.onError(""); }); }); }); - it('should be able to access non-empty writeBuffer at closing (client)', function (done) { - var opts = {allowUpgrades: false}; - listen(opts, function (port) { - var socket = new eioc.Socket('http://localhost:%d'.s(port)); - socket.on('open', function () { - socket.on('close', function (reason) { + it("should be able to access non-empty writeBuffer at closing (client)", function(done) { + var opts = { allowUpgrades: false }; + listen(opts, function(port) { + var socket = new eioc.Socket("http://localhost:%d".s(port)); + socket.on("open", function() { + socket.on("close", function(reason) { expect(socket.writeBuffer.length).to.be(1); - setTimeout(function () { + setTimeout(function() { expect(socket.writeBuffer.length).to.be(0); }, 10); done(); }); - socket.writeBuffer.push({ type: 'message', data: 'foo' }); - socket.onError(''); + socket.writeBuffer.push({ type: "message", data: "foo" }); + socket.onError(""); }); }); }); - it('should trigger on server if the client does not pong', function (done) { + it("should trigger on server if the client does not pong", function(done) { var opts = { allowUpgrades: false, pingInterval: 5, pingTimeout: 5 }; - var engine = listen(opts, function (port) { - var socket = new eioc.Socket('http://localhost:%d'.s(port)); - socket.sendPacket = function () {}; - engine.on('connection', function (conn) { - conn.on('close', function (reason) { - expect(reason).to.be('ping timeout'); + var engine = listen(opts, function(port) { + var socket = new eioc.Socket("http://localhost:%d".s(port)); + socket.sendPacket = function() {}; + engine.on("connection", function(conn) { + conn.on("close", function(reason) { + expect(reason).to.be("ping timeout"); done(); }); }); }); }); - it('should trigger on server even when there is no outstanding polling request (GH-198)', function (done) { + it("should trigger on server even when there is no outstanding polling request (GH-198)", function(done) { var opts = { allowUpgrades: false, pingInterval: 500, pingTimeout: 500 }; - var engine = listen(opts, function (port) { - var socket = new eioc.Socket('http://localhost:%d'.s(port)); - engine.on('connection', function (conn) { - conn.on('close', function (reason) { - expect(reason).to.be('ping timeout'); + var engine = listen(opts, function(port) { + var socket = new eioc.Socket("http://localhost:%d".s(port)); + engine.on("connection", function(conn) { + conn.on("close", function(reason) { + expect(reason).to.be("ping timeout"); done(); }); // client abruptly disconnects, no polling request on this tick since we've just connected - socket.sendPacket = socket.onPacket = function () {}; + socket.sendPacket = socket.onPacket = function() {}; socket.close(); // then server app tries to close the socket, since client disappeared conn.close(); @@ -504,441 +565,474 @@ describe('server', function () { }); }); - it('should trigger on client if server does not meet ping timeout', function (done) { + it("should trigger on client if server does not meet ping timeout", function(done) { var opts = { allowUpgrades: false, pingInterval: 50, pingTimeout: 30 }; - listen(opts, function (port) { - var socket = new eioc.Socket('ws://localhost:%d'.s(port)); - socket.on('open', function () { + listen(opts, function(port) { + var socket = new eioc.Socket("ws://localhost:%d".s(port)); + socket.on("open", function() { // override onPacket and Transport#onClose to simulate an inactive server after handshake - socket.onPacket = function () {}; - socket.transport.onClose = function () {}; - socket.on('close', function (reason, err) { - expect(reason).to.be('ping timeout'); + socket.onPacket = function() {}; + socket.transport.onClose = function() {}; + socket.on("close", function(reason, err) { + expect(reason).to.be("ping timeout"); done(); }); }); }); }); - it('should trigger on both ends upon ping timeout', function (done) { + it("should trigger on both ends upon ping timeout", function(done) { var opts = { allowUpgrades: false, pingTimeout: 50, pingInterval: 50 }; - var engine = listen(opts, function (port) { - var socket = new eioc.Socket('ws://localhost:%d'.s(port)); + var engine = listen(opts, function(port) { + var socket = new eioc.Socket("ws://localhost:%d".s(port)); var total = 2; - function onClose (reason, err) { - expect(reason).to.be('ping timeout'); + function onClose(reason, err) { + expect(reason).to.be("ping timeout"); --total || done(); } - engine.on('connection', function (conn) { - conn.on('close', onClose); + engine.on("connection", function(conn) { + conn.on("close", onClose); }); - socket.on('open', function () { + socket.on("open", function() { // override onPacket and Transport#onClose to simulate an inactive server after handshake - socket.onPacket = socket.sendPacket = function () {}; - socket.transport.onClose = function () {}; - socket.on('close', onClose); + socket.onPacket = socket.sendPacket = function() {}; + socket.transport.onClose = function() {}; + socket.on("close", onClose); }); }); }); - it('should trigger when server closes a client', function (done) { - var engine = listen({ allowUpgrades: false }, function (port) { - var socket = new eioc.Socket('ws://localhost:%d'.s(port)); + it("should trigger when server closes a client", function(done) { + var engine = listen({ allowUpgrades: false }, function(port) { + var socket = new eioc.Socket("ws://localhost:%d".s(port)); var total = 2; - engine.on('connection', function (conn) { - conn.on('close', function (reason) { - expect(reason).to.be('forced close'); + engine.on("connection", function(conn) { + conn.on("close", function(reason) { + expect(reason).to.be("forced close"); --total || done(); }); - setTimeout(function () { + setTimeout(function() { conn.close(); }, 10); }); - socket.on('open', function () { - socket.on('close', function (reason) { - expect(reason).to.be('transport close'); + socket.on("open", function() { + socket.on("close", function(reason) { + expect(reason).to.be("transport close"); --total || done(); }); }); }); }); - it('should trigger when server closes a client (ws)', function (done) { - var opts = { allowUpgrades: false, transports: ['websocket'] }; - var engine = listen(opts, function (port) { - var socket = new eioc.Socket('ws://localhost:%d'.s(port), { transports: ['websocket'] }); + it("should trigger when server closes a client (ws)", function(done) { + var opts = { allowUpgrades: false, transports: ["websocket"] }; + var engine = listen(opts, function(port) { + var socket = new eioc.Socket("ws://localhost:%d".s(port), { + transports: ["websocket"] + }); var total = 2; - engine.on('connection', function (conn) { - conn.on('close', function (reason) { - expect(reason).to.be('forced close'); + engine.on("connection", function(conn) { + conn.on("close", function(reason) { + expect(reason).to.be("forced close"); --total || done(); }); - setTimeout(function () { + setTimeout(function() { conn.close(); }, 10); }); - socket.on('open', function () { - socket.on('close', function (reason) { - expect(reason).to.be('transport close'); + socket.on("open", function() { + socket.on("close", function(reason) { + expect(reason).to.be("transport close"); --total || done(); }); }); }); }); - it('should allow client reconnect after restarting (ws)', function (done) { - var opts = { transports: ['websocket'] }; - var engine = listen(opts, function (port) { + it("should allow client reconnect after restarting (ws)", function(done) { + var opts = { transports: ["websocket"] }; + var engine = listen(opts, function(port) { engine.httpServer.close(); engine.httpServer.listen(port); - var socket = new eioc.Socket('ws://localhost:%d'.s(port), { transports: ['websocket'] }); + var socket = new eioc.Socket("ws://localhost:%d".s(port), { + transports: ["websocket"] + }); - engine.once('connection', function (conn) { - setTimeout(function () { + engine.once("connection", function(conn) { + setTimeout(function() { conn.close(); }, 10); }); - socket.once('close', function (reason) { - expect(reason).to.be('transport close'); + socket.once("close", function(reason) { + expect(reason).to.be("transport close"); done(); }); }); }); - it('should trigger when client closes', function (done) { - var engine = listen({ allowUpgrades: false }, function (port) { - var socket = new eioc.Socket('ws://localhost:%d'.s(port)); + it("should trigger when client closes", function(done) { + var engine = listen({ allowUpgrades: false }, function(port) { + var socket = new eioc.Socket("ws://localhost:%d".s(port)); var total = 2; - engine.on('connection', function (conn) { - conn.on('close', function (reason) { - expect(reason).to.be('transport close'); + engine.on("connection", function(conn) { + conn.on("close", function(reason) { + expect(reason).to.be("transport close"); --total || done(); }); }); - socket.on('open', function () { - socket.on('close', function (reason) { - expect(reason).to.be('forced close'); + socket.on("open", function() { + socket.on("close", function(reason) { + expect(reason).to.be("forced close"); --total || done(); }); - setTimeout(function () { + setTimeout(function() { socket.close(); }, 10); }); }); }); - it('should trigger when client closes (ws)', function (done) { - var opts = { allowUpgrades: false, transports: ['websocket'] }; - var engine = listen(opts, function (port) { - var socket = new eioc.Socket('ws://localhost:%d'.s(port), { transports: ['websocket'] }); + it("should trigger when client closes (ws)", function(done) { + var opts = { allowUpgrades: false, transports: ["websocket"] }; + var engine = listen(opts, function(port) { + var socket = new eioc.Socket("ws://localhost:%d".s(port), { + transports: ["websocket"] + }); var total = 2; - engine.on('connection', function (conn) { - conn.on('close', function (reason) { - expect(reason).to.be('transport close'); + engine.on("connection", function(conn) { + conn.on("close", function(reason) { + expect(reason).to.be("transport close"); --total || done(); }); }); - socket.on('open', function () { - socket.on('close', function (reason) { - expect(reason).to.be('forced close'); + socket.on("open", function() { + socket.on("close", function(reason) { + expect(reason).to.be("forced close"); --total || done(); }); - setTimeout(function () { + setTimeout(function() { socket.close(); }, 10); }); }); }); - it('should trigger when calling socket.close() in payload', function (done) { - var engine = listen({ allowUpgrades: false }, function (port) { - var socket = new eioc.Socket('ws://localhost:%d'.s(port)); + it("should trigger when calling socket.close() in payload", function(done) { + var engine = listen({ allowUpgrades: false }, function(port) { + var socket = new eioc.Socket("ws://localhost:%d".s(port)); - engine.on('connection', function (conn) { - conn.send(null, function () { socket.close(); }); - conn.send('this should not be handled'); + engine.on("connection", function(conn) { + conn.send(null, function() { + socket.close(); + }); + conn.send("this should not be handled"); - conn.on('close', function (reason) { - expect(reason).to.be('transport close'); + conn.on("close", function(reason) { + expect(reason).to.be("transport close"); done(); }); }); - socket.on('open', function () { - socket.on('message', function (msg) { - expect(msg).to.not.be('this should not be handled'); + socket.on("open", function() { + socket.on("message", function(msg) { + expect(msg).to.not.be("this should not be handled"); }); - socket.on('close', function (reason) { - expect(reason).to.be('forced close'); + socket.on("close", function(reason) { + expect(reason).to.be("forced close"); }); }); }); }); - it('should abort upgrade if socket is closed (GH-35)', function (done) { - listen({ allowUpgrades: true }, function (port) { - var socket = new eioc.Socket('ws://localhost:%d'.s(port)); - socket.on('open', function () { + it("should abort upgrade if socket is closed (GH-35)", function(done) { + listen({ allowUpgrades: true }, function(port) { + var socket = new eioc.Socket("ws://localhost:%d".s(port)); + socket.on("open", function() { socket.close(); // we wait until complete to see if we get an uncaught EPIPE - setTimeout(function () { + setTimeout(function() { done(); }, 100); }); }); }); - it('should trigger if a poll request is ongoing and the underlying ' + - 'socket closes, as in a browser tab close', function ($done) { - var engine = listen({ allowUpgrades: false }, function (port) { - // hack to access the sockets created by node-xmlhttprequest - // see: https://github.com/driverdan/node-XMLHttpRequest/issues/44 - var request = require('http').request; - var sockets = []; - http.request = function (opts) { - var req = request.apply(null, arguments); - req.on('socket', function (socket) { - sockets.push(socket); - }); - return req; - }; + it( + "should trigger if a poll request is ongoing and the underlying " + + "socket closes, as in a browser tab close", + function($done) { + var engine = listen({ allowUpgrades: false }, function(port) { + // hack to access the sockets created by node-xmlhttprequest + // see: https://github.com/driverdan/node-XMLHttpRequest/issues/44 + var request = require("http").request; + var sockets = []; + http.request = function(opts) { + var req = request.apply(null, arguments); + req.on("socket", function(socket) { + sockets.push(socket); + }); + return req; + }; - function done () { - http.request = request; - $done(); - } + function done() { + http.request = request; + $done(); + } - var socket = new eioc.Socket('ws://localhost:%d'.s(port)); - var serverSocket; + var socket = new eioc.Socket("ws://localhost:%d".s(port)); + var serverSocket; - engine.on('connection', function (s) { - serverSocket = s; - }); + engine.on("connection", function(s) { + serverSocket = s; + }); - socket.transport.on('poll', function () { - // we set a timer to wait for the request to actually reach - setTimeout(function () { - // at this time server's `connection` should have been fired - expect(serverSocket).to.be.an('object'); + socket.transport.on("poll", function() { + // we set a timer to wait for the request to actually reach + setTimeout(function() { + // at this time server's `connection` should have been fired + expect(serverSocket).to.be.an("object"); - // OPENED readyState is expected - we are actually polling - expect(socket.transport.pollXhr.xhr.readyState).to.be(1); + // OPENED readyState is expected - we are actually polling + expect(socket.transport.pollXhr.xhr.readyState).to.be(1); - // 2 requests sent to the server over an unique port means - // we should have been assigned 2 sockets - expect(sockets.length).to.be(2); + // 2 requests sent to the server over an unique port means + // we should have been assigned 2 sockets + expect(sockets.length).to.be(2); - // expect the socket to be open at this point - expect(serverSocket.readyState).to.be('open'); + // expect the socket to be open at this point + expect(serverSocket.readyState).to.be("open"); - // kill the underlying connection - sockets[1].end(); - serverSocket.on('close', function (reason, err) { - expect(reason).to.be('transport error'); - expect(err.message).to.be('poll connection closed prematurely'); - done(); - }); - }, 50); + // kill the underlying connection + sockets[1].end(); + serverSocket.on("close", function(reason, err) { + expect(reason).to.be("transport error"); + expect(err.message).to.be("poll connection closed prematurely"); + done(); + }); + }, 50); + }); }); - }); - }); + } + ); - it('should not trigger with connection: close header', function ($done) { - var engine = listen({ allowUpgrades: false }, function (port) { + it("should not trigger with connection: close header", function($done) { + var engine = listen({ allowUpgrades: false }, function(port) { // intercept requests to add connection: close var request = http.request; - http.request = function () { + http.request = function() { var opts = arguments[0]; opts.headers = opts.headers || {}; - opts.headers.Connection = 'close'; + opts.headers.Connection = "close"; return request.apply(this, arguments); }; - function done () { + function done() { http.request = request; $done(); } - engine.on('connection', function (socket) { - socket.on('message', function (msg) { - expect(msg).to.equal('test'); - socket.send('woot'); + engine.on("connection", function(socket) { + socket.on("message", function(msg) { + expect(msg).to.equal("test"); + socket.send("woot"); }); }); - var socket = new eioc.Socket('ws://localhost:%d'.s(port)); - socket.on('open', function () { - socket.send('test'); + var socket = new eioc.Socket("ws://localhost:%d".s(port)); + socket.on("open", function() { + socket.send("test"); }); - socket.on('message', function (msg) { - expect(msg).to.be('woot'); + socket.on("message", function(msg) { + expect(msg).to.be("woot"); done(); }); }); }); - it('should not trigger early with connection `ping timeout`' + - 'after post handshake timeout', function (done) { - // first timeout should trigger after `pingInterval + pingTimeout`, - // not just `pingTimeout`. - var opts = { allowUpgrades: false, pingInterval: 300, pingTimeout: 100 }; - listen(opts, function (port) { - var socket = new eioc.Socket('ws://localhost:%d'.s(port)); - var clientCloseReason = null; + it( + "should not trigger early with connection `ping timeout`" + + "after post handshake timeout", + function(done) { + // first timeout should trigger after `pingInterval + pingTimeout`, + // not just `pingTimeout`. + var opts = { + allowUpgrades: false, + pingInterval: 300, + pingTimeout: 100 + }; + listen(opts, function(port) { + var socket = new eioc.Socket("ws://localhost:%d".s(port)); + var clientCloseReason = null; - socket.on('handshake', function () { - socket.onPacket = function () {}; - }); - socket.on('open', function () { - socket.on('close', function (reason) { - clientCloseReason = reason; + socket.on("handshake", function() { + socket.onPacket = function() {}; }); - }); - - setTimeout(function () { - expect(clientCloseReason).to.be(null); - done(); - }, 200); - }); - }); - - it('should not trigger early with connection `ping timeout` ' + - 'after post ping timeout', function (done) { - // ping timeout should trigger after `pingInterval + pingTimeout`, - // not just `pingTimeout`. - var opts = { allowUpgrades: false, pingInterval: 80, pingTimeout: 50 }; - var engine = listen(opts, function (port) { - var socket = new eioc.Socket('ws://localhost:%d'.s(port)); - var clientCloseReason = null; - - engine.on('connection', function (conn) { - conn.on('heartbeat', function () { - conn.onPacket = function () {}; + socket.on("open", function() { + socket.on("close", function(reason) { + clientCloseReason = reason; + }); }); - }); - socket.on('open', function () { - socket.on('close', function (reason) { - clientCloseReason = reason; - }); + setTimeout(function() { + expect(clientCloseReason).to.be(null); + done(); + }, 200); }); - - setTimeout(function () { - expect(clientCloseReason).to.be(null); - done(); - }, 100); - }); - }); - - it('should trigger early with connection `transport close` ' + - 'after missing pong', function (done) { - // ping timeout should trigger after `pingInterval + pingTimeout`, - // not just `pingTimeout`. - var opts = { allowUpgrades: false, pingInterval: 80, pingTimeout: 50 }; - var engine = listen(opts, function (port) { - var socket = new eioc.Socket('ws://localhost:%d'.s(port)); - var clientCloseReason = null; - - socket.on('open', function () { - socket.on('close', function (reason) { - clientCloseReason = reason; + } + ); + + it( + "should not trigger early with connection `ping timeout` " + + "after post ping timeout", + function(done) { + // ping timeout should trigger after `pingInterval + pingTimeout`, + // not just `pingTimeout`. + var opts = { allowUpgrades: false, pingInterval: 80, pingTimeout: 50 }; + var engine = listen(opts, function(port) { + var socket = new eioc.Socket("ws://localhost:%d".s(port)); + var clientCloseReason = null; + + engine.on("connection", function(conn) { + conn.on("heartbeat", function() { + conn.onPacket = function() {}; + }); }); - }); - engine.on('connection', function (conn) { - conn.on('heartbeat', function () { - setTimeout(function () { - conn.close(); - }, 20); - setTimeout(function () { - expect(clientCloseReason).to.be('transport close'); - done(); - }, 100); + socket.on("open", function() { + socket.on("close", function(reason) { + clientCloseReason = reason; + }); }); - }); - }); - }); - it('should trigger with connection `ping timeout` ' + - 'after `pingInterval + pingTimeout`', function (done) { - var opts = { allowUpgrades: false, pingInterval: 300, pingTimeout: 100 }; - var engine = listen(opts, function (port) { - var socket = new eioc.Socket('ws://localhost:%d'.s(port)); - var clientCloseReason = null; - - socket.on('open', function () { - socket.on('close', function (reason) { - clientCloseReason = reason; - }); + setTimeout(function() { + expect(clientCloseReason).to.be(null); + done(); + }, 100); }); + } + ); + + it( + "should trigger early with connection `transport close` " + + "after missing pong", + function(done) { + // ping timeout should trigger after `pingInterval + pingTimeout`, + // not just `pingTimeout`. + var opts = { allowUpgrades: false, pingInterval: 80, pingTimeout: 50 }; + var engine = listen(opts, function(port) { + var socket = new eioc.Socket("ws://localhost:%d".s(port)); + var clientCloseReason = null; + + socket.on("open", function() { + socket.on("close", function(reason) { + clientCloseReason = reason; + }); + }); - engine.on('connection', function (conn) { - conn.once('heartbeat', function () { - setTimeout(function () { - socket.onPacket = function () {}; - expect(clientCloseReason).to.be(null); - }, 150); - setTimeout(function () { - expect(clientCloseReason).to.be(null); - }, 350); - setTimeout(function () { - expect(clientCloseReason).to.be('ping timeout'); - done(); - }, 500); + engine.on("connection", function(conn) { + conn.on("heartbeat", function() { + setTimeout(function() { + conn.close(); + }, 20); + setTimeout(function() { + expect(clientCloseReason).to.be("transport close"); + done(); + }, 100); + }); }); }); - }); - }); + } + ); + + it( + "should trigger with connection `ping timeout` " + + "after `pingInterval + pingTimeout`", + function(done) { + var opts = { + allowUpgrades: false, + pingInterval: 300, + pingTimeout: 100 + }; + var engine = listen(opts, function(port) { + var socket = new eioc.Socket("ws://localhost:%d".s(port)); + var clientCloseReason = null; - it('should abort the polling data request if it is ' + - 'in progress', function (done) { - var engine = listen({ transports: [ 'polling' ] }, function (port) { - var socket = new eioc.Socket('http://localhost:%d'.s(port)); + socket.on("open", function() { + socket.on("close", function(reason) { + clientCloseReason = reason; + }); + }); - engine.on('connection', function (conn) { - var onDataRequest = conn.transport.onDataRequest; - conn.transport.onDataRequest = function (req, res) { - engine.httpServer.close(done); - onDataRequest.call(conn.transport, req, res); - req.removeAllListeners(); - conn.close(); - }; + engine.on("connection", function(conn) { + conn.once("heartbeat", function() { + setTimeout(function() { + socket.onPacket = function() {}; + expect(clientCloseReason).to.be(null); + }, 150); + setTimeout(function() { + expect(clientCloseReason).to.be(null); + }, 350); + setTimeout(function() { + expect(clientCloseReason).to.be("ping timeout"); + done(); + }, 500); + }); + }); }); + } + ); + + it( + "should abort the polling data request if it is " + "in progress", + function(done) { + var engine = listen({ transports: ["polling"] }, function(port) { + var socket = new eioc.Socket("http://localhost:%d".s(port)); + + engine.on("connection", function(conn) { + var onDataRequest = conn.transport.onDataRequest; + conn.transport.onDataRequest = function(req, res) { + engine.httpServer.close(done); + onDataRequest.call(conn.transport, req, res); + req.removeAllListeners(); + conn.close(); + }; + }); - socket.on('open', function () { - socket.send('test'); + socket.on("open", function() { + socket.send("test"); + }); }); - }); - }); + } + ); // tests https://github.com/LearnBoost/engine.io-client/issues/207 // websocket test, transport error - it('should trigger transport close before open for ws', function (done) { - var opts = { transports: ['websocket'] }; - listen(opts, function (port) { - var url = 'ws://%s:%d'.s('0.0.0.50', port); + it("should trigger transport close before open for ws", function(done) { + var opts = { transports: ["websocket"] }; + listen(opts, function(port) { + var url = "ws://%s:%d".s("0.0.0.50", port); var socket = new eioc.Socket(url); - socket.on('open', function () { - done(new Error('Test invalidation')); + socket.on("open", function() { + done(new Error("Test invalidation")); }); - socket.on('close', function (reason) { - expect(reason).to.be('transport error'); + socket.on("close", function(reason) { + expect(reason).to.be("transport error"); done(); }); }); @@ -946,15 +1040,15 @@ describe('server', function () { // tests https://github.com/LearnBoost/engine.io-client/issues/207 // polling test, transport error - it('should trigger transport close before open for xhr', function (done) { - var opts = { transports: ['polling'] }; - listen(opts, function (port) { - var socket = new eioc.Socket('http://invalidserver:%d'.s(port)); - socket.on('open', function () { - done(new Error('Test invalidation')); - }); - socket.on('close', function (reason) { - expect(reason).to.be('transport error'); + it("should trigger transport close before open for xhr", function(done) { + var opts = { transports: ["polling"] }; + listen(opts, function(port) { + var socket = new eioc.Socket("http://invalidserver:%d".s(port)); + socket.on("open", function() { + done(new Error("Test invalidation")); + }); + socket.on("close", function(reason) { + expect(reason).to.be("transport error"); done(); }); }); @@ -962,15 +1056,15 @@ describe('server', function () { // tests https://github.com/LearnBoost/engine.io-client/issues/207 // websocket test, force close - it('should trigger force close before open for ws', function (done) { - var opts = { transports: ['websocket'] }; - listen(opts, function (port) { - var socket = new eioc.Socket('ws://localhost:%d'.s(port)); - socket.on('open', function () { - done(new Error('Test invalidation')); - }); - socket.on('close', function (reason) { - expect(reason).to.be('forced close'); + it("should trigger force close before open for ws", function(done) { + var opts = { transports: ["websocket"] }; + listen(opts, function(port) { + var socket = new eioc.Socket("ws://localhost:%d".s(port)); + socket.on("open", function() { + done(new Error("Test invalidation")); + }); + socket.on("close", function(reason) { + expect(reason).to.be("forced close"); done(); }); socket.close(); @@ -979,332 +1073,373 @@ describe('server', function () { // tests https://github.com/LearnBoost/engine.io-client/issues/207 // polling test, force close - it('should trigger force close before open for xhr', function (done) { - var opts = { transports: ['polling'] }; - listen(opts, function (port) { - var socket = new eioc.Socket('http://localhost:%d'.s(port)); - socket.on('open', function () { - done(new Error('Test invalidation')); - }); - socket.on('close', function (reason) { - expect(reason).to.be('forced close'); + it("should trigger force close before open for xhr", function(done) { + var opts = { transports: ["polling"] }; + listen(opts, function(port) { + var socket = new eioc.Socket("http://localhost:%d".s(port)); + socket.on("open", function() { + done(new Error("Test invalidation")); + }); + socket.on("close", function(reason) { + expect(reason).to.be("forced close"); done(); }); socket.close(); }); }); - it('should close transport upon ping timeout (ws)', function (done) { - var opts = { allowUpgrades: false, transports: ['websocket'], pingInterval: 50, pingTimeout: 30 }; - var engine = listen(opts, function (port) { - engine.on('connection', function (conn) { - conn.transport.on('close', done); + it("should close transport upon ping timeout (ws)", function(done) { + var opts = { + allowUpgrades: false, + transports: ["websocket"], + pingInterval: 50, + pingTimeout: 30 + }; + var engine = listen(opts, function(port) { + engine.on("connection", function(conn) { + conn.transport.on("close", done); + }); + var socket = new eioc.Socket("ws://localhost:%d".s(port), { + transports: ["websocket"] }); - var socket = new eioc.Socket('ws://localhost:%d'.s(port), { transports: ['websocket'] }); // override to simulate an inactive client - socket.sendPacket = socket.onHeartbeat = function () {}; + socket.sendPacket = socket.onHeartbeat = function() {}; }); }); - it('should close transport upon ping timeout (polling)', function (done) { - var opts = { allowUpgrades: false, transports: ['polling'], pingInterval: 50, pingTimeout: 30 }; - var engine = listen(opts, function (port) { - engine.on('connection', function (conn) { - conn.transport.on('close', done); + it("should close transport upon ping timeout (polling)", function(done) { + var opts = { + allowUpgrades: false, + transports: ["polling"], + pingInterval: 50, + pingTimeout: 30 + }; + var engine = listen(opts, function(port) { + engine.on("connection", function(conn) { + conn.transport.on("close", done); + }); + var socket = new eioc.Socket("ws://localhost:%d".s(port), { + transports: ["polling"] }); - var socket = new eioc.Socket('ws://localhost:%d'.s(port), { transports: ['polling'] }); // override to simulate an inactive client - socket.sendPacket = socket.onHeartbeat = function () {}; + socket.sendPacket = socket.onHeartbeat = function() {}; }); }); - it('should close transport upon parse error (ws)', function (done) { - var opts = { allowUpgrades: false, transports: ['websocket'] }; - var engine = listen(opts, function (port) { - engine.on('connection', function (conn) { - conn.transport.on('close', done); + it("should close transport upon parse error (ws)", function(done) { + var opts = { allowUpgrades: false, transports: ["websocket"] }; + var engine = listen(opts, function(port) { + engine.on("connection", function(conn) { + conn.transport.on("close", done); + }); + var socket = new eioc.Socket("ws://localhost:%d".s(port), { + transports: ["websocket"] }); - var socket = new eioc.Socket('ws://localhost:%d'.s(port), { transports: ['websocket'] }); - socket.on('open', function () { - socket.transport.ws.send('invalid'); + socket.on("open", function() { + socket.transport.ws.send("invalid"); }); }); }); - it('should close transport upon parse error (polling)', function (done) { - var opts = { allowUpgrades: false, transports: ['polling'] }; - var engine = listen(opts, function (port) { - engine.on('connection', function (conn) { + it("should close transport upon parse error (polling)", function(done) { + var opts = { allowUpgrades: false, transports: ["polling"] }; + var engine = listen(opts, function(port) { + engine.on("connection", function(conn) { conn.transport.closeTimeout = 100; - conn.transport.on('close', done); + conn.transport.on("close", done); + }); + var socket = new eioc.Socket("ws://localhost:%d".s(port), { + transports: ["polling"] }); - var socket = new eioc.Socket('ws://localhost:%d'.s(port), { transports: ['polling'] }); - socket.on('open', function () { - socket.transport.doWrite('invalid', function () {}); + socket.on("open", function() { + socket.transport.doWrite("invalid", function() {}); }); }); }); - it('should close upgrading transport upon socket close', function (done) { - var engine = listen(function (port) { - engine.on('connection', function (conn) { - conn.on('upgrading', function (transport) { - transport.on('close', done); + it("should close upgrading transport upon socket close", function(done) { + var engine = listen(function(port) { + engine.on("connection", function(conn) { + conn.on("upgrading", function(transport) { + transport.on("close", done); conn.close(); }); }); - eioc('ws://localhost:%d'.s(port)); + eioc("ws://localhost:%d".s(port)); }); }); - it('should close upgrading transport upon upgrade timeout', function (done) { + it("should close upgrading transport upon upgrade timeout", function(done) { var opts = { upgradeTimeout: 100 }; - var engine = listen(opts, function (port) { - engine.on('connection', function (conn) { - conn.on('upgrading', function (transport) { - transport.on('close', done); + var engine = listen(opts, function(port) { + engine.on("connection", function(conn) { + conn.on("upgrading", function(transport) { + transport.on("close", done); }); }); - var socket = new eioc.Socket('ws://localhost:%d'.s(port)); - socket.on('upgrading', function (transport) { + var socket = new eioc.Socket("ws://localhost:%d".s(port)); + socket.on("upgrading", function(transport) { // override not to complete upgrading - transport.send = function () {}; + transport.send = function() {}; }); }); }); - it('should not crash when messing with Object prototype', function (done) { - Object.prototype.foo = 'bar'; // eslint-disable-line no-extend-native - var engine = listen({ allowUpgrades: true }, function (port) { - var socket = new eioc.Socket('ws://localhost:%d'.s(port)); - socket.on('open', function () { + it("should not crash when messing with Object prototype", function(done) { + Object.prototype.foo = "bar"; // eslint-disable-line no-extend-native + var engine = listen({ allowUpgrades: true }, function(port) { + var socket = new eioc.Socket("ws://localhost:%d".s(port)); + socket.on("open", function() { engine.close(); - setTimeout(function () { + setTimeout(function() { done(); }, 100); }); }); }); - describe('graceful close', function () { - function fixture (filename) { - return process.execPath + ' ' + - path.join(__dirname, 'fixtures', filename); + describe("graceful close", function() { + function fixture(filename) { + return ( + process.execPath + " " + path.join(__dirname, "fixtures", filename) + ); } - it('should stop socket and timers', function (done) { - exec(fixture('server-close.js'), done); + it("should stop socket and timers", function(done) { + exec(fixture("server-close.js"), done); }); - it('should stop upgraded socket and timers', function (done) { - exec(fixture('server-close-upgraded.js'), done); + it("should stop upgraded socket and timers", function(done) { + exec(fixture("server-close-upgraded.js"), done); }); - it('should stop upgrading socket and timers', function (done) { - exec(fixture('server-close-upgrading.js'), done); + it("should stop upgrading socket and timers", function(done) { + exec(fixture("server-close-upgrading.js"), done); }); }); }); - describe('messages', function () { + describe("messages", function() { this.timeout(5000); - it('should arrive from server to client', function (done) { - var engine = listen({ allowUpgrades: false }, function (port) { - var socket = new eioc.Socket('ws://localhost:%d'.s(port)); - engine.on('connection', function (conn) { - conn.send('a'); + it("should arrive from server to client", function(done) { + var engine = listen({ allowUpgrades: false }, function(port) { + var socket = new eioc.Socket("ws://localhost:%d".s(port)); + engine.on("connection", function(conn) { + conn.send("a"); }); - socket.on('open', function () { - socket.on('message', function (msg) { - expect(msg).to.be('a'); + socket.on("open", function() { + socket.on("message", function(msg) { + expect(msg).to.be("a"); done(); }); }); }); }); - it('should arrive from server to client (multiple)', function (done) { - var engine = listen({ allowUpgrades: false }, function (port) { - var socket = new eioc.Socket('ws://localhost:%d'.s(port)); - var expected = ['a', 'b', 'c']; + it("should arrive from server to client (multiple)", function(done) { + var engine = listen({ allowUpgrades: false }, function(port) { + var socket = new eioc.Socket("ws://localhost:%d".s(port)); + var expected = ["a", "b", "c"]; var i = 0; - engine.on('connection', function (conn) { - conn.send('a'); + engine.on("connection", function(conn) { + conn.send("a"); // we use set timeouts to ensure the messages are delivered as part // of different. - setTimeout(function () { - conn.send('b'); + setTimeout(function() { + conn.send("b"); - setTimeout(function () { + setTimeout(function() { // here we make sure we buffer both the close packet and // a regular packet - conn.send('c'); + conn.send("c"); conn.close(); }, 50); }, 50); - conn.on('close', function () { + conn.on("close", function() { // since close fires right after the buffer is drained - setTimeout(function () { + setTimeout(function() { expect(i).to.be(3); done(); }, 50); }); }); - socket.on('open', function () { - socket.on('message', function (msg) { + socket.on("open", function() { + socket.on("message", function(msg) { expect(msg).to.be(expected[i++]); }); }); }); }); - it('should not be receiving data when getting a message longer than maxHttpBufferSize when polling', function (done) { - var opts = { allowUpgrades: false, transports: ['polling'], maxHttpBufferSize: 5 }; - var engine = listen(opts, function (port) { - var socket = new eioc.Socket('ws://localhost:%d'.s(port)); - engine.on('connection', function (conn) { - conn.on('message', function (msg) { - done(new Error('Test invalidation (message is longer than allowed)')); + it("should not be receiving data when getting a message longer than maxHttpBufferSize when polling", function(done) { + var opts = { + allowUpgrades: false, + transports: ["polling"], + maxHttpBufferSize: 5 + }; + var engine = listen(opts, function(port) { + var socket = new eioc.Socket("ws://localhost:%d".s(port)); + engine.on("connection", function(conn) { + conn.on("message", function(msg) { + done( + new Error("Test invalidation (message is longer than allowed)") + ); }); }); - socket.on('open', function () { - socket.send('aasdasdakjhasdkjhasdkjhasdkjhasdkjhasdkjhasdkjha'); + socket.on("open", function() { + socket.send("aasdasdakjhasdkjhasdkjhasdkjhasdkjhasdkjhasdkjha"); }); - socket.on('close', function () { + socket.on("close", function() { done(); }); }); }); - it('should not be receiving data when getting a message longer than maxHttpBufferSize (websocket)', function (done) { + it("should not be receiving data when getting a message longer than maxHttpBufferSize (websocket)", function(done) { var opts = { maxHttpBufferSize: 5 }; - var engine = listen(opts, function (port) { - var socket = new eioc.Socket('ws://localhost:%d'.s(port), { transports: ['websocket'] }); - engine.on('connection', function (conn) { - conn.on('message', function (msg) { - done(new Error('Test invalidation (message is longer than allowed)')); + var engine = listen(opts, function(port) { + var socket = new eioc.Socket("ws://localhost:%d".s(port), { + transports: ["websocket"] + }); + engine.on("connection", function(conn) { + conn.on("message", function(msg) { + done( + new Error("Test invalidation (message is longer than allowed)") + ); }); }); - socket.on('open', function () { - socket.send('aasdasdakjhasdkjhasdkjhasdkjhasdkjhasdkjhasdkjha'); + socket.on("open", function() { + socket.send("aasdasdakjhasdkjhasdkjhasdkjhasdkjhasdkjhasdkjha"); }); - socket.on('close', function () { + socket.on("close", function() { done(); }); }); }); - it('should receive data when getting a message shorter than maxHttpBufferSize when polling', function (done) { - var opts = { allowUpgrades: false, transports: ['polling'], maxHttpBufferSize: 5 }; - var engine = listen(opts, function (port) { - var socket = new eioc.Socket('ws://localhost:%d'.s(port)); - engine.on('connection', function (conn) { - conn.on('message', function (msg) { - expect(msg).to.be('a'); + it("should receive data when getting a message shorter than maxHttpBufferSize when polling", function(done) { + var opts = { + allowUpgrades: false, + transports: ["polling"], + maxHttpBufferSize: 5 + }; + var engine = listen(opts, function(port) { + var socket = new eioc.Socket("ws://localhost:%d".s(port)); + engine.on("connection", function(conn) { + conn.on("message", function(msg) { + expect(msg).to.be("a"); done(); }); }); - socket.on('open', function () { - socket.send('a'); + socket.on("open", function() { + socket.send("a"); }); }); }); - it('should arrive from server to client (ws)', function (done) { - var opts = { allowUpgrades: false, transports: ['websocket'] }; - var engine = listen(opts, function (port) { - var socket = new eioc.Socket('ws://localhost:%d'.s(port), { transports: ['websocket'] }); - engine.on('connection', function (conn) { - conn.send('a'); + it("should arrive from server to client (ws)", function(done) { + var opts = { allowUpgrades: false, transports: ["websocket"] }; + var engine = listen(opts, function(port) { + var socket = new eioc.Socket("ws://localhost:%d".s(port), { + transports: ["websocket"] }); - socket.on('open', function () { - socket.on('message', function (msg) { - expect(msg).to.be('a'); + engine.on("connection", function(conn) { + conn.send("a"); + }); + socket.on("open", function() { + socket.on("message", function(msg) { + expect(msg).to.be("a"); done(); }); }); }); }); - it('should arrive from server to client (multiple, ws)', function (done) { - var opts = { allowUpgrades: false, transports: ['websocket'] }; - var engine = listen(opts, function (port) { - var socket = new eioc.Socket('ws://localhost:%d'.s(port), { transports: ['websocket'] }); - var expected = ['a', 'b', 'c']; + it("should arrive from server to client (multiple, ws)", function(done) { + var opts = { allowUpgrades: false, transports: ["websocket"] }; + var engine = listen(opts, function(port) { + var socket = new eioc.Socket("ws://localhost:%d".s(port), { + transports: ["websocket"] + }); + var expected = ["a", "b", "c"]; var i = 0; - engine.on('connection', function (conn) { - conn.send('a'); - setTimeout(function () { - conn.send('b'); - setTimeout(function () { - conn.send('c'); + engine.on("connection", function(conn) { + conn.send("a"); + setTimeout(function() { + conn.send("b"); + setTimeout(function() { + conn.send("c"); conn.close(); }, 50); }, 50); - conn.on('close', function () { - setTimeout(function () { + conn.on("close", function() { + setTimeout(function() { expect(i).to.be(3); done(); }, 50); }); }); - socket.on('open', function () { - socket.on('message', function (msg) { + socket.on("open", function() { + socket.on("message", function(msg) { expect(msg).to.be(expected[i++]); }); }); }); }); - it('should arrive from server to client (multiple, no delay, ws)', function (done) { - var opts = { allowUpgrades: false, transports: ['websocket'] }; - var engine = listen(opts, function (port) { - var socket = new eioc.Socket('ws://localhost:%d'.s(port), { transports: ['websocket'] }); - var expected = ['a', 'b', 'c']; + it("should arrive from server to client (multiple, no delay, ws)", function(done) { + var opts = { allowUpgrades: false, transports: ["websocket"] }; + var engine = listen(opts, function(port) { + var socket = new eioc.Socket("ws://localhost:%d".s(port), { + transports: ["websocket"] + }); + var expected = ["a", "b", "c"]; var i = 0; - engine.on('connection', function (conn) { - conn.on('close', function () { - setTimeout(function () { + engine.on("connection", function(conn) { + conn.on("close", function() { + setTimeout(function() { expect(i).to.be(3); done(); }, 50); }); - conn.send('a'); - conn.send('b'); - conn.send('c'); + conn.send("a"); + conn.send("b"); + conn.send("c"); conn.close(); }); - socket.on('open', function () { - socket.on('message', function (msg) { + socket.on("open", function() { + socket.on("message", function(msg) { expect(msg).to.be(expected[i++]); }); }); }); }); - it('should arrive when binary data is sent as Int8Array (ws)', function (done) { + it("should arrive when binary data is sent as Int8Array (ws)", function(done) { var binaryData = new Int8Array(5); for (var i = 0; i < binaryData.length; i++) { binaryData[i] = i; } - var opts = { allowUpgrades: false, transports: ['websocket'] }; - var engine = listen(opts, function (port) { - var socket = new eioc.Socket('ws://localhost:%d'.s(port), { transports: ['websocket'] }); + var opts = { allowUpgrades: false, transports: ["websocket"] }; + var engine = listen(opts, function(port) { + var socket = new eioc.Socket("ws://localhost:%d".s(port), { + transports: ["websocket"] + }); - engine.on('connection', function (conn) { + engine.on("connection", function(conn) { conn.send(binaryData); }); - socket.on('open', function () { - socket.on('message', function (msg) { + socket.on("open", function() { + socket.on("message", function(msg) { for (var i = 0; i < binaryData.length; i++) { var num = msg.readInt8(i); expect(num).to.be(i); @@ -1315,22 +1450,24 @@ describe('server', function () { }); }); - it('should arrive when binary data is sent as Int32Array (ws)', function (done) { + it("should arrive when binary data is sent as Int32Array (ws)", function(done) { var binaryData = new Int32Array(5); for (var i = 0; i < binaryData.length; i++) { binaryData[i] = (i + 100) * 9823; } - var opts = { allowUpgrades: false, transports: ['websocket'] }; - var engine = listen(opts, function (port) { - var socket = new eioc.Socket('ws://localhost:%d'.s(port), { transports: ['websocket'] }); + var opts = { allowUpgrades: false, transports: ["websocket"] }; + var engine = listen(opts, function(port) { + var socket = new eioc.Socket("ws://localhost:%d".s(port), { + transports: ["websocket"] + }); - engine.on('connection', function (conn) { + engine.on("connection", function(conn) { conn.send(binaryData); }); - socket.on('open', function () { - socket.on('message', function (msg) { + socket.on("open", function() { + socket.on("message", function(msg) { for (var i = 0, ii = 0; ii < binaryData.length; i += 4, ii++) { var num = msg.readInt32LE(i); expect(num).to.be((ii + 100) * 9823); @@ -1341,22 +1478,24 @@ describe('server', function () { }); }); - it('should arrive when binary data is sent as Int32Array, given as ArrayBuffer(ws)', function (done) { + it("should arrive when binary data is sent as Int32Array, given as ArrayBuffer(ws)", function(done) { var binaryData = new Int32Array(5); for (var i = 0; i < binaryData.length; i++) { binaryData[i] = (i + 100) * 9823; } - var opts = { allowUpgrades: false, transports: ['websocket'] }; - var engine = listen(opts, function (port) { - var socket = new eioc.Socket('ws://localhost:%d'.s(port), { transports: ['websocket'] }); + var opts = { allowUpgrades: false, transports: ["websocket"] }; + var engine = listen(opts, function(port) { + var socket = new eioc.Socket("ws://localhost:%d".s(port), { + transports: ["websocket"] + }); - engine.on('connection', function (conn) { + engine.on("connection", function(conn) { conn.send(binaryData.buffer); }); - socket.on('open', function () { - socket.on('message', function (msg) { + socket.on("open", function() { + socket.on("message", function(msg) { for (var i = 0, ii = 0; ii < binaryData.length; i += 4, ii++) { var num = msg.readInt32LE(i); expect(num).to.be((ii + 100) * 9823); @@ -1367,22 +1506,24 @@ describe('server', function () { }); }); - it('should arrive when binary data is sent as Buffer (ws)', function (done) { + it("should arrive when binary data is sent as Buffer (ws)", function(done) { var binaryData = Buffer.allocUnsafe(5); for (var i = 0; i < binaryData.length; i++) { binaryData.writeInt8(i, i); } - var opts = { allowUpgrades: false, transports: ['websocket'] }; - var engine = listen(opts, function (port) { - var socket = new eioc.Socket('ws://localhost:%d'.s(port), { transports: ['websocket'] }); + var opts = { allowUpgrades: false, transports: ["websocket"] }; + var engine = listen(opts, function(port) { + var socket = new eioc.Socket("ws://localhost:%d".s(port), { + transports: ["websocket"] + }); - engine.on('connection', function (conn) { + engine.on("connection", function(conn) { conn.send(binaryData); }); - socket.on('open', function () { - socket.on('message', function (msg) { + socket.on("open", function() { + socket.on("message", function(msg) { for (var i = 0; i < binaryData.length; i++) { var num = msg.readInt8(i); expect(num).to.be(i); @@ -1393,22 +1534,24 @@ describe('server', function () { }); }); - it('should arrive when binary data sent as Buffer (polling)', function (done) { + it("should arrive when binary data sent as Buffer (polling)", function(done) { var binaryData = Buffer.allocUnsafe(5); for (var i = 0; i < binaryData.length; i++) { binaryData.writeInt8(i, i); } - var opts = { allowUpgrades: false, transports: ['polling'] }; - var engine = listen(opts, function (port) { - var socket = new eioc.Socket('ws://localhost:%d'.s(port), { transports: ['polling'] }); + var opts = { allowUpgrades: false, transports: ["polling"] }; + var engine = listen(opts, function(port) { + var socket = new eioc.Socket("ws://localhost:%d".s(port), { + transports: ["polling"] + }); - engine.on('connection', function (conn) { + engine.on("connection", function(conn) { conn.send(binaryData); }); - socket.on('open', function () { - socket.on('message', function (msg) { + socket.on("open", function() { + socket.on("message", function(msg) { for (var i = 0; i < binaryData.length; i++) { var num = msg.readInt8(i); expect(num).to.be(i); @@ -1420,23 +1563,25 @@ describe('server', function () { }); }); - it('should arrive as ArrayBuffer if requested when binary data sent as Buffer (ws)', function (done) { + it("should arrive as ArrayBuffer if requested when binary data sent as Buffer (ws)", function(done) { var binaryData = Buffer.allocUnsafe(5); for (var i = 0; i < binaryData.length; i++) { binaryData.writeInt8(i, i); } - var opts = { allowUpgrades: false, transports: ['websocket'] }; - var engine = listen(opts, function (port) { - var socket = new eioc.Socket('ws://localhost:%d'.s(port), { transports: ['websocket'] }); - socket.binaryType = 'arraybuffer'; + var opts = { allowUpgrades: false, transports: ["websocket"] }; + var engine = listen(opts, function(port) { + var socket = new eioc.Socket("ws://localhost:%d".s(port), { + transports: ["websocket"] + }); + socket.binaryType = "arraybuffer"; - engine.on('connection', function (conn) { + engine.on("connection", function(conn) { conn.send(binaryData); }); - socket.on('open', function () { - socket.on('message', function (msg) { + socket.on("open", function() { + socket.on("message", function(msg) { expect(msg instanceof ArrayBuffer).to.be(true); var intArray = new Int8Array(msg); for (var i = 0; i < binaryData.length; i++) { @@ -1449,23 +1594,25 @@ describe('server', function () { }); }); - it('should arrive as ArrayBuffer if requested when binary data sent as Buffer (polling)', function (done) { + it("should arrive as ArrayBuffer if requested when binary data sent as Buffer (polling)", function(done) { var binaryData = Buffer.allocUnsafe(5); for (var i = 0; i < binaryData.length; i++) { binaryData.writeInt8(i, i); } - var opts = { allowUpgrades: false, transports: ['polling'] }; - var engine = listen(opts, function (port) { - var socket = new eioc.Socket('ws://localhost:%d'.s(port), { transports: ['polling'] }); - socket.binaryType = 'arraybuffer'; + var opts = { allowUpgrades: false, transports: ["polling"] }; + var engine = listen(opts, function(port) { + var socket = new eioc.Socket("ws://localhost:%d".s(port), { + transports: ["polling"] + }); + socket.binaryType = "arraybuffer"; - engine.on('connection', function (conn) { + engine.on("connection", function(conn) { conn.send(binaryData); }); - socket.on('open', function () { - socket.on('message', function (msg) { + socket.on("open", function() { + socket.on("message", function(msg) { expect(msg instanceof ArrayBuffer).to.be(true); var intArray = new Int8Array(msg); for (var i = 0; i < binaryData.length; i++) { @@ -1478,101 +1625,106 @@ describe('server', function () { }); }); - it('should trigger a flush/drain event', function (done) { - var engine = listen({ allowUpgrades: false }, function (port) { - engine.on('connection', function (socket) { + it("should trigger a flush/drain event", function(done) { + var engine = listen({ allowUpgrades: false }, function(port) { + engine.on("connection", function(socket) { var totalEvents = 4; - engine.on('flush', function (sock, buf) { + engine.on("flush", function(sock, buf) { expect(sock).to.be(socket); - expect(buf).to.be.an('array'); + expect(buf).to.be.an("array"); --totalEvents || done(); }); - socket.on('flush', function (buf) { - expect(buf).to.be.an('array'); + socket.on("flush", function(buf) { + expect(buf).to.be.an("array"); --totalEvents || done(); }); - engine.on('drain', function (sock) { + engine.on("drain", function(sock) { expect(sock).to.be(socket); expect(socket.writeBuffer.length).to.be(0); --totalEvents || done(); }); - socket.on('drain', function () { + socket.on("drain", function() { expect(socket.writeBuffer.length).to.be(0); --totalEvents || done(); }); - socket.send('aaaa'); + socket.send("aaaa"); }); - eioc('ws://localhost:%d'.s(port)); + eioc("ws://localhost:%d".s(port)); }); }); - it('should interleave with pongs if many messages buffered ' + - 'after connection open', function (done) { - this.slow(4000); - this.timeout(8000); + it( + "should interleave with pongs if many messages buffered " + + "after connection open", + function(done) { + this.slow(4000); + this.timeout(8000); - var opts = { - transports: ['websocket'], - pingInterval: 200, - pingTimeout: 100 - }; + var opts = { + transports: ["websocket"], + pingInterval: 200, + pingTimeout: 100 + }; - var engine = listen(opts, function (port) { - var messageCount = 100; - var messagePayload = new Array(256 * 256).join('a'); - var connection = null; - engine.on('connection', function (conn) { - connection = conn; - }); - var socket = new eioc.Socket('ws://localhost:%d'.s(port), { transports: ['websocket'] }); - socket.on('open', function () { - for (var i = 0; i < messageCount; i++) { - // connection.send('message: ' + i); // works - connection.send(messagePayload + '|message: ' + i); // does not work - } - var receivedCount = 0; - socket.on('message', function (msg) { - receivedCount += 1; - if (receivedCount === messageCount) { - done(); + var engine = listen(opts, function(port) { + var messageCount = 100; + var messagePayload = new Array(256 * 256).join("a"); + var connection = null; + engine.on("connection", function(conn) { + connection = conn; + }); + var socket = new eioc.Socket("ws://localhost:%d".s(port), { + transports: ["websocket"] + }); + socket.on("open", function() { + for (var i = 0; i < messageCount; i++) { + // connection.send('message: ' + i); // works + connection.send(messagePayload + "|message: " + i); // does not work } + var receivedCount = 0; + socket.on("message", function(msg) { + receivedCount += 1; + if (receivedCount === messageCount) { + done(); + } + }); }); }); - }); - }); - - it('should support chinese', function (done) { - var engine = listen({ allowUpgrades: false }, function (port) { - var socket = new eioc.Socket('ws://localhost:%d'.s(port)); - var shi = '石室詩士施氏,嗜獅,誓食十獅。'; - var shi2 = '氏時時適市視獅。'; - engine.on('connection', function (conn) { - conn.send('.'); + } + ); + + it("should support chinese", function(done) { + var engine = listen({ allowUpgrades: false }, function(port) { + var socket = new eioc.Socket("ws://localhost:%d".s(port)); + var shi = "石室詩士施氏,嗜獅,誓食十獅。"; + var shi2 = "氏時時適市視獅。"; + engine.on("connection", function(conn) { + conn.send("."); conn.send(shi); conn.send(shi2); - conn.once('message', function (msg0) { - expect(msg0).to.be('.'); - conn.once('message', function (msg) { + conn.once("message", function(msg0) { + expect(msg0).to.be("."); + conn.once("message", function(msg) { expect(msg).to.be(shi); - conn.once('message', function (msg2) { + conn.once("message", function(msg2) { expect(msg2).to.be(shi2); done(); }); }); }); }); - socket.on('open', function () { - socket.once('message', function (msg0) { - expect(msg0).to.be('.'); - socket.once('message', function (msg) { + socket.on("open", function() { + socket.once("message", function(msg0) { + expect(msg0).to.be("."); + socket.once("message", function(msg) { expect(msg).to.be(shi); - socket.once('message', function (msg2) { + socket.once("message", function(msg2) { expect(msg2).to.be(shi2); - socket.send('.'); + socket.send("."); socket.send(shi); socket.send(shi2); }); @@ -1582,237 +1734,241 @@ describe('server', function () { }); }); - it('should send and receive data with key and cert (polling)', function (done) { + it("should send and receive data with key and cert (polling)", function(done) { if (UWS_ENGINE && NODE_LT_443) return done(); var srvOpts = { - key: fs.readFileSync('test/fixtures/server.key'), - cert: fs.readFileSync('test/fixtures/server.crt'), - ca: fs.readFileSync('test/fixtures/ca.crt'), + key: fs.readFileSync("test/fixtures/server.key"), + cert: fs.readFileSync("test/fixtures/server.crt"), + ca: fs.readFileSync("test/fixtures/ca.crt"), requestCert: true, rejectUnauthorized: true }; var opts = { - key: fs.readFileSync('test/fixtures/client.key'), - cert: fs.readFileSync('test/fixtures/client.crt'), - ca: fs.readFileSync('test/fixtures/ca.crt'), - transports: ['polling'] + key: fs.readFileSync("test/fixtures/client.key"), + cert: fs.readFileSync("test/fixtures/client.crt"), + ca: fs.readFileSync("test/fixtures/ca.crt"), + transports: ["polling"] }; - var srv = https.createServer(srvOpts, function (req, res) { + var srv = https.createServer(srvOpts, function(req, res) { res.writeHead(200); - res.end('hello world\n'); + res.end("hello world\n"); }); - var engine = eio({ transports: ['polling'], allowUpgrades: false }); + var engine = eio({ transports: ["polling"], allowUpgrades: false }); engine.attach(srv); - srv.listen(function () { + srv.listen(function() { var port = srv.address().port; - var socket = new eioc.Socket('https://localhost:%d'.s(port), opts); + var socket = new eioc.Socket("https://localhost:%d".s(port), opts); - engine.on('connection', function (conn) { - conn.on('message', function (msg) { - expect(msg).to.be('hello'); + engine.on("connection", function(conn) { + conn.on("message", function(msg) { + expect(msg).to.be("hello"); done(); }); }); - socket.on('open', function () { - socket.send('hello'); + socket.on("open", function() { + socket.send("hello"); }); }); }); - it('should send and receive data with ca when not requiring auth (polling)', function (done) { + it("should send and receive data with ca when not requiring auth (polling)", function(done) { if (UWS_ENGINE && NODE_LT_443) return done(); var srvOpts = { - key: fs.readFileSync('test/fixtures/server.key'), - cert: fs.readFileSync('test/fixtures/server.crt'), - ca: fs.readFileSync('test/fixtures/ca.crt'), + key: fs.readFileSync("test/fixtures/server.key"), + cert: fs.readFileSync("test/fixtures/server.crt"), + ca: fs.readFileSync("test/fixtures/ca.crt"), requestCert: true, rejectUnauthorized: false }; var opts = { - ca: fs.readFileSync('test/fixtures/ca.crt'), - transports: ['polling'] + ca: fs.readFileSync("test/fixtures/ca.crt"), + transports: ["polling"] }; - var srv = https.createServer(srvOpts, function (req, res) { + var srv = https.createServer(srvOpts, function(req, res) { res.writeHead(200); - res.end('hello world\n'); + res.end("hello world\n"); }); - var engine = eio({ transports: ['polling'], allowUpgrades: false }); + var engine = eio({ transports: ["polling"], allowUpgrades: false }); engine.attach(srv); - srv.listen(function () { + srv.listen(function() { var port = srv.address().port; - var socket = new eioc.Socket('https://localhost:%d'.s(port), opts); + var socket = new eioc.Socket("https://localhost:%d".s(port), opts); - engine.on('connection', function (conn) { - conn.on('message', function (msg) { - expect(msg).to.be('hello'); + engine.on("connection", function(conn) { + conn.on("message", function(msg) { + expect(msg).to.be("hello"); done(); }); }); - socket.on('open', function () { - socket.send('hello'); + socket.on("open", function() { + socket.send("hello"); }); }); }); - it('should send and receive data with key and cert (ws)', function (done) { + it("should send and receive data with key and cert (ws)", function(done) { var srvOpts = { - key: fs.readFileSync('test/fixtures/server.key'), - cert: fs.readFileSync('test/fixtures/server.crt'), - ca: fs.readFileSync('test/fixtures/ca.crt'), + key: fs.readFileSync("test/fixtures/server.key"), + cert: fs.readFileSync("test/fixtures/server.crt"), + ca: fs.readFileSync("test/fixtures/ca.crt"), requestCert: true, rejectUnauthorized: true }; var opts = { - key: fs.readFileSync('test/fixtures/client.key'), - cert: fs.readFileSync('test/fixtures/client.crt'), - ca: fs.readFileSync('test/fixtures/ca.crt'), - transports: ['websocket'] + key: fs.readFileSync("test/fixtures/client.key"), + cert: fs.readFileSync("test/fixtures/client.crt"), + ca: fs.readFileSync("test/fixtures/ca.crt"), + transports: ["websocket"] }; - var srv = https.createServer(srvOpts, function (req, res) { + var srv = https.createServer(srvOpts, function(req, res) { res.writeHead(200); - res.end('hello world\n'); + res.end("hello world\n"); }); - var engine = eio({ transports: ['websocket'], allowUpgrades: false }); + var engine = eio({ transports: ["websocket"], allowUpgrades: false }); engine.attach(srv); - srv.listen(function () { + srv.listen(function() { var port = srv.address().port; - var socket = new eioc.Socket('https://localhost:%d'.s(port), opts); + var socket = new eioc.Socket("https://localhost:%d".s(port), opts); - engine.on('connection', function (conn) { - conn.on('message', function (msg) { - expect(msg).to.be('hello'); + engine.on("connection", function(conn) { + conn.on("message", function(msg) { + expect(msg).to.be("hello"); done(); }); }); - socket.on('open', function () { - socket.send('hello'); + socket.on("open", function() { + socket.send("hello"); }); }); }); - it('should send and receive data with pfx (polling)', function (done) { + it("should send and receive data with pfx (polling)", function(done) { if (UWS_ENGINE && NODE_LT_443) return done(); var srvOpts = { - key: fs.readFileSync('test/fixtures/server.key'), - cert: fs.readFileSync('test/fixtures/server.crt'), - ca: fs.readFileSync('test/fixtures/ca.crt'), + key: fs.readFileSync("test/fixtures/server.key"), + cert: fs.readFileSync("test/fixtures/server.crt"), + ca: fs.readFileSync("test/fixtures/ca.crt"), requestCert: true, rejectUnauthorized: true }; var opts = { - pfx: fs.readFileSync('test/fixtures/client.pfx'), - ca: fs.readFileSync('test/fixtures/ca.crt'), - transports: ['polling'] + pfx: fs.readFileSync("test/fixtures/client.pfx"), + ca: fs.readFileSync("test/fixtures/ca.crt"), + transports: ["polling"] }; - var srv = https.createServer(srvOpts, function (req, res) { + var srv = https.createServer(srvOpts, function(req, res) { res.writeHead(200); - res.end('hello world\n'); + res.end("hello world\n"); }); - var engine = eio({ transports: ['polling'], allowUpgrades: false }); + var engine = eio({ transports: ["polling"], allowUpgrades: false }); engine.attach(srv); - srv.listen(function () { + srv.listen(function() { var port = srv.address().port; - var socket = new eioc.Socket('https://localhost:%d'.s(port), opts); + var socket = new eioc.Socket("https://localhost:%d".s(port), opts); - engine.on('connection', function (conn) { - conn.on('message', function (msg) { - expect(msg).to.be('hello'); + engine.on("connection", function(conn) { + conn.on("message", function(msg) { + expect(msg).to.be("hello"); done(); }); }); - socket.on('open', function () { - socket.send('hello'); + socket.on("open", function() { + socket.send("hello"); }); }); }); - it('should send and receive data with pfx (ws)', function (done) { + it("should send and receive data with pfx (ws)", function(done) { if (UWS_ENGINE && NODE_LT_443) return done(); var srvOpts = { - key: fs.readFileSync('test/fixtures/server.key'), - cert: fs.readFileSync('test/fixtures/server.crt'), - ca: fs.readFileSync('test/fixtures/ca.crt'), + key: fs.readFileSync("test/fixtures/server.key"), + cert: fs.readFileSync("test/fixtures/server.crt"), + ca: fs.readFileSync("test/fixtures/ca.crt"), requestCert: true, rejectUnauthorized: true }; var opts = { - pfx: fs.readFileSync('test/fixtures/client.pfx'), - ca: fs.readFileSync('test/fixtures/ca.crt'), - transports: ['websocket'] + pfx: fs.readFileSync("test/fixtures/client.pfx"), + ca: fs.readFileSync("test/fixtures/ca.crt"), + transports: ["websocket"] }; - var srv = https.createServer(srvOpts, function (req, res) { + var srv = https.createServer(srvOpts, function(req, res) { res.writeHead(200); - res.end('hello world\n'); + res.end("hello world\n"); }); - var engine = eio({ transports: ['websocket'], allowUpgrades: false }); + var engine = eio({ transports: ["websocket"], allowUpgrades: false }); engine.attach(srv); - srv.listen(function () { + srv.listen(function() { var port = srv.address().port; - var socket = new eioc.Socket('https://localhost:%d'.s(port), opts); + var socket = new eioc.Socket("https://localhost:%d".s(port), opts); - engine.on('connection', function (conn) { - conn.on('message', function (msg) { - expect(msg).to.be('hello'); + engine.on("connection", function(conn) { + conn.on("message", function(msg) { + expect(msg).to.be("hello"); done(); }); }); - socket.on('open', function () { - socket.send('hello'); + socket.on("open", function() { + socket.send("hello"); }); }); }); }); - describe('send', function () { - describe('writeBuffer', function () { - it('should not empty until `drain` event (polling)', function (done) { - listen({ allowUpgrades: false }, function (port) { - var socket = new eioc.Socket('ws://localhost:%d'.s(port), { transports: ['polling'] }); + describe("send", function() { + describe("writeBuffer", function() { + it("should not empty until `drain` event (polling)", function(done) { + listen({ allowUpgrades: false }, function(port) { + var socket = new eioc.Socket("ws://localhost:%d".s(port), { + transports: ["polling"] + }); var totalEvents = 2; - socket.on('open', function () { - socket.send('a'); - socket.send('b'); + socket.on("open", function() { + socket.send("a"); + socket.send("b"); // writeBuffer should be nonempty, with 'a' still in it expect(socket.writeBuffer.length).to.eql(2); }); - socket.transport.on('drain', function () { + socket.transport.on("drain", function() { expect(socket.writeBuffer.length).to.eql(--totalEvents); totalEvents || done(); }); }); }); - it('should not empty until `drain` event (websocket)', function (done) { - listen({ allowUpgrades: false }, function (port) { - var socket = new eioc.Socket('ws://localhost:%d'.s(port), { transports: ['websocket'] }); + it("should not empty until `drain` event (websocket)", function(done) { + listen({ allowUpgrades: false }, function(port) { + var socket = new eioc.Socket("ws://localhost:%d".s(port), { + transports: ["websocket"] + }); var totalEvents = 2; - socket.on('open', function () { - socket.send('a'); - socket.send('b'); + socket.on("open", function() { + socket.send("a"); + socket.send("b"); // writeBuffer should be nonempty, with 'a' still in it expect(socket.writeBuffer.length).to.eql(2); }); - socket.transport.on('drain', function () { + socket.transport.on("drain", function() { expect(socket.writeBuffer.length).to.eql(--totalEvents); totalEvents || done(); }); @@ -1820,21 +1976,23 @@ describe('server', function () { }); }); - describe('callback', function () { - it('should execute in order when message sent (client) (polling)', function (done) { - var engine = listen({ allowUpgrades: false }, function (port) { - var socket = new eioc.Socket('ws://localhost:%d'.s(port), { transports: ['polling'] }); + describe("callback", function() { + it("should execute in order when message sent (client) (polling)", function(done) { + var engine = listen({ allowUpgrades: false }, function(port) { + var socket = new eioc.Socket("ws://localhost:%d".s(port), { + transports: ["polling"] + }); var i = 0; var j = 0; - engine.on('connection', function (conn) { - conn.on('message', function (msg) { + engine.on("connection", function(conn) { + conn.on("message", function(msg) { conn.send(msg); }); }); - socket.on('open', function () { - socket.on('message', function (msg) { + socket.on("open", function() { + socket.on("message", function(msg) { // send another packet until we've sent 3 total if (++i < 3) { expect(i).to.eql(j); @@ -1844,10 +2002,13 @@ describe('server', function () { } }); - function sendFn () { - socket.send(j, (function (value) { - j++; - })(j)); + function sendFn() { + socket.send( + j, + (function(value) { + j++; + })(j) + ); } sendFn(); @@ -1855,20 +2016,22 @@ describe('server', function () { }); }); - it('should execute in order when message sent (client) (websocket)', function (done) { - var engine = listen({ allowUpgrades: false }, function (port) { - var socket = new eioc.Socket('ws://localhost:%d'.s(port), { transports: ['websocket'] }); + it("should execute in order when message sent (client) (websocket)", function(done) { + var engine = listen({ allowUpgrades: false }, function(port) { + var socket = new eioc.Socket("ws://localhost:%d".s(port), { + transports: ["websocket"] + }); var i = 0; var j = 0; - engine.on('connection', function (conn) { - conn.on('message', function (msg) { + engine.on("connection", function(conn) { + conn.on("message", function(msg) { conn.send(msg); }); }); - socket.on('open', function () { - socket.on('message', function (msg) { + socket.on("open", function() { + socket.on("message", function(msg) { // send another packet until we've sent 3 total if (++i < 3) { expect(i).to.eql(j); @@ -1878,10 +2041,13 @@ describe('server', function () { } }); - function sendFn () { - socket.send(j, (function (value) { - j++; - })(j)); + function sendFn() { + socket.send( + j, + (function(value) { + j++; + })(j) + ); } sendFn(); @@ -1889,25 +2055,27 @@ describe('server', function () { }); }); - it('should execute in order with payloads (client) (polling)', function (done) { - var engine = listen({ allowUpgrades: false }, function (port) { - var socket = new eioc.Socket('ws://localhost:%d'.s(port), { transports: ['polling'] }); + it("should execute in order with payloads (client) (polling)", function(done) { + var engine = listen({ allowUpgrades: false }, function(port) { + var socket = new eioc.Socket("ws://localhost:%d".s(port), { + transports: ["polling"] + }); var i = 0; var lastCbFired = 0; - engine.on('connection', function (conn) { - conn.on('message', function (msg) { + engine.on("connection", function(conn) { + conn.on("message", function(msg) { conn.send(msg); }); }); - socket.on('open', function () { - socket.on('message', function (msg) { + socket.on("open", function() { + socket.on("message", function(msg) { expect(msg).to.eql(i + 1); i++; }); - function cb (value) { + function cb(value) { expect(value).to.eql(lastCbFired + 1); lastCbFired = value; if (value === 3) { @@ -1916,35 +2084,43 @@ describe('server', function () { } // 2 and 3 will be in the same payload - socket.once('flush', function () { - socket.send(2, function () { cb(2); }); - socket.send(3, function () { cb(3); }); + socket.once("flush", function() { + socket.send(2, function() { + cb(2); + }); + socket.send(3, function() { + cb(3); + }); }); - socket.send(1, function () { cb(1); }); + socket.send(1, function() { + cb(1); + }); }); }); }); - it('should execute in order with payloads (client) (websocket)', function (done) { - var engine = listen({ allowUpgrades: false }, function (port) { - var socket = new eioc.Socket('ws://localhost:%d'.s(port), { transports: ['websocket'] }); + it("should execute in order with payloads (client) (websocket)", function(done) { + var engine = listen({ allowUpgrades: false }, function(port) { + var socket = new eioc.Socket("ws://localhost:%d".s(port), { + transports: ["websocket"] + }); var i = 0; var lastCbFired = 0; - engine.on('connection', function (conn) { - conn.on('message', function (msg) { + engine.on("connection", function(conn) { + conn.on("message", function(msg) { conn.send(msg); }); }); - socket.on('open', function () { - socket.on('message', function (msg) { + socket.on("open", function() { + socket.on("message", function(msg) { expect(msg).to.eql(i + 1); i++; }); - function cb (value) { + function cb(value) { expect(value).to.eql(lastCbFired + 1); lastCbFired = value; if (value === 3) { @@ -1953,84 +2129,94 @@ describe('server', function () { } // 2 and 3 will be in the same payload - socket.once('flush', function () { - socket.send(2, function () { cb(2); }); - socket.send(3, function () { cb(3); }); + socket.once("flush", function() { + socket.send(2, function() { + cb(2); + }); + socket.send(3, function() { + cb(3); + }); }); - socket.send(1, function () { cb(1); }); + socket.send(1, function() { + cb(1); + }); }); }); }); - it('should execute when message sent (polling)', function (done) { - var engine = listen({ allowUpgrades: false }, function (port) { - var socket = new eioc.Socket('ws://localhost:%d'.s(port), { transports: ['polling'] }); + it("should execute when message sent (polling)", function(done) { + var engine = listen({ allowUpgrades: false }, function(port) { + var socket = new eioc.Socket("ws://localhost:%d".s(port), { + transports: ["polling"] + }); var i = 0; var j = 0; - engine.on('connection', function (conn) { - conn.send('a', function (transport) { + engine.on("connection", function(conn) { + conn.send("a", function(transport) { i++; }); }); - socket.on('open', function () { - socket.on('message', function (msg) { + socket.on("open", function() { + socket.on("message", function(msg) { j++; }); }); - setTimeout(function () { + setTimeout(function() { expect(i).to.be(j); done(); }, 100); }); }); - it('should execute when message sent (websocket)', function (done) { - var engine = listen({ allowUpgrades: false }, function (port) { - var socket = new eioc.Socket('ws://localhost:%d'.s(port), { transports: ['websocket'] }); + it("should execute when message sent (websocket)", function(done) { + var engine = listen({ allowUpgrades: false }, function(port) { + var socket = new eioc.Socket("ws://localhost:%d".s(port), { + transports: ["websocket"] + }); var i = 0; var j = 0; - engine.on('connection', function (conn) { - conn.send('a', function (transport) { + engine.on("connection", function(conn) { + conn.send("a", function(transport) { i++; }); }); - socket.on('open', function () { - socket.on('message', function (msg) { + socket.on("open", function() { + socket.on("message", function(msg) { j++; }); }); - setTimeout(function () { + setTimeout(function() { expect(i).to.be(j); done(); }, 100); }); }); - it('should execute once for each send', function (done) { - var engine = listen(function (port) { - var socket = new eioc.Socket('ws://localhost:%d'.s(port)); + it("should execute once for each send", function(done) { + var engine = listen(function(port) { + var socket = new eioc.Socket("ws://localhost:%d".s(port)); var a = 0; var b = 0; var c = 0; var all = 0; - engine.on('connection', function (conn) { - conn.send('a'); - conn.send('b'); - conn.send('c'); + engine.on("connection", function(conn) { + conn.send("a"); + conn.send("b"); + conn.send("c"); }); - socket.on('open', function () { - socket.on('message', function (msg) { - if (msg === 'a') a++; - if (msg === 'b') b++; - if (msg === 'c') c++; + socket.on("open", function() { + socket.on("message", function(msg) { + if (msg === "a") a++; + if (msg === "b") b++; + if (msg === "c") c++; if (++all === 3) { expect(a).to.be(1); @@ -2043,89 +2229,93 @@ describe('server', function () { }); }); - it('should execute in multipart packet', function (done) { - var engine = listen(function (port) { - var socket = new eioc.Socket('ws://localhost:%d'.s(port)); + it("should execute in multipart packet", function(done) { + var engine = listen(function(port) { + var socket = new eioc.Socket("ws://localhost:%d".s(port)); var i = 0; var j = 0; - engine.on('connection', function (conn) { - conn.send('b', function (transport) { + engine.on("connection", function(conn) { + conn.send("b", function(transport) { i++; }); - conn.send('a', function (transport) { + conn.send("a", function(transport) { i++; }); }); - socket.on('open', function () { - socket.on('message', function (msg) { + socket.on("open", function() { + socket.on("message", function(msg) { j++; }); }); - setTimeout(function () { + setTimeout(function() { expect(i).to.be(j); done(); }, 200); }); }); - it('should execute in multipart packet (polling)', function (done) { - var engine = listen(function (port) { - var socket = new eioc.Socket('ws://localhost:%d'.s(port), { transports: ['polling'] }); + it("should execute in multipart packet (polling)", function(done) { + var engine = listen(function(port) { + var socket = new eioc.Socket("ws://localhost:%d".s(port), { + transports: ["polling"] + }); var i = 0; var j = 0; - engine.on('connection', function (conn) { - conn.send('d', function (transport) { + engine.on("connection", function(conn) { + conn.send("d", function(transport) { i++; }); - conn.send('c', function (transport) { + conn.send("c", function(transport) { i++; }); - conn.send('b', function (transport) { + conn.send("b", function(transport) { i++; }); - conn.send('a', function (transport) { + conn.send("a", function(transport) { i++; }); }); - socket.on('open', function () { - socket.on('message', function (msg) { + socket.on("open", function() { + socket.on("message", function(msg) { j++; }); }); - setTimeout(function () { + setTimeout(function() { expect(i).to.be(j); done(); }, 200); }); }); - it('should clean callback references when socket gets closed with pending callbacks', function (done) { - var engine = listen({ allowUpgrades: false }, function (port) { - var socket = new eioc.Socket('ws://localhost:%d'.s(port), { transports: ['polling'] }); + it("should clean callback references when socket gets closed with pending callbacks", function(done) { + var engine = listen({ allowUpgrades: false }, function(port) { + var socket = new eioc.Socket("ws://localhost:%d".s(port), { + transports: ["polling"] + }); - engine.on('connection', function (conn) { - socket.transport.on('pollComplete', function () { - conn.send('a', function (transport) { - done(new Error('Test invalidation')); + engine.on("connection", function(conn) { + socket.transport.on("pollComplete", function() { + conn.send("a", function(transport) { + done(new Error("Test invalidation")); }); if (!conn.writeBuffer.length) { - done(new Error('Test invalidation')); + done(new Error("Test invalidation")); } // force to close the socket when we have one or more packet(s) in buffer socket.close(); }); - conn.on('close', function (reason) { + conn.on("close", function(reason) { expect(conn.packetsFn).to.be.empty(); expect(conn.sentCallbackFn).to.be.empty(); done(); @@ -2134,21 +2324,23 @@ describe('server', function () { }); }); - it('should not execute when it is not actually sent (polling)', function (done) { - var engine = listen({ allowUpgrades: false }, function (port) { - var socket = new eioc.Socket('ws://localhost:%d'.s(port), { transports: ['polling'] }); + it("should not execute when it is not actually sent (polling)", function(done) { + var engine = listen({ allowUpgrades: false }, function(port) { + var socket = new eioc.Socket("ws://localhost:%d".s(port), { + transports: ["polling"] + }); - socket.transport.on('pollComplete', function (msg) { + socket.transport.on("pollComplete", function(msg) { socket.close(); }); - engine.on('connection', function (conn) { + engine.on("connection", function(conn) { var err; - conn.send('a'); - conn.send('b', function (transport) { - err = new Error('Test invalidation'); + conn.send("a"); + conn.send("b", function(transport) { + err = new Error("Test invalidation"); }); - conn.on('close', function (reason) { + conn.on("close", function(reason) { done(err); }); }); @@ -2157,30 +2349,32 @@ describe('server', function () { }); }); - describe('packet', function () { - it('should emit when socket receives packet', function (done) { - var engine = listen({ allowUpgrades: false }, function (port) { - var socket = new eioc.Socket('ws://localhost:%d'.s(port)); - engine.on('connection', function (conn) { - conn.on('packet', function (packet) { - expect(packet.type).to.be('message'); - expect(packet.data).to.be('a'); + describe("packet", function() { + it("should emit when socket receives packet", function(done) { + var engine = listen({ allowUpgrades: false }, function(port) { + var socket = new eioc.Socket("ws://localhost:%d".s(port)); + engine.on("connection", function(conn) { + conn.on("packet", function(packet) { + expect(packet.type).to.be("message"); + expect(packet.data).to.be("a"); done(); }); }); - socket.on('open', function () { - socket.send('a'); + socket.on("open", function() { + socket.send("a"); }); }); }); - it('should emit when receives ping', function (done) { - var engine = listen({ allowUpgrades: false, pingInterval: 4 }, function (port) { - eioc('ws://localhost:%d'.s(port)); - engine.on('connection', function (conn) { - conn.on('packet', function (packet) { + it("should emit when receives ping", function(done) { + var engine = listen({ allowUpgrades: false, pingInterval: 4 }, function( + port + ) { + eioc("ws://localhost:%d".s(port)); + engine.on("connection", function(conn) { + conn.on("packet", function(packet) { conn.close(); - expect(packet.type).to.be('ping'); + expect(packet.type).to.be("ping"); done(); }); }); @@ -2188,28 +2382,30 @@ describe('server', function () { }); }); - describe('packetCreate', function () { - it('should emit before socket send message', function (done) { - var engine = listen({ allowUpgrades: false }, function (port) { - eioc('ws://localhost:%d'.s(port)); - engine.on('connection', function (conn) { - conn.on('packetCreate', function (packet) { - expect(packet.type).to.be('message'); - expect(packet.data).to.be('a'); + describe("packetCreate", function() { + it("should emit before socket send message", function(done) { + var engine = listen({ allowUpgrades: false }, function(port) { + eioc("ws://localhost:%d".s(port)); + engine.on("connection", function(conn) { + conn.on("packetCreate", function(packet) { + expect(packet.type).to.be("message"); + expect(packet.data).to.be("a"); done(); }); - conn.send('a'); + conn.send("a"); }); }); }); - it('should emit before send pong', function (done) { - var engine = listen({ allowUpgrades: false, pingInterval: 4 }, function (port) { - eioc('ws://localhost:%d'.s(port)); - engine.on('connection', function (conn) { - conn.on('packetCreate', function (packet) { + it("should emit before send pong", function(done) { + var engine = listen({ allowUpgrades: false, pingInterval: 4 }, function( + port + ) { + eioc("ws://localhost:%d".s(port)); + engine.on("connection", function(conn) { + conn.on("packetCreate", function(packet) { conn.close(); - expect(packet.type).to.be('pong'); + expect(packet.type).to.be("pong"); done(); }); }); @@ -2217,24 +2413,24 @@ describe('server', function () { }); }); - describe('upgrade', function () { - it('should upgrade', function (done) { - var engine = listen(function (port) { + describe("upgrade", function() { + it("should upgrade", function(done) { + var engine = listen(function(port) { // it takes both to send 50 to verify var ready = 2; var closed = 2; - function finish () { - setTimeout(function () { + function finish() { + setTimeout(function() { socket.close(); }, 10); } // server - engine.on('connection', function (conn) { + engine.on("connection", function(conn) { var lastSent = 0; var lastReceived = 0; var upgraded = false; - var interval = setInterval(function () { + var interval = setInterval(function() { lastSent++; conn.send(lastSent); if (50 === lastSent) { @@ -2243,23 +2439,23 @@ describe('server', function () { } }, 2); - expect(conn.request._query.transport).to.be('polling'); + expect(conn.request._query.transport).to.be("polling"); - conn.on('message', function (msg) { - expect(conn.request._query).to.be.an('object'); + conn.on("message", function(msg) { + expect(conn.request._query).to.be.an("object"); lastReceived++; expect(msg).to.eql(lastReceived); }); - conn.on('upgrade', function (to) { - expect(conn.request._query.transport).to.be('polling'); + conn.on("upgrade", function(to) { + expect(conn.request._query.transport).to.be("polling"); upgraded = true; - expect(to.name).to.be('websocket'); - expect(conn.transport.name).to.be('websocket'); + expect(to.name).to.be("websocket"); + expect(conn.transport.name).to.be("websocket"); }); - conn.on('close', function (reason) { - expect(reason).to.be('transport close'); + conn.on("close", function(reason) { + expect(reason).to.be("transport close"); expect(lastSent).to.be(50); expect(lastReceived).to.be(50); expect(upgraded).to.be(true); @@ -2268,12 +2464,12 @@ describe('server', function () { }); // client - var socket = new eioc.Socket('ws://localhost:%d'.s(port)); - socket.on('open', function () { + var socket = new eioc.Socket("ws://localhost:%d".s(port)); + socket.on("open", function() { var lastSent = 0; var lastReceived = 0; var upgrades = 0; - var interval = setInterval(function () { + var interval = setInterval(function() { lastSent++; socket.send(lastSent); if (50 === lastSent) { @@ -2281,9 +2477,9 @@ describe('server', function () { --ready || finish(); } }, 2); - socket.on('upgrading', function (to) { + socket.on("upgrading", function(to) { // we want to make sure for the sake of this test that we have a buffer - expect(to.name).to.equal('websocket'); + expect(to.name).to.equal("websocket"); upgrades++; // force send a few packets to ensure we test buffer transfer @@ -2294,16 +2490,16 @@ describe('server', function () { expect(socket.writeBuffer).to.not.be.empty(); }); - socket.on('upgrade', function (to) { - expect(to.name).to.equal('websocket'); + socket.on("upgrade", function(to) { + expect(to.name).to.equal("websocket"); upgrades++; }); - socket.on('message', function (msg) { + socket.on("message", function(msg) { lastReceived++; expect(lastReceived).to.eql(msg); }); - socket.on('close', function (reason) { - expect(reason).to.be('forced close'); + socket.on("close", function(reason) { + expect(reason).to.be("forced close"); expect(lastSent).to.be(50); expect(upgrades).to.be(2); --closed || done(); @@ -2312,202 +2508,249 @@ describe('server', function () { }); // attach another engine to make sure it doesn't break upgrades - eio.attach(engine.httpServer, { path: '/foo' }); + eio.attach(engine.httpServer, { path: "/foo" }); }); }); - describe('http compression', function () { - function getSidFromResponse (res) { - var c = cookieMod.parse(res.headers['set-cookie'][0]); + describe("http compression", function() { + function getSidFromResponse(res) { + var c = cookieMod.parse(res.headers["set-cookie"][0]); return c[Object.keys(c)[0]]; } - it('should compress by default', function (done) { - var engine = listen({ transports: ['polling'] }, function (port) { - engine.on('connection', function (conn) { + it("should compress by default", function(done) { + var engine = listen({ transports: ["polling"] }, function(port) { + engine.on("connection", function(conn) { var buf = Buffer.allocUnsafe(1024); for (var i = 0; i < buf.length; i++) buf[i] = i % 0xff; conn.send(buf); }); - http.get({ - port: port, - path: '/engine.io/default/?transport=polling' - }, function (res) { - var sid = getSidFromResponse(res); - http.get({ - port: port, - path: '/engine.io/default/?transport=polling&sid=' + sid, - headers: { 'Accept-Encoding': 'gzip, deflate' } - }, function (res) { - expect(res.headers['content-encoding']).to.equal('gzip'); - res.pipe(zlib.createGunzip()) - .on('error', done) - .on('end', done) - .resume(); - }); - }); - }); - }); - - it('should compress using deflate', function (done) { - var engine = listen({ transports: ['polling'] }, function (port) { - engine.on('connection', function (conn) { - var buf = Buffer.allocUnsafe(1024); - for (var i = 0; i < buf.length; i++) buf[i] = i % 0xff; - conn.send(buf); - }); - - http.get({ - port: port, - path: '/engine.io/default/?transport=polling' - }, function (res) { - var sid = getSidFromResponse(res); - http.get({ - port: port, - path: '/engine.io/default/?transport=polling&sid=' + sid, - headers: { 'Accept-Encoding': 'deflate' } - }, function (res) { - expect(res.headers['content-encoding']).to.equal('deflate'); - res.pipe(zlib.createDeflate()) - .on('error', done) - .on('end', done) - .resume(); - }); - }); - }); - }); - - it('should set threshold', function (done) { - var engine = listen({ transports: ['polling'], httpCompression: { threshold: 0 } }, function (port) { - engine.on('connection', function (conn) { - var buf = Buffer.allocUnsafe(10); - for (var i = 0; i < buf.length; i++) buf[i] = i % 0xff; - conn.send(buf); - }); - - http.get({ - port: port, - path: '/engine.io/default/?transport=polling' - }, function (res) { - var sid = getSidFromResponse(res); - http.get({ + http.get( + { port: port, - path: '/engine.io/default/?transport=polling&sid=' + sid, - headers: { 'Accept-Encoding': 'gzip, deflate' } - }, function (res) { - expect(res.headers['content-encoding']).to.equal('gzip'); - done(); - }); - }); + path: "/engine.io/default/?transport=polling" + }, + function(res) { + var sid = getSidFromResponse(res); + http.get( + { + port: port, + path: "/engine.io/default/?transport=polling&sid=" + sid, + headers: { "Accept-Encoding": "gzip, deflate" } + }, + function(res) { + expect(res.headers["content-encoding"]).to.equal("gzip"); + res + .pipe(zlib.createGunzip()) + .on("error", done) + .on("end", done) + .resume(); + } + ); + } + ); }); }); - it('should disable compression', function (done) { - var engine = listen({ transports: ['polling'], httpCompression: false }, function (port) { - engine.on('connection', function (conn) { + it("should compress using deflate", function(done) { + var engine = listen({ transports: ["polling"] }, function(port) { + engine.on("connection", function(conn) { var buf = Buffer.allocUnsafe(1024); for (var i = 0; i < buf.length; i++) buf[i] = i % 0xff; conn.send(buf); }); - http.get({ - port: port, - path: '/engine.io/default/?transport=polling' - }, function (res) { - var sid = getSidFromResponse(res); - http.get({ + http.get( + { port: port, - path: '/engine.io/default/?transport=polling&sid=' + sid, - headers: { 'Accept-Encoding': 'gzip, deflate' } - }, function (res) { - expect(res.headers['content-encoding']).to.be(undefined); - done(); - }); - }); - }); + path: "/engine.io/default/?transport=polling" + }, + function(res) { + var sid = getSidFromResponse(res); + http.get( + { + port: port, + path: "/engine.io/default/?transport=polling&sid=" + sid, + headers: { "Accept-Encoding": "deflate" } + }, + function(res) { + expect(res.headers["content-encoding"]).to.equal("deflate"); + res + .pipe(zlib.createDeflate()) + .on("error", done) + .on("end", done) + .resume(); + } + ); + } + ); + }); + }); + + it("should set threshold", function(done) { + var engine = listen( + { transports: ["polling"], httpCompression: { threshold: 0 } }, + function(port) { + engine.on("connection", function(conn) { + var buf = Buffer.allocUnsafe(10); + for (var i = 0; i < buf.length; i++) buf[i] = i % 0xff; + conn.send(buf); + }); + + http.get( + { + port: port, + path: "/engine.io/default/?transport=polling" + }, + function(res) { + var sid = getSidFromResponse(res); + http.get( + { + port: port, + path: "/engine.io/default/?transport=polling&sid=" + sid, + headers: { "Accept-Encoding": "gzip, deflate" } + }, + function(res) { + expect(res.headers["content-encoding"]).to.equal("gzip"); + done(); + } + ); + } + ); + } + ); + }); + + it("should disable compression", function(done) { + var engine = listen( + { transports: ["polling"], httpCompression: false }, + function(port) { + engine.on("connection", function(conn) { + var buf = Buffer.allocUnsafe(1024); + for (var i = 0; i < buf.length; i++) buf[i] = i % 0xff; + conn.send(buf); + }); + + http.get( + { + port: port, + path: "/engine.io/default/?transport=polling" + }, + function(res) { + var sid = getSidFromResponse(res); + http.get( + { + port: port, + path: "/engine.io/default/?transport=polling&sid=" + sid, + headers: { "Accept-Encoding": "gzip, deflate" } + }, + function(res) { + expect(res.headers["content-encoding"]).to.be(undefined); + done(); + } + ); + } + ); + } + ); }); - it('should disable compression per message', function (done) { - var engine = listen({ transports: ['polling'] }, function (port) { - engine.on('connection', function (conn) { + it("should disable compression per message", function(done) { + var engine = listen({ transports: ["polling"] }, function(port) { + engine.on("connection", function(conn) { var buf = Buffer.allocUnsafe(1024); for (var i = 0; i < buf.length; i++) buf[i] = i % 0xff; conn.send(buf, { compress: false }); }); - http.get({ - port: port, - path: '/engine.io/default/?transport=polling' - }, function (res) { - var sid = getSidFromResponse(res); - http.get({ + http.get( + { port: port, - path: '/engine.io/default/?transport=polling&sid=' + sid, - headers: { 'Accept-Encoding': 'gzip, deflate' } - }, function (res) { - expect(res.headers['content-encoding']).to.be(undefined); - done(); - }); - }); + path: "/engine.io/default/?transport=polling" + }, + function(res) { + var sid = getSidFromResponse(res); + http.get( + { + port: port, + path: "/engine.io/default/?transport=polling&sid=" + sid, + headers: { "Accept-Encoding": "gzip, deflate" } + }, + function(res) { + expect(res.headers["content-encoding"]).to.be(undefined); + done(); + } + ); + } + ); }); }); - it('should not compress when the byte size is below threshold', function (done) { - var engine = listen({ transports: ['polling'] }, function (port) { - engine.on('connection', function (conn) { + it("should not compress when the byte size is below threshold", function(done) { + var engine = listen({ transports: ["polling"] }, function(port) { + engine.on("connection", function(conn) { var buf = Buffer.allocUnsafe(100); for (var i = 0; i < buf.length; i++) buf[i] = i % 0xff; conn.send(buf); }); - http.get({ - port: port, - path: '/engine.io/default/?transport=polling' - }, function (res) { - var sid = getSidFromResponse(res); - http.get({ + http.get( + { port: port, - path: '/engine.io/default/?transport=polling&sid=' + sid, - headers: { 'Accept-Encoding': 'gzip, deflate' } - }, function (res) { - expect(res.headers['content-encoding']).to.be(undefined); - done(); - }); - }); + path: "/engine.io/default/?transport=polling" + }, + function(res) { + var sid = getSidFromResponse(res); + http.get( + { + port: port, + path: "/engine.io/default/?transport=polling&sid=" + sid, + headers: { "Accept-Encoding": "gzip, deflate" } + }, + function(res) { + expect(res.headers["content-encoding"]).to.be(undefined); + done(); + } + ); + } + ); }); }); }); - describe('permessage-deflate', function () { - it('should set threshold', function (done) { - var engine = listen({ transports: ['websocket'], perMessageDeflate: { threshold: 0 } }, function (port) { - engine.on('connection', function (conn) { - var socket = conn.transport.socket; - var send = socket.send; - socket.send = function (data, opts, callback) { - socket.send = send; - socket.send(data, opts, callback); - - expect(opts.compress).to.be(true); - conn.close(); - done(); - }; + describe("permessage-deflate", function() { + it("should set threshold", function(done) { + var engine = listen( + { transports: ["websocket"], perMessageDeflate: { threshold: 0 } }, + function(port) { + engine.on("connection", function(conn) { + var socket = conn.transport.socket; + var send = socket.send; + socket.send = function(data, opts, callback) { + socket.send = send; + socket.send(data, opts, callback); + + expect(opts.compress).to.be(true); + conn.close(); + done(); + }; - var buf = Buffer.allocUnsafe(100); - for (var i = 0; i < buf.length; i++) buf[i] = i % 0xff; - conn.send(buf, { compress: true }); - }); - eioc('http://localhost:%d'.s(port), { transports: ['websocket'] }); - }); + var buf = Buffer.allocUnsafe(100); + for (var i = 0; i < buf.length; i++) buf[i] = i % 0xff; + conn.send(buf, { compress: true }); + }); + eioc("http://localhost:%d".s(port), { transports: ["websocket"] }); + } + ); }); - it('should not compress when the byte size is below threshold', function (done) { - var engine = listen({ transports: ['websocket'] }, function (port) { - engine.on('connection', function (conn) { + it("should not compress when the byte size is below threshold", function(done) { + var engine = listen({ transports: ["websocket"] }, function(port) { + engine.on("connection", function(conn) { var socket = conn.transport.socket; var send = socket.send; - socket.send = function (data, opts, callback) { + socket.send = function(data, opts, callback) { socket.send = send; socket.send(data, opts, callback); @@ -2520,97 +2763,110 @@ describe('server', function () { for (var i = 0; i < buf.length; i++) buf[i] = i % 0xff; conn.send(buf, { compress: true }); }); - eioc('http://localhost:%d'.s(port), { transports: ['websocket'] }); + eioc("http://localhost:%d".s(port), { transports: ["websocket"] }); }); }); }); - describe('extraHeaders', function () { + describe("extraHeaders", function() { this.timeout(5000); var headers = { - 'x-custom-header-for-my-project': 'my-secret-access-token', - 'cookie': 'user_session=NI2JlCKF90aE0sJZD9ZzujtdsUqNYSBYxzlTsvdSUe35ZzdtVRGqYFr0kdGxbfc5gUOkR9RGp20GVKza; path=/; expires=Tue, 07-Apr-2015 18:18:08 GMT; secure; HttpOnly' + "x-custom-header-for-my-project": "my-secret-access-token", + cookie: + "user_session=NI2JlCKF90aE0sJZD9ZzujtdsUqNYSBYxzlTsvdSUe35ZzdtVRGqYFr0kdGxbfc5gUOkR9RGp20GVKza; path=/; expires=Tue, 07-Apr-2015 18:18:08 GMT; secure; HttpOnly" }; - function testForTransport (transport, done) { - var engine = listen(function (port) { - var socket = new eioc.Socket('ws://localhost:%d'.s(port), { + function testForTransport(transport, done) { + var engine = listen(function(port) { + var socket = new eioc.Socket("ws://localhost:%d".s(port), { extraHeaders: headers, transports: [transport] }); - engine.on('connection', function (conn) { + engine.on("connection", function(conn) { for (var h in headers) { expect(conn.request.headers[h]).to.equal(headers[h]); } done(); }); - socket.on('open', function () {}); + socket.on("open", function() {}); }); } - it('should arrive from client to server via WebSockets', function (done) { - testForTransport('websocket', done); + it("should arrive from client to server via WebSockets", function(done) { + testForTransport("websocket", done); }); - it('should arrive from client to server via XMLHttpRequest', function (done) { - testForTransport('polling', done); + it("should arrive from client to server via XMLHttpRequest", function(done) { + testForTransport("polling", done); }); }); - describe('response headers', function () { - function testForHeaders (headers, done) { - var engine = listen(function (port) { - engine.on('connection', function (conn) { - conn.transport.once('headers', function (headers) { - expect(headers['X-XSS-Protection']).to.be('0'); + describe("response headers", function() { + function testForHeaders(headers, done) { + var engine = listen(function(port) { + engine.on("connection", function(conn) { + conn.transport.once("headers", function(headers) { + expect(headers["X-XSS-Protection"]).to.be("0"); conn.close(); done(); }); - conn.send('hi'); + conn.send("hi"); }); - eioc('ws://localhost:%d'.s(port), { + eioc("ws://localhost:%d".s(port), { extraHeaders: headers, - transports: ['polling'] + transports: ["polling"] }); }); } - it('should contain X-XSS-Protection: 0 for IE8', function (done) { - var headers = { 'user-agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; Tablet PC 2.0)' }; + it("should contain X-XSS-Protection: 0 for IE8", function(done) { + var headers = { + "user-agent": + "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; Tablet PC 2.0)" + }; testForHeaders(headers, done); }); - it('should contain X-XSS-Protection: 0 for IE11', function (done) { - var headers = { 'user-agent': 'Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko' }; + it("should contain X-XSS-Protection: 0 for IE11", function(done) { + var headers = { + "user-agent": + "Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko" + }; testForHeaders(headers, done); }); }); - describe('cors', function () { - it('should handle OPTIONS requests', function (done) { - listen({handlePreflightRequest: true}, function (port) { - request.options('http://localhost:%d/engine.io/default/'.s(port)) - .set('Origin', 'http://engine.io') - .query({ transport: 'polling' }) - .end(function (err, res) { + describe("cors", function() { + it("should handle OPTIONS requests", function(done) { + listen({ handlePreflightRequest: true }, function(port) { + request + .options("http://localhost:%d/engine.io/default/".s(port)) + .set("Origin", "http://engine.io") + .query({ transport: "polling" }) + .end(function(err, res) { expect(err).to.be.an(Error); expect(res.status).to.be(400); expect(res.body.code).to.be(2); - expect(res.body.message).to.be('Bad handshake method'); - expect(res.header['access-control-allow-credentials']).to.be('true'); - expect(res.header['access-control-allow-origin']).to.be('http://engine.io'); + expect(res.body.message).to.be("Bad handshake method"); + expect(res.header["access-control-allow-credentials"]).to.be( + "true" + ); + expect(res.header["access-control-allow-origin"]).to.be( + "http://engine.io" + ); done(); }); }); }); - it('should not handle OPTIONS requests', function (done) { - listen({handlePreflightRequest: false}, function (port) { - request.options('http://localhost:%d/engine.io/default/'.s(port)) - .set('Origin', 'http://engine.io') - .query({ transport: 'polling' }) - .end(function (err, res) { + it("should not handle OPTIONS requests", function(done) { + listen({ handlePreflightRequest: false }, function(port) { + request + .options("http://localhost:%d/engine.io/default/".s(port)) + .set("Origin", "http://engine.io") + .query({ transport: "polling" }) + .end(function(err, res) { expect(err).to.be.an(Error); expect(res.status).to.be(501); expect(res.body.code).to.be(undefined); @@ -2619,49 +2875,64 @@ describe('server', function () { }); }); - it('should handle OPTIONS requests with the given function', function (done) { - var handlePreflightRequest = function (req, res) { + it("should handle OPTIONS requests with the given function", function(done) { + var handlePreflightRequest = function(req, res) { var headers = {}; if (req.headers.origin) { - headers['Access-Control-Allow-Credentials'] = 'true'; - headers['Access-Control-Allow-Origin'] = req.headers.origin; + headers["Access-Control-Allow-Credentials"] = "true"; + headers["Access-Control-Allow-Origin"] = req.headers.origin; } else { - headers['Access-Control-Allow-Origin'] = '*'; + headers["Access-Control-Allow-Origin"] = "*"; } - headers['Access-Control-Allow-Methods'] = 'GET,HEAD,PUT,PATCH,POST,DELETE'; - headers['Access-Control-Allow-Headers'] = 'origin, content-type, accept'; + headers["Access-Control-Allow-Methods"] = + "GET,HEAD,PUT,PATCH,POST,DELETE"; + headers["Access-Control-Allow-Headers"] = + "origin, content-type, accept"; res.writeHead(200, headers); res.end(); }; - listen({handlePreflightRequest: handlePreflightRequest}, function (port) { - request.options('http://localhost:%d/engine.io/default/'.s(port)) - .set('Origin', 'http://engine.io') - .query({ transport: 'polling' }) - .end(function (err, res) { + listen({ handlePreflightRequest: handlePreflightRequest }, function( + port + ) { + request + .options("http://localhost:%d/engine.io/default/".s(port)) + .set("Origin", "http://engine.io") + .query({ transport: "polling" }) + .end(function(err, res) { expect(err).to.be(null); expect(res.status).to.be(200); expect(res.body).to.be.empty(); - expect(res.header['access-control-allow-credentials']).to.be('true'); - expect(res.header['access-control-allow-origin']).to.be('http://engine.io'); - expect(res.header['access-control-allow-methods']).to.be('GET,HEAD,PUT,PATCH,POST,DELETE'); - expect(res.header['access-control-allow-headers']).to.be('origin, content-type, accept'); + expect(res.header["access-control-allow-credentials"]).to.be( + "true" + ); + expect(res.header["access-control-allow-origin"]).to.be( + "http://engine.io" + ); + expect(res.header["access-control-allow-methods"]).to.be( + "GET,HEAD,PUT,PATCH,POST,DELETE" + ); + expect(res.header["access-control-allow-headers"]).to.be( + "origin, content-type, accept" + ); done(); }); }); }); }); - describe('wsEngine option', function () { - it('should allow loading of other websocket server implementation like uws', function (done) { - var engine = listen({ allowUpgrades: false, wsEngine: 'uws' }, function (port) { - expect(engine.ws instanceof require('uws').Server).to.be.ok(); - var socket = new eioc.Socket('ws://localhost:%d'.s(port)); - engine.on('connection', function (conn) { - conn.send('a'); - }); - socket.on('open', function () { - socket.on('message', function (msg) { - expect(msg).to.be('a'); + describe("wsEngine option", function() { + it("should allow loading of other websocket server implementation like uws", function(done) { + var engine = listen({ allowUpgrades: false, wsEngine: "uws" }, function( + port + ) { + expect(engine.ws instanceof require("uws").Server).to.be.ok(); + var socket = new eioc.Socket("ws://localhost:%d".s(port)); + engine.on("connection", function(conn) { + conn.send("a"); + }); + socket.on("open", function() { + socket.on("message", function(msg) { + expect(msg).to.be("a"); done(); }); }); @@ -2669,22 +2940,22 @@ describe('server', function () { }); }); - describe('remoteAddress', function () { - it('should be defined (polling)', function (done) { - var engine = listen({ transports: ['polling'] }, port => { - eioc('ws://localhost:%d'.s(port), { transports: ['polling'] }); - engine.on('connection', socket => { - expect(socket.remoteAddress).to.be('::ffff:127.0.0.1'); + describe("remoteAddress", function() { + it("should be defined (polling)", function(done) { + var engine = listen({ transports: ["polling"] }, port => { + eioc("ws://localhost:%d".s(port), { transports: ["polling"] }); + engine.on("connection", socket => { + expect(socket.remoteAddress).to.be("::ffff:127.0.0.1"); done(); }); }); }); - it('should be defined (ws)', function (done) { - var engine = listen({ transports: ['websocket'] }, port => { - eioc('ws://localhost:%d'.s(port), { transports: ['websocket'] }); - engine.on('connection', socket => { - expect(socket.remoteAddress).to.be('::ffff:127.0.0.1'); + it("should be defined (ws)", function(done) { + var engine = listen({ transports: ["websocket"] }, port => { + eioc("ws://localhost:%d".s(port), { transports: ["websocket"] }); + engine.on("connection", socket => { + expect(socket.remoteAddress).to.be("::ffff:127.0.0.1"); done(); }); });