Skip to content

Commit a74bf93

Browse files
committed
add origins information to engine.io
Allows responses with the correct Access-Control-Allow-Origin value instead of: Access-Control-Allow-Origin: *
1 parent e76e035 commit a74bf93

File tree

9 files changed

+41
-31
lines changed

9 files changed

+41
-31
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ to a single process.
203203
- `maxHttpBufferSize` (`Number`): how many bytes or characters a message
204204
can be, before closing the session (to avoid DoS). Default
205205
value is `10E7`.
206+
- `origins` (`String`): : the allowed origins (`*`)
206207
- `allowRequest` (`Function`): A function that receives a given handshake
207208
or upgrade request as its first parameter, and can decide whether to
208209
continue or not. The second argument is a function that needs to be

lib/server.js

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ function Server (opts) {
4545
this.allowUpgrades = false !== opts.allowUpgrades;
4646
this.allowRequest = opts.allowRequest;
4747
this.cookie = false !== opts.cookie ? (opts.cookie || 'io') : false;
48+
this.origins = opts.origins !== undefined ? opts.origins : '*';
4849
this.cookiePath = false !== opts.cookiePath ? (opts.cookiePath || '/') : false;
4950
this.cookieHttpOnly = false !== opts.cookieHttpOnly;
5051
this.perMessageDeflate = false !== opts.perMessageDeflate ? (opts.perMessageDeflate || true) : false;
@@ -224,7 +225,7 @@ Server.prototype.handleRequest = function (req, res) {
224225
var self = this;
225226
this.verify(req, false, function (err, success) {
226227
if (!success) {
227-
sendErrorMessage(req, res, err);
228+
self.sendErrorMessage(req, res, err);
228229
return;
229230
}
230231

@@ -245,7 +246,7 @@ Server.prototype.handleRequest = function (req, res) {
245246
* @api private
246247
*/
247248

248-
function sendErrorMessage (req, res, code) {
249+
Server.prototype.sendErrorMessage = function (req, res, code) {
249250
var headers = { 'Content-Type': 'application/json' };
250251

251252
var isForbidden = !Server.errorMessages.hasOwnProperty(code);
@@ -257,18 +258,19 @@ function sendErrorMessage (req, res, code) {
257258
}));
258259
return;
259260
}
261+
262+
headers['Access-Control-Allow-Origin'] = this.origins;
263+
headers['Vary'] = 'Origin';
260264
if (req.headers.origin) {
261265
headers['Access-Control-Allow-Credentials'] = 'true';
262-
headers['Access-Control-Allow-Origin'] = req.headers.origin;
263-
} else {
264-
headers['Access-Control-Allow-Origin'] = '*';
265266
}
267+
266268
res.writeHead(400, headers);
267269
res.end(JSON.stringify({
268270
code: code,
269271
message: Server.errorMessages[code]
270272
}));
271-
}
273+
};
272274

273275
/**
274276
* generate a socket id.
@@ -294,9 +296,12 @@ Server.prototype.handshake = function (transportName, req) {
294296
var id = this.generateId(req);
295297

296298
debug('handshaking client "%s"', id);
299+
var opts = {
300+
origins: this.origins
301+
};
297302

298303
try {
299-
var transport = new transports[transportName](req);
304+
var transport = new transports[transportName](req, opts);
300305
if ('polling' === transportName) {
301306
transport.maxHttpBufferSize = this.maxHttpBufferSize;
302307
transport.httpCompression = this.httpCompression;
@@ -310,7 +315,7 @@ Server.prototype.handshake = function (transportName, req) {
310315
transport.supportsBinary = true;
311316
}
312317
} catch (e) {
313-
sendErrorMessage(req, req.res, Server.errors.BAD_REQUEST);
318+
this.sendErrorMessage(req, req.res, Server.errors.BAD_REQUEST);
314319
return;
315320
}
316321
var socket = new Socket(id, this, transport, req);
@@ -405,7 +410,10 @@ Server.prototype.onWebSocket = function (req, socket) {
405410
// transport error handling takes over
406411
socket.removeListener('error', onUpgradeError);
407412

408-
var transport = new transports[req._query.transport](req);
413+
var opts = {
414+
origins: this.origins
415+
};
416+
var transport = new transports[req._query.transport](req, opts);
409417
if (req._query && req._query.b64) {
410418
transport.supportsBinary = false;
411419
} else {

lib/transport.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,14 @@ function noop () {}
2626
* Transport constructor.
2727
*
2828
* @param {http.IncomingMessage} request
29+
* @param {Object} opts allows the origins option to be passed along
2930
* @api public
3031
*/
3132

32-
function Transport (req) {
33+
function Transport (req, opts) {
3334
this.readyState = 'open';
3435
this.discarded = false;
36+
this.origins = opts.origins;
3537
}
3638

3739
/**

lib/transports/index.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ exports.polling.upgradesTo = ['websocket'];
2727
* @api private
2828
*/
2929

30-
function polling (req) {
30+
function polling (req, opts) {
3131
if ('string' === typeof req._query.j) {
32-
return new JSONP(req);
32+
return new JSONP(req, opts);
3333
} else {
34-
return new XHR(req);
34+
return new XHR(req, opts);
3535
}
3636
}

lib/transports/polling-jsonp.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ module.exports = JSONP;
2121
* @api public
2222
*/
2323

24-
function JSONP (req) {
25-
Polling.call(this, req);
24+
function JSONP (req, opts) {
25+
Polling.call(this, req, opts);
2626

2727
this.head = '___eio[' + (req._query.j || '').replace(/[^0-9]/g, '') + '](';
2828
this.foot = ');';

lib/transports/polling-xhr.js

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ module.exports = XHR;
1818
* @api public
1919
*/
2020

21-
function XHR (req) {
22-
Polling.call(this, req);
21+
function XHR (req, opts) {
22+
Polling.call(this, req, opts);
2323
}
2424

2525
/**
@@ -58,11 +58,10 @@ XHR.prototype.onRequest = function (req) {
5858
XHR.prototype.headers = function (req, headers) {
5959
headers = headers || {};
6060

61+
headers['Access-Control-Allow-Origin'] = this.origins;
62+
headers['Vary'] = 'Origin';
6163
if (req.headers.origin) {
6264
headers['Access-Control-Allow-Credentials'] = 'true';
63-
headers['Access-Control-Allow-Origin'] = req.headers.origin;
64-
} else {
65-
headers['Access-Control-Allow-Origin'] = '*';
6665
}
6766

6867
return Polling.prototype.headers.call(this, req, headers);

lib/transports/polling.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ module.exports = Polling;
2727
* @api public.
2828
*/
2929

30-
function Polling (req) {
31-
Transport.call(this, req);
30+
function Polling (req, opts) {
31+
Transport.call(this, req, opts);
3232

3333
this.closeTimeout = 30 * 1000;
3434
this.maxHttpBufferSize = null;

lib/transports/websocket.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ module.exports = WebSocket;
2121
* @api public
2222
*/
2323

24-
function WebSocket (req) {
25-
Transport.call(this, req);
24+
function WebSocket (req, opts) {
25+
Transport.call(this, req, opts);
2626
var self = this;
2727
this.socket = req.websocket;
2828
this.socket.on('message', this.onData.bind(this));

test/server.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ describe('server', function () {
5555
expect(res.body.code).to.be(0);
5656
expect(res.body.message).to.be('Transport unknown');
5757
expect(res.header['access-control-allow-credentials']).to.be('true');
58-
expect(res.header['access-control-allow-origin']).to.be('http://engine.io');
58+
expect(res.header['access-control-allow-origin']).to.be('*');
5959
done();
6060
});
6161
});
@@ -71,7 +71,7 @@ describe('server', function () {
7171
expect(res.body.code).to.be(1);
7272
expect(res.body.message).to.be('Session ID unknown');
7373
expect(res.header['access-control-allow-credentials']).to.be('true');
74-
expect(res.header['access-control-allow-origin']).to.be('http://engine.io');
74+
expect(res.header['access-control-allow-origin']).to.be('*');
7575
done();
7676
});
7777
});
@@ -401,7 +401,7 @@ describe('server', function () {
401401
expect(res.body.code).to.be(3);
402402
expect(res.body.message).to.be('Bad request');
403403
expect(res.header['access-control-allow-credentials']).to.be('true');
404-
expect(res.header['access-control-allow-origin']).to.be('http://engine.io');
404+
expect(res.header['access-control-allow-origin']).to.be('*');
405405
done();
406406
});
407407
});
@@ -2573,7 +2573,7 @@ describe('server', function () {
25732573

25742574
describe('cors', function () {
25752575
it('should handle OPTIONS requests', function (done) {
2576-
listen({handlePreflightRequest: true}, function (port) {
2576+
listen({handlePreflightRequest: true, origins: 'engine.io:*'}, function (port) {
25772577
request.options('http://localhost:%d/engine.io/default/'.s(port))
25782578
.set('Origin', 'http://engine.io')
25792579
.query({ transport: 'polling' })
@@ -2582,7 +2582,7 @@ describe('server', function () {
25822582
expect(res.body.code).to.be(2);
25832583
expect(res.body.message).to.be('Bad handshake method');
25842584
expect(res.header['access-control-allow-credentials']).to.be('true');
2585-
expect(res.header['access-control-allow-origin']).to.be('http://engine.io');
2585+
expect(res.header['access-control-allow-origin']).to.be('engine.io:*');
25862586
done();
25872587
});
25882588
});
@@ -2606,7 +2606,7 @@ describe('server', function () {
26062606
var headers = {};
26072607
if (req.headers.origin) {
26082608
headers['Access-Control-Allow-Credentials'] = 'true';
2609-
headers['Access-Control-Allow-Origin'] = req.headers.origin;
2609+
headers['Access-Control-Allow-Origin'] = '*';
26102610
} else {
26112611
headers['Access-Control-Allow-Origin'] = '*';
26122612
}
@@ -2623,7 +2623,7 @@ describe('server', function () {
26232623
expect(res.status).to.be(200);
26242624
expect(res.body).to.be.empty();
26252625
expect(res.header['access-control-allow-credentials']).to.be('true');
2626-
expect(res.header['access-control-allow-origin']).to.be('http://engine.io');
2626+
expect(res.header['access-control-allow-origin']).to.be('*');
26272627
expect(res.header['access-control-allow-methods']).to.be('GET,HEAD,PUT,PATCH,POST,DELETE');
26282628
expect(res.header['access-control-allow-headers']).to.be('origin, content-type, accept');
26292629
done();

0 commit comments

Comments
 (0)