Skip to content

Commit

Permalink
Add 'client tracking' and 'path' options
Browse files Browse the repository at this point in the history
  • Loading branch information
nicokaiser committed Mar 27, 2012
1 parent 4dec85c commit cf8ccd0
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 8 deletions.
4 changes: 4 additions & 0 deletions README.md
Expand Up @@ -147,9 +147,13 @@ These are exposed by `require('websocket.io')`
- **Parameters**
- `Object`: optional, options object
- **Options**
- `path` (`String`): If set, the server listens only on this path. By default,
it listens for `upgrade` events on any path.
- `logger` (`Object`/`Boolean`): logger object. If you want to customize the
logger options, please supply a new `Logger` object (see API below). If you
want to enable it, set this option to `true`.
- `client tracking` (`Boolean`): enables client tracking (`Server.clients`).
Defaults is `true`.
- ``handleUpgrade``
- Handles an incoming request that triggered an `upgrade` event
- **Parameters**
Expand Down
49 changes: 41 additions & 8 deletions lib/server.js
Expand Up @@ -5,6 +5,7 @@

var protocols = require('./protocols')
, EventEmitter = process.EventEmitter
, url = require('url')
, Logger = require('./logger')

/**
Expand All @@ -20,10 +21,19 @@ module.exports = Server;
*/

function Server (options) {
this.options = options || {}
this.options = {
'path': null
, 'logger': new Logger()
, 'client tracking': true
};

for (var i in options) {
this.options[i] = options[i];
}

this.clients = [];
this.clientsCount = 0;
this.log = this.options.logger || new Logger()
this.log = this.options.logger;
}

/**
Expand Down Expand Up @@ -54,26 +64,49 @@ Server.prototype.handleUpgrade = function (req, socket, head) {
var i = this.clients.length
, self = this;

if (! this.checkRequest(req)) {
return this;
}

// attach the legacy `head` property to request
req.head = head;

var client = this.createClient(req);

if (client.open) {
this.clients.push(client);
this.clientsCount++;
if (this.options['client tracking']) {
this.clients.push(client);
this.clientsCount++;

client.on('close', function () {
self.clients[i] = null;
self.clientsCount--;
});
client.on('close', function () {
self.clients[i] = null;
self.clientsCount--;
});
}

self.emit('connection', client);
}

return this;
};

/**
* Checks whether the request path matches.
*
* @return {Bool}
* @api private
*/

Server.prototype.checkRequest = function (req) {
if (this.options.path) {
var u = url.parse(req.url);
if (u && u.pathname !== this.options.path) return false;
}

// no options.path => match all paths
return true;
};

/**
* Initializes a client for the request with appropriate protocol.
*
Expand Down
69 changes: 69 additions & 0 deletions test/server.js
Expand Up @@ -116,6 +116,44 @@ describe('websocket server', function () {
});
});

describe('request path', function() {
it('must be checked if present', function (done) {
listen({path: '/mypath'}, function (addr, server) {
var cl = client(addr, '/mypath')

cl.on('open', function () {
cl.close();
server.close();
done();
});
});
});

it('must be checked, connection rejected if not matches', function (done) {
listen({path: '/mypath'}, function (addr, server) {
var cl = client(addr, '/mypath2');
cl.on('open', function () {
cl.close();
server.close();
throw new Error('paths do not match');
});
done();
});
});

it('can be left null, so any path matches', function (done) {
listen(function (addr, server) {
var cl = client(addr, '/mypath');

cl.on('open', function () {
cl.close();
server.close();
done();
});
});
});
});

describe('client tracking', function () {
it('must have client objects', function (done) {
listen(function (addr, server) {
Expand Down Expand Up @@ -172,6 +210,37 @@ describe('websocket server', function () {
});
});
});

it('can be disabled', function (done) {
listen({'client tracking': false}, function (addr, server) {
var cl = client(addr);

cl.on('open', function () {
server.clients.should.have.length(0);
server.clientsCount.should.equal(0);

var cl2 = client(addr);
cl2.on('open', function () {
server.clients.should.have.length(0);
server.clientsCount.should.equal(0);

cl.close();
cl.on('close', function () {
server.clients.should.have.length(0);
server.clientsCount.should.equal(0);

cl2.close();
cl2.on('close', function () {
server.clients.should.have.length(0);
server.clientsCount.should.equal(0);
server.close();
done();
});
})
});
});
});
});
});

});

0 comments on commit cf8ccd0

Please sign in to comment.