From f0f0bfc951a306f48c21e05f83f059fc2c567298 Mon Sep 17 00:00:00 2001 From: James Coglan Date: Sat, 17 Dec 2011 17:23:17 +0000 Subject: [PATCH 1/5] Inline draft-75 parsing function. --- lib/faye/websocket/draft75_parser.js | 37 +++++++++++++--------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/lib/faye/websocket/draft75_parser.js b/lib/faye/websocket/draft75_parser.js index a60fa71..d2abe64 100644 --- a/lib/faye/websocket/draft75_parser.js +++ b/lib/faye/websocket/draft75_parser.js @@ -22,8 +22,23 @@ var instance = { }, parse: function(data) { - for (var i = 0, n = data.length; i < n; i++) - this._handleChar(data[i]); + for (var i = 0, n = data.length; i < n; i++) { + switch (data[i]) { + case 0x00: + this._buffering = true; + break; + + case 0xFF: + this._buffer = new Buffer(this._buffer); + this._socket.receive(this._buffer.toString('utf8', 0, this._buffer.length)); + this._buffer = []; + this._buffering = false; + break; + + default: + if (this._buffering) this._buffer.push(data[i]); + } + } }, frame: function(data) { @@ -35,24 +50,6 @@ var instance = { this.FRAME_END.copy(frame, buffer.length + 1); return frame; - }, - - _handleChar: function(data) { - switch (data) { - case 0x00: - this._buffering = true; - break; - - case 0xFF: - this._buffer = new Buffer(this._buffer); - this._socket.receive(this._buffer.toString('utf8', 0, this._buffer.length)); - this._buffer = []; - this._buffering = false; - break; - - default: - if (this._buffering) this._buffer.push(data); - } } }; From f5a78efcfd313d92d6ec3dd0ed79b189d0e68a45 Mon Sep 17 00:00:00 2001 From: James Coglan Date: Sat, 17 Dec 2011 19:22:46 +0000 Subject: [PATCH 2/5] Extract 255 into a constant. --- lib/faye/websocket/protocol8_parser.js | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/lib/faye/websocket/protocol8_parser.js b/lib/faye/websocket/protocol8_parser.js index cd1dbdb..69c828b 100644 --- a/lib/faye/websocket/protocol8_parser.js +++ b/lib/faye/websocket/protocol8_parser.js @@ -11,6 +11,7 @@ var Protocol8Parser = function(webSocket, options) { }; var instance = { + BYTE: 255, FIN: 128, MASK: 128, RSV1: 64, @@ -169,6 +170,7 @@ var instance = { offset = header + (this._masking ? 4 : 0), masked = this._masking ? this.MASK : 0, frame = new Buffer(length + offset), + BYTE = this.BYTE, mask, i; frame[0] = this.FIN | opcode; @@ -178,22 +180,22 @@ var instance = { } else if (length <= 65535) { frame[1] = masked | 126; frame[2] = Math.floor(length / 256); - frame[3] = length & 255; + frame[3] = length & BYTE; } else { frame[1] = masked | 127; - frame[2] = Math.floor(length / Math.pow(2,56)) & 255; - frame[3] = Math.floor(length / Math.pow(2,48)) & 255; - frame[4] = Math.floor(length / Math.pow(2,40)) & 255; - frame[5] = Math.floor(length / Math.pow(2,32)) & 255; - frame[6] = Math.floor(length / Math.pow(2,24)) & 255; - frame[7] = Math.floor(length / Math.pow(2,16)) & 255; - frame[8] = Math.floor(length / Math.pow(2,8)) & 255; - frame[9] = length & 255; + frame[2] = Math.floor(length / Math.pow(2,56)) & BYTE; + frame[3] = Math.floor(length / Math.pow(2,48)) & BYTE; + frame[4] = Math.floor(length / Math.pow(2,40)) & BYTE; + frame[5] = Math.floor(length / Math.pow(2,32)) & BYTE; + frame[6] = Math.floor(length / Math.pow(2,24)) & BYTE; + frame[7] = Math.floor(length / Math.pow(2,16)) & BYTE; + frame[8] = Math.floor(length / Math.pow(2,8)) & BYTE; + frame[9] = length & BYTE; } if (code) { - frame[offset] = Math.floor(code / 256); - frame[offset+1] = code & 255; + frame[offset] = Math.floor(code / 256) & BYTE; + frame[offset+1] = code & BYTE; } buffer.copy(frame, offset + insert); From 5a0c9410759303819b65ac95ad1551a3b9139662 Mon Sep 17 00:00:00 2001 From: James Coglan Date: Sat, 17 Dec 2011 19:23:56 +0000 Subject: [PATCH 3/5] Explicitly return null where parser methods hit an error. --- lib/faye/websocket/protocol8_parser.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/faye/websocket/protocol8_parser.js b/lib/faye/websocket/protocol8_parser.js index 69c828b..fb0e32e 100644 --- a/lib/faye/websocket/protocol8_parser.js +++ b/lib/faye/websocket/protocol8_parser.js @@ -54,7 +54,7 @@ var instance = { handshakeResponse: function() { var secKey = this._socket.request.headers['sec-websocket-key']; - if (!secKey) return; + if (!secKey) return null; var SHA1 = crypto.createHash('sha1'); SHA1.update(secKey + Handshake.GUID); @@ -159,7 +159,7 @@ var instance = { }, frame: function(data, type, code) { - if (this._closed) return; + if (this._closed) return null; var isText = (typeof data === 'string'), opcode = this.OPCODES[type || (isText ? 'text' : 'binary')], From 390882f7206ca4c6f948348cca9b9839f0ffe71a Mon Sep 17 00:00:00 2001 From: James Coglan Date: Sun, 18 Dec 2011 09:20:56 +0000 Subject: [PATCH 4/5] Change package description. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5acb851..336d7ff 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { "name" : "faye-websocket" -, "description" : "Robust general-purpose WebSocket server and client" +, "description" : "Standards-compliant WebSocket server and client" , "homepage" : "http://github.com/jcoglan/faye-websocket-node" , "author" : "James Coglan (http://jcoglan.com/)" , "keywords" : ["websocket"] From b129b447a25bacf428fd58edf31f11c006d55847 Mon Sep 17 00:00:00 2001 From: James Coglan Date: Sun, 18 Dec 2011 11:52:47 +0000 Subject: [PATCH 5/5] Refactor masking code. --- lib/faye/websocket/protocol8_parser.js | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/lib/faye/websocket/protocol8_parser.js b/lib/faye/websocket/protocol8_parser.js index fb0e32e..1e9b249 100644 --- a/lib/faye/websocket/protocol8_parser.js +++ b/lib/faye/websocket/protocol8_parser.js @@ -10,6 +10,16 @@ var Protocol8Parser = function(webSocket, options) { this._masking = options && options.masking; }; +Protocol8Parser.mask = function(payload, mask, offset) { + if (mask.length === 0) return payload; + offset = offset || 0; + + for (var i = 0, n = payload.length - offset; i < n; i++) { + payload[offset + i] = payload[offset + i] ^ mask[i % 4]; + } + return payload; +}; + var instance = { BYTE: 255, FIN: 128, @@ -202,8 +212,7 @@ var instance = { if (this._masking) { mask = new Buffer([1,2,3,4].map(function() { return Math.floor(Math.random() * 256) })); mask.copy(frame, header); - for (i = 0; i < length; i++) - frame[offset + i] = frame[offset + i] ^ mask[i % 4]; + Protocol8Parser.mask(frame, mask, offset); } return frame; @@ -222,7 +231,7 @@ var instance = { }, _emitFrame: function() { - var payload = this._unmask(this._payload, this._mask), + var payload = Protocol8Parser.mask(this._payload, this._mask), opcode = this._opcode; if (opcode === this.OPCODES.continuation) { @@ -294,16 +303,6 @@ var instance = { for (var i = 0, n = bytes.length; i < n; i++) number += bytes[i] << (8 * (n - 1 - i)); return number; - }, - - _unmask: function(payload, mask) { - var unmasked = new Buffer(payload.length), b; - for (var i = 0, n = payload.length; i < n; i++) { - b = payload[i]; - if (mask.length > 0) b = b ^ mask[i % 4]; - unmasked[i] = b; - } - return unmasked; } };