diff --git a/lib/ws/connection.js b/lib/ws/connection.js index 5a9c626..c26ba18 100644 --- a/lib/ws/connection.js +++ b/lib/ws/connection.js @@ -49,19 +49,16 @@ Connection.prototype.initializeParser = function(){ if(ws.readyState == 1) { ws.onmessage(slice); - } else if(slice.substr(0,4) != "GET ") { - ws.key3 = slice.replace("\r\n", ""); - ws.onConnect(ws.req); } else { - Utils.debug(data.toString("binary", start, end)); - var parts = slice.split("\r\n\r\n"); - if(parts > 1){ - var body = parts[1].replace("\r\n", ""); - ws.key3 = body; - ws.parser.execute(data, start, end-start-body.length); - } else { - ws.parser.execute(data, start, end-start); + var bytesParsed = ws.parser.execute(data, start, end - start); + if (ws.parser.incoming && ws.parser.incoming.upgrade) { + ws.parser.incoming.upgradeHead = data.toString("utf8", start + bytesParsed + 1, end - start - 2); + + ws.readyState = 1; + + Utils.debug(ws.parser.incoming); } + } }; }; diff --git a/lib/ws/http_parser.js b/lib/ws/http_parser.js index 9ce5956..91b83f1 100644 --- a/lib/ws/http_parser.js +++ b/lib/ws/http_parser.js @@ -21,19 +21,18 @@ function IncomingMessage () { }; }; -var Parser = function (){ +module.exports = new FreeList('parsers', 1000, function () { var parser = new HTTPParser('request'); - + parser.onMessageBegin = function () { - parser.incoming = IncomingMessage(); + parser.incoming = new IncomingMessage(parser.socket); parser.field = null; parser.value = null; }; // Only servers will get URL events. parser.onURL = function (b, start, len) { - var slice = b.toString('utf8', start, start+len); - + var slice = b.toString('ascii', start, start+len); if (parser.incoming.url) { parser.incoming.url += slice; } else { @@ -43,8 +42,7 @@ var Parser = function (){ }; parser.onHeaderField = function (b, start, len) { - var slice = b.toString('utf8', start, start+len).toLowerCase(); - + var slice = b.toString('ascii', start, start+len).toLowerCase(); if (parser.value) { parser.incoming._addHeaderLine(parser.field, parser.value); parser.field = null; @@ -58,7 +56,7 @@ var Parser = function (){ }; parser.onHeaderValue = function (b, start, len) { - var slice = b.toString('utf8', start, start+len); + var slice = b.toString('ascii', start, start+len); if (parser.value) { parser.value += slice; } else { @@ -73,28 +71,45 @@ var Parser = function (){ parser.incoming.httpVersionMajor = info.versionMajor; parser.incoming.httpVersionMinor = info.versionMinor; - parser.incoming.httpVersion = info.versionMajor + '.' + info.versionMinor ; + parser.incoming.httpVersion = info.versionMajor + + '.' + + info.versionMinor ; - parser.incoming.method = info.method; - - if(parser["onIncoming"]){ - parser.onIncoming(); + if (info.method) { + // server only + parser.incoming.method = info.method; + } else { + // client only + parser.incoming.statusCode = info.statusCode; + } + + parser.incoming.upgrade = info.upgrade; + + if (!info.upgrade) { + // For upgraded connections, we'll emit this after parser.execute + // so that we can capture the first part of the new protocol + parser.onIncoming(parser.incoming, info.shouldKeepAlive); } }; parser.onBody = function (b, start, len) { - parser.incoming.body = b.slice(start, start+len); + // TODO body encoding? + var enc = parser.incoming._encoding; + if (!enc) { + parser.incoming.emit('data', b.slice(start, start+len)); + } else { + var string = b.toString(enc, start, start+len); + parser.incoming.emit('data', string); + } }; parser.onMessageComplete = function () { - if(parser["onEnd"]){ - parser.onEnd(parser.incoming); + if (!parser.incoming.upgrade) { + // For upgraded connections, also emit this after parser.execute + parser.incoming.emit("end"); } }; return parser; -} - -module.exports = new FreeList('parsers', 1000, Parser); - +});