From 4f98e2deb31ae015ce98e9503e73c20decddef8b Mon Sep 17 00:00:00 2001 From: Ryan Dahl Date: Mon, 14 Sep 2009 16:25:41 +0200 Subject: [PATCH] Fix buffering logic for HTTP outgoing messages. Was sending two packets instead of one for some short messages, and even 3, for short chunked-encoded messages. Also use the more general Encode() function for receiving HTTP bodies. Gives ~6% improvement on "hello world" web server benchmarks. --- src/http.cc | 19 ++----------------- src/http.js | 38 +++++++++++++++++++++++++++++++++----- 2 files changed, 35 insertions(+), 22 deletions(-) diff --git a/src/http.cc b/src/http.cc index 8d697bd..d0202a0 100644 --- a/src/http.cc +++ b/src/http.cc @@ -191,23 +191,8 @@ HTTPConnection::on_body (http_parser *parser, const char *buf, size_t len) // TODO each message should have their encoding. // don't look at the conneciton for encoding - - if (connection->encoding_ == RAW) { - // raw encoding - Local array = Array::New(len); - for (size_t i = 0; i < len; i++) { - unsigned char val = reinterpret_cast(buf)[i]; - array->Set(Integer::New(i), Integer::New(val)); - } - argv[0] = array; - - } else { - // utf8 or ascii encoding - Handle chunk = String::New((const char*)buf, len); - argv[0] = chunk; - } - - connection->Emit("body", 1, argv); + Local data = Encode(buf, len, connection->encoding_); + connection->Emit("body", 1, &data); return 0; } diff --git a/src/http.js b/src/http.js index 3048c15..777bfd5 100644 --- a/src/http.js +++ b/src/http.js @@ -167,13 +167,37 @@ function OutgoingMessage () { this.should_keep_alive = true; this.use_chunked_encoding_by_default = true; + this.flushing = false; + this.finished = false; } node.inherits(OutgoingMessage, node.EventEmitter); OutgoingMessage.prototype.send = function (data, encoding) { + var length = this.output.length; + + if (length === 0) { + this.output.push(data); + encoding = encoding || (data.constructor === Array ? "raw" : "ascii"); + this.outputEncodings.push(encoding); + return; + } + + var lastEncoding = this.outputEncodings[length-1]; + var lastData = this.output[length-1]; + + if ((lastEncoding === encoding) || + (!encoding && data.constructor === lastData.constructor)) { + if (lastData.constructor === String) { + this.output[length-1] = lastData + data; + } else { + this.output[length-1] = lastData.concat(data); + } + return; + } + this.output.push(data); - encoding = encoding || (data.constructor === Array ? "raw" : "raws"); + encoding = encoding || (data.constructor === Array ? "raw" : "ascii"); this.outputEncodings.push(encoding); }; @@ -237,15 +261,19 @@ OutgoingMessage.prototype.sendHeaderLines = function (first_line, headers) { OutgoingMessage.prototype.sendBody = function (chunk, encoding) { if (this.chunked_encoding) { - this.send(chunk.length.toString(16), "ascii"); - this.send(CRLF, "ascii"); + this.send(chunk.length.toString(16)); + this.send(CRLF); this.send(chunk, encoding); - this.send(CRLF, "ascii"); + this.send(CRLF); } else { this.send(chunk, encoding); } - this.flush(); + if (this.flushing) { + this.flush(); + } else { + this.flushing = true; + } }; OutgoingMessage.prototype.flush = function () { -- 2.7.4