Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Adding pluggable ID generation see #497 #858

Closed
wants to merge 1 commit into from

3 participants

@martinthomson

I want control over session IDs (see #497), but I don't need to give that control to the client. This enables both options.

In my example, I am embedding application state in the session ID so that I can forward messages to back end processing without maintaining additional mappings.

I've also added the ability to get the handshake data through to the ID generator and for the authorize method to add to or override the handshake data. This was obviously intended originally, but never quite connected up (repeated use of ``newData || handshakeData''). This handshake data can be seen by the ID generator as well in order to advise in its processing.

A few more tests added to cover these capabilities.

@rauchg
Owner

It doesn't apply cleanly

@martinthomson

My sincerest apologies for the apply failure. Put that down to me being a complete git (novice). I've managed to bludgeon git into submission and (pending unmerged changes) this should apply cleanly now.

@englercj

Is this something that will be integrated soonish? Definitely something that would help reduce the additional mappings I have to maintain.

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on May 15, 2012
  1. @martinthomson
This page is out of date. Refresh to see the latest.
Showing with 137 additions and 5 deletions.
  1. +9 −5 lib/manager.js
  2. +128 −0 test/manager.test.js
View
14 lib/manager.js
@@ -705,8 +705,12 @@ Manager.prototype.handleClient = function (data, req) {
* @api private
*/
-Manager.prototype.generateId = function () {
- var rand = new Buffer(15); // multiple of 3 for base64
+Manager.prototype.generateId = function (data) {
+ var rand;
+ if (this.get('id generator')) {
+ return this.get('id generator').call(this, data);
+ }
+ rand = new Buffer(15); // multiple of 3 for base64
this.sequenceNumber = (this.sequenceNumber + 1) | 0;
rand.writeInt32BE(this.sequenceNumber, 11);
if (crypto.randomBytes) {
@@ -765,7 +769,7 @@ Manager.prototype.handleHandshake = function (data, req, res) {
if (err) return error(err);
if (authorized) {
- var id = self.generateId()
+ var id = self.generateId(newData || handshakeData)
, hs = [
id
, self.enabled('heartbeats') ? self.get('heartbeat timeout') || '' : ''
@@ -885,9 +889,9 @@ Manager.prototype.authorize = function (data, fn) {
if (this.get('authorization')) {
var self = this;
- this.get('authorization').call(this, data, function (err, authorized) {
+ this.get('authorization').call(this, data, function (err, authorized, newData) {
self.log.debug('client ' + authorized ? 'authorized' : 'unauthorized');
- fn(err, authorized);
+ fn(err, authorized, newData);
});
} else {
this.log.debug('client authorized');
View
128 test/manager.test.js
@@ -220,6 +220,134 @@ module.exports = {
});
},
+ 'test authorization gets handshake data': function (done) {
+ var port = ++ports
+ , io = sio.listen(port)
+ , cl = client(port);
+
+ io.configure(function () {
+ function auth (data, fn) {
+ data.query.should.have.foo;
+ data.query.foo.should.eql('bar');
+ fn(null, false);
+ };
+
+ io.set('authorization', auth);
+ });
+
+ cl.get('/socket.io/{protocol}/?foo=bar', function (res, data) {
+ res.statusCode.should.eql(403);
+ data.should.match(/handshake unauthorized/);
+
+ cl.end();
+ io.server.close();
+ done();
+ });
+ },
+
+ 'test that authorization can view handshake data': function (done) {
+ var port = ++ports
+ , io = sio.listen(port)
+ , cl = client(port);
+
+ io.configure(function () {
+ function auth (data, fn) {
+ data.query.should.have.foo;
+ data.query.foo.should.eql('bar');
+ fn(null, true);
+ };
+
+ io.set('authorization', auth);
+ });
+
+ cl.get('/socket.io/{protocol}/?foo=bar', function (res, data) {
+ res.statusCode.should.eql(200);
+
+ cl.end();
+ io.server.close();
+ done();
+ });
+ },
+
+ 'test that authorization can change handshake data': function (done) {
+ var port = ++ports
+ , io = sio.listen(port)
+ , cl = client(port);
+
+ io.configure(function () {
+ function auth (data, fn) {
+ var replacement = { baz: 'qu' };
+ for (i in data) {
+ if (data.hasOwnProperty(i)) {
+ replacement[i] = data[i];
+ }
+ }
+ fn(null, true, replacement);
+ };
+
+ io.set('authorization', auth);
+ });
+
+ cl.get('/socket.io/{protocol}/', function (res, data) {
+ var id = data.split(':', 2)[0];
+ res.statusCode.should.eql(200);
+ io.handshaken[id].should.have.baz;
+ io.handshaken[id].baz.should.eql('qu');
+
+ cl.end();
+ io.server.close();
+ done();
+ });
+ },
+
+ 'test that id generation can be overridden': function (done) {
+ var port = ++ports
+ , io = sio.listen(port)
+ , cl = client(port);
+
+ io.configure(function () {
+ function idgen (data) {
+ return 'foo';
+ };
+
+ io.set('id generator', idgen);
+ });
+
+ cl.get('/socket.io/{protocol}/', function (res, data) {
+ var id = data.split(':', 2)[0];
+ id.should.eql('foo');
+
+ cl.end();
+ io.server.close();
+ done();
+ });
+ },
+
+ 'test that id generator can see handshake data': function (done) {
+ var port = ++ports
+ , io = sio.listen(port)
+ , cl = client(port);
+
+ io.configure(function () {
+ function idgen (data) {
+ data.query.should.have.foo;
+ data.query.foo.should.eql('bar');
+ return 'foo';
+ };
+
+ io.set('id generator', idgen);
+ });
+
+ cl.get('/socket.io/{protocol}/?foo=bar', function (res, data) {
+ var id = data.split(':', 2)[0];
+ id.should.eql('foo');
+
+ cl.end();
+ io.server.close();
+ done();
+ });
+ },
+
'test a handshake error': function (done) {
var port = ++ports
, io = sio.listen(port)
Something went wrong with that request. Please try again.