🚀 Big News: Socket Acquires Coana to Bring Reachability Analysis to Every Appsec Team.Learn more
Socket
Book a DemoInstallSign in
Socket

ws

Package Overview
Dependencies
Maintainers
1
Versions
172
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ws - npm Package Compare versions

Comparing version

to
0.4.1

.travis.yml

@@ -0,1 +1,12 @@

v0.4.1 - Jan 25th 2012
=====================
* Use readline in wscat [tricknotes]
* Refactor _state away, in favor of the new _readyState [tricknotes]
* travis-ci integration [einaros]
* Fixed race condition in testsuite, causing a few tests to fail (without actually indicating errors) on travis [einaros]
* Expose pong event [paddybyers]
* Enabled running of WebSocketServer in noServer-mode, meaning that upgrades are passed in manually. [einaros]
* Reworked connection procedure for WebSocketServer, and cleaned up tests. [einaros]
v0.4.0 - Jan 2nd 2012

@@ -2,0 +13,0 @@ =====================

93

lib/WebSocket.js

@@ -30,2 +30,3 @@ /*!

function WebSocket(address, options) {
var self = this;
if (Object.prototype.toString.call(address) == '[object Array]') {

@@ -57,9 +58,4 @@ /**

});
Object.defineProperty(this, '_state', { writable: true, value: 'connecting' });
Object.defineProperty(this, '_isServer', { writable: true, value: true });
var self = this;
process.nextTick(function() {
upgrade.apply(self, address);
});
Object.defineProperty(this, '_readyState', { writable: true, value: WebSocket.CONNECTING });
Object.defineProperty(this, '_isServer', { writable: false, value: true });
}

@@ -71,3 +67,3 @@ else {

Object.defineProperty(this, '_isServer', { writable: true, value: false });
Object.defineProperty(this, '_isServer', { writable: false, value: false });

@@ -77,3 +73,3 @@ var serverUrl = url.parse(address);

var httpObj = (serverUrl.protocol === 'wss:' || serverUrl.protocol === 'https:') ? https : http;
Object.defineProperty(this, 'url', {

@@ -135,3 +131,2 @@ writable: false,

var req = httpObj.request(requestOptions);
var self = this;
(isNodeV4 ? agent : req).on('error', function(error) {

@@ -141,4 +136,4 @@ self.emit('error', error);

(isNodeV4 ? agent : req).on('upgrade', function(res, socket, upgradeHead) {
if (self._state == 'disconnected') {
// client disconnected before server accepted connection
if (self.readyState == WebSocket.CLOSED) {
// client closed before server accepted connection
self.emit('close');

@@ -159,3 +154,3 @@ socket.end();

req.end();
Object.defineProperty(this, '_state', { writable: true, value: 'connecting' });
Object.defineProperty(this, '_readyState', { writable: true, value: WebSocket.CONNECTING });
}

@@ -171,14 +166,9 @@

get: function() {
switch(this._state) {
case 'connecting':
return WebSocket.CONNECTING;
case 'connected':
return WebSocket.OPEN;
case 'closing':
return WebSocket.CLOSING;
case 'disconnected':
return WebSocket.CLOSED;
}
return this._readyState;
}
});
if (this._isServer) {
upgrade.apply(this, address);
}
}

@@ -218,10 +208,10 @@

WebSocket.prototype.close = function(code, data) {
if (this._state == 'closing') return;
if (this._state == 'connecting') {
this._state = 'disconnected';
if (this.readyState == WebSocket.CLOSING) return;
if (this.readyState == WebSocket.CONNECTING) {
this._readyState = WebSocket.CLOSED;
return;
}
if (this._state != 'connected') throw new Error('not connected');
if (this.readyState != WebSocket.OPEN) throw new Error('not opened');
try {
this._state = 'closing';
this._readyState = WebSocket.CLOSING;
this._closeCode = code;

@@ -247,3 +237,3 @@ this._closeMessage = data;

WebSocket.prototype.ping = function(data, options) {
if (this._state != 'connected') throw new Error('not connected');
if (this.readyState != WebSocket.OPEN) throw new Error('not opened');
options = options || {};

@@ -263,3 +253,3 @@ if (typeof options.mask == 'undefined') options.mask = !this._isServer;

WebSocket.prototype.pong = function(data, options) {
if (this._state != 'connected') throw new Error('not connected');
if (this.readyState != WebSocket.OPEN) throw new Error('not opened');
options = options || {};

@@ -284,5 +274,5 @@ if (typeof options.mask == 'undefined') options.mask = !this._isServer;

}
if (this._state != 'connected') {
if (typeof cb == 'function') cb(new Error('not connected'));
else throw new Error('not connected');
if (this.readyState != WebSocket.OPEN) {
if (typeof cb == 'function') cb(new Error('not opened'));
else throw new Error('not opened');
return;

@@ -324,5 +314,5 @@ }

if (typeof cb != 'function') throw new Error('callback must be provided');
if (this._state != 'connected') {
if (typeof cb == 'function') cb(new Error('not connected'));
else throw new Error('not connected');
if (this.readyState != WebSocket.OPEN) {
if (typeof cb == 'function') cb(new Error('not opened'));
else throw new Error('not opened');
return;

@@ -341,3 +331,3 @@ }

try {
if (self._state != 'connected') throw new Error('not connected');
if (self.readyState != WebSocket.OPEN) throw new Error('not opened');
options.fin = final === true;

@@ -367,4 +357,4 @@ self._sender.send(data, options);

}
else if (this._state == 'connecting') {
this._state = 'disconnected';
else if (this.readyState == WebSocket.CONNECTING) {
this._readyState = WebSocket.CLOSED;
}

@@ -437,9 +427,9 @@ };

socket.on('end', function() {
if (self._state == 'disconnected') return;
self._state = 'disconnected';
if (self.readyState == WebSocket.CLOSED) return;
self._readyState = WebSocket.CLOSED;
self.emit('close', self._closeCode || 1000, self._closeMessage || '');
});
socket.on('close', function() {
if (self._state == 'disconnected') return;
self._state = 'disconnected';
if (self.readyState == WebSocket.CLOSED) return;
self._readyState = WebSocket.CLOSED;
self.emit('close', self._closeCode || 1000, self._closeMessage || '');

@@ -466,2 +456,5 @@ });

});
receiver.on('pong', function(data, flags) {
self.emit('pong', data, flags);
});
receiver.on('close', function(code, data, flags) {

@@ -483,3 +476,3 @@ flags = flags || {};

});
this._state = 'connected';
this._readyState = WebSocket.OPEN;
this.emit('open');

@@ -505,5 +498,5 @@

stream.on('data', function(data) {
if (instance._state != 'connected') {
if (typeof cb == 'function') cb(new Error('not connected'));
else instance.emit('error', new Error('not connected'));
if (instance.readyState != WebSocket.OPEN) {
if (typeof cb == 'function') cb(new Error('not opened'));
else instance.emit('error', new Error('not opened'));
return;

@@ -515,5 +508,5 @@ }

stream.on('end', function() {
if (instance._state != 'connected') {
if (typeof cb == 'function') cb(new Error('not connected'));
else instance.emit('error', new Error('not connected'));
if (instance.readyState != WebSocket.OPEN) {
if (typeof cb == 'function') cb(new Error('not opened'));
else instance.emit('error', new Error('not opened'));
return;

@@ -520,0 +513,0 @@ }

@@ -26,9 +26,12 @@ /*!

verifyOrigin: null,
path: null
path: null,
noServer: false
}).merge(options);
if (!options.value.port && !options.value.server) {
if (!options.value.port && !options.value.server && !options.value.noServer) {
throw new TypeError('`port` or a `server` must be provided');
}
if (!options.value.server) {
var self = this;
if (options.value.port) {
Object.defineProperty(this, '_server', {

@@ -43,6 +46,6 @@ configurable: true,

Object.defineProperty(this, '_closeServer', {
value: function() { this._server.close(); }
value: function() { self._server.close(); }
});
}
else {
else if (options.value.server) {
Object.defineProperty(this, '_server', { value: options.value.server, configurable: true });

@@ -55,3 +58,3 @@ if (options.value.path) {

}
if (typeof this._server._webSocketPaths !== 'object') {
if (typeof this._server._webSocketPaths !== 'object') {
Object.defineProperty(this._server, '_webSocketPaths', { value: {}, configurable: true });

@@ -63,89 +66,16 @@ }

Object.defineProperty(this, 'path', { value: options.value.path });
Object.defineProperty(this, '_clients', { value: [] });
var self = this;
this._server.on('error', function(error) {
self.emit('error', error)
});
this._server.on('upgrade', function(req, socket, upgradeHead) {
// check for wrong path
if (options.value.path) {
var u = url.parse(req.url);
if (u && u.pathname !== options.value.path) return;
}
if (typeof req.headers.upgrade === 'undefined' || req.headers.upgrade.toLowerCase() !== 'websocket') {
abortConnection(socket, 400, 'Bad Request');
return;
}
// verify key presence
if (!req.headers['sec-websocket-key']) {
abortConnection(socket, 400, 'Bad Request');
return;
}
// verify version
var version = parseInt(req.headers['sec-websocket-version']);
if ([8, 13].indexOf(version) === -1) {
abortConnection(socket, 400, 'Bad Request');
return;
}
// verify origin
var origin = version < 13 ?
req.headers['sec-websocket-origin'] :
req.headers['origin'];
if (typeof options.value.verifyOrigin == 'function') {
if (!options.value.verifyOrigin(origin)) {
abortConnection(socket, 401, 'Unauthorized');
return;
}
}
var protocol = req.headers['sec-websocket-protocol'];
// calc key
var key = req.headers['sec-websocket-key'];
var shasum = crypto.createHash('sha1');
shasum.update(key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11");
key = shasum.digest('base64');
var headers = [
'HTTP/1.1 101 Switching Protocols'
, 'Upgrade: websocket'
, 'Connection: Upgrade'
, 'Sec-WebSocket-Accept: ' + key
];
if (typeof protocol != 'undefined') {
headers['Sec-WebSocket-Protocol'] = protocol;
}
try {
socket.write(headers.concat('', '').join('\r\n'));
}
catch (e) {
try { socket.end(); } catch (_) {}
return;
}
socket.setTimeout(0);
socket.setNoDelay(true);
var client = new WebSocket(Array.prototype.slice.call(arguments, 0), {
protocolVersion: version,
protocol: protocol
if (typeof this._server != 'undefined') {
this._server.on('error', function(error) {
self.emit('error', error)
});
self._clients.push(client);
client.on('open', function() {
self.emit('connection', client);
this._server.on('upgrade', function(req, socket, upgradeHead) {
var client = self.handleUpgrade(req, socket, upgradeHead);
if (client) self.emit('connection', client);
});
client.on('close', function() {
var index = self._clients.indexOf(client);
if (index != -1) {
self._clients.splice(index, 1);
}
});
});
Object.defineProperty(this, 'clients', {
}
Object.defineProperty(this, 'options', { value: options.value });
Object.defineProperty(this, 'path', { value: options.value.path });
Object.defineProperty(this, '_clients', { value: [] });
Object.defineProperty(this, 'clients', {
get: function() { return self._clients; }

@@ -178,3 +108,3 @@ });

}
// remove path descriptor, if any

@@ -187,3 +117,3 @@ if (this.path && this._server._webSocketPaths) {

}
// close the http server if it was internally created

@@ -201,2 +131,79 @@ try {

WebSocketServer.prototype.handleUpgrade = function(req, socket, upgradeHead) {
// check for wrong path
if (this.options.path) {
var u = url.parse(req.url);
if (u && u.pathname !== this.options.path) return;
}
if (typeof req.headers.upgrade === 'undefined' || req.headers.upgrade.toLowerCase() !== 'websocket') {
abortConnection(socket, 400, 'Bad Request');
return;
}
// verify key presence
if (!req.headers['sec-websocket-key']) {
abortConnection(socket, 400, 'Bad Request');
return;
}
// verify version
var version = parseInt(req.headers['sec-websocket-version']);
if ([8, 13].indexOf(version) === -1) {
abortConnection(socket, 400, 'Bad Request');
return;
}
// verify origin
var origin = version < 13 ?
req.headers['sec-websocket-origin'] :
req.headers['origin'];
if (typeof this.options.verifyOrigin == 'function') {
if (!this.options.verifyOrigin(origin)) {
abortConnection(socket, 401, 'Unauthorized');
return;
}
}
var protocol = req.headers['sec-websocket-protocol'];
// calc key
var key = req.headers['sec-websocket-key'];
var shasum = crypto.createHash('sha1');
shasum.update(key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11");
key = shasum.digest('base64');
var headers = [
'HTTP/1.1 101 Switching Protocols'
, 'Upgrade: websocket'
, 'Connection: Upgrade'
, 'Sec-WebSocket-Accept: ' + key
];
if (typeof protocol != 'undefined') {
headers['Sec-WebSocket-Protocol'] = protocol;
}
try {
socket.write(headers.concat('', '').join('\r\n'));
}
catch (e) {
try { socket.end(); } catch (_) {}
return;
}
socket.setTimeout(0);
socket.setNoDelay(true);
var client = new WebSocket(Array.prototype.slice.call(arguments, 0), {
protocolVersion: version,
protocol: protocol
});
this._clients.push(client);
var self = this;
client.on('close', function() {
var index = self._clients.indexOf(client);
if (index != -1) {
self._clients.splice(index, 1);
}
});
return client;
}
module.exports = WebSocketServer;

@@ -203,0 +210,0 @@

@@ -5,3 +5,3 @@ {

"description": "simple and very fast websocket protocol client for node.js",
"version": "0.4.0",
"version": "0.4.1",
"repository": {

@@ -8,0 +8,0 @@ "type": "git",

@@ -0,5 +1,9 @@

[![Build Status](https://secure.travis-ci.org/einaros/ws.png)](http://travis-ci.org/einaros/ws)
# ws: a node.js websocket implementation #
`ws` is a simple to use, blazing fast, websocket implementation for node.js, up-to-date against RFC-6455.
`ws` is a simple to use websocket implementation, up-to-date against RFC-6455.
It is probably also the fastest websocket library running on node.js (http://hobbycoding.posterous.com/the-fastest-websocket-module-for-nodejs).
Passes the quite extensible Autobahn test suite. See http://einaros.github.com/ws for the full reports.

@@ -50,2 +54,15 @@

### Server example ###
```js
var WebSocketServer = require('ws').Server
, wss = new WebSocketServer({port: 8080});
wss.on('connection', function(ws) {
ws.on('message', function(message) {
console.log('received: %s', message);
});
ws.send('something');
});
```
### echo.websocket.org demo ###

@@ -52,0 +69,0 @@

@@ -1,3 +0,2 @@

var assert = require('assert')
, Sender = require('../lib/Sender');
var Sender = require('../lib/Sender');
require('should');

@@ -4,0 +3,0 @@

@@ -1,3 +0,2 @@

var assert = require('assert')
, Validation = require('../lib/Validation').Validation;
var Validation = require('../lib/Validation').Validation;
require('should');

@@ -4,0 +3,0 @@

@@ -67,3 +67,3 @@ var assert = require('assert')

it('set to connected once connection is established', function(done) {
it('set to open once connection is established', function(done) {
server.createServer(++port, function(srv) {

@@ -124,5 +124,32 @@ var ws = new WebSocket('ws://localhost:' + port);

it('can disconnect before connection is established', function(done) {
server.createServer(++port, function(srv) {
describe('events', function() {
it('emits a ping event', function(done) {
var wss = new WebSocketServer({port: ++port});
wss.on('connection', function(client) {
client.ping();
});
var ws = new WebSocket('ws://localhost:' + port);
ws.on('ping', function() {
ws.terminate();
wss.close();
done();
});
});
it('emits a pong event', function(done) {
var wss = new WebSocketServer({port: ++port});
wss.on('connection', function(client) {
client.pong();
});
var ws = new WebSocket('ws://localhost:' + port);
ws.on('pong', function() {
ws.terminate();
wss.close();
done();
});
});
});
it('can disconnect before connection is established', function(done) {server.createServer(++port, function(srv) {
var ws = new WebSocket('ws://localhost:' + port);
ws.terminate();

@@ -129,0 +156,0 @@ ws.on('open', function() {

@@ -1,3 +0,2 @@

var assert = require('assert')
, http = require('http')
var http = require('http')
, WebSocket = require('../')

@@ -51,2 +50,13 @@ , WebSocketServer = WebSocket.Server

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) {

@@ -57,8 +67,2 @@ var wss = new WebSocketServer({port: 1});

it('uses passed server object', function () {
var srv = http.createServer()
, wss = new WebSocketServer({server: srv});
wss._server.should.equal(srv);
});
it('starts a server on a given port', function(done) {

@@ -74,3 +78,3 @@ var wss = new WebSocketServer({port: ++port}, function() {

it('works with a precreated http server', function (done) {
it('uses a precreated http server', function (done) {
var srv = http.createServer();

@@ -83,2 +87,3 @@ srv.listen(++port, function () {

wss.close();
srv.close();
done();

@@ -113,4 +118,4 @@ });

});
it('cannot have two different instances listening on the same http server with two different paths', function(done) {
it('cannot have two different instances listening on the same http server with the same path', function(done) {
var srv = http.createServer();

@@ -120,5 +125,7 @@ srv.listen(++port, function () {

try {
var wss2 = new WebSocketServer({server: srv, path: '/wss1'});
var wss2 = new WebSocketServer({server: srv, path: '/wss1'});
}
catch (e) {
wss1.close();
srv.close();
done();

@@ -146,3 +153,3 @@ }

});
it('does not close a precreated server', function(done) {

@@ -183,120 +190,122 @@ var srv = http.createServer();

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();
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('error', function() {});
});
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();
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('error', function() {});
});
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();
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('error', function() {});
});
wss.on('error', function() {});
});
it('does not accept connections with invalid sec-websocket-origin (8)', function(done) {
var wss = new WebSocketServer({port: ++port, verifyOrigin: function(o) {
o.should.eql('http://foobar.com');
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);
wss.close();
done();
it('does not accept connections with invalid sec-websocket-origin (8)', function(done) {
var wss = new WebSocketServer({port: ++port, verifyOrigin: function(o) {
o.should.eql('http://foobar.com');
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);
wss.close();
done();
});
});
wss.on('error', function() {});
});
wss.on('error', function() {});
});
it('does not accept connections with invalid origin', function(done) {
var wss = new WebSocketServer({port: ++port, verifyOrigin: function(o) {
o.should.eql('http://foobar.com');
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://foobar.com'
}
};
var req = http.request(options);
req.end();
req.on('response', function(res) {
res.statusCode.should.eql(401);
wss.close();
done();
it('does not accept connections with invalid origin', function(done) {
var wss = new WebSocketServer({port: ++port, verifyOrigin: function(o) {
o.should.eql('http://foobar.com');
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://foobar.com'
}
};
var req = http.request(options);
req.end();
req.on('response', function(res) {
res.statusCode.should.eql(401);
wss.close();
done();
});
});
wss.on('error', function() {});
});
wss.on('error', function() {});
});

@@ -318,3 +327,3 @@

describe('properties', function() {
describe('client properties', function() {
it('protocol is exposed', function(done) {

@@ -366,3 +375,3 @@ var wss = new WebSocketServer({port: ++port}, function() {

});
it('is updated when client terminates the connection', function(done) {

@@ -382,3 +391,3 @@ var ws;

});
it('is updated when client closes the connection', function(done) {

@@ -399,3 +408,33 @@ var ws;

});
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) {
var client = wss.handleUpgrade(req, socket, upgradeHead);
client.send('hello');
});
var ws = new WebSocket('ws://localhost:' + port);
ws.on('message', function(message) {
message.should.eql('hello');
wss.close();
srv.close();
done();
})
});
});
});
});

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet