mirror of
https://github.com/socketio/socket.io.git
synced 2026-01-11 16:08:24 -05:00
Compare commits
84 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1bbc3951bd | ||
|
|
039eed2c2a | ||
|
|
6de022b180 | ||
|
|
a06331d29f | ||
|
|
e639685370 | ||
|
|
1f2e681ce2 | ||
|
|
397944fcbe | ||
|
|
27dada65b9 | ||
|
|
99f1ac9aae | ||
|
|
ee8d0fbae0 | ||
|
|
8e08a6d419 | ||
|
|
318ae87f50 | ||
|
|
2c1b61148d | ||
|
|
507054c0a8 | ||
|
|
dfceb006d7 | ||
|
|
4d83456f74 | ||
|
|
201aad83b1 | ||
|
|
72eb61d01f | ||
|
|
163a2a696e | ||
|
|
199a479ebc | ||
|
|
d383ff9662 | ||
|
|
416b550189 | ||
|
|
536b338a01 | ||
|
|
a06ae10895 | ||
|
|
35a85084b1 | ||
|
|
0c2b44a846 | ||
|
|
0f6ee2dbd9 | ||
|
|
68ac0d6d24 | ||
|
|
00ef9ca652 | ||
|
|
2febbce87d | ||
|
|
31c45862cb | ||
|
|
809e2bc3f8 | ||
|
|
10adcb089e | ||
|
|
5bc75ea944 | ||
|
|
cd4f6ad5e9 | ||
|
|
54e6c79014 | ||
|
|
237b234cab | ||
|
|
547440605d | ||
|
|
d763c8b6ea | ||
|
|
5d210ac46c | ||
|
|
ea89e520bc | ||
|
|
c8bf064b10 | ||
|
|
08fe191211 | ||
|
|
0842729c1f | ||
|
|
9720c76d10 | ||
|
|
0f127d2b7d | ||
|
|
e87e9e18e1 | ||
|
|
46351d38b8 | ||
|
|
ce68fb3105 | ||
|
|
94905500e4 | ||
|
|
f830899e39 | ||
|
|
3444f017bc | ||
|
|
0588dc0fc4 | ||
|
|
57425ab1dd | ||
|
|
463d7a16a1 | ||
|
|
5d74847123 | ||
|
|
f8b4d87331 | ||
|
|
e9928b2b1d | ||
|
|
d33553a4bd | ||
|
|
45a98970d7 | ||
|
|
0b4e4f6a67 | ||
|
|
656047536a | ||
|
|
97b7ab4fe2 | ||
|
|
6a435ce677 | ||
|
|
6aa553b211 | ||
|
|
024af23b2c | ||
|
|
b50d9f8f5d | ||
|
|
874c194210 | ||
|
|
f537560bcc | ||
|
|
7197d6a29d | ||
|
|
8dba96511d | ||
|
|
f8d1d33dfa | ||
|
|
736106a9e7 | ||
|
|
f5a8ac293a | ||
|
|
afc83ad65a | ||
|
|
b5f90923a2 | ||
|
|
c574f5f959 | ||
|
|
ba339cc460 | ||
|
|
aee4dd9a6d | ||
|
|
7d4aa670ad | ||
|
|
620f94a007 | ||
|
|
4823d20cf1 | ||
|
|
612d35194f | ||
|
|
a5ff1d854e |
54
History.md
54
History.md
@@ -1,4 +1,58 @@
|
||||
|
||||
1.0.3 / 2014-05-31
|
||||
==================
|
||||
|
||||
* package: bump `socket.io-client`
|
||||
* package: bump `socket.io-parser` for binary ACK fix
|
||||
* package: bump `engine.io` for binary UTF8 fix
|
||||
* example: fix XSS in chat example
|
||||
|
||||
1.0.2 / 2014-05-28
|
||||
==================
|
||||
|
||||
* package: bump `socket.io-parser` for windows fix
|
||||
|
||||
1.0.1 / 2014-05-28
|
||||
==================
|
||||
|
||||
* bump due to bad npm tag
|
||||
|
||||
1.0.0 / 2014-05-28
|
||||
==================
|
||||
|
||||
* stable release
|
||||
|
||||
1.0.0-pre5 / 2014-05-22
|
||||
=======================
|
||||
|
||||
* package: bump `socket.io-client` for parser fixes
|
||||
* package: bump `engine.io`
|
||||
|
||||
1.0.0-pre4 / 2014-05-19
|
||||
=======================
|
||||
|
||||
* package: bump client
|
||||
|
||||
1.0.0-pre3 / 2014-05-17
|
||||
=======================
|
||||
|
||||
* package: bump parser
|
||||
* package: bump engine.io
|
||||
|
||||
1.0.0-pre2 / 2014-04-27
|
||||
=======================
|
||||
|
||||
* package: bump `engine.io`
|
||||
* added backwards compatible of engine.io maxHttpBufferSize
|
||||
* added test that server and client using same protocol
|
||||
* added support for setting allowed origins
|
||||
* added information about logging
|
||||
* the set function in server can be used to set some attributes for BC
|
||||
* fix error in callback call 'done' instead of 'next' in docs
|
||||
* package: bump `socket.io-parser`
|
||||
* package: bump `expect.js`
|
||||
* added some new tests, including binary with acks
|
||||
|
||||
1.0.0-pre / 2014-03-14
|
||||
======================
|
||||
|
||||
|
||||
41
Readme.md
41
Readme.md
@@ -1,11 +1,7 @@
|
||||
|
||||
### This Readme corresponds to the upcoming 1.0 release. Please refer to http://socket.io for the current 0.9.x documentation.
|
||||
|
||||
<hr />
|
||||
|
||||
# socket.io
|
||||
|
||||
[](http://travis-ci.org/LearnBoost/socket.io)
|
||||
[](http://travis-ci.org/Automattic/socket.io)
|
||||
[](http://badge.fury.io/js/socket.io)
|
||||
|
||||
## How to use
|
||||
@@ -31,7 +27,7 @@ io.on('connection', function(socket){});
|
||||
io.listen(3000);
|
||||
```
|
||||
|
||||
### In conjunction with `Express`
|
||||
### In conjunction with Express
|
||||
|
||||
Starting with **3.0**, express applications have become request handler
|
||||
functions that you pass to `http` or `http` `Server` instances. You need
|
||||
@@ -42,11 +38,11 @@ function.
|
||||
var app = require('express')();
|
||||
var server = require('http').Server(app);
|
||||
var io = require('socket.io')(server);
|
||||
io.on('connection', function(){ // … });
|
||||
io.on('connection', function(){ /* … */ });
|
||||
server.listen(3000);
|
||||
```
|
||||
|
||||
### In conjunction with `Koa`
|
||||
### In conjunction with Koa
|
||||
|
||||
Like Express.JS, Koa works by exposing an application as a request
|
||||
handler function, but only by calling the `callback` method.
|
||||
@@ -55,7 +51,7 @@ handler function, but only by calling the `callback` method.
|
||||
var app = require('koa')();
|
||||
var server = require('http').Server(app.callback());
|
||||
var io = require('socket.io')(server);
|
||||
io.on('connection', function(){ // … });
|
||||
io.on('connection', function(){ /* … */ });
|
||||
server.listen(3000);
|
||||
```
|
||||
|
||||
@@ -130,10 +126,17 @@ server.listen(3000);
|
||||
|
||||
Sets the adapter `v`. Defaults to an instance of the `Adapter` that
|
||||
ships with socket.io which is memory based. See
|
||||
[socket.io-adapter](https://github.com/learnboost/socket.io-adapter).
|
||||
[socket.io-adapter](https://github.com/Automattic/socket.io-adapter).
|
||||
|
||||
If no arguments are supplied this method returns the current value.
|
||||
|
||||
### Server#origins(v:String):Server
|
||||
|
||||
Sets the allowed origins `v`. Defaults to any origins being allowed.
|
||||
|
||||
If no arguments are supplied this method returns the current value.
|
||||
|
||||
|
||||
### Server#sockets:Namespace
|
||||
|
||||
The default (`/`) namespace.
|
||||
@@ -220,7 +223,7 @@ server.listen(3000);
|
||||
var io = require('socket.io')();
|
||||
io.use(function(socket, next){
|
||||
if (socket.request.headers.cookie) return next();
|
||||
done(new Error('Authentication error'));
|
||||
next(new Error('Authentication error'));
|
||||
});
|
||||
```
|
||||
|
||||
@@ -282,7 +285,7 @@ server.listen(3000);
|
||||
|
||||
The mechanics of joining rooms are handled by the `Adapter`
|
||||
that has been configured (see `Server#adapter` above), defaulting to
|
||||
[socket.io-adapter](https://github.com/socket.io/socket.io-adapter).
|
||||
[socket.io-adapter](https://github.com/Automattic/socket.io-adapter).
|
||||
|
||||
### Socket#leave(name:String[, fn:Function]):Socket
|
||||
|
||||
@@ -293,7 +296,7 @@ server.listen(3000);
|
||||
|
||||
The mechanics of leaving rooms are handled by the `Adapter`
|
||||
that has been configured (see `Server#adapter` above), defaulting to
|
||||
[socket.io-adapter](https://github.com/socket.io/socket.io-adapter).
|
||||
[socket.io-adapter](https://github.com/Automattic/socket.io-adapter).
|
||||
|
||||
### Socket#to(room:String):Socket
|
||||
### Socket#in(room:String):Socket
|
||||
@@ -326,6 +329,18 @@ server.listen(3000);
|
||||
originated the engine.io connection. Useful for accessing
|
||||
request headers such as `Cookie` or `User-Agent`.
|
||||
|
||||
## Debug / logging
|
||||
|
||||
Socket.IO is powered by [debug](http://github.com/visionmedia/debug).
|
||||
In order to see all the debug output, run your app with the environment variable
|
||||
`DEBUG` including the desired scope.
|
||||
|
||||
To see the output from all of Socket.IO's debugging scopes you can use:
|
||||
|
||||
```
|
||||
DEBUG=socket.io* node myapp
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
|
||||
@@ -70,8 +70,8 @@ $(function() {
|
||||
|
||||
// Log a message
|
||||
function log (message, options) {
|
||||
var el = '<li class="log">' + message + '</li>';
|
||||
addMessageElement(el, options);
|
||||
var $el = $('<li>').addClass('log').text(message);
|
||||
addMessageElement($el, options);
|
||||
}
|
||||
|
||||
// Adds the visual chat message to the message list
|
||||
@@ -84,16 +84,17 @@ $(function() {
|
||||
$typingMessages.remove();
|
||||
}
|
||||
|
||||
var colorStyle = 'style="color:' + getUsernameColor(data.username) + '"';
|
||||
var usernameDiv = '<span class="username"' + colorStyle + '>' +
|
||||
data.username + '</span>';
|
||||
var messageBodyDiv = '<span class="messageBody">' +
|
||||
data.message + '</span>';
|
||||
var $usernameDiv = $('<span class="username"/>')
|
||||
.text(data.username)
|
||||
.css('color', getUsernameColor(data.username));
|
||||
var $messageBodyDiv = $('<span class="messageBody">')
|
||||
.text(data.message);
|
||||
|
||||
var typingClass = data.typing ? 'typing' : '';
|
||||
var messageDiv = '<li class="message ' + typingClass + '">' +
|
||||
usernameDiv + messageBodyDiv + '</li>';
|
||||
var $messageDiv = $(messageDiv).data('username', data.username);
|
||||
var $messageDiv = $('<li class="message"/>')
|
||||
.data('username', data.username)
|
||||
.addClass(typingClass)
|
||||
.append($usernameDiv, $messageBodyDiv);
|
||||
|
||||
addMessageElement($messageDiv, options);
|
||||
}
|
||||
@@ -145,7 +146,7 @@ $(function() {
|
||||
|
||||
// Prevents input from having injected markup
|
||||
function cleanInput (input) {
|
||||
return $('<div/>').text(input).html() || input;
|
||||
return $('<div/>').text(input).text();
|
||||
}
|
||||
|
||||
// Updates the typing event
|
||||
|
||||
@@ -25,6 +25,7 @@ html, body {
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
/* Pages */
|
||||
|
||||
@@ -199,9 +199,10 @@ Client.prototype.onclose = function(reason){
|
||||
this.destroy();
|
||||
|
||||
// `nsps` and `sockets` are cleaned up seamlessly
|
||||
this.sockets.forEach(function(socket){
|
||||
var socket;
|
||||
while (socket = this.sockets.shift()) {
|
||||
socket.onclose(reason);
|
||||
});
|
||||
}
|
||||
|
||||
this.decoder.destroy(); // clean up decoder
|
||||
};
|
||||
|
||||
83
lib/index.js
83
lib/index.js
@@ -13,6 +13,7 @@ var Client = require('./client');
|
||||
var Namespace = require('./namespace');
|
||||
var Adapter = require('socket.io-adapter');
|
||||
var debug = require('debug')('socket.io:server');
|
||||
var url = require('url');
|
||||
|
||||
/**
|
||||
* Module exports.
|
||||
@@ -45,10 +46,40 @@ function Server(srv, opts){
|
||||
this.path(opts.path || '/socket.io');
|
||||
this.serveClient(false !== opts.serveClient);
|
||||
this.adapter(opts.adapter || Adapter);
|
||||
this.origins(opts.origins || '*:*');
|
||||
this.sockets = this.of('/');
|
||||
if (srv) this.attach(srv, opts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Server request verification function, that checks for allowed origins
|
||||
*
|
||||
* @param {http.IncomingMessage} request
|
||||
* @param {Function} callback to be called with the result: `fn(err, success)`
|
||||
*/
|
||||
|
||||
Server.prototype.checkRequest = function(req, fn) {
|
||||
var origin = req.headers.origin || req.headers.referer;
|
||||
|
||||
// file:// URLs produce a null Origin which can't be authorized via echo-back
|
||||
if ('null' == origin) origin = '*';
|
||||
|
||||
if (this._origins.indexOf('*:*') !== -1) return fn(null, true);
|
||||
if (origin) {
|
||||
try {
|
||||
var parts = url.parse(origin);
|
||||
parts.port = parts.port || 80;
|
||||
var ok =
|
||||
~this._origins.indexOf(parts.hostname + ':' + parts.port) ||
|
||||
~this._origins.indexOf(parts.hostname + ':*') ||
|
||||
~this._origins.indexOf('*:' + parts.port);
|
||||
return fn(null, !!ok);
|
||||
} catch (ex) {
|
||||
}
|
||||
}
|
||||
fn(null, false);
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets/gets whether client code is being served.
|
||||
*
|
||||
@@ -63,13 +94,42 @@ Server.prototype.serveClient = function(v){
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Old settings for backwards compatibility
|
||||
*/
|
||||
|
||||
var oldSettings = {
|
||||
"transports": "transports",
|
||||
"heartbeat timeout": "pingTimeout",
|
||||
"heartbeat interval": "pingInterval",
|
||||
"destroy buffer size": "maxHttpBufferSize"
|
||||
};
|
||||
|
||||
/**
|
||||
* Backwards compatiblity.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Server.prototype.set = function(){
|
||||
Server.prototype.set = function(key, val){
|
||||
if ('authorization' == key && val) {
|
||||
this.use(function(socket, next) {
|
||||
val(socket.request, function(err, authorized) {
|
||||
if (err) return next(new Error(err));
|
||||
if (!authorized) return next(new Error('Not authorized'));
|
||||
next();
|
||||
});
|
||||
});
|
||||
} else if ('origins' == key && val) {
|
||||
this.origins(val);
|
||||
} else if ('resource' == key) {
|
||||
this.path(val);
|
||||
} else if (oldSettings[key] && this.eio[oldSettings[key]]) {
|
||||
this.eio[oldSettings[key]] = val;
|
||||
} else {
|
||||
console.error('Option %s is not valid. Please refer to the README.', key);
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
@@ -104,6 +164,21 @@ Server.prototype.adapter = function(v){
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the allowed origins for requests.
|
||||
*
|
||||
* @param {String} origins
|
||||
* @return {Server|Adapter} self when setting or value when getting
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Server.prototype.origins = function(v){
|
||||
if (!arguments.length) return this._origins;
|
||||
|
||||
this._origins = v;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Attaches socket.io to a server or port.
|
||||
*
|
||||
@@ -139,16 +214,18 @@ Server.prototype.attach = function(srv, opts){
|
||||
// set engine.io path to `/socket.io`
|
||||
opts = opts || {};
|
||||
opts.path = opts.path || '/socket.io';
|
||||
// set origins verification
|
||||
opts.allowRequest = this.checkRequest.bind(this);
|
||||
|
||||
// initialize engine
|
||||
debug('creating engine.io instance with opts %j', opts);
|
||||
var eio = engine.attach(srv, opts);
|
||||
this.eio = engine.attach(srv, opts);
|
||||
|
||||
// attach static file serving
|
||||
if (this._serveClient) this.attachServe(srv);
|
||||
|
||||
// bind to engine events
|
||||
this.bind(eio);
|
||||
this.bind(this.eio);
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
var Emitter = require('events').EventEmitter;
|
||||
var parser = require('socket.io-parser');
|
||||
var url = require('url');
|
||||
var debug = require('debug')('socket.io:socket');
|
||||
var hasBin = require('has-binary-data');
|
||||
|
||||
@@ -65,6 +66,7 @@ function Socket(nsp, client){
|
||||
this.acks = {};
|
||||
this.connected = true;
|
||||
this.disconnected = false;
|
||||
this.handshake = this.buildHandshake();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -95,6 +97,25 @@ Socket.prototype.__defineGetter__('request', function(){
|
||||
return this.conn.request;
|
||||
});
|
||||
|
||||
/**
|
||||
* Builds the `handshake` BC object
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Socket.prototype.buildHandshake = function(){
|
||||
return {
|
||||
headers: this.request.headers,
|
||||
time: (new Date) + '',
|
||||
address: this.request.connection.address(),
|
||||
xdomain: !!this.request.headers.origin,
|
||||
secure: !!this.request.connection.encrypted,
|
||||
issued: +(new Date),
|
||||
url: this.request.url,
|
||||
query: url.parse(this.request.url, true).query || {}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Emits to this client.
|
||||
*
|
||||
@@ -272,6 +293,10 @@ Socket.prototype.onpacket = function(packet){
|
||||
this.onack(packet);
|
||||
break;
|
||||
|
||||
case parser.BINARY_ACK:
|
||||
this.onack(packet);
|
||||
break;
|
||||
|
||||
case parser.DISCONNECT:
|
||||
this.ondisconnect();
|
||||
break;
|
||||
@@ -315,9 +340,11 @@ Socket.prototype.ack = function(id){
|
||||
if (sent) return;
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
debug('sending ack %j', args);
|
||||
|
||||
var type = hasBin(args) ? parser.BINARY_ACK : parser.ACK;
|
||||
self.packet({
|
||||
id: id,
|
||||
type: parser.ACK,
|
||||
type: type,
|
||||
data: args
|
||||
});
|
||||
};
|
||||
|
||||
17
package.json
17
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "socket.io",
|
||||
"version": "1.0.0-pre",
|
||||
"version": "1.0.3",
|
||||
"description": "node.js realtime framework server",
|
||||
"keywords": [
|
||||
"realtime",
|
||||
@@ -11,21 +11,26 @@
|
||||
"socket",
|
||||
"io"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/LearnBoost/socket.io"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "make test"
|
||||
},
|
||||
"dependencies": {
|
||||
"engine.io": "1.0.4",
|
||||
"socket.io-parser": "2.1.1",
|
||||
"socket.io-client": "1.0.0-pre",
|
||||
"engine.io": "1.2.2",
|
||||
"socket.io-parser": "2.2.0",
|
||||
"socket.io-client": "1.0.3",
|
||||
"socket.io-adapter": "0.2.0",
|
||||
"has-binary-data": "0.1.0",
|
||||
"has-binary-data": "0.1.1",
|
||||
"debug": "0.7.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"mocha": "1.16.2",
|
||||
"expect.js": "0.2.1",
|
||||
"expect.js": "0.3.1",
|
||||
"supertest": "0.8.2",
|
||||
"superagent": "0.17.0",
|
||||
"istanbul": "0.2.3"
|
||||
},
|
||||
"contributors": [
|
||||
|
||||
BIN
test/fixtures/big.jpg
vendored
Normal file
BIN
test/fixtures/big.jpg
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.5 MiB |
174066
test/fixtures/big.json
vendored
Normal file
174066
test/fixtures/big.json
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@@ -20,6 +20,121 @@ function client(srv, nsp, opts){
|
||||
}
|
||||
|
||||
describe('socket.io', function(){
|
||||
|
||||
it('should be the same version as client', function(){
|
||||
var version = require('../package').version;
|
||||
expect(version).to.be(require('socket.io-client/package').version);
|
||||
});
|
||||
|
||||
describe('set', function() {
|
||||
it('should be able to set ping timeout to engine.io', function() {
|
||||
var srv = io(http());
|
||||
srv.set('heartbeat timeout', 10);
|
||||
expect(srv.eio.pingTimeout).to.be(10);
|
||||
});
|
||||
|
||||
it('should be able to set ping interval to engine.io', function() {
|
||||
var srv = io(http());
|
||||
srv.set('heartbeat interval', 10);
|
||||
expect(srv.eio.pingInterval).to.be(10);
|
||||
});
|
||||
|
||||
it('should be able to set transports to engine.io', function() {
|
||||
var srv = io(http());
|
||||
srv.set('transports', ['polling']);
|
||||
expect(srv.eio.transports).to.eql(['polling']);
|
||||
});
|
||||
|
||||
it('should be able to set maxHttpBufferSize to engine.io', function() {
|
||||
var srv = io(http());
|
||||
srv.set('destroy buffer size', 10);
|
||||
expect(srv.eio.maxHttpBufferSize).to.eql(10);
|
||||
});
|
||||
|
||||
it('should be able to set path with setting resource', function() {
|
||||
var srv = io(http());
|
||||
srv.set('resource', '/random');
|
||||
expect(srv.path()).to.be('/random');
|
||||
});
|
||||
|
||||
it('should be able to set origins to engine.io', function() {
|
||||
var srv = io(http());
|
||||
srv.set('origins', 'http://hostname.com:*');
|
||||
expect(srv.origins()).to.be('http://hostname.com:*');
|
||||
});
|
||||
|
||||
it('should be able to set authorization and send error packet', function(done) {
|
||||
var httpSrv = http();
|
||||
var srv = io(httpSrv);
|
||||
srv.set('authorization', function(o, f) { f(null, false); });
|
||||
|
||||
var socket = client(httpSrv);
|
||||
socket.on('connect', function(){
|
||||
expect().fail();
|
||||
});
|
||||
socket.on('error', function(err) {
|
||||
expect(err).to.be('Not authorized');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should be able to set authorization and succeed', function(done) {
|
||||
var httpSrv = http();
|
||||
var srv = io(httpSrv);
|
||||
srv.set('authorization', function(o, f) { f(null, true); });
|
||||
|
||||
srv.on('connection', function(s) {
|
||||
s.on('yoyo', function(data) {
|
||||
expect(data).to.be('data');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
var socket = client(httpSrv);
|
||||
socket.on('connect', function(){
|
||||
socket.emit('yoyo', 'data');
|
||||
});
|
||||
|
||||
socket.on('error', function(err) {
|
||||
expect().fail();
|
||||
});
|
||||
});
|
||||
|
||||
it('should set the handshake BC object', function(done){
|
||||
var httpSrv = http();
|
||||
var srv = io(httpSrv);
|
||||
|
||||
srv.on('connection', function(s) {
|
||||
expect(s.handshake).to.not.be(undefined);
|
||||
|
||||
// Headers set and has some valid properties
|
||||
expect(s.handshake.headers).to.be.an('object');
|
||||
expect(s.handshake.headers['user-agent']).to.be('node-XMLHttpRequest');
|
||||
|
||||
// Time set and is valid looking string
|
||||
expect(s.handshake.time).to.be.a('string');
|
||||
expect(s.handshake.time.split(' ').length > 0); // Is "multipart" string representation
|
||||
|
||||
// Address, xdomain, secure, issued and url set
|
||||
expect(s.handshake.address).to.not.be(undefined);
|
||||
expect(s.handshake.xdomain).to.be.a('boolean');
|
||||
expect(s.handshake.secure).to.be.a('boolean');
|
||||
expect(s.handshake.issued).to.be.a('number');
|
||||
expect(s.handshake.url).to.be.a('string');
|
||||
|
||||
// Query set and has some right properties
|
||||
expect(s.handshake.query).to.be.an('object');
|
||||
expect(s.handshake.query.EIO).to.not.be(undefined);
|
||||
expect(s.handshake.query.transport).to.not.be(undefined);
|
||||
expect(s.handshake.query.t).to.not.be(undefined);
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
var socket = client(httpSrv);
|
||||
});
|
||||
});
|
||||
|
||||
describe('server attachment', function(){
|
||||
describe('http.Server', function(){
|
||||
var clientVersion = require('socket.io-client/package').version;
|
||||
@@ -87,6 +202,13 @@ describe('socket.io', function(){
|
||||
.expect(200, done);
|
||||
});
|
||||
|
||||
it('should be bound as a string', function(done) {
|
||||
var sockets = io('54020');
|
||||
request('http://localhost:54020')
|
||||
.get('/socket.io/socket.io.js')
|
||||
.expect(200, done);
|
||||
});
|
||||
|
||||
it('with listen', function(done){
|
||||
var sockets = io().listen(54011);
|
||||
request('http://localhost:54011')
|
||||
@@ -103,6 +225,42 @@ describe('socket.io', function(){
|
||||
});
|
||||
});
|
||||
|
||||
describe('handshake', function(){
|
||||
var request = require('superagent');
|
||||
|
||||
it('should disallow request when origin defined and none specified', function(done) {
|
||||
var sockets = io({ origins: 'http://foo.example:*' }).listen('54013');
|
||||
request.get('http://localhost:54013/socket.io/default/')
|
||||
.query({ transport: 'polling' })
|
||||
.end(function (err, res) {
|
||||
expect(res.status).to.be(400);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should disallow request when origin defined and a different one specified', function(done) {
|
||||
var sockets = io({ origins: 'http://foo.example:*' }).listen('54014');
|
||||
request.get('http://localhost:54014/socket.io/default/')
|
||||
.query({ transport: 'polling' })
|
||||
.set('origin', 'http://herp.derp')
|
||||
.end(function (err, res) {
|
||||
expect(res.status).to.be(400);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should allow request when origin defined an the same is specified', function(done) {
|
||||
var sockets = io({ origins: 'http://foo.example:*' }).listen('54015');
|
||||
request.get('http://localhost:54015/socket.io/default/')
|
||||
.set('origin', 'http://foo.example')
|
||||
.query({ transport: 'polling' })
|
||||
.end(function (err, res) {
|
||||
expect(res.status).to.be(200);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('namespaces', function(){
|
||||
var Socket = require('../lib/socket');
|
||||
var Namespace = require('../lib/namespace');
|
||||
@@ -237,6 +395,33 @@ describe('socket.io', function(){
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('should disconnect both default and custom namespace upon disconnect', function(done){
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
srv.listen(function(){
|
||||
var lolcats = client(srv, '/lolcats');
|
||||
var total = 2;
|
||||
var totald = 2;
|
||||
var s;
|
||||
sio.of('/', function(socket){
|
||||
socket.on('disconnect', function(reason){
|
||||
--totald || done();
|
||||
});
|
||||
--total || close();
|
||||
});
|
||||
sio.of('/lolcats', function(socket){
|
||||
s = socket;
|
||||
socket.on('disconnect', function(reason){
|
||||
--totald || done();
|
||||
});
|
||||
--total || close();
|
||||
});
|
||||
function close(){
|
||||
s.disconnect(true);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -288,6 +473,28 @@ describe('socket.io', function(){
|
||||
});
|
||||
});
|
||||
|
||||
it('should emit events with utf8 multibyte character', function(done) {
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
srv.listen(function(){
|
||||
var socket = client(srv);
|
||||
var i = 0;
|
||||
socket.on('hoot', function(a){
|
||||
expect(a).to.be('utf8 — string');
|
||||
i++;
|
||||
|
||||
if (3 == i) {
|
||||
done();
|
||||
}
|
||||
});
|
||||
sio.on('connection', function(s){
|
||||
s.emit('hoot', 'utf8 — string');
|
||||
s.emit('hoot', 'utf8 — string');
|
||||
s.emit('hoot', 'utf8 — string');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should emit events with binary data', function(done){
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
@@ -464,6 +671,76 @@ describe('socket.io', function(){
|
||||
});
|
||||
});
|
||||
|
||||
it('should receive events with binary args and callbacks', function(done) {
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
srv.listen(function(){
|
||||
var socket = client(srv);
|
||||
sio.on('connection', function(s){
|
||||
s.on('woot', function(buf, fn){
|
||||
expect(Buffer.isBuffer(buf)).to.be(true);
|
||||
fn(1, 2);
|
||||
});
|
||||
socket.emit('woot', new Buffer(3), function(a, b){
|
||||
expect(a).to.be(1);
|
||||
expect(b).to.be(2);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should emit events with binary args and callback', function(done){
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
srv.listen(function(){
|
||||
var socket = client(srv);
|
||||
sio.on('connection', function(s){
|
||||
socket.on('hi', function(a, fn){
|
||||
expect(Buffer.isBuffer(a)).to.be(true);
|
||||
fn();
|
||||
});
|
||||
s.emit('hi', new Buffer(4), function(){
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should emit events and receive binary data in a callback', function(done) {
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
srv.listen(function(){
|
||||
var socket = client(srv);
|
||||
sio.on('connection', function(s){
|
||||
socket.on('hi', function(fn){
|
||||
fn(new Buffer(1));
|
||||
});
|
||||
s.emit('hi', function(a){
|
||||
expect(Buffer.isBuffer(a)).to.be(true);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should receive events and pass binary data in a callback', function(done) {
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
srv.listen(function(){
|
||||
var socket = client(srv);
|
||||
sio.on('connection', function(s){
|
||||
s.on('woot', function(fn){
|
||||
fn(new Buffer(2));
|
||||
});
|
||||
socket.emit('woot', function(a){
|
||||
expect(Buffer.isBuffer(a)).to.be(true);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should have access to the client', function(done){
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
@@ -501,6 +778,76 @@ describe('socket.io', function(){
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should see query parameters in the request', function(done) {
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
srv.listen(function() {
|
||||
var addr = srv.listen().address();
|
||||
var url = 'ws://' + addr.address + ':' + addr.port + '?key1=1&key2=2';
|
||||
var socket = ioc(url);
|
||||
sio.on('connection', function(s) {
|
||||
var parsed = require('url').parse(s.request.url);
|
||||
var query = require('querystring').parse(parsed.query);
|
||||
expect(query.key1).to.be('1');
|
||||
expect(query.key2).to.be('2');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle very large json', function(done){
|
||||
this.timeout();
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
var received = 0;
|
||||
srv.listen(function(){
|
||||
var socket = client(srv);
|
||||
socket.on('big', function(a){
|
||||
expect(Buffer.isBuffer(a.json)).to.be(false);
|
||||
if (++received == 3)
|
||||
done();
|
||||
else
|
||||
socket.emit('big', a);
|
||||
});
|
||||
sio.on('connection', function(s){
|
||||
fs.readFile(join(__dirname, 'fixtures', 'big.json'), function(err, data){
|
||||
if (err) return done(err);
|
||||
data = JSON.parse(data);
|
||||
s.emit('big', {hello: 'friend', json: data});
|
||||
});
|
||||
s.on('big', function(a){
|
||||
s.emit('big', a);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle very large binary data', function(done){
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
var received = 0;
|
||||
srv.listen(function(){
|
||||
var socket = client(srv);
|
||||
socket.on('big', function(a){
|
||||
expect(Buffer.isBuffer(a.image)).to.be(true);
|
||||
if (++received == 3)
|
||||
done();
|
||||
else
|
||||
socket.emit('big', a);
|
||||
});
|
||||
sio.on('connection', function(s){
|
||||
fs.readFile(join(__dirname, 'fixtures', 'big.jpg'), function(err, data){
|
||||
if (err) return done(err);
|
||||
s.emit('big', {hello: 'friend', image: data});
|
||||
});
|
||||
s.on('big', function(a){
|
||||
expect(Buffer.isBuffer(a.image)).to.be(true);
|
||||
s.emit('big', a);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('messaging many', function(){
|
||||
|
||||
Reference in New Issue
Block a user