From 32a44a3b5dcc2d0484fd7359c27db95f3a2d053a Mon Sep 17 00:00:00 2001 From: Justin Matthews Date: Sat, 8 Sep 2012 20:08:37 -0700 Subject: [PATCH] Websocket: accept a pong (IE10 sends them) --- lib/transports/websocket/hybi-16.js | 108 ++++++++++++++++------------ 1 file changed, 62 insertions(+), 46 deletions(-) diff --git a/lib/transports/websocket/hybi-16.js b/lib/transports/websocket/hybi-16.js index 69967dad28..12d4c3c56f 100644 --- a/lib/transports/websocket/hybi-16.js +++ b/lib/transports/websocket/hybi-16.js @@ -279,6 +279,62 @@ function Parser () { this.currentMessage = ''; var self = this; + + function onPingOrPong (data, pingpong) { + if (self.state.lastFragment == false) { + self.error('fragmented ping is not supported'); + return; + } + + var finish = function(mask, finaldata) { + self.emit(pingpong, self.unmask(mask, finaldata)); + self.endPacket(); + }; + + var expectData = function(length, mask) { + if (length == 0) { + finish(null,null); + } + else { + self.expect('Data', length, function(finaldata) { + finish(mask, finaldata); + }); + } + }; + + var checkMask = function (length) { + if (self.state.masked) { + self.expect('Mask', 4, function(mask) { + expectData(length, mask); + }); + } + else { + expectData(length, null); + } + }; + + var getLength = function () { + // decode length + var firstLength = data[1] & 0x7f; + + if (firstLength < 126) { + checkMask(firstLength); + } + else if (firstLength == 126) { + self.expect('Length', 2, function(data) { + checkMask(util.unpack(data)); + }); + } + else if (firstLength == 127) { + self.expect('Length', 8, function(data) { + checkMask(util.unpack(data)); + }); + } + }; + + getLength(); //step1 + } + this.opcodeHandlers = { // text '1': function(data) { @@ -384,55 +440,15 @@ function Parser () { }, // ping '9': function(data) { - if (self.state.lastFragment == false) { - self.error('fragmented ping is not supported'); - return; - } - - var finish = function(mask, data) { - self.emit('ping', self.unmask(mask, data)); - self.endPacket(); - } - - var expectData = function(length) { - if (self.state.masked) { - self.expect('Mask', 4, function(data) { - var mask = data; - self.expect('Data', length, function(data) { - finish(mask, data); - }); - }); - } - else { - self.expect('Data', length, function(data) { - finish(null, data); - }); - } - } - - // decode length - var firstLength = data[1] & 0x7f; - if (firstLength == 0) { - finish(null, null); - } - else if (firstLength < 126) { - expectData(firstLength); - } - else if (firstLength == 126) { - self.expect('Length', 2, function(data) { - expectData(util.unpack(data)); - }); - } - else if (firstLength == 127) { - self.expect('Length', 8, function(data) { - expectData(util.unpack(data)); - }); - } + onPingOrPong(data,'ping'); + }, + '10': function(data) { + onPingOrPong(data,'pong'); } - } + }; this.expect('Opcode', 2, this.processPacket); -}; +} /** * Inherits from EventEmitter.