Compare commits

...

8 Commits

8 changed files with 70 additions and 9 deletions
+18 -3
View File
@@ -1,7 +1,20 @@
### 0.5.4 / 2015-03-29
* Don't emit extra close frames if we receive a close frame after we already
sent one
* Fail the connection when the driver receives an invalid
`Sec-WebSocket-Extensions` header
### 0.5.3 / 2015-02-22
* Don't treat incoming data as WebSocket frames if a client driver is closed
before receiving the server handshake
### 0.5.2 / 2015-02-19
* Fix compatibility with the HTTP parser on io.js
* Use `websocket-extensions` to make sure messages and close frames are kept in order
* Use `websocket-extensions` to make sure messages and close frames are kept in
order
* Don't emit multiple `error` events
### 0.5.1 / 2014-12-18
@@ -27,7 +40,8 @@
### 0.3.4 / 2014-05-08
* Don't hold memory-leaking references to I/O buffers after they have been parsed
* Don't hold memory-leaking references to I/O buffers after they have been
parsed
### 0.3.3 / 2014-04-24
@@ -35,7 +49,8 @@
### 0.3.2 / 2013-12-29
* Expand `maxLength` to cover sequences of continuation frames and `draft-{75,76}`
* Expand `maxLength` to cover sequences of continuation frames and
`draft-{75,76}`
* Decrease default maximum frame buffer size to 64MB
* Stop parsing when the protocol enters a failure mode, to save CPU cycles
+1 -1
View File
@@ -298,7 +298,7 @@ when the headers are serialized and sent.
Initiates the protocol by sending the handshake - either the response for a
server-side driver or the request for a client-side one. This should be the
first method you invoke. Returns `true` iff a handshake was sent.
first method you invoke. Returns `true` if and only if a handshake was sent.
#### `driver.parse(string)`
+1 -1
View File
@@ -1,5 +1,5 @@
var net = require('net'),
websocket = require('../lib/websocket/driver'),
websocket = require('..'),
deflate = require('permessage-deflate');
var server = net.createServer(function(connection) {
+3 -1
View File
@@ -77,7 +77,9 @@ var instance = {
start: function() {
if (this.readyState !== 0) return false;
this._write(this._handshakeResponse());
var response = this._handshakeResponse();
if (!response) return false;
this._write(response);
if (this._stage !== -1) this._open();
return true;
},
+1
View File
@@ -53,6 +53,7 @@ var instance = {
},
parse: function(data) {
if (this.readyState === 3) return;
if (this.readyState > 0) return Hybi.prototype.parse.call(this, data);
this._http.parse(data);
+9 -2
View File
@@ -281,7 +281,12 @@ var instance = {
},
_handshakeResponse: function() {
var extensions = this._extensions.generateResponse(this._request.headers['sec-websocket-extensions']);
try {
var extensions = this._extensions.generateResponse(this._request.headers['sec-websocket-extensions']);
} catch (e) {
return this._fail('protocol_error', e.message);
}
if (extensions) this._headers.set('Sec-WebSocket-Extensions', extensions);
var start = 'HTTP/1.1 101 Switching Protocols',
@@ -293,11 +298,13 @@ var instance = {
_shutdown: function(code, reason) {
delete this._frame;
delete this._message;
var sendCloseFrame = (this.readyState === 1);
this.readyState = 2;
this._stage = 5;
this._extensions.close(function() {
this.frame(reason, 'close', code);
if (sendCloseFrame) this.frame(reason, 'close', code);
this.readyState = 3;
this.emit('close', new Base.CloseEvent(code, reason));
}, this);
+1 -1
View File
@@ -5,7 +5,7 @@
, "keywords" : ["websocket"]
, "license" : "MIT"
, "version" : "0.5.2"
, "version" : "0.5.4"
, "engines" : {"node": ">=0.6.0"}
, "main" : "./lib/websocket/driver"
, "dependencies" : {"websocket-extensions": ">=0.1.1"}
+36
View File
@@ -79,6 +79,37 @@ test.describe("Hybi", function() { with(this) {
}})
}})
describe("with invalid extensions", function() { with(this) {
before(function() { with(this) {
request().headers["sec-websocket-extensions"] = "x-webkit- -frame"
}})
it("does not write a handshake", function() { with(this) {
expect(driver().io, "emit").exactly(0)
driver().start()
}})
it("does not trigger the onopen event", function() { with(this) {
driver().start()
assertEqual( false, open )
}})
it("triggers the onerror event", function() { with(this) {
driver().start()
assertEqual( "Invalid Sec-WebSocket-Extensions header: x-webkit- -frame", error.message )
}})
it("triggers the onclose event", function() { with(this) {
driver().start()
assertEqual( [1002, "Invalid Sec-WebSocket-Extensions header: x-webkit- -frame"], close )
}})
it("changes the state to closed", function() { with(this) {
driver().start()
assertEqual( "closed", driver().getState() )
}})
}})
describe("with custom headers", function() { with(this) {
before(function() { with(this) {
driver().setHeader("Authorization", "Bearer WAT")
@@ -490,6 +521,11 @@ test.describe("Hybi", function() { with(this) {
it("changes the state to closed", function() { with(this) {
assertEqual( "closed", driver().getState() )
}})
it("does not write another close frame", function() { with(this) {
expect(driver().io, "emit").exactly(0)
this.driver().parse([0x88, 0x04, 0x03, 0xe9, 0x4f, 0x4b])
}})
}})
}})