Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

socket.io

Package Overview
Dependencies
Maintainers
1
Versions
159
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

socket.io - npm Package Compare versions

Comparing version 0.7.11 to 0.8.0

lib/transports/websocket/7.js

8

History.md
0.8.0 / 2011-08-28
==================
* Updated to work with two-level websocket versioning. [einaros]
* Added hybi07 support. [einaros]
* Added hybi10 support. [einaros]
* Added http referrer verification to manager.js verifyOrigin. [einaors]
0.7.11 / 2011-08-27

@@ -3,0 +11,0 @@ ===================

19

lib/manager.js

@@ -869,3 +869,3 @@ /*!

Manager.prototype.verifyOrigin = function (request) {
var origin = request.headers.origin
var origin = request.headers.origin || request.headers.referer
, origins = this.get('origins');

@@ -882,10 +882,15 @@

var parts = url.parse(origin);
return
~origins.indexOf(parts.host + ':' + parts.port) ||
~origins.indexOf(parts.host + ':*') ||
var ok =
~origins.indexOf(parts.hostname + ':' + parts.port) ||
~origins.indexOf(parts.hostname + ':*') ||
~origins.indexOf('*:' + parts.port);
} catch (ex) {}
if (!ok) this.log.warn('illegal origin: ' + origin);
return ok;
} catch (ex) {
this.log.warn('error parsing origin');
}
}
else {
this.log.warn('origin missing from handshake, yet required by config');
}
return false;

@@ -892,0 +897,0 @@ };

@@ -18,3 +18,3 @@

exports.version = '0.7.11';
exports.version = '0.8.0';

@@ -21,0 +21,0 @@ /**

@@ -27,3 +27,3 @@

function FlashSocket (mng, data, req) {
WebSocket.call(this, mng, data, req);
return WebSocket.call(this, mng, data, req);
}

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

@@ -12,6 +12,3 @@

var Transport = require('../transport')
, EventEmitter = process.EventEmitter
, crypto = require('crypto')
, parser = require('../parser');
var protocolVersions = require('./websocket/');

@@ -32,321 +29,7 @@ /**

function WebSocket (mng, data, req) {
// parser
var self = this;
this.parser = new Parser();
this.parser.on('data', function (packet) {
self.log.debug(self.name + ' received data packet', packet);
self.onMessage(parser.decodePacket(packet));
});
this.parser.on('close', function () {
self.end();
});
this.parser.on('error', function () {
self.end();
});
Transport.call(this, mng, data, req);
};
/**
* Inherits from Transport.
*/
WebSocket.prototype.__proto__ = Transport.prototype;
/**
* Transport name
*
* @api public
*/
WebSocket.prototype.name = 'websocket';
/**
* Called when the socket connects.
*
* @api private
*/
WebSocket.prototype.onSocketConnect = function () {
var self = this;
this.socket.setNoDelay(true);
this.buffer = true;
this.buffered = [];
if (this.req.headers.upgrade !== 'WebSocket') {
this.log.warn(this.name + ' connection invalid');
this.end();
return;
var version = req.headers['sec-websocket-version'];
if (typeof version !== 'undefined' && typeof protocolVersions[version] !== 'undefined') {
return new protocolVersions[version](mng, data, req);
}
var origin = this.req.headers.origin
, location = (this.socket.encrypted ? 'wss' : 'ws')
+ '://' + this.req.headers.host + this.req.url
, waitingForNonce = false;
if (this.req.headers['sec-websocket-key1']) {
// If we don't have the nonce yet, wait for it (HAProxy compatibility).
if (! (this.req.head && this.req.head.length >= 8)) {
waitingForNonce = true;
}
var headers = [
'HTTP/1.1 101 WebSocket Protocol Handshake'
, 'Upgrade: WebSocket'
, 'Connection: Upgrade'
, 'Sec-WebSocket-Origin: ' + origin
, 'Sec-WebSocket-Location: ' + location
];
if (this.req.headers['sec-websocket-protocol']){
headers.push('Sec-WebSocket-Protocol: '
+ this.req.headers['sec-websocket-protocol']);
}
} else {
var headers = [
'HTTP/1.1 101 Web Socket Protocol Handshake'
, 'Upgrade: WebSocket'
, 'Connection: Upgrade'
, 'WebSocket-Origin: ' + origin
, 'WebSocket-Location: ' + location
];
}
try {
this.socket.write(headers.concat('', '').join('\r\n'));
this.socket.setTimeout(0);
this.socket.setNoDelay(true);
this.socket.setEncoding('utf8');
} catch (e) {
this.end();
return;
}
if (waitingForNonce) {
this.socket.setEncoding('binary');
} else if (this.proveReception(headers)) {
self.flush();
}
var headBuffer = '';
this.socket.on('data', function (data) {
if (waitingForNonce) {
headBuffer += data;
if (headBuffer.length < 8) {
return;
}
// Restore the connection to utf8 encoding after receiving the nonce
self.socket.setEncoding('utf8');
waitingForNonce = false;
// Stuff the nonce into the location where it's expected to be
self.req.head = headBuffer.substr(0, 8);
headBuffer = '';
if (self.proveReception(headers)) {
self.flush();
}
return;
}
self.parser.add(data);
});
return new protocolVersions['default'](mng, data, req);
};
/**
* Writes to the socket.
*
* @api private
*/
WebSocket.prototype.write = function (data) {
if (this.open) {
this.drained = false;
if (this.buffer) {
this.buffered.push(data);
return this;
}
var length = Buffer.byteLength(data)
, buffer = new Buffer(2 + length);
buffer.write('\u0000', 'binary');
buffer.write(data, 1, 'utf8');
buffer.write('\uffff', 1 + length, 'binary');
try {
if (this.socket.write(buffer)) {
this.drained = true;
}
} catch (e) {
this.end();
}
this.log.debug(this.name + ' writing', data);
}
};
/**
* Flushes the internal buffer
*
* @api private
*/
WebSocket.prototype.flush = function () {
this.buffer = false;
for (var i = 0, l = this.buffered.length; i < l; i++) {
this.write(this.buffered.splice(0, 1)[0]);
}
};
/**
* Finishes the handshake.
*
* @api private
*/
WebSocket.prototype.proveReception = function (headers) {
var self = this
, k1 = this.req.headers['sec-websocket-key1']
, k2 = this.req.headers['sec-websocket-key2'];
if (k1 && k2){
var md5 = crypto.createHash('md5');
[k1, k2].forEach(function (k) {
var n = parseInt(k.replace(/[^\d]/g, ''))
, spaces = k.replace(/[^ ]/g, '').length;
if (spaces === 0 || n % spaces !== 0){
self.log.warn('Invalid ' + self.name + ' key: "' + k + '".');
self.end();
return false;
}
n /= spaces;
md5.update(String.fromCharCode(
n >> 24 & 0xFF,
n >> 16 & 0xFF,
n >> 8 & 0xFF,
n & 0xFF));
});
md5.update(this.req.head.toString('binary'));
try {
this.socket.write(md5.digest('binary'), 'binary');
} catch (e) {
this.end();
}
}
return true;
};
/**
* Writes a payload.
*
* @api private
*/
WebSocket.prototype.payload = function (msgs) {
for (var i = 0, l = msgs.length; i < l; i++) {
this.write(msgs[i]);
}
return this;
};
/**
* Closes the connection.
*
* @api private
*/
WebSocket.prototype.doClose = function () {
this.socket.end();
};
/**
* WebSocket parser
*
* @api public
*/
function Parser () {
this.buffer = '';
this.i = 0;
};
/**
* Inherits from EventEmitter.
*/
Parser.prototype.__proto__ = EventEmitter.prototype;
/**
* Adds data to the buffer.
*
* @api public
*/
Parser.prototype.add = function (data) {
this.buffer += data;
this.parse();
};
/**
* Parses the buffer.
*
* @api private
*/
Parser.prototype.parse = function () {
for (var i = this.i, chr, l = this.buffer.length; i < l; i++){
chr = this.buffer[i];
if (this.buffer.length == 2 && this.buffer[1] == '\u0000') {
this.emit('close');
this.buffer = '';
this.i = 0;
return;
}
if (i === 0){
if (chr != '\u0000')
this.error('Bad framing. Expected null byte as first frame');
else
continue;
}
if (chr == '\ufffd'){
this.emit('data', this.buffer.substr(1, i - 1));
this.buffer = this.buffer.substr(i + 1);
this.i = 0;
return this.parse();
}
}
};
/**
* Handles an error
*
* @api private
*/
Parser.prototype.error = function (reason) {
this.buffer = '';
this.i = 0;
this.emit('error', reason);
return this;
};

@@ -26,1 +26,26 @@

};
/**
* Unpacks a buffer to a number.
*
* @api public
*/
exports.unpack = function (buffer) {
var n = 0;
for (var i = 0; i < buffer.length; ++i) {
n = (i == 0) ? buffer[i] : (n * 256) + buffer[i];
}
return n;
}
/**
* Left pads a string.
*
* @api public
*/
exports.padl = function (s,n,c) {
return new Array(1 + n - s.length).join(c) + s;
}
{
"name": "socket.io"
, "version": "0.7.11"
, "version": "0.8.0"
, "description": "Real-time apps made cross-browser & easy with a WebSocket-like API"

@@ -12,2 +12,3 @@ , "homepage": "http://socket.io"

, { "name": "Vladimir Dronnikov", "email": "dronnikov@gmail.com" }
, { "name": "Einar Otto Stangvik", "email": "einaros@gmail.com" }
]

