Socket
Socket
Sign inDemoInstall

engine.io

Package Overview
Dependencies
Maintainers
1
Versions
151
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

engine.io - npm Package Compare versions

Comparing version 0.5.0 to 0.6.0

test/jsonp.js

10

History.md
0.6.0 / 2013-05-31
==================
* socket: clear timer after sending one noop packet (fixes #174)
* clear all timers on socket close
* sending error on transport creation upon a bad request
* added test for client-side buffer cleanup
* changed flushComplete to flush
* ended support for node 0.6
0.5.0 / 2013-03-16

@@ -3,0 +13,0 @@ ==================

36

lib/server.js

@@ -55,3 +55,4 @@

UNKNOWN_SID: 1,
BAD_HANDSHAKE_METHOD: 2
BAD_HANDSHAKE_METHOD: 2,
BAD_REQUEST: 3
};

@@ -62,3 +63,4 @@

1: 'Session ID unknown',
2: 'Bad handshake method'
2: 'Bad handshake method',
3: 'Bad request'
};

@@ -163,7 +165,3 @@

if (code !== true) {
res.writeHead(400, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({
code: code,
message: Server.errorMessages[code]
}));
sendErrorMessage(res, code);
return this;

@@ -183,2 +181,18 @@ }

/**
* Sends an Engine.IO Error Message
*
* @param {http.ServerResponse} response
* @param {code} error code
* @api private
*/
function sendErrorMessage(res, code) {
res.writeHead(400, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({
code: code,
message: Server.errorMessages[code]
}));
}
/**
* Handshakes a new client.

@@ -196,3 +210,9 @@ *

var transport = new transports[transport](req);
try {
var transport = new transports[transport](req);
}
catch (e) {
sendErrorMessage(req.res, Server.errors.BAD_REQUEST);
return;
}
var socket = new Socket(id, this, transport);

@@ -199,0 +219,0 @@ var self = this;

@@ -5,4 +5,4 @@ /**

var EventEmitter = require('events').EventEmitter
, debug = require('debug')('engine:socket')
var EventEmitter = require('events').EventEmitter;
var debug = require('debug')('engine:socket');

@@ -165,7 +165,8 @@ /**

var self = this;
// set transport upgrade timer
var checkInterval;
var upgradeTimeout = setTimeout(function () {
self.upgradeTimeoutTimer = setTimeout(function () {
debug('client did not complete upgrade - closing transport');
clearInterval(checkInterval);
clearInterval(self.checkIntervalTimer);
if ('open' == transport.readyState) {

@@ -176,3 +177,2 @@ transport.close();

var self = this;
function onPacket (packet) {

@@ -183,10 +183,9 @@ if ('ping' == packet.type && 'probe' == packet.data) {

// we force a polling cycle to ensure a fast upgrade
function check () {
self.checkIntervalTimer = setInterval(function(){
if ('polling' == self.transport.name && self.transport.writable) {
debug('writing a noop packet to polling for fast upgrade');
self.transport.send([{ type: 'noop' }]);
clearInterval(self.checkIntervalTimer);
}
}
checkInterval = setInterval(check, 100);
}, 100);
} else if ('upgrade' == packet.type && self.readyState == 'open') {

@@ -200,4 +199,4 @@ debug('got upgrade packet - upgrading');

self.flush();
clearInterval(checkInterval);
clearTimeout(upgradeTimeout);
clearInterval(self.checkIntervalTimer);
clearTimeout(self.upgradeTimeoutTimer);
transport.removeListener('packet', onPacket);

@@ -234,2 +233,5 @@ } else {

if ('closed' != this.readyState) {
clearTimeout(this.pingTimeoutTimer);
clearInterval(this.checkIntervalTimer);
clearTimeout(this.upgradeTimeoutTimer);
var self = this;

@@ -257,4 +259,4 @@ // clean writeBuffer in next tick, so developers can still

var self = this;
//the message was sent successfully, execute the callback
this.transport.on('drain', function() {
//the message was sent successfully, execute the callback
this.transport.on('drain', function() {
if (self.sentCallbackFn.length > 0) {

@@ -334,3 +336,3 @@ var seqFn = self.sentCallbackFn.splice(0,1)[0];

if (!this.transport.supportsFraming) {
this.sentCallbackFn.push(this.packetsFn)
this.sentCallbackFn.push(this.packetsFn);
} else {

@@ -373,2 +375,5 @@ this.sentCallbackFn.push.apply(this.sentCallbackFn, this.packetsFn);

if ('open' == this.readyState) {
clearTimeout(this.pingTimeoutTimer);
clearInterval(this.checkIntervalTimer);
clearTimeout(this.upgradeTimeoutTimer);
this.readyState = 'closing';

@@ -375,0 +380,0 @@ var self = this;

{
"name": "engine.io"
, "version": "0.5.0"
, "version": "0.6.0"
, "description": "The realtime engine behind Socket.IO. Provides the foundation of a bidirectional connection between client and server"

@@ -27,3 +27,3 @@ , "main": "./lib/engine.io"

, "superagent": "*"
, "engine.io-client": "0.5.0"
, "engine.io-client": "git://github.com/LearnBoost/engine.io-client#68780141ef"
, "s": "*"

@@ -30,0 +30,0 @@ }

# Engine.IO: the realtime engine
[![Build Status](https://secure.travis-ci.org/LearnBoost/engine.io.png)](http://travis-ci.org/LearnBoost/engine.io)
[![NPM version](https://badge.fury.io/js/engine.io.png)](http://badge.fury.io/js/engine.io)

@@ -131,3 +132,3 @@ `Engine` is the implementation of transport-based cross-browser/cross-device

- Captures `upgrade` requests for a `http.Server`. In other words, makes
a regular http.Server websocket-compatible.
a regular http.Server WebSocket-compatible.
- **Parameters**

@@ -159,3 +160,3 @@ - `http.Server`: server to attach to.

**Important**: if you plan to use engine.io in a scalable way, please
**Important**: if you plan to use Engine.IO in a scalable way, please
keep in mind the properties below will only reflect the clients connected

@@ -180,3 +181,3 @@ to a single process.

to (`['polling', 'websocket', 'flashsocket']`)
- `allowUpgrades` (`Boolean`): whether to allow tranport upgrades
- `allowUpgrades` (`Boolean`): whether to allow transport upgrades
(`true`)

@@ -225,3 +226,3 @@ - `cookie` (`String|Boolean`): name of the HTTP cookie that

- **Arguments**
- `String`: unicode string
- `String`: Unicode string
- `error`

@@ -238,3 +239,3 @@ - Fired when an error occurs.

- `packet`
- Called when a socket reseived a packet (`message`, `ping`)
- Called when a socket received a packet (`message`, `ping`)
- **Arguments**

@@ -282,3 +283,3 @@ - `type`: packet type

Engine.IO is powered by [debug](http://github.com/visionmedia/debug).
In order to see all the debug output, run your app with the env variable
In order to see all the debug output, run your app with the environment variable
`DEBUG` including the desired scope.

@@ -362,7 +363,7 @@

The main goal of `Engine` is ensuring the most reliable realtime communication.
Unlike the previous socket.io core, it always establishes a long-polling
Unlike the previous Socket.IO core, it always establishes a long-polling
connection first, then tries to upgrade to better transports that are "tested" on
the side.
During the lifetime of the socket.io projects, we've found countless drawbacks
During the lifetime of the Socket.IO projects, we've found countless drawbacks
to relying on `HTML5 WebSocket` or `Flash Socket` as the first connection

@@ -415,3 +416,3 @@ mechanisms.

As a result of our research, we've found that at least 3 personal security
applications block websocket traffic.
applications block WebSocket traffic.

@@ -422,3 +423,3 @@ 3. **Cloud application platforms**<br>

inevitably using long polling, but the seamless installation experience of
socket.io we strive for (_"require() it and it just works"_) disappears.
Socket.IO we strive for (_"require() it and it just works"_) disappears.

@@ -425,0 +426,0 @@ Some of these problems have solutions. In the case of proxies and personal programs,

@@ -226,10 +226,24 @@ /*global eio,eioc,listen,request,expect*/

});
it('should disallow bad requests', function (done) {
var engine = listen(function (port) {
request.get('http://localhost:%d/engine.io/default/'.s(port))
.query({ transport: 'websocket' })
.end(function (res) {
expect(res.status).to.be(400);
expect(res.body.code).to.be(3);
expect(res.body.message).to.be('Bad request');
done();
});
});
});
});
describe('close', function () {
it('should be able to access non-empty writeBuffer at closing', function(done) {
var opts = {allowUpgrades: false, pingInterval: 10, pingTimeout: 10 };
it('should be able to access non-empty writeBuffer at closing (server)', function(done) {
var opts = {allowUpgrades: false};
var engine = listen(opts, function (port) {
var socket = new eioc.Socket('http://localhost:%d'.s(port));
socket.sendPacket = function (){};
engine.on('connection', function (conn) {

@@ -249,2 +263,23 @@ conn.on('close', function (reason) {

it('should be able to access non-empty writeBuffer at closing (client)', function(done) {
var opts = {allowUpgrades: false};
var engine = listen(opts, function (port) {
var socket = new eioc.Socket('http://localhost:%d'.s(port));
socket.on('open', function() {
socket.on('close', function (reason) {
expect(socket.writeBuffer.length).to.be(1);
expect(socket.callbackBuffer.length).to.be(1);
setTimeout(function() {
expect(socket.writeBuffer.length).to.be(0);
expect(socket.callbackBuffer.length).to.be(0);
}, 10);
done();
});
socket.writeBuffer.push({ type: 'message', data: 'foo'});
socket.callbackBuffer.push(function() {});
socket.onError('');
});
});
});
it('should trigger on server if the client does not pong', function (done) {

@@ -402,2 +437,29 @@ var opts = { allowUpgrades: false, pingInterval: 5, pingTimeout: 5 };

it('should trigger when calling socket.close() in payload', function (done) {
var engine = listen({ allowUpgrades: false }, function (port) {
var socket = new eioc.Socket('ws://localhost:%d'.s(port))
engine.on('connection', function (conn) {
conn.send(null, function () {socket.close();});
conn.send('this should not be handled');
conn.on('close', function (reason) {
expect(reason).to.be('transport close');
done();
});
});
socket.on('open', function () {
socket.on('message', function (msg) {
expect(msg).to.not.be('this should not be handled');
});
socket.on('close', function (reason) {
expect(reason).to.be('forced close');
});
});
});
});
it('should abort upgrade if socket is closed (GH-35)', function (done) {

@@ -809,3 +871,181 @@ var engine = listen({ allowUpgrades: true }, function (port) {

describe('send', function() {
describe('writeBuffer', function() {
it('should not empty until `drain` event (polling)', function (done) {
var engine = listen({ allowUpgrades: false }, function (port) {
var socket = new eioc.Socket('ws://localhost:%d'.s(port), { transports: ['polling'] });
var totalEvents = 2;
socket.on('open', function() {
socket.send('a');
socket.send('b');
// writeBuffer should be nonempty, with 'a' still in it
expect(socket.writeBuffer.length).to.eql(2);
});
socket.transport.on('drain', function() {
expect(socket.writeBuffer.length).to.eql(--totalEvents);
totalEvents || done();
});
});
});
it('should not empty until `drain` event (websocket)', function (done) {
var engine = listen({ allowUpgrades: false }, function (port) {
var socket = new eioc.Socket('ws://localhost:%d'.s(port), { transports: ['websocket'] });
var totalEvents = 2;
socket.on('open', function() {
socket.send('a');
socket.send('b');
// writeBuffer should be nonempty, with 'a' still in it
expect(socket.writeBuffer.length).to.eql(2);
});
socket.transport.on('drain', function() {
expect(socket.writeBuffer.length).to.eql(--totalEvents);
totalEvents || done();
});
});
});
});
describe('callback', function() {
it('should execute in order when message sent (client) (polling)', function (done) {
var engine = listen({ allowUpgrades: false }, function (port) {
var socket = new eioc.Socket('ws://localhost:%d'.s(port), { transports: ['polling'] });
var i = 0;
var j = 0;
engine.on('connection', function(conn) {
conn.on('message', function(msg) {
conn.send(msg);
});
});
socket.on('open', function () {
socket.on('message', function(msg) {
// send another packet until we've sent 3 total
if (++i < 3) {
expect(i).to.eql(j);
sendFn();
} else {
done();
}
});
function sendFn() {
socket.send(j, (function(value) {
j++;
})(j));
}
sendFn();
});
});
});
it('should execute in order when message sent (client) (websocket)', function (done) {
var engine = listen({ allowUpgrades: false }, function (port) {
var socket = new eioc.Socket('ws://localhost:%d'.s(port), { transports: ['websocket'] });
var i = 0;
var j = 0;
engine.on('connection', function(conn) {
conn.on('message', function(msg) {
conn.send(msg);
});
});
socket.on('open', function () {
socket.on('message', function(msg) {
// send another packet until we've sent 3 total
if (++i < 3) {
expect(i).to.eql(j);
sendFn();
} else {
done();
}
});
function sendFn() {
socket.send(j, (function(value) {
j++;
})(j));
}
sendFn();
});
});
});
it('should execute in order with payloads (client) (polling)', function (done) {
var engine = listen({ allowUpgrades: false }, function (port) {
var socket = new eioc.Socket('ws://localhost:%d'.s(port), { transports: ['polling'] });
var i = 0;
var lastCbFired = 0;
engine.on('connection', function(conn) {
conn.on('message', function(msg) {
conn.send(msg);
});
});
socket.on('open', function () {
socket.on('message', function(msg) {
expect(msg).to.eql(i + 1);
i++;
});
function cb(value) {
expect(value).to.eql(lastCbFired + 1);
lastCbFired = value;
if (value == 3) {
done();
}
}
// 2 and 3 will be in the same payload
socket.once('flush', function() {
socket.send(2, function() { cb(2); });
socket.send(3, function() { cb(3); });
});
socket.send(1, function() { cb(1); });
});
});
});
it('should execute in order with payloads (client) (websocket)', function (done) {
var engine = listen({ allowUpgrades: false }, function (port) {
var socket = new eioc.Socket('ws://localhost:%d'.s(port), { transports: ['websocket'] });
var i = 0;
var lastCbFired = 0;
engine.on('connection', function(conn) {
conn.on('message', function(msg) {
conn.send(msg);
});
});
socket.on('open', function () {
socket.on('message', function(msg) {
expect(msg).to.eql(i + 1);
i++;
});
function cb(value) {
expect(value).to.eql(lastCbFired + 1);
lastCbFired = value;
if (value == 3) {
done();
}
}
// 2 and 3 will be in the same payload
socket.once('flush', function() {
socket.send(2, function() { cb(2); });
socket.send(3, function() { cb(3); });
});
socket.send(1, function() { cb(1); });
});
});
});
it('should execute when message sent (polling)', function (done) {

@@ -1159,162 +1399,2 @@ var engine = listen({ allowUpgrades: false }, function (port) {

describe('JSONP', function () {
before(function () {
///we have to override the browser's functionality for JSONP
document = {
body: {
appendChild: function () {}
, removeChild: function () {}
}
}
document.createElement = function (name) {
var self = this;
if('script' == name) {
var script = {};
script.__defineGetter__('parentNode', function () {
return document.body;
});
script.__defineSetter__('src', function (uri) {
request.get(uri).end(function(res) {
eval(res.text);
});
});
return script;
}
else if ('form' == name) {
var form = {
style: {}
, action: ''
, parentNode: { removeChild: function () {} }
, removeChild: function () {}
, setAttribute: function () {}
, appendChild: function (elem) { area: elem; }
, submit: function () {
request.post(this.action).type('form').send({ d: self.areaValue }).end(function (res) {});
}
}
return form;
}
else if ('textarea' == name) {
var textarea = {};
//a hack to be able to access the area data when form is sent
textarea.__defineSetter__('value', function (data) {
self.areaValue = data;
});
return textarea;
} else {
return {}
}
}
document.getElementsByTagName = function (name) {
return [{
parentNode: {
insertBefore: function () {}
}
}]
}
});
after(function () {
delete document.getElementsByTagName
, document.createElement
, document;
});
describe('handshake', function () {
it('should open with polling JSONP when requested', function (done) {
var engine = listen( { allowUpgrades: false, transports: ['polling'] }, function (port) {
var socket = new eioc.Socket('ws://localhost:' + port
, { transports: ['polling'], forceJSONP: true, upgrade: false });
engine.on('connection', function (socket) {
expect(socket.transport.name).to.be('polling');
expect(socket.transport.head).to.be('___eio[0](');
done();
});
});
});
});
describe('messages', function () {
it('should arrive from client to server and back (pollingJSONP)', function (done) {
var engine = listen( { allowUpgrades: false, transports: ['polling'] }, function (port) {
var socket = new eioc.Socket('ws://localhost:' + port
, { transports: ['polling'], forceJSONP: true, upgrade: false });
engine.on('connection', function (conn) {
conn.on('message', function (msg) {
conn.send('a');
});
});
socket.on('open', function () {
socket.send('a');
socket.on('message', function (msg) {
expect(socket.transport.query.j).to.not.be(undefined);
expect(msg).to.be('a');
done();
});
});
});
});
});
describe('close', function () {
it('should trigger when server closes a client', function (done) {
var engine = listen( { allowUpgrades: false, transports: ['polling'] }, function (port) {
var socket = new eioc.Socket('ws://localhost:' + port
, { transports: ['polling'], forceJSONP: true, upgrade: false })
, total = 2;
engine.on('connection', function (conn) {
conn.on('close', function (reason) {
expect(reason).to.be('forced close');
--total || done();
});
setTimeout(function () {
conn.close();
}, 10);
});
socket.on('open', function () {
socket.on('close', function (reason) {
expect(reason).to.be('transport close');
--total || done();
});
});
});
});
it('should trigger when client closes', function (done) {
var engine = listen( { allowUpgrades: false, transports: ['polling'] }, function (port) {
var socket = new eioc.Socket('ws://localhost:' + port
, { transports: ['polling'], forceJSONP: true, upgrade: false })
, total = 2;
engine.on('connection', function (conn) {
conn.on('close', function (reason) {
expect(reason).to.be('transport close');
--total || done();
});
});
socket.on('open', function () {
socket.send('a');
socket.on('close', function (reason) {
expect(reason).to.be('forced close');
--total || done();
});
setTimeout(function () {
socket.close();
}, 10);
});
});
});
});
});
});

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc