Compare commits

...

14 Commits

Author SHA1 Message Date
James Coglan f50de64532 Update changelog. 2012-07-09 08:58:00 +01:00
James Coglan d071ec3acd Check that incoming requests have an output stream before doing anything with it. 2012-07-08 20:30:53 +01:00
James Coglan 59fd729a03 Bump version to 0.4.3. 2012-07-01 18:15:01 +01:00
James Coglan b458959e6a Update Node versions for Travis. 2012-07-01 18:12:54 +01:00
James Coglan 7f18af7c90 Use Connection:close on EventSource connections. 2012-05-21 19:41:26 +01:00
James Coglan 680d8fc759 Remove an expensive test. 2012-05-21 19:37:40 +01:00
James Coglan 90d039e371 Bump version to 0.4.2. 2012-04-06 18:57:29 +01:00
James Coglan b42cdf741d Add error code 1011. 2012-04-06 13:52:21 +01:00
James Coglan bd7c52dfa2 Use / as the default path if the client URI has no path. 2012-04-01 22:57:16 +01:00
James Coglan adee8ba51c Bump version to 0.4.1. 2012-02-26 19:00:04 +00:00
James Coglan 3675cfb798 Treat anything but a Buffer as a text message in WebSocket#send. 2012-02-25 09:49:53 +00:00
James Coglan 1222308201 Return boolean from EventSource.send(). 2012-02-16 23:15:16 +00:00
James Coglan 8c9ae84740 Treat numbers as strings when passed to Socket.send(). 2012-02-16 23:09:29 +00:00
James Coglan d404c78c46 Add items to .npmignore. 2012-02-13 12:43:12 +00:00
11 changed files with 86 additions and 47 deletions
+2
View File
@@ -1,4 +1,6 @@
.git
.gitignore
.npmignore
.redcar
.travis.yml
node_modules
+1 -1
View File
@@ -2,4 +2,4 @@ language: node_js
node_js:
- 0.4
- 0.6
- 0.7
- 0.8
+17
View File
@@ -1,3 +1,20 @@
=== 0.4.3 / 2012-07-09
* Add 'Connection: close' to EventSource response
* Handle situations where request.socket is undefined
=== 0.4.2 / 2012-04-06
* Add WebSocket error code 1011.
* Handle URLs with no path correctly by sending 'GET /'
=== 0.4.1 / 2012-02-26
* Treat anything other than a Buffer as a string when calling send()
=== 0.4.0 / 2012-02-13
* Add ping() method to server-side WebSocket and EventSource
+15 -9
View File
@@ -19,9 +19,6 @@ var EventSource = function(request, response, options) {
this._ping = options.ping || this.DEFAULT_PING;
this._retry = options.retry || this.DEFAULT_RETRY;
this._stream.setTimeout(0);
this._stream.setNoDelay(true);
var scheme = isSecureConnection(request) ? 'https:' : 'http:';
this.url = scheme + '//' + request.headers.host + request.url;
@@ -35,18 +32,22 @@ var EventSource = function(request, response, options) {
var handshake = 'HTTP/1.1 200 OK\r\n' +
'Content-Type: text/event-stream\r\n' +
'Cache-Control: no-cache, no-store\r\n' +
'Connection: close\r\n' +
'\r\n\r\n' +
'retry: ' + Math.floor(this._retry * 1000) + '\r\n\r\n';
try {
this._stream.write(handshake, 'utf8');
} catch (e) {}
this.readyState = API.OPEN;
if (this._ping)
this._pingLoop = setInterval(function() { self.ping() }, this._ping * 1000);
if (!this._stream || !this._stream.writable) return;
this._stream.setTimeout(0);
this._stream.setNoDelay(true);
try { this._stream.write(handshake, 'utf8') } catch (e) {}
['close', 'end', 'error'].forEach(function(event) {
self._stream.addListener(event, function() { self.close() });
});
@@ -62,7 +63,9 @@ var instance = {
DEFAULT_RETRY: 5,
send: function(message, options) {
message = message.replace(/(\r\n|\r|\n)/g, '$1data: ');
if (this.readyState !== API.OPEN) return false;
message = String(message).replace(/(\r\n|\r|\n)/g, '$1data: ');
options = options || {};
var frame = '';
@@ -72,7 +75,10 @@ var instance = {
try {
this._stream.write(frame, 'utf8');
} catch (e) {}
return true;
} catch (e) {
return false;
}
},
ping: function() {
+7 -5
View File
@@ -37,9 +37,6 @@ var WebSocket = function(request, socket, head, supportedProtos, options) {
this._ping = options && options.ping;
this._pingId = 0;
this._stream.setTimeout(0);
this._stream.setNoDelay(true);
var scheme = isSecureConnection(request) ? 'wss:' : 'ws:';
this.url = scheme + '//' + request.headers.host + request.url;
this.readyState = API.CONNECTING;
@@ -53,8 +50,6 @@ var WebSocket = function(request, socket, head, supportedProtos, options) {
process.nextTick(function() { self._open() });
var handshake = this._parser.handshakeResponse(head);
try { this._stream.write(handshake, 'binary') } catch (e) {}
if (this._parser.isOpen()) this.readyState = API.OPEN;
if (this._ping)
@@ -66,6 +61,13 @@ var WebSocket = function(request, socket, head, supportedProtos, options) {
this.protocol = this._parser.protocol || '';
this.version = this._parser.getVersion();
if (!this._stream || !this._stream.writable) return;
this._stream.setTimeout(0);
this._stream.setNoDelay(true);
try { this._stream.write(handshake, 'binary') } catch (e) {}
this._stream.addListener('data', function(data) {
var response = self._parser.parse(data);
if (!response) return;
+3 -1
View File
@@ -43,6 +43,8 @@ var API = {
if (this.readyState === API.CLOSED)
return false;
if (!(data instanceof Buffer)) data = String(data);
var frame = this._parser.frame(data, type, errorType);
try {
this._stream.write(frame, 'binary');
@@ -61,7 +63,7 @@ var API = {
var close = function() {
this.readyState = API.CLOSED;
if (this._pingLoop) clearInterval(this._pingLoop);
this._stream.end();
if (this._stream) this._stream.end();
var event = new Event('close', {code: code || 1000, reason: reason || ''});
event.initEvent('close', false, false);
this.dispatchEvent(event);
+10 -9
View File
@@ -46,20 +46,21 @@ var instance = {
},
ERRORS: {
normal_closure: 1000,
going_away: 1001,
protocol_error: 1002,
unacceptable: 1003,
encoding_error: 1007,
policy_violation: 1008,
too_large: 1009,
extension_error: 1010
normal_closure: 1000,
going_away: 1001,
protocol_error: 1002,
unacceptable: 1003,
encoding_error: 1007,
policy_violation: 1008,
too_large: 1009,
extension_error: 1010,
unexpected_condition: 1011
},
FRAGMENTED_OPCODES: [0,1,2],
OPENING_OPCODES: [1,2],
ERROR_CODES: [1000,1001,1002,1003,1007,1008,1009,1010],
ERROR_CODES: [1000,1001,1002,1003,1007,1008,1009,1010,1011],
UTF8_MATCH: /^([\x00-\x7F]|[\xC2-\xDF][\x80-\xBF]|\xE0[\xA0-\xBF][\x80-\xBF]|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}|\xED[\x80-\x9F][\x80-\xBF]|\xF0[\x90-\xBF][\x80-\xBF]{2}|[\xF1-\xF3][\x80-\xBF]{3}|\xF4[\x80-\x8F][\x80-\xBF]{2})*$/,
+1 -1
View File
@@ -46,7 +46,7 @@ Handshake.prototype.requestData = function() {
var u = this._uri;
var headers = [
'GET ' + u.pathname + (u.search || '') + ' HTTP/1.1',
'GET ' + (u.pathname || '/') + (u.search || '') + ' HTTP/1.1',
'Host: ' + u.hostname + (u.port ? ':' + u.port : ''),
'Upgrade: websocket',
'Connection: Upgrade',
+5 -5
View File
@@ -4,7 +4,7 @@
, "author" : "James Coglan <jcoglan@gmail.com> (http://jcoglan.com/)"
, "keywords" : ["websocket", "eventsource"]
, "version" : "0.4.0"
, "version" : "0.4.3"
, "engines" : {"node": ">=0.4.0"}
, "main" : "./lib/faye/websocket"
, "devDependencies" : {"jsclass": ""}
@@ -13,13 +13,13 @@
, "bugs" : "http://github.com/faye/faye-websocket-node/issues"
, "licenses" : [ { "type" : "MIT"
, "url" : "http://www.opensource.org/licenses/mit-license.php"
, "licenses" : [ { "type" : "MIT"
, "url" : "http://www.opensource.org/licenses/mit-license.php"
}
]
, "repositories" : [ { "type" : "git"
, "url" : "git://github.com/faye/faye-websocket-node.git"
, "repositories" : [ { "type" : "git"
, "url" : "git://github.com/faye/faye-websocket-node.git"
}
]
}
+25 -7
View File
@@ -60,13 +60,13 @@ JS.ENV.WebSocketSteps = JS.Test.asyncSteps({
callback()
},
send_message: function(callback) {
this._ws.send("I expect this to be echoed")
send_message: function(message, callback) {
this._ws.send(message)
setTimeout(callback, 100)
},
check_response: function(callback) {
this.assertEqual( "I expect this to be echoed", this._message )
check_response: function(message, callback) {
this.assertEqual( message, this._message )
callback()
},
@@ -116,8 +116,26 @@ JS.ENV.ClientSpec = JS.Test.describe("Client", function() { with(this) {
it("can send and receive messages", function() { with(this) {
listen_for_message()
send_message()
check_response()
send_message("I expect this to be echoed")
check_response("I expect this to be echoed")
}})
it("sends numbers as strings", function() { with(this) {
listen_for_message()
send_message(13)
check_response("13")
}})
it("sends booleans as strings", function() { with(this) {
listen_for_message()
send_message(false)
check_response("false")
}})
it("sends arrays as strings", function() { with(this) {
listen_for_message()
send_message([13,14,15])
check_response("13,14,15")
}})
}})
@@ -129,7 +147,7 @@ JS.ENV.ClientSpec = JS.Test.describe("Client", function() { with(this) {
it("cannot send and receive messages", function() { with(this) {
listen_for_message()
send_message()
send_message("I expect this to be echoed")
check_no_response()
}})
}})
-9
View File
@@ -137,15 +137,6 @@ JS.ENV.HybiParserSpec = JS.Test.describe("HybiParser", function() { with(this) {
assertBufferEqual( [129, 126, 0, 200, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111], parser.frame("HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello") )
}})
it("encodes long strings using extra length bytes", function() { with(this) {
var reps = 13108, message = '', output = [0x81, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x04]
while (reps--) {
message += "Hello"
output = output.concat([0x48, 0x65, 0x6c, 0x6c, 0x6f])
}
assertBufferEqual( output, parser.frame(message) )
}})
it("encodes close frames with an error code", function() { with(this) {
assertBufferEqual( [0x88, 0x07, 0x03, 0xea, 0x48, 0x65, 0x6c, 0x6c, 0x6f], parser.frame("Hello", "close", 1002) )
}})