@@ -19,3 +20,3 @@ , "repository":{

, "dependencies": {
"socket.io-client": "0.7.11"
"socket.io-client": "0.8.0"
, "policyfile": "0.0.4"

@@ -22,0 +23,0 @@ , "redis": "0.6.6"

@@ -475,2 +475,87 @@ /*!

'test that a referer is accepted for *:* origin': function (done) {
var port = ++ports
, io = sio.listen(port)
, cl = client(port);
io.configure(function () {
io.set('origins', '*:*');
});
cl.get('/socket.io/{protocol}', { headers: { referer: 'http://foo.bar.com:82/something' } }, function (res, data) {
res.statusCode.should.eql(200);
cl.end();
io.server.close();
done();
});
},
'test that valid referer is accepted for addr:* origin': function (done) {
var port = ++ports
, io = sio.listen(port)
, cl = client(port);
io.configure(function () {
io.set('origins', 'foo.bar.com:*');
});
cl.get('/socket.io/{protocol}', { headers: { referer: 'http://foo.bar.com/something' } }, function (res, data) {
res.statusCode.should.eql(200);
cl.end();
io.server.close();
done();
});
},
'test that erroneous referer is denied for addr:* origin': function (done) {
var port = ++ports
, io = sio.listen(port)
, cl = client(port);
io.configure(function () {
io.set('origins', 'foo.bar.com:*');
});
cl.get('/socket.io/{protocol}', { headers: { referer: 'http://baz.bar.com/something' } }, function (res, data) {
res.statusCode.should.eql(403);
cl.end();
io.server.close();
done();
});
},
'test that valid referer port is accepted for addr:port origin': function (done) {
var port = ++ports
, io = sio.listen(port)
, cl = client(port);
io.configure(function () {
io.set('origins', 'foo.bar.com:81');
});
cl.get('/socket.io/{protocol}', { headers: { referer: 'http://foo.bar.com:81/something' } }, function (res, data) {
res.statusCode.should.eql(200);
cl.end();
io.server.close();
done();
});
},
'test that erroneous referer port is denied for addr:port origin': function (done) {
var port = ++ports
, io = sio.listen(port)
, cl = client(port);
io.configure(function () {
io.set('origins', 'foo.bar.com:81');
});
cl.get('/socket.io/{protocol}', { headers: { referer: 'http://foo.bar.com/something' } }, function (res, data) {
res.statusCode.should.eql(403);
cl.end();
io.server.close();
done();
});
},
'test limiting the supported transports for a manager': function (done) {

@@ -477,0 +562,0 @@ var port = ++ports

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