From ec4e12a063f1f3a837ab1cbcc399569bbc717c13 Mon Sep 17 00:00:00 2001 From: Damien Arrachequesne Date: Thu, 29 Nov 2018 22:49:34 +0100 Subject: [PATCH 1/9] [revert] Allow configuration of `Access-Control-Allow-Origin` value (#511) This reverts commit ebf1a96f4285a7326e42fd21b33f53b64c65050e. Related: https://github.com/socketio/socket.io/issues/3381 --- README.md | 1 - lib/server.js | 26 +++++++++----------------- lib/transport.js | 4 +--- lib/transports/index.js | 6 +++--- lib/transports/polling-jsonp.js | 4 ++-- lib/transports/polling-xhr.js | 9 +++++---- lib/transports/polling.js | 4 ++-- lib/transports/websocket.js | 4 ++-- test/server.js | 16 ++++++++-------- 9 files changed, 32 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index 332e99c33..7c632064a 100644 --- a/README.md +++ b/README.md @@ -228,7 +228,6 @@ to a single process. - `maxHttpBufferSize` (`Number`): how many bytes or characters a message can be, before closing the session (to avoid DoS). Default value is `10E7`. - - `origins` (`String`): the allowed origins (`*`) - `allowRequest` (`Function`): A function that receives a given handshake or upgrade request as its first parameter, and can decide whether to continue or not. The second argument is a function that needs to be diff --git a/lib/server.js b/lib/server.js index afc808a12..df4058ea5 100644 --- a/lib/server.js +++ b/lib/server.js @@ -45,7 +45,6 @@ function Server (opts) { this.allowUpgrades = false !== opts.allowUpgrades; this.allowRequest = opts.allowRequest; this.cookie = false !== opts.cookie ? (opts.cookie || 'io') : false; - this.origins = opts.origins || '*'; this.cookiePath = false !== opts.cookiePath ? (opts.cookiePath || '/') : false; this.cookieHttpOnly = false !== opts.cookieHttpOnly; this.perMessageDeflate = false !== opts.perMessageDeflate ? (opts.perMessageDeflate || true) : false; @@ -222,7 +221,7 @@ Server.prototype.handleRequest = function (req, res) { var self = this; this.verify(req, false, function (err, success) { if (!success) { - self.sendErrorMessage(req, res, err); + sendErrorMessage(req, res, err); return; } @@ -243,7 +242,7 @@ Server.prototype.handleRequest = function (req, res) { * @api private */ -Server.prototype.sendErrorMessage = function (req, res, code) { +function sendErrorMessage (req, res, code) { var headers = { 'Content-Type': 'application/json' }; var isForbidden = !Server.errorMessages.hasOwnProperty(code); @@ -255,13 +254,12 @@ Server.prototype.sendErrorMessage = function (req, res, code) { })); return; } - - headers['Access-Control-Allow-Origin'] = this.origins; - headers['Vary'] = 'Origin'; if (req.headers.origin) { headers['Access-Control-Allow-Credentials'] = 'true'; + headers['Access-Control-Allow-Origin'] = req.headers.origin; + } else { + headers['Access-Control-Allow-Origin'] = '*'; } - if (res !== undefined) { res.writeHead(400, headers); res.end(JSON.stringify({ @@ -269,7 +267,7 @@ Server.prototype.sendErrorMessage = function (req, res, code) { message: Server.errorMessages[code] })); } -}; +} /** * generate a socket id. @@ -295,12 +293,9 @@ Server.prototype.handshake = function (transportName, req) { var id = this.generateId(req); debug('handshaking client "%s"', id); - var opts = { - origins: this.origins - }; try { - var transport = new transports[transportName](req, opts); + var transport = new transports[transportName](req); if ('polling' === transportName) { transport.maxHttpBufferSize = this.maxHttpBufferSize; transport.httpCompression = this.httpCompression; @@ -314,7 +309,7 @@ Server.prototype.handshake = function (transportName, req) { transport.supportsBinary = true; } } catch (e) { - this.sendErrorMessage(req, req.res, Server.errors.BAD_REQUEST); + sendErrorMessage(req, req.res, Server.errors.BAD_REQUEST); return; } var socket = new Socket(id, this, transport, req); @@ -408,10 +403,7 @@ Server.prototype.onWebSocket = function (req, socket) { // transport error handling takes over socket.removeListener('error', onUpgradeError); - var opts = { - origins: this.origins - }; - var transport = new transports[req._query.transport](req, opts); + var transport = new transports[req._query.transport](req); if (req._query && req._query.b64) { transport.supportsBinary = false; } else { diff --git a/lib/transport.js b/lib/transport.js index 2f8501d9e..933dad5bb 100644 --- a/lib/transport.js +++ b/lib/transport.js @@ -26,14 +26,12 @@ function noop () {} * Transport constructor. * * @param {http.IncomingMessage} request - * @param {Object} opts allows the origins option to be passed along * @api public */ -function Transport (req, opts) { +function Transport (req) { this.readyState = 'open'; this.discarded = false; - this.origins = opts.origins; } /** diff --git a/lib/transports/index.js b/lib/transports/index.js index 91ef8ab53..fcff3223a 100644 --- a/lib/transports/index.js +++ b/lib/transports/index.js @@ -27,10 +27,10 @@ exports.polling.upgradesTo = ['websocket']; * @api private */ -function polling (req, opts) { +function polling (req) { if ('string' === typeof req._query.j) { - return new JSONP(req, opts); + return new JSONP(req); } else { - return new XHR(req, opts); + return new XHR(req); } } diff --git a/lib/transports/polling-jsonp.js b/lib/transports/polling-jsonp.js index 450953ce5..62e66e779 100644 --- a/lib/transports/polling-jsonp.js +++ b/lib/transports/polling-jsonp.js @@ -21,8 +21,8 @@ module.exports = JSONP; * @api public */ -function JSONP (req, opts) { - Polling.call(this, req, opts); +function JSONP (req) { + Polling.call(this, req); this.head = '___eio[' + (req._query.j || '').replace(/[^0-9]/g, '') + ']('; this.foot = ');'; diff --git a/lib/transports/polling-xhr.js b/lib/transports/polling-xhr.js index ddcd5ed99..3562524e1 100644 --- a/lib/transports/polling-xhr.js +++ b/lib/transports/polling-xhr.js @@ -18,8 +18,8 @@ module.exports = XHR; * @api public */ -function XHR (req, opts) { - Polling.call(this, req, opts); +function XHR (req) { + Polling.call(this, req); } /** @@ -58,10 +58,11 @@ XHR.prototype.onRequest = function (req) { XHR.prototype.headers = function (req, headers) { headers = headers || {}; - headers['Access-Control-Allow-Origin'] = this.origins; - headers['Vary'] = 'Origin'; if (req.headers.origin) { headers['Access-Control-Allow-Credentials'] = 'true'; + headers['Access-Control-Allow-Origin'] = req.headers.origin; + } else { + headers['Access-Control-Allow-Origin'] = '*'; } return Polling.prototype.headers.call(this, req, headers); diff --git a/lib/transports/polling.js b/lib/transports/polling.js index 08048a914..7c29c29ea 100644 --- a/lib/transports/polling.js +++ b/lib/transports/polling.js @@ -27,8 +27,8 @@ module.exports = Polling; * @api public. */ -function Polling (req, opts) { - Transport.call(this, req, opts); +function Polling (req) { + Transport.call(this, req); this.closeTimeout = 30 * 1000; this.maxHttpBufferSize = null; diff --git a/lib/transports/websocket.js b/lib/transports/websocket.js index 64a3a5fdf..7d5511b1d 100644 --- a/lib/transports/websocket.js +++ b/lib/transports/websocket.js @@ -21,8 +21,8 @@ module.exports = WebSocket; * @api public */ -function WebSocket (req, opts) { - Transport.call(this, req, opts); +function WebSocket (req) { + Transport.call(this, req); var self = this; this.socket = req.websocket; this.socket.on('message', this.onData.bind(this)); diff --git a/test/server.js b/test/server.js index b694f81aa..9da4d109b 100644 --- a/test/server.js +++ b/test/server.js @@ -58,7 +58,7 @@ describe('server', function () { 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('*'); + expect(res.header['access-control-allow-origin']).to.be('http://engine.io'); done(); }); }); @@ -75,7 +75,7 @@ describe('server', function () { 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('*'); + expect(res.header['access-control-allow-origin']).to.be('http://engine.io'); done(); }); }); @@ -416,7 +416,7 @@ describe('server', function () { 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('*'); + expect(res.header['access-control-allow-origin']).to.be('http://engine.io'); done(); }); }); @@ -932,7 +932,7 @@ describe('server', function () { 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.0', 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')); @@ -2589,7 +2589,7 @@ describe('server', function () { describe('cors', function () { it('should handle OPTIONS requests', function (done) { - listen({handlePreflightRequest: true, origins: 'engine.io:*'}, function (port) { + listen({handlePreflightRequest: true}, function (port) { request.options('http://localhost:%d/engine.io/default/'.s(port)) .set('Origin', 'http://engine.io') .query({ transport: 'polling' }) @@ -2599,7 +2599,7 @@ describe('server', function () { 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('engine.io:*'); + expect(res.header['access-control-allow-origin']).to.be('http://engine.io'); done(); }); }); @@ -2624,7 +2624,7 @@ describe('server', function () { var headers = {}; if (req.headers.origin) { headers['Access-Control-Allow-Credentials'] = 'true'; - headers['Access-Control-Allow-Origin'] = '*'; + headers['Access-Control-Allow-Origin'] = req.headers.origin; } else { headers['Access-Control-Allow-Origin'] = '*'; } @@ -2642,7 +2642,7 @@ describe('server', function () { 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('*'); + 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(); From cb0ac6fddcad12c454651bf0e1a312a154e228a4 Mon Sep 17 00:00:00 2001 From: Damien Arrachequesne Date: Thu, 29 Nov 2018 22:51:12 +0100 Subject: [PATCH 2/9] [chore] Release 3.3.2 --- package.json | 2 +- test/engine.io.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 5e3f411ad..caac4c850 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "engine.io", - "version": "3.3.1", + "version": "3.3.2", "description": "The realtime engine behind Socket.IO. Provides the foundation of a bidirectional connection between client and server", "main": "lib/engine.io", "author": "Guillermo Rauch ", diff --git a/test/engine.io.js b/test/engine.io.js index 9387094c9..c29d3934c 100644 --- a/test/engine.io.js +++ b/test/engine.io.js @@ -19,7 +19,7 @@ describe('engine', function () { expect(eio.protocol).to.be.a('number'); }); - it('should be the same version as client', function () { + it.skip('should be the same version as client', function () { var version = require('../package').version; expect(version).to.be(require('engine.io-client/package').version); }); From ad844f4b32a15f475f227a2b0277d6df2d063541 Mon Sep 17 00:00:00 2001 From: Oliver Salzburg Date: Tue, 18 Jun 2019 08:51:50 +0200 Subject: [PATCH 3/9] [fix] Deprecated Buffer usage in dependency (#585) The `Buffer` constructor has been deprecated in favor of safer alternatives. See https://nodejs.org/en/docs/guides/buffer-constructor-deprecation/ This was fixed in base64id@2.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index caac4c850..0a93a82b9 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "license": "MIT", "dependencies": { "accepts": "~1.3.4", - "base64id": "1.0.0", + "base64id": "2.0.0", "debug": "~3.1.0", "engine.io-parser": "~2.1.0", "ws": "~6.1.0", From 5bbbfe241188b570c1a8417780baf81e344ce089 Mon Sep 17 00:00:00 2001 From: Damien Arrachequesne Date: Fri, 13 Sep 2019 10:26:18 +0200 Subject: [PATCH 4/9] [ci] remove Node.js 4 and 6 from the build matrix We keep Node.js 9 for compatibility with the 'uws' dependency (as Node.js 10 fails), but we'll upgrade later. --- .travis.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 968ece7d4..fbda89be8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,6 @@ sudo: false language: node_js node_js: - - "4" - - "6" - "8" - "9" git: From a967626a1d1ec990090a63b4999337fd83abf223 Mon Sep 17 00:00:00 2001 From: Dimitar Nestorov Date: Wed, 15 May 2019 22:55:56 +0300 Subject: [PATCH 5/9] [chore] Bump debug to version 4.1.0 (#581) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0a93a82b9..018ed62b6 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "dependencies": { "accepts": "~1.3.4", "base64id": "2.0.0", - "debug": "~3.1.0", + "debug": "~4.1.0", "engine.io-parser": "~2.1.0", "ws": "~6.1.0", "cookie": "0.3.1" From c1448951334c7cfc5f1d1fff83c35117b6cf729f Mon Sep 17 00:00:00 2001 From: Brian Kopp Date: Fri, 13 Sep 2019 03:21:37 -0600 Subject: [PATCH 6/9] [feat] add additional debug messages (#586) These additional messages will help more quickly diagnose the reason for error messages. --- lib/server.js | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/lib/server.js b/lib/server.js index df4058ea5..2d9a45c7a 100644 --- a/lib/server.js +++ b/lib/server.js @@ -148,6 +148,7 @@ Server.prototype.verify = function (req, upgrade, fn) { var isOriginInvalid = checkInvalidHeaderChar(req.headers.origin); if (isOriginInvalid) { req.headers.origin = null; + debug('origin header invalid'); return fn(Server.errors.BAD_REQUEST, false); } @@ -155,6 +156,7 @@ Server.prototype.verify = function (req, upgrade, fn) { var sid = req._query.sid; if (sid) { if (!this.clients.hasOwnProperty(sid)) { + debug('unknown sid "%s"', sid); return fn(Server.errors.UNKNOWN_SID, false); } if (!upgrade && this.clients[sid].transport.name !== transport) { @@ -309,6 +311,7 @@ Server.prototype.handshake = function (transportName, req) { transport.supportsBinary = true; } } catch (e) { + debug('error handshaking to transport "%s"', transportName); sendErrorMessage(req, req.res, Server.errors.BAD_REQUEST); return; } @@ -552,23 +555,33 @@ function checkInvalidHeaderChar(val) { val += ''; if (val.length < 1) return false; - if (!validHdrChars[val.charCodeAt(0)]) + if (!validHdrChars[val.charCodeAt(0)]) { + debug('invalid header, index 0, char "%s"', val.charCodeAt(0)); return true; + } if (val.length < 2) return false; - if (!validHdrChars[val.charCodeAt(1)]) + if (!validHdrChars[val.charCodeAt(1)]) { + debug('invalid header, index 1, char "%s"', val.charCodeAt(1)); return true; + } if (val.length < 3) return false; - if (!validHdrChars[val.charCodeAt(2)]) + if (!validHdrChars[val.charCodeAt(2)]) { + debug('invalid header, index 2, char "%s"', val.charCodeAt(2)); return true; + } if (val.length < 4) return false; - if (!validHdrChars[val.charCodeAt(3)]) + if (!validHdrChars[val.charCodeAt(3)]) { + debug('invalid header, index 3, char "%s"', val.charCodeAt(3)); return true; + } for (var i = 4; i < val.length; ++i) { - if (!validHdrChars[val.charCodeAt(i)]) + if (!validHdrChars[val.charCodeAt(i)]) { + debug('invalid header, index "%i", char "%s"', i, val.charCodeAt(i)); return true; + } } return false; } From c471e03e09ce2201c8807fda94babf85455c4bb2 Mon Sep 17 00:00:00 2001 From: Yosi Attias Date: Mon, 12 Aug 2019 20:11:56 +0300 Subject: [PATCH 7/9] [chore] Bump `ws` to latest version (#587) --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 018ed62b6..b235dab57 100644 --- a/package.json +++ b/package.json @@ -27,10 +27,10 @@ "dependencies": { "accepts": "~1.3.4", "base64id": "2.0.0", + "cookie": "0.3.1", "debug": "~4.1.0", "engine.io-parser": "~2.1.0", - "ws": "~6.1.0", - "cookie": "0.3.1" + "ws": "^7.1.2" }, "devDependencies": { "babel-eslint": "^8.0.2", From 7bf75812c300aed1b62a10980c84187fddc2d346 Mon Sep 17 00:00:00 2001 From: Damien Arrachequesne Date: Fri, 13 Sep 2019 13:46:43 +0200 Subject: [PATCH 8/9] [chore] Bump engine.io-parser to version 2.2.0 Diff: https://github.com/socketio/engine.io-parser/compare/2.1.3...2.2.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b235dab57..a8e37e3fe 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "base64id": "2.0.0", "cookie": "0.3.1", "debug": "~4.1.0", - "engine.io-parser": "~2.1.0", + "engine.io-parser": "~2.2.0", "ws": "^7.1.2" }, "devDependencies": { From ecfcc69a7ae8c63dde8861a87715a8be718d510e Mon Sep 17 00:00:00 2001 From: Damien Arrachequesne Date: Fri, 13 Sep 2019 13:51:49 +0200 Subject: [PATCH 9/9] [chore] Release 3.4.0 Diff: https://github.com/socketio/engine.io/compare/3.3.2...3.4.0 --- package.json | 4 ++-- test/engine.io.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index a8e37e3fe..d99b2c31b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "engine.io", - "version": "3.3.2", + "version": "3.4.0", "description": "The realtime engine behind Socket.IO. Provides the foundation of a bidirectional connection between client and server", "main": "lib/engine.io", "author": "Guillermo Rauch ", @@ -35,7 +35,7 @@ "devDependencies": { "babel-eslint": "^8.0.2", "babel-preset-es2015": "^6.24.0", - "engine.io-client": "3.3.1", + "engine.io-client": "3.4.0", "eslint": "^4.5.0", "eslint-config-standard": "^10.2.1", "eslint-plugin-import": "^2.7.0", diff --git a/test/engine.io.js b/test/engine.io.js index c29d3934c..9387094c9 100644 --- a/test/engine.io.js +++ b/test/engine.io.js @@ -19,7 +19,7 @@ describe('engine', function () { expect(eio.protocol).to.be.a('number'); }); - it.skip('should be the same version as client', function () { + it('should be the same version as client', function () { var version = require('../package').version; expect(version).to.be(require('engine.io-client/package').version); });