Comparing version 0.2.6 to 0.2.8
@@ -14,3 +14,3 @@ /*! | ||
initialSize = 0; | ||
} | ||
} | ||
else if (typeof initialSize === 'undefined') { | ||
@@ -29,6 +29,6 @@ initialSize = 0; | ||
this.__defineGetter__('size', function(){ | ||
return this._buffer.length; | ||
return this._buffer == null ? 0 : this._buffer.length; | ||
}); | ||
this.__defineGetter__('used', function(){ | ||
return this._used; | ||
return this._used; | ||
}); | ||
@@ -38,3 +38,3 @@ } | ||
BufferPool.prototype.get = function(length) { | ||
if (this._offset + length > this._buffer.length) { | ||
if (this._buffer == null || this._offset + length > this._buffer.length) { | ||
// detaches previous buffer, activates a new area | ||
@@ -55,3 +55,4 @@ // may cause leak-like effects, although not actually to be considered leaks | ||
BufferPool.prototype.reset = function() { | ||
this._buffer = new Buffer(this._shrinkStrategy()); | ||
var len = this._shrinkStrategy(); | ||
this._buffer = len ? new Buffer(this._shrinkStrategy()) : null; | ||
this._offset = 0; | ||
@@ -58,0 +59,0 @@ this._used = 0; |
@@ -10,3 +10,3 @@ /*! | ||
, EventEmitter = events.EventEmitter | ||
, Validation = require('../build/Release/validation').Validation | ||
, Validation = require('./Validation').Validation | ||
, ErrorCodes = require('./ErrorCodes') | ||
@@ -16,2 +16,25 @@ , BufferPool = require('./BufferPool'); | ||
/** | ||
* Node version 0.4 and 0.6 compatibility | ||
*/ | ||
var isNodeV4 = /^v0\.4/.test(process.version); | ||
var readUInt16BE = !isNodeV4 | ||
? Buffer.prototype.readUInt16BE | ||
: function(start) { | ||
var n = 0; | ||
for (var i = start; i < start + 2; ++i) { | ||
n = (i == 0) ? this[i] : (n * 256) + this[i]; | ||
} | ||
return n; | ||
}; | ||
var readUInt32BE = !isNodeV4 | ||
? Buffer.prototype.readUInt32BE | ||
: function(start) { | ||
var n = 0; | ||
for (var i = start; i < start + 4; ++i) { | ||
n = (i == 0) ? this[i] : (n * 256) + this[i]; | ||
} | ||
return n; | ||
}; | ||
/** | ||
* HyBi Receiver implementation | ||
@@ -53,3 +76,3 @@ */ | ||
self.expect(2, function(data) { | ||
opcodes['1'].getData(unpack(data)); | ||
opcodes['1'].getData(readUInt16BE.call(data, 0)); | ||
}); | ||
@@ -59,8 +82,7 @@ } | ||
self.expect(8, function(data) { | ||
if (unpack(data.slice(0, 4)) != 0) { | ||
if (readUInt32BE.call(data, 0) != 0) { | ||
self.error('packets with length spanning more than 32 bit is currently not supported', 1008); | ||
return; | ||
} | ||
var lengthBytes = data.slice(4); // note: cap to 32 bit length | ||
opcodes['1'].getData(unpack(data)); | ||
opcodes['1'].getData(readUInt32BE.call(data, 4)); | ||
}); | ||
@@ -97,4 +119,4 @@ } | ||
self.endPacket(); | ||
} | ||
}, | ||
} | ||
}, | ||
// binary | ||
@@ -113,3 +135,3 @@ '2': { | ||
self.expect(2, function(data) { | ||
opcodes['2'].getData(unpack(data)); | ||
opcodes['2'].getData(readUInt16BE.call(data, 0)); | ||
}); | ||
@@ -119,8 +141,7 @@ } | ||
self.expect(8, function(data) { | ||
if (unpack(data.slice(0, 4)) != 0) { | ||
if (readUInt32BE.call(data, 0) != 0) { | ||
self.error('packets with length spanning more than 32 bit is currently not supported', 1008); | ||
return; | ||
} | ||
var lengthBytes = data.slice(4); // note: cap to 32 bit length | ||
opcodes['2'].getData(unpack(data)); | ||
opcodes['2'].getData(readUInt32BE.call(data, 4)); | ||
}); | ||
@@ -196,3 +217,3 @@ } | ||
} | ||
var code = data && data.length > 1 ? data.readUInt16BE(0) : 1000; | ||
var code = data && data.length > 1 ? readUInt16BE.call(data, 0, true) : 1000; | ||
if (!ErrorCodes.isValidErrorCode(code)) { | ||
@@ -233,3 +254,3 @@ self.error('invalid error code', 1002); | ||
self.error('control frames cannot have more than 125 bytes of data', 1002); | ||
} | ||
} | ||
}, | ||
@@ -341,3 +362,2 @@ getData: function(length) { | ||
var prevOverflow = this.overflow; | ||
// this.overflow = new Buffer(this.overflow.length + data.length); | ||
this.overflow = this.allocateFromPool(this.overflow.length + data.length); | ||
@@ -357,3 +377,2 @@ prevOverflow.copy(this.overflow, 0); | ||
this.expectBuffer = this.allocateFromPool(length); | ||
// this.expectBuffer = new Buffer(length); | ||
this.expectOffset = 0; | ||
@@ -374,5 +393,5 @@ this.expectHandler = handler; | ||
Receiver.prototype.allocateFromPool = function(length) { | ||
return this.bufferPool.get(length); | ||
} | ||
Receiver.prototype.allocateFromPool = !isNodeV4 | ||
? function(length) { return this.bufferPool.get(length); } | ||
: function(length) { return new Buffer(length); }; | ||
@@ -509,10 +528,2 @@ /** | ||
function unpack(buffer) { | ||
var n = 0; | ||
for (var i = 0; i < buffer.length; ++i) { | ||
n = (i == 0) ? buffer[i] : (n * 256) + buffer[i]; | ||
} | ||
return n; | ||
} | ||
module.exports = Receiver; |
@@ -13,2 +13,21 @@ /*! | ||
/** | ||
* Node version 0.4 and 0.6 compatibility | ||
*/ | ||
var isNodeV4 = /^v0\.4/.test(process.version); | ||
var writeUInt16BE = !isNodeV4 | ||
? Buffer.prototype.writeUInt16BE | ||
: function(value, offset) { | ||
this[offset] = value >>> 8; | ||
this[offset + 1] = value % 256; | ||
}; | ||
var writeUInt32BE = !isNodeV4 | ||
? Buffer.prototype.writeUInt32BE | ||
: function(value, offset) { | ||
for (var i = offset + 3; i >= offset; --i) { | ||
this[i] = value & 0xff; | ||
value >>>= 8; | ||
} | ||
}; | ||
/** | ||
* HyBi Sender implementation | ||
@@ -36,3 +55,3 @@ */ | ||
if (typeof code !== 'undefined') { | ||
if (typeof code !== 'number' || | ||
if (typeof code !== 'number' || | ||
!ErrorCodes.isValidErrorCode(code)) throw new Error('first argument must be a valid error code number'); | ||
@@ -42,3 +61,3 @@ } | ||
var dataBuffer = new Buffer(2 + (data ? Buffer.byteLength(data) : 0)); | ||
dataBuffer.writeUInt16BE(code, 0); | ||
writeUInt16BE.call(dataBuffer, code, 0); | ||
if (dataBuffer.length > 2) dataBuffer.write(data, 2); | ||
@@ -115,7 +134,7 @@ var buf = this.frameData(0x8, dataBuffer, true, true); // always masked | ||
case 126: | ||
outputBuffer.writeUInt16BE(dataLength, 2); | ||
writeUInt16BE.call(outputBuffer, dataLength, 2); | ||
break; | ||
case 127: | ||
outputBuffer.writeUInt32BE(0, 2); | ||
outputBuffer.writeUInt32BE(dataLength, 6); | ||
writeUInt32BE.call(outputBuffer, 0, 2); | ||
writeUInt32BE.call(outputBuffer, dataLength, 6); | ||
} | ||
@@ -122,0 +141,0 @@ if (maskData) { |
@@ -30,3 +30,3 @@ /*! | ||
if (!serverUrl.host) throw new Error('invalid url'); | ||
options = options || {}; | ||
@@ -44,6 +44,16 @@ options.origin = options.origin || null; | ||
// node<=v0.4.x compatibility | ||
var isNodeV4 = false; | ||
var agent; | ||
if (/^v0\.4/.test(process.version)) { | ||
isNodeV4 = true; | ||
agent = new http.Agent({ | ||
host: serverUrl.hostname, | ||
port: serverUrl.port || 80 | ||
}); | ||
} | ||
var requestOptions = { | ||
port: serverUrl.port || 80, | ||
host: serverUrl.hostname, | ||
path: serverUrl.path || '/', | ||
headers: { | ||
@@ -56,2 +66,7 @@ 'Connection': 'Upgrade', | ||
}; | ||
if (isNodeV4) { | ||
requestOptions.path = (serverUrl.pathname || '/') + (serverUrl.search || ''); | ||
requestOptions.agent = agent; | ||
} | ||
else requestOptions.path = serverUrl.path || '/'; | ||
if (options.origin) { | ||
@@ -61,8 +76,6 @@ if (options.protocolVersion < 13) requestOptions.headers['Sec-WebSocket-Origin'] = options.origin; | ||
} | ||
var req = http.request(requestOptions); | ||
req.end(); | ||
this._socket = null; | ||
this._state = 'connecting'; | ||
var self = this; | ||
req.on('upgrade', function(res, socket, upgradeHead) { | ||
(isNodeV4 ? agent : req).on('upgrade', function(res, socket, upgradeHead) { | ||
if (self._state == 'disconnected') { | ||
@@ -80,3 +93,3 @@ // client disconnected before server accepted connection | ||
} | ||
self._socket = socket; | ||
@@ -125,4 +138,5 @@ socket.setTimeout(0); | ||
if (upgradeHead) receiver.add(upgradeHead); | ||
if (upgradeHead && upgradeHead.length > 0) receiver.add(upgradeHead); | ||
}); | ||
var realEmit = this.emit; | ||
@@ -133,2 +147,6 @@ this.emit = function(event) { | ||
} | ||
req.end(); | ||
this._socket = null; | ||
this._state = 'connecting'; | ||
} | ||
@@ -143,3 +161,3 @@ | ||
/** | ||
* Gracefully closes the connection, after sending a description message to the server | ||
* Gracefully closes the connection, after sending a description message to the server | ||
* | ||
@@ -158,3 +176,3 @@ * @param {Object} data to be sent to the server | ||
this._sender.close(code, data, options); | ||
this.terminate(); | ||
this.terminate(); | ||
} | ||
@@ -167,3 +185,3 @@ catch (e) { | ||
/** | ||
* Sends a ping | ||
* Sends a ping | ||
* | ||
@@ -186,3 +204,3 @@ * @param {Object} data to be sent to the server | ||
/** | ||
* Sends a pong | ||
* Sends a pong | ||
* | ||
@@ -205,3 +223,3 @@ * @param {Object} data to be sent to the server | ||
/** | ||
* Sends a piece of data | ||
* Sends a piece of data | ||
* | ||
@@ -244,3 +262,3 @@ * @param {Object} data to be sent to the server | ||
this.emit('error', e); | ||
} | ||
} | ||
} | ||
@@ -250,3 +268,3 @@ } | ||
/** | ||
* Streams data through calls to a user supplied function | ||
* Streams data through calls to a user supplied function | ||
* | ||
@@ -290,3 +308,3 @@ * @param {Object} Members - mask: boolean, binary: boolean | ||
* Immediately shuts down the connection | ||
* | ||
* | ||
* @api public | ||
@@ -308,3 +326,3 @@ */ | ||
/** | ||
* Entirely private apis, | ||
* Entirely private apis, | ||
* which may or may not be bound to a sepcific WebSocket instance. | ||
@@ -322,3 +340,3 @@ */ | ||
delete instance._queue; | ||
queue.forEach(function(method) { method(); }); | ||
queue.forEach(function(method) { method(); }); | ||
} | ||
@@ -338,3 +356,3 @@ catch (e) { | ||
catch (e) { | ||
if (typeof cb == 'function') cb(e); | ||
if (typeof cb == 'function') cb(e); | ||
else self.emit('error', e); | ||
@@ -350,6 +368,6 @@ } | ||
catch (e) { | ||
if (typeof cb == 'function') cb(e); | ||
if (typeof cb == 'function') cb(e); | ||
else self.emit('error', e); | ||
} | ||
} | ||
}); | ||
} |
@@ -5,3 +5,3 @@ { | ||
"description": "simple and very fast websocket protocol client for node.js", | ||
"version": "0.2.6", | ||
"version": "0.2.8", | ||
"repository": { | ||
@@ -16,3 +16,3 @@ "type": "git", | ||
"engines": { | ||
"node": "~0.6.0" | ||
"node": ">0.4.0" | ||
}, | ||
@@ -19,0 +19,0 @@ "dependencies": { |
var assert = require('assert') | ||
, Parser = require('../lib/Receiver'); | ||
require('should'); | ||
require('./hybi-common'); | ||
@@ -4,0 +5,0 @@ |
var assert = require('assert') | ||
, Validation = require('../build/Release/validation').Validation; | ||
, Validation = require('../lib/Validation').Validation; | ||
require('should'); | ||
@@ -4,0 +4,0 @@ |
@@ -82,20 +82,24 @@ var assert = require('assert') | ||
it('can disconnect before connection is established', function(done) { | ||
var ws = new WebSocket('ws://echo.websocket.org'); | ||
ws.terminate(); | ||
ws.on('open', function() { | ||
assert.fail('connect shouldnt be raised here'); | ||
server.createServer(++port, function(srv) { | ||
var ws = new WebSocket('ws://localhost:' + port); | ||
ws.terminate(); | ||
ws.on('open', function() { | ||
assert.fail('connect shouldnt be raised here'); | ||
}); | ||
ws.on('close', function() { | ||
done(); | ||
}); | ||
}); | ||
ws.on('close', function() { | ||
done(); | ||
}); | ||
}) | ||
it('send before connect should fail', function(done) { | ||
var ws = new WebSocket('ws://echo.websocket.org'); | ||
try { | ||
ws.send('hi'); | ||
} | ||
catch (e) { | ||
ws.terminate(); | ||
done(); | ||
} | ||
server.createServer(++port, function(srv) { | ||
var ws = new WebSocket('ws://localhost:' + port); | ||
try { | ||
ws.send('hi'); | ||
} | ||
catch (e) { | ||
ws.terminate(); | ||
done(); | ||
} | ||
}); | ||
}) | ||
@@ -118,10 +122,12 @@ it('send without data should fail', function(done) { | ||
it('ping before connect should fail', function(done) { | ||
var ws = new WebSocket('ws://echo.websocket.org'); | ||
try { | ||
ws.ping(); | ||
} | ||
catch (e) { | ||
ws.terminate(); | ||
done(); | ||
} | ||
server.createServer(++port, function(srv) { | ||
var ws = new WebSocket('ws://localhost:' + port); | ||
try { | ||
ws.ping(); | ||
} | ||
catch (e) { | ||
ws.terminate(); | ||
done(); | ||
} | ||
}); | ||
}) | ||
@@ -274,10 +280,12 @@ it('invalid server key is denied', function(done) { | ||
it('stream before connect should fail', function(done) { | ||
var ws = new WebSocket('ws://echo.websocket.org'); | ||
try { | ||
ws.stream(function() {}); | ||
} | ||
catch (e) { | ||
ws.terminate(); | ||
done(); | ||
} | ||
server.createServer(++port, function(srv) { | ||
var ws = new WebSocket('ws://localhost:' + port); | ||
try { | ||
ws.stream(function() {}); | ||
} | ||
catch (e) { | ||
ws.terminate(); | ||
done(); | ||
} | ||
}); | ||
}) | ||
@@ -284,0 +292,0 @@ it('stream without callback should fail', function(done) { |
Sorry, the diff of this file is not supported yet
93546
23
2542