|
|
var http = require('http') , https = require('https') , WebSocket = require('../') , WebSocketServer = WebSocket.Server , fs = require('fs') , should = require('should');
var port = 8000;
function getArrayBuffer(buf) { var l = buf.length; var arrayBuf = new ArrayBuffer(l); for (var i = 0; i < l; ++i) { arrayBuf[i] = buf[i]; } return arrayBuf; }
function areArraysEqual(x, y) { if (x.length != y.length) return false; for (var i = 0, l = x.length; i < l; ++i) { if (x[i] !== y[i]) return false; } return true; }
describe('WebSocketServer', function() { describe('#ctor', function() { it('throws an error if no option object is passed', function() { var gotException = false; try { var wss = new WebSocketServer(); } catch (e) { gotException = true; } gotException.should.be.ok; });
it('throws an error if no port or server is specified', function() { var gotException = false; try { var wss = new WebSocketServer({}); } catch (e) { gotException = true; } gotException.should.be.ok; });
it('does not throw an error if no port or server is specified, when the noServer option is true', function() { var gotException = false; try { var wss = new WebSocketServer({noServer: true}); } catch (e) { gotException = true; } gotException.should.eql(false); });
it('emits an error if http server bind fails', function(done) { var wss = new WebSocketServer({port: 1}); wss.on('error', function() { done(); }); });
it('starts a server on a given port', function(done) { var wss = new WebSocketServer({port: ++port}, function() { var ws = new WebSocket('ws://localhost:' + port); }); wss.on('connection', function(client) { wss.close(); done(); }); });
it('uses a precreated http server', function (done) { var srv = http.createServer(); srv.listen(++port, function () { var wss = new WebSocketServer({server: srv}); var ws = new WebSocket('ws://localhost:' + port);
wss.on('connection', function(client) { wss.close(); srv.close(); done(); }); }); });
it('uses a precreated http server listening on unix socket', function (done) { var srv = http.createServer(); var sockPath = '/tmp/ws_socket_'+new Date().getTime()+'.'+Math.floor(Math.random() * 1000); srv.listen(sockPath, function () { var wss = new WebSocketServer({server: srv}); var ws = new WebSocket('ws+unix://'+sockPath);
wss.on('connection', function(client) { wss.close(); srv.close(); done(); }); }); });
it('emits path specific connection event', function (done) { var srv = http.createServer(); srv.listen(++port, function () { var wss = new WebSocketServer({server: srv}); var ws = new WebSocket('ws://localhost:' + port+'/endpointName');
wss.on('connection/endpointName', function(client) { wss.close(); srv.close(); done(); }); }); });
it('can have two different instances listening on the same http server with two different paths', function(done) { var srv = http.createServer(); srv.listen(++port, function () { var wss1 = new WebSocketServer({server: srv, path: '/wss1'}) , wss2 = new WebSocketServer({server: srv, path: '/wss2'}); var doneCount = 0; wss1.on('connection', function(client) { wss1.close(); if (++doneCount == 2) { srv.close(); done(); } }); wss2.on('connection', function(client) { wss2.close(); if (++doneCount == 2) { srv.close(); done(); } }); var ws1 = new WebSocket('ws://localhost:' + port + '/wss1'); var ws2 = new WebSocket('ws://localhost:' + port + '/wss2?foo=1'); }); });
it('cannot have two different instances listening on the same http server with the same path', function(done) { var srv = http.createServer(); srv.listen(++port, function () { var wss1 = new WebSocketServer({server: srv, path: '/wss1'}); try { var wss2 = new WebSocketServer({server: srv, path: '/wss1'}); } catch (e) { wss1.close(); srv.close(); done(); } }); }); });
describe('#close', function() { it('will close all clients', function(done) { var wss = new WebSocketServer({port: ++port}, function() { var ws = new WebSocket('ws://localhost:' + port); ws.on('close', function() { if (++closes == 2) done(); }); }); var closes = 0; wss.on('connection', function(client) { client.on('close', function() { if (++closes == 2) done(); }); wss.close(); }); });
it('does not close a precreated server', function(done) { var srv = http.createServer(); var realClose = srv.close; srv.close = function() { should.fail('must not close pre-created server'); } srv.listen(++port, function () { var wss = new WebSocketServer({server: srv}); var ws = new WebSocket('ws://localhost:' + port); wss.on('connection', function(client) { wss.close(); srv.close = realClose; srv.close(); done(); }); }); });
it('cleans up websocket data on a precreated server', function(done) { var srv = http.createServer(); srv.listen(++port, function () { var wss1 = new WebSocketServer({server: srv, path: '/wss1'}) , wss2 = new WebSocketServer({server: srv, path: '/wss2'}); (typeof srv._webSocketPaths).should.eql('object'); Object.keys(srv._webSocketPaths).length.should.eql(2); wss1.close(); Object.keys(srv._webSocketPaths).length.should.eql(1); wss2.close(); (typeof srv._webSocketPaths).should.eql('undefined'); srv.close(); done(); }); }); });
describe('#clients', function() { it('returns a list of connected clients', function(done) { var wss = new WebSocketServer({port: ++port}, function() { wss.clients.length.should.eql(0); var ws = new WebSocket('ws://localhost:' + port); }); wss.on('connection', function(client) { wss.clients.length.should.eql(1); wss.close(); done(); }); });
it('can be disabled', function(done) { var wss = new WebSocketServer({port: ++port, clientTracking: false}, function() { wss.clients.length.should.eql(0); var ws = new WebSocket('ws://localhost:' + port); }); wss.on('connection', function(client) { wss.clients.length.should.eql(0); wss.close(); done(); }); });
it('is updated when client terminates the connection', function(done) { var ws; var wss = new WebSocketServer({port: ++port}, function() { ws = new WebSocket('ws://localhost:' + port); }); wss.on('connection', function(client) { client.on('close', function() { wss.clients.length.should.eql(0); wss.close(); done(); }); ws.terminate(); }); });
it('is updated when client closes the connection', function(done) { var ws; var wss = new WebSocketServer({port: ++port}, function() { ws = new WebSocket('ws://localhost:' + port); }); wss.on('connection', function(client) { client.on('close', function() { wss.clients.length.should.eql(0); wss.close(); done(); }); ws.close(); }); }); });
describe('#options', function() { it('exposes options passed to constructor', function(done) { var wss = new WebSocketServer({port: ++port}, function() { wss.options.port.should.eql(port); wss.close(); done(); }); }); });
describe('#handleUpgrade', function() { it('can be used for a pre-existing server', function (done) { var srv = http.createServer(); srv.listen(++port, function () { var wss = new WebSocketServer({noServer: true}); srv.on('upgrade', function(req, socket, upgradeHead) { wss.handleUpgrade(req, socket, upgradeHead, function(client) { client.send('hello'); }); }); var ws = new WebSocket('ws://localhost:' + port); ws.on('message', function(message) { message.should.eql('hello'); wss.close(); srv.close(); done(); }); }); }); });
describe('hybi mode', function() { describe('connection establishing', function() { it('does not accept connections with no sec-websocket-key', function(done) { var wss = new WebSocketServer({port: ++port}, function() { var options = { port: port, host: '127.0.0.1', headers: { 'Connection': 'Upgrade', 'Upgrade': 'websocket' } }; var req = http.request(options); req.end(); req.on('response', function(res) { res.statusCode.should.eql(400); wss.close(); done(); }); }); wss.on('connection', function(ws) { done(new Error('connection must not be established')); }); wss.on('error', function() {}); });
it('does not accept connections with no sec-websocket-version', function(done) { var wss = new WebSocketServer({port: ++port}, function() { var options = { port: port, host: '127.0.0.1', headers: { 'Connection': 'Upgrade', 'Upgrade': 'websocket', 'Sec-WebSocket-Key': 'dGhlIHNhbXBsZSBub25jZQ==' } }; var req = http.request(options); req.end(); req.on('response', function(res) { res.statusCode.should.eql(400); wss.close(); done(); }); }); wss.on('connection', function(ws) { done(new Error('connection must not be established')); }); wss.on('error', function() {}); });
it('does not accept connections with invalid sec-websocket-version', function(done) { var wss = new WebSocketServer({port: ++port}, function() { var options = { port: port, host: '127.0.0.1', headers: { 'Connection': 'Upgrade', 'Upgrade': 'websocket', 'Sec-WebSocket-Key': 'dGhlIHNhbXBsZSBub25jZQ==', 'Sec-WebSocket-Version': 12 } }; var req = http.request(options); req.end(); req.on('response', function(res) { res.statusCode.should.eql(400); wss.close(); done(); }); }); wss.on('connection', function(ws) { done(new Error('connection must not be established')); }); wss.on('error', function() {}); });
it('client can be denied', function(done) { var wss = new WebSocketServer({port: ++port, verifyClient: function(o) { return false; }}, function() { var options = { port: port, host: '127.0.0.1', headers: { 'Connection': 'Upgrade', 'Upgrade': 'websocket', 'Sec-WebSocket-Key': 'dGhlIHNhbXBsZSBub25jZQ==', 'Sec-WebSocket-Version': 8, 'Sec-WebSocket-Origin': 'http://foobar.com' } }; var req = http.request(options); req.end(); req.on('response', function(res) { res.statusCode.should.eql(401); process.nextTick(function() { wss.close(); done(); }); }); }); wss.on('connection', function(ws) { done(new Error('connection must not be established')); }); wss.on('error', function() {}); });
it('client can be accepted', function(done) { var wss = new WebSocketServer({port: ++port, verifyClient: function(o) { return true; }}, function() { var options = { port: port, host: '127.0.0.1', headers: { 'Connection': 'Upgrade', 'Upgrade': 'websocket', 'Sec-WebSocket-Key': 'dGhlIHNhbXBsZSBub25jZQ==', 'Sec-WebSocket-Version': 13, 'Origin': 'http://foobar.com' } }; var req = http.request(options); req.end(); }); wss.on('connection', function(ws) { ws.terminate(); wss.close(); done(); }); wss.on('error', function() {}); });
it('verifyClient gets client origin', function(done) { var verifyClientCalled = false; var wss = new WebSocketServer({port: ++port, verifyClient: function(info) { info.origin.should.eql('http://foobarbaz.com'); verifyClientCalled = true; return false; }}, function() { var options = { port: port, host: '127.0.0.1', headers: { 'Connection': 'Upgrade', 'Upgrade': 'websocket', 'Sec-WebSocket-Key': 'dGhlIHNhbXBsZSBub25jZQ==', 'Sec-WebSocket-Version': 13, 'Origin': 'http://foobarbaz.com' } }; var req = http.request(options); req.end(); req.on('response', function(res) { verifyClientCalled.should.be.ok; wss.close(); done(); }); }); wss.on('error', function() {}); });
it('verifyClient gets original request', function(done) { var verifyClientCalled = false; var wss = new WebSocketServer({port: ++port, verifyClient: function(info) { info.req.headers['sec-websocket-key'].should.eql('dGhlIHNhbXBsZSBub25jZQ=='); verifyClientCalled = true; return false; }}, function() { var options = { port: port, host: '127.0.0.1', headers: { 'Connection': 'Upgrade', 'Upgrade': 'websocket', 'Sec-WebSocket-Key': 'dGhlIHNhbXBsZSBub25jZQ==', 'Sec-WebSocket-Version': 13, 'Origin': 'http://foobarbaz.com' } }; var req = http.request(options); req.end(); req.on('response', function(res) { verifyClientCalled.should.be.ok; wss.close(); done(); }); }); wss.on('error', function() {}); });
it('verifyClient has secure:true for ssl connections', function(done) { var options = { key: fs.readFileSync('test/fixtures/key.pem'), cert: fs.readFileSync('test/fixtures/certificate.pem') }; var app = https.createServer(options, function (req, res) { res.writeHead(200); res.end(); }); var success = false; var wss = new WebSocketServer({ server: app, verifyClient: function(info) { success = info.secure === true; return true; } }); app.listen(++port, function() { var ws = new WebSocket('wss://localhost:' + port); }); wss.on('connection', function(ws) { app.close(); ws.terminate(); wss.close(); success.should.be.ok; done(); }); });
it('verifyClient has secure:false for non-ssl connections', function(done) { var app = http.createServer(function (req, res) { res.writeHead(200); res.end(); }); var success = false; var wss = new WebSocketServer({ server: app, verifyClient: function(info) { success = info.secure === false; return true; } }); app.listen(++port, function() { var ws = new WebSocket('ws://localhost:' + port); }); wss.on('connection', function(ws) { app.close(); ws.terminate(); wss.close(); success.should.be.ok; done(); }); });
it('client can be denied asynchronously', function(done) { var wss = new WebSocketServer({port: ++port, verifyClient: function(o, cb) { process.nextTick(function() { cb(false); }); }}, function() { var options = { port: port, host: '127.0.0.1', headers: { 'Connection': 'Upgrade', 'Upgrade': 'websocket', 'Sec-WebSocket-Key': 'dGhlIHNhbXBsZSBub25jZQ==', 'Sec-WebSocket-Version': 8, 'Sec-WebSocket-Origin': 'http://foobar.com' } }; var req = http.request(options); req.end(); req.on('response', function(res) { res.statusCode.should.eql(401); process.nextTick(function() { wss.close(); done(); }); }); }); wss.on('connection', function(ws) { done(new Error('connection must not be established')); }); wss.on('error', function() {}); });
it('client can be accepted asynchronously', function(done) { var wss = new WebSocketServer({port: ++port, verifyClient: function(o, cb) { process.nextTick(function() { cb(true); }); }}, function() { var options = { port: port, host: '127.0.0.1', headers: { 'Connection': 'Upgrade', 'Upgrade': 'websocket', 'Sec-WebSocket-Key': 'dGhlIHNhbXBsZSBub25jZQ==', 'Sec-WebSocket-Version': 13, 'Origin': 'http://foobar.com' } }; var req = http.request(options); req.end(); }); wss.on('connection', function(ws) { ws.terminate(); wss.close(); done(); }); wss.on('error', function() {}); });
it('handles messages passed along with the upgrade request (upgrade head)', function(done) { var wss = new WebSocketServer({port: ++port, verifyClient: function(o) { return true; }}, function() { var options = { port: port, host: '127.0.0.1', headers: { 'Connection': 'Upgrade', 'Upgrade': 'websocket', 'Sec-WebSocket-Key': 'dGhlIHNhbXBsZSBub25jZQ==', 'Sec-WebSocket-Version': 13, 'Origin': 'http://foobar.com' } }; var req = http.request(options); req.write(new Buffer([0x81, 0x05, 0x48, 0x65, 0x6c, 0x6c, 0x6f], 'binary')); req.end(); }); wss.on('connection', function(ws) { ws.on('message', function(data) { data.should.eql('Hello'); ws.terminate(); wss.close(); done(); }); }); wss.on('error', function() {}); });
it('selects the first protocol by default', function(done) { var wss = new WebSocketServer({port: ++port}, function() { var ws = new WebSocket('ws://localhost:' + port, {protocol: 'prot1, prot2'}); ws.on('open', function(client) { ws.protocol.should.eql('prot1'); wss.close(); done(); }); }); });
it('selects the last protocol via protocol handler', function(done) { var wss = new WebSocketServer({port: ++port, handleProtocols: function(ps, cb) { cb(true, ps[ps.length-1]); }}, function() { var ws = new WebSocket('ws://localhost:' + port, {protocol: 'prot1, prot2'}); ws.on('open', function(client) { ws.protocol.should.eql('prot2'); wss.close(); done(); }); }); });
it('client detects invalid server protocol', function(done) { var wss = new WebSocketServer({port: ++port, handleProtocols: function(ps, cb) { cb(true, 'prot3'); }}, function() { var ws = new WebSocket('ws://localhost:' + port, {protocol: 'prot1, prot2'}); ws.on('open', function(client) { done(new Error('connection must not be established')); }); ws.on('error', function() { done(); }); }); });
it('client detects no server protocol', function(done) { var wss = new WebSocketServer({port: ++port, handleProtocols: function(ps, cb) { cb(true); }}, function() { var ws = new WebSocket('ws://localhost:' + port, {protocol: 'prot1, prot2'}); ws.on('open', function(client) { done(new Error('connection must not be established')); }); ws.on('error', function() { done(); }); }); });
it('client refuses server protocols', function(done) { var wss = new WebSocketServer({port: ++port, handleProtocols: function(ps, cb) { cb(false); }}, function() { var ws = new WebSocket('ws://localhost:' + port, {protocol: 'prot1, prot2'}); ws.on('open', function(client) { done(new Error('connection must not be established')); }); ws.on('error', function() { done(); }); }); });
it('server detects invalid protocol handler', function(done) { var wss = new WebSocketServer({port: ++port, handleProtocols: function(ps, cb) { // not calling callback is an error and shouldn't timeout
}}, function() { var options = { port: port, host: '127.0.0.1', headers: { 'Connection': 'Upgrade', 'Upgrade': 'websocket', 'Sec-WebSocket-Key': 'dGhlIHNhbXBsZSBub25jZQ==', 'Sec-WebSocket-Version': 13, 'Sec-WebSocket-Origin': 'http://foobar.com' } }; options.port = port; var req = http.request(options); req.end(); req.on('response', function(res) { res.statusCode.should.eql(501); wss.close(); done(); }); }); wss.on('connection', function(ws) { done(new Error('connection must not be established')); }); wss.on('error', function() {}); }); });
describe('messaging', function() { it('can send and receive data', function(done) { var data = new Array(65*1024); for (var i = 0; i < data.length; ++i) { data[i] = String.fromCharCode(65 + ~~(25 * Math.random())); } data = data.join(''); var wss = new WebSocketServer({port: ++port}, function() { var ws = new WebSocket('ws://localhost:' + port); ws.on('message', function(message, flags) { ws.send(message); }); }); wss.on('connection', function(client) { client.on('message', function(message) { message.should.eql(data); wss.close(); done(); }); client.send(data); }); }); }); });
describe('hixie mode', function() { it('can be disabled', function(done) { var wss = new WebSocketServer({port: ++port, disableHixie: true}, function() { var options = { port: port, host: '127.0.0.1', headers: { 'Connection': 'Upgrade', 'Upgrade': 'WebSocket', 'Sec-WebSocket-Key1': '3e6b263 4 17 80', 'Sec-WebSocket-Key2': '17 9 G`ZD9 2 2b 7X 3 /r90' } }; var req = http.request(options); req.write('WjN}|M(6'); req.end(); req.on('response', function(res) { res.statusCode.should.eql(401); process.nextTick(function() { wss.close(); done(); }); }); }); wss.on('connection', function(ws) { done(new Error('connection must not be established')); }); wss.on('error', function() {}); });
describe('connection establishing', function() { it('does not accept connections with no sec-websocket-key1', function(done) { var wss = new WebSocketServer({port: ++port}, function() { var options = { port: port, host: '127.0.0.1', headers: { 'Connection': 'Upgrade', 'Upgrade': 'WebSocket', 'Sec-WebSocket-Key1': '3e6b263 4 17 80' } }; var req = http.request(options); req.end(); req.on('response', function(res) { res.statusCode.should.eql(400); wss.close(); done(); }); }); wss.on('connection', function(ws) { done(new Error('connection must not be established')); }); wss.on('error', function() {}); });
it('does not accept connections with no sec-websocket-key2', function(done) { var wss = new WebSocketServer({port: ++port}, function() { var options = { port: port, host: '127.0.0.1', headers: { 'Connection': 'Upgrade', 'Upgrade': 'WebSocket', 'Sec-WebSocket-Key2': '17 9 G`ZD9 2 2b 7X 3 /r90' } }; var req = http.request(options); req.end(); req.on('response', function(res) { res.statusCode.should.eql(400); wss.close(); done(); }); }); wss.on('connection', function(ws) { done(new Error('connection must not be established')); }); wss.on('error', function() {}); });
it('accepts connections with valid handshake', function(done) { var wss = new WebSocketServer({port: ++port}, function() { var options = { port: port, host: '127.0.0.1', headers: { 'Connection': 'Upgrade', 'Upgrade': 'WebSocket', 'Sec-WebSocket-Key1': '3e6b263 4 17 80', 'Sec-WebSocket-Key2': '17 9 G`ZD9 2 2b 7X 3 /r90' } }; var req = http.request(options); req.write('WjN}|M(6'); req.end(); }); wss.on('connection', function(ws) { ws.terminate(); wss.close(); done(); }); wss.on('error', function() {}); });
it('client can be denied', function(done) { var wss = new WebSocketServer({port: ++port, verifyClient: function(o) { return false; }}, function() { var options = { port: port, host: '127.0.0.1', headers: { 'Connection': 'Upgrade', 'Upgrade': 'WebSocket', 'Sec-WebSocket-Key1': '3e6b263 4 17 80', 'Sec-WebSocket-Key2': '17 9 G`ZD9 2 2b 7X 3 /r90' } }; var req = http.request(options); req.write('WjN}|M(6'); req.end(); req.on('response', function(res) { res.statusCode.should.eql(401); process.nextTick(function() { wss.close(); done(); }); }); }); wss.on('connection', function(ws) { done(new Error('connection must not be established')); }); wss.on('error', function() {}); });
it('client can be accepted', function(done) { var wss = new WebSocketServer({port: ++port, verifyClient: function(o) { return true; }}, function() { var options = { port: port, host: '127.0.0.1', headers: { 'Connection': 'Upgrade', 'Upgrade': 'WebSocket', 'Sec-WebSocket-Key1': '3e6b263 4 17 80', 'Sec-WebSocket-Key2': '17 9 G`ZD9 2 2b 7X 3 /r90' } }; var req = http.request(options); req.write('WjN}|M(6'); req.end(); }); wss.on('connection', function(ws) { ws.terminate(); wss.close(); done(); }); wss.on('error', function() {}); });
it('verifyClient gets client origin', function(done) { var verifyClientCalled = false; var wss = new WebSocketServer({port: ++port, verifyClient: function(info) { info.origin.should.eql('http://foobarbaz.com'); verifyClientCalled = true; return false; }}, function() { var options = { port: port, host: '127.0.0.1', headers: { 'Connection': 'Upgrade', 'Upgrade': 'WebSocket', 'Origin': 'http://foobarbaz.com', 'Sec-WebSocket-Key1': '3e6b263 4 17 80', 'Sec-WebSocket-Key2': '17 9 G`ZD9 2 2b 7X 3 /r90' } }; var req = http.request(options); req.write('WjN}|M(6'); req.end(); req.on('response', function(res) { verifyClientCalled.should.be.ok; wss.close(); done(); }); }); wss.on('error', function() {}); });
it('verifyClient gets original request', function(done) { var verifyClientCalled = false; var wss = new WebSocketServer({port: ++port, verifyClient: function(info) { info.req.headers['sec-websocket-key1'].should.eql('3e6b263 4 17 80'); verifyClientCalled = true; return false; }}, function() { var options = { port: port, host: '127.0.0.1', headers: { 'Connection': 'Upgrade', 'Upgrade': 'WebSocket', 'Origin': 'http://foobarbaz.com', 'Sec-WebSocket-Key1': '3e6b263 4 17 80', 'Sec-WebSocket-Key2': '17 9 G`ZD9 2 2b 7X 3 /r90' } }; var req = http.request(options); req.write('WjN}|M(6'); req.end(); req.on('response', function(res) { verifyClientCalled.should.be.ok; wss.close(); done(); }); }); wss.on('error', function() {}); });
it('client can be denied asynchronously', function(done) { var wss = new WebSocketServer({port: ++port, verifyClient: function(o, cb) { cb(false); }}, function() { var options = { port: port, host: '127.0.0.1', headers: { 'Connection': 'Upgrade', 'Upgrade': 'WebSocket', 'Origin': 'http://foobarbaz.com', 'Sec-WebSocket-Key1': '3e6b263 4 17 80', 'Sec-WebSocket-Key2': '17 9 G`ZD9 2 2b 7X 3 /r90' } }; var req = http.request(options); req.write('WjN}|M(6'); req.end(); req.on('response', function(res) { res.statusCode.should.eql(401); process.nextTick(function() { wss.close(); done(); }); }); }); wss.on('connection', function(ws) { done(new Error('connection must not be established')); }); wss.on('error', function() {}); });
it('client can be accepted asynchronously', function(done) { var wss = new WebSocketServer({port: ++port, verifyClient: function(o, cb) { cb(true); }}, function() { var options = { port: port, host: '127.0.0.1', headers: { 'Connection': 'Upgrade', 'Upgrade': 'WebSocket', 'Origin': 'http://foobarbaz.com', 'Sec-WebSocket-Key1': '3e6b263 4 17 80', 'Sec-WebSocket-Key2': '17 9 G`ZD9 2 2b 7X 3 /r90' } }; var req = http.request(options); req.write('WjN}|M(6'); req.end(); }); wss.on('connection', function(ws) { wss.close(); done(); }); wss.on('error', function() {}); });
it('handles messages passed along with the upgrade request (upgrade head)', function(done) { var wss = new WebSocketServer({port: ++port, verifyClient: function(o) { return true; }}, function() { var options = { port: port, host: '127.0.0.1', headers: { 'Connection': 'Upgrade', 'Upgrade': 'WebSocket', 'Sec-WebSocket-Key1': '3e6b263 4 17 80', 'Sec-WebSocket-Key2': '17 9 G`ZD9 2 2b 7X 3 /r90', 'Origin': 'http://foobar.com' } }; var req = http.request(options); req.write('WjN}|M(6'); req.write(new Buffer([0x00, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0xff], 'binary')); req.end(); }); wss.on('connection', function(ws) { ws.on('message', function(data) { data.should.eql('Hello'); ws.terminate(); wss.close(); done(); }); }); wss.on('error', function() {}); }); }); });
describe('client properties', function() { it('protocol is exposed', function(done) { var wss = new WebSocketServer({port: ++port}, function() { var ws = new WebSocket('ws://localhost:' + port, {protocol: 'hi'}); }); wss.on('connection', function(client) { client.protocol.should.eql('hi'); wss.close(); done(); }); });
it('protocolVersion is exposed', function(done) { var wss = new WebSocketServer({port: ++port}, function() { var ws = new WebSocket('ws://localhost:' + port, {protocolVersion: 8}); }); wss.on('connection', function(client) { client.protocolVersion.should.eql(8); wss.close(); done(); }); });
it('upgradeReq is the original request object', function(done) { var wss = new WebSocketServer({port: ++port}, function() { var ws = new WebSocket('ws://localhost:' + port, {protocolVersion: 8}); }); wss.on('connection', function(client) { client.upgradeReq.httpVersion.should.eql('1.1'); wss.close(); done(); }); }); });
});
|