engine.io
Advanced tools
Comparing version 0.1.2 to 0.2.0
0.2.0 / 2012-08-06 | ||
================== | ||
* Bumped client | ||
* test: added closing connection test | ||
* server: implemented stronger id generator with collision detection | ||
0.1.2 / 2012-08-02 | ||
@@ -3,0 +10,0 @@ ================== |
@@ -9,7 +9,8 @@ | ||
, readFileSync = require('fs').readFileSync | ||
, crypto = require('crypto') | ||
, transports = require('./transports') | ||
, debug = require('debug')('engine') | ||
, EventEmitter = require('events').EventEmitter | ||
, Socket = require('./socket') | ||
, WebSocketServer = require('ws').Server | ||
, debug = require('debug')('engine') | ||
@@ -122,3 +123,9 @@ /** | ||
Server.prototype.id = function () { | ||
return String(Math.random() * Math.random()).substr(3); | ||
var rand = new Buffer(15); | ||
this.sequenceNumber = (this.sequenceNumber + 1) | 0; | ||
rand.writeInt32BE(this.sequenceNumber, 11); | ||
crypto.randomBytes(12).copy(rand); | ||
var id = rand.toString('base64').replace(/\//g, '_').replace(/\+/g, '-'); | ||
if (this.clients[id]) return this.id(); | ||
return id; | ||
}; | ||
@@ -228,3 +235,3 @@ | ||
* | ||
* @param {wsio.Socket} websocket | ||
* @param {ws.Socket} websocket | ||
* @api private | ||
@@ -234,4 +241,14 @@ */ | ||
Server.prototype.onWebSocket = function (req, socket) { | ||
if (!transports[req.query.transport].prototype.handlesUpgrades) { | ||
debug('transport doesnt handle upgraded requests'); | ||
socket.close(); | ||
return; | ||
} | ||
// get client id | ||
var id = req.query.sid; | ||
// keep a reference to the ws.Socket | ||
req.websocket = socket; | ||
if (id) { | ||
@@ -246,9 +263,8 @@ if (!this.clients[id]) { | ||
debug('upgrading existing transport'); | ||
var transport = new transports[req.query.transport](socket); | ||
var transport = new transports[req.query.transport](req); | ||
this.clients[id].maybeUpgrade(transport); | ||
} | ||
} else { | ||
this.handshake(req.query.transport, socket); | ||
this.handshake(req.query.transport, req); | ||
} | ||
}; | ||
@@ -255,0 +271,0 @@ |
@@ -255,4 +255,8 @@ /** | ||
debug('flushing buffer to transport'); | ||
this.emit('flush', this.writeBuffer); | ||
this.server.emit('flush', this, this.writeBuffer); | ||
this.transport.send(this.writeBuffer); | ||
this.writeBuffer = []; | ||
this.emit('drain'); | ||
this.server.emit('drain', this); | ||
} | ||
@@ -277,3 +281,3 @@ }; | ||
return availableUpgrades; | ||
} | ||
}; | ||
@@ -280,0 +284,0 @@ /** |
@@ -15,10 +15,10 @@ | ||
/** | ||
* The FlashSocket transport is just a proxy | ||
* for WebSocket connections. | ||
* The FlashSocket transport is just a proxy for WebSocket connections. | ||
* | ||
* @param {http.ServerRequest} request | ||
* @api public | ||
*/ | ||
function FlashSocket (socket) { | ||
WebSocket.call(this, socket); | ||
function FlashSocket (req) { | ||
WebSocket.call(this, req); | ||
} | ||
@@ -25,0 +25,0 @@ |
@@ -19,10 +19,10 @@ | ||
* | ||
* @param {wsio.Socket} | ||
* @param {http.ServerRequest} | ||
* @api public | ||
*/ | ||
function WebSocket (socket) { | ||
Transport.call(this, socket.req); | ||
function WebSocket (req) { | ||
Transport.call(this, req); | ||
var self = this; | ||
this.socket = socket; | ||
this.socket = req.websocket; | ||
this.socket.on('message', this.onData.bind(this)); | ||
@@ -52,2 +52,10 @@ this.socket.once('close', this.onClose.bind(this)); | ||
/** | ||
* Advertise upgrade support. | ||
* | ||
* @api public | ||
*/ | ||
WebSocket.prototype.handlesUpgrades = true; | ||
/** | ||
* Processes the incoming data. | ||
@@ -54,0 +62,0 @@ * |
{ | ||
"name": "engine.io" | ||
, "version": "0.1.2" | ||
, "version": "0.2.0" | ||
, "description": "The realtime engine behind Socket.IO. Provides the foundation of a bidirectional connection between client and server" | ||
@@ -8,3 +8,3 @@ , "main": "./lib/engine.io" | ||
"debug": "0.6.0" | ||
, "engine.io-client": "0.1.2" | ||
, "engine.io-client": "0.2.0" | ||
, "ws": "~0.4.21" | ||
@@ -11,0 +11,0 @@ } |
101
README.md
@@ -100,2 +100,14 @@ # Engine.IO: the realtime engine | ||
##### Events | ||
- `flush` | ||
- Called when a socket buffer is being flushed. | ||
- **Arguments** | ||
- `Socket`: socket being flushed | ||
- `Array`: write buffer | ||
- `drain` | ||
- Called when a socket buffer is drained | ||
- **Arguments** | ||
- `Socket`: socket being flushed | ||
##### Properties | ||
@@ -144,3 +156,3 @@ | ||
- `connection` | ||
- Fired when a new connection is established. | ||
- Fired when a new connection is established. | ||
- **Arguments** | ||
@@ -220,2 +232,8 @@ - `Socket`: a Socket object | ||
- `Error`: error object | ||
- `flush` | ||
- Called when the write buffer is being flushed. | ||
- **Arguments** | ||
- `Array`: write buffer | ||
- `drain` | ||
- Called when the write buffer is drained | ||
@@ -245,79 +263,6 @@ ##### Properties | ||
#### Top-level | ||
These are exposed in the `eio` global namespace (in the browser), or by | ||
Exposed in the `eio` global namespace (in the browser), or by | ||
`require('engine.io-client')` (in Node.JS). | ||
##### Properties | ||
- `version` _(String)_: client version | ||
- `protocol` _(Number)_: protocol revision number | ||
- `Socket` _(Function)_: client constructor | ||
#### Socket | ||
The client class. _Inherits from EventEmitter_. | ||
#### Properties | ||
- `onopen` (_Function_) | ||
- `open` event handler | ||
- `onmessage` (_Function_) | ||
- `message` event handler | ||
- `onclose` (_Function_) | ||
- `message` event handler | ||
##### Events | ||
- `open` | ||
- Fired upon successful connection. | ||
- `message` | ||
- Fired when data is received from the server. | ||
- **Arguments** | ||
- `String`: utf-8 encoded data | ||
- `close` | ||
- Fired upon disconnection. | ||
- **Arguments** | ||
- `String`: reason for closing | ||
- `Object`: description object (optional) | ||
- `error` | ||
- Fired when an error occurs. | ||
##### Methods | ||
- **constructor** | ||
- Initializes the client | ||
- **Parameters** | ||
- `Object`: optional, options object | ||
- **Options** | ||
- `host` (`String`): host name (`localhost`) | ||
- `port` (`Number`): port name (`80`) | ||
- `path` (`String`): path to intercept requests to (`/engine.io`) | ||
- `resource` (`String`): name of resource for this server (`default`). | ||
Setting a resource allows you to initialize multiple engine.io | ||
endpoints on the same host without them interfering, and without | ||
changing the `path` directly. | ||
- `query` (`Object`): optional query string addition (eg: `{ a: 'b' }`) | ||
- `secure` (`Boolean): whether the connection is secure | ||
- `upgrade` (`Boolean`): defaults to true, whether the client should try | ||
to upgrade the transport from long-polling to something better. | ||
- `forceJSONP` (`Boolean`): forces JSONP for polling transport. | ||
- `timestampRequests` (`Boolean`): whether to add the timestamp with | ||
each transport request. Note: this is ignored if the browser is | ||
IE or Android, in which case requests are always stamped (`false`) | ||
- `timestampParam` (`String`): timestamp parameter (`t`) | ||
- `flashPath` (`String`): path to flash client files with trailing slash | ||
- `policyPort` (`Number`): port the policy server listens on (`843`) | ||
- `transports` (`Array`): a list of transports to try (in order). | ||
Defaults to `['polling', 'websocket', 'flashsocket']`. `Engine` | ||
always attempts to connect directly with the first one, provided the | ||
feature detection test for it passes. | ||
- `send` | ||
- Sends a message to the server | ||
- **Parameters** | ||
- `String`: data to send | ||
- `close` | ||
- Disconnects the client. | ||
For more information on the client refer to the | ||
For the client API refer to the | ||
[engine-client](http://github.com/learnboost/engine-client) repository. | ||
@@ -331,2 +276,6 @@ | ||
## Plugins | ||
- [engine.io-conflation](https://github.com/EugenDueck/engine.io-conflation) | ||
## Support | ||
@@ -333,0 +282,0 @@ |
@@ -6,3 +6,4 @@ | ||
var parser = eio.parser | ||
var http = require('http') | ||
, parser = eio.parser | ||
, WebSocket = require('ws') | ||
@@ -59,3 +60,3 @@ | ||
// hack-obtain sid | ||
var sid = res.text.match(/"sid":"([0-9]+)"/)[1]; | ||
var sid = res.text.match(/"sid":"([^"]+)"/)[1]; | ||
expect(res.headers['set-cookie'][0]).to.be('io=' + sid); | ||
@@ -72,3 +73,3 @@ done(); | ||
.end(function (res) { | ||
var sid = res.text.match(/"sid":"([0-9]+)"/)[1]; | ||
var sid = res.text.match(/"sid":"([^"]+)"/)[1]; | ||
expect(res.headers['set-cookie'][0]).to.be('woot=' + sid); | ||
@@ -377,2 +378,68 @@ done(); | ||
}); | ||
it('should trigger if a poll request is ongoing and the underlying' | ||
+ ' socket closes, as in a browser tab close', function (done) { | ||
var engine = listen({ allowUpgrades: false }, function (port) { | ||
var socket = new eioc.Socket('ws://localhost:%d'.s(port)) | ||
, serverSocket | ||
engine.on('connection', function(socket){ | ||
serverSocket = socket; | ||
}); | ||
socket.transport.on('poll', function(){ | ||
// at this time server's `connection` should have been fired | ||
expect(serverSocket).to.be.an('object'); | ||
// OPENED readyState is expected - we qre actually polling | ||
expect(socket.transport.pollXhr.xhr.readyState).to.be(1); | ||
// 2 requests sent to the server over an unique port means | ||
// we should have been assigned 2 sockets | ||
var sockets = http.globalAgent.sockets['localhost:%d'.s(port)]; | ||
expect(sockets.length).to.be(2); | ||
// expect the socket to be open at this point | ||
expect(serverSocket.readyState).to.be('open'); | ||
// kill the underlying connection | ||
serverSocket.on('close', function(reason, err){ | ||
expect(reason).to.be('transport error'); | ||
expect(err.message).to.be('poll connection closed prematurely'); | ||
done(); | ||
}); | ||
sockets[1].end(); | ||
}); | ||
}); | ||
}); | ||
it('should not trigger with connection: close header', function(done){ | ||
var engine = listen({ allowUpgrades: false }, function(port){ | ||
// intercept requests to add connection: close | ||
var oldRequest = http.request; | ||
http.request = function(){ | ||
var opts = arguments[0]; | ||
opts.headers = opts.headers || {}; | ||
opts.headers.Connection = 'close'; | ||
return oldRequest.apply(this, arguments); | ||
} | ||
engine.on('connection', function(socket){ | ||
socket.on('message', function(msg){ | ||
expect(msg).to.equal('test'); | ||
socket.send('woot'); | ||
}); | ||
}); | ||
var socket = new eioc.Socket('ws://localhost:%d'.s(port)) | ||
socket.on('open', function(){ | ||
socket.send('test'); | ||
}); | ||
socket.on('message', function(msg){ | ||
expect(msg).to.be('woot'); | ||
http.request = oldRequest; | ||
done(); | ||
}); | ||
}); | ||
}); | ||
}); | ||
@@ -498,2 +565,34 @@ | ||
}); | ||
it('should trigger a flush/drain event', function(done){ | ||
var engine = listen({ allowUpgrades: false }, function(port){ | ||
engine.on('connection', function(socket){ | ||
var totalEvents = 4; | ||
engine.on('flush', function(sock, buf){ | ||
expect(sock).to.be(socket); | ||
expect(buf).to.be.an('array'); | ||
--totalEvents || done(); | ||
}); | ||
socket.on('flush', function(buf){ | ||
expect(buf).to.be.an('array'); | ||
--totalEvents || done(); | ||
}); | ||
engine.on('drain', function(sock){ | ||
expect(sock).to.be(socket); | ||
expect(socket.writeBuffer.length).to.be(0); | ||
--totalEvents || done(); | ||
}); | ||
socket.on('drain', function(){ | ||
expect(socket.writeBuffer.length).to.be(0); | ||
--totalEvents || done(); | ||
}); | ||
socket.send('aaaa'); | ||
}); | ||
new eioc.Socket('ws://localhost:%d'.s(port)); | ||
}); | ||
}); | ||
}); | ||
@@ -500,0 +599,0 @@ |
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 2 instances in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
80198
24
2132
6
488
5
+ Addedengine.io-client@0.2.0(transitive)
- Removedengine.io-client@0.1.2(transitive)
Updatedengine.io-client@0.2.0