Showing with 79 additions and 18 deletions.
  1. +4 −5 benchmark/http_simple.js
  2. +4 −5 benchmark/http_simple_auto.js
  3. +71 −8 lib/http.js
@@ -96,13 +96,12 @@ var server = http.createServer(function (req, res) {
'Transfer-Encoding': 'chunked' });
// send body in chunks
var len = body.length;
var step = ~~(len / n_chunks) || len;
var step = Math.floor(len / n_chunks) || 1;

for (var i = 0; i < len; i += step) {
res.write(body.slice(i, i + step));
for (var i = 0, n = (n_chunks - 1); i < n; ++i) {
res.write(body.slice(i * step, i * step + step));
}

res.end();
res.end(body.slice((n_chunks - 1) * step));
} else {
var content_length = body.length.toString();

@@ -77,13 +77,12 @@ var server = http.createServer(function (req, res) {
"Transfer-Encoding": "chunked" });
// send body in chunks
var len = body.length;
var step = ~~(len / n_chunks) || len;
var step = Math.floor(len / n_chunks) || 1;

for (var i = 0; i < len; i += step) {
res.write(body.slice(i, i + step));
for (var i = 0, n = (n_chunks - 1); i < n; ++i) {
res.write(body.slice(i * step, i * step + step));
}

res.end();
res.end(body.slice((n_chunks - 1) * step));
} else {
var content_length = body.length.toString();

@@ -759,6 +759,10 @@ OutgoingMessage.prototype.addTrailers = function(headers) {
};


var zero_chunk_buf = new Buffer('\r\n0\r\n');
var crlf_buf = new Buffer('\r\n');


OutgoingMessage.prototype.end = function(data, encoding) {
if (this.finished) {
return false;
@@ -776,8 +780,7 @@ OutgoingMessage.prototype.end = function(data, encoding) {
var ret;

var hot = this._headerSent === false &&
typeof(data) === 'string' &&
data.length > 0 &&
(data && data.length > 0) &&
this.output.length === 0 &&
this.connection &&
this.connection.writable &&
@@ -789,13 +792,73 @@ OutgoingMessage.prototype.end = function(data, encoding) {
// res.end(blah);
// HACKY.

if (this.chunkedEncoding) {
var l = Buffer.byteLength(data, encoding).toString(16);
ret = this.connection.write(this._header + l + CRLF +
data + '\r\n0\r\n' +
this._trailer + '\r\n', encoding);
if (typeof data === 'string') {
if (this.chunkedEncoding) {
var l = Buffer.byteLength(data, encoding).toString(16);
ret = this.connection.write(this._header + l + CRLF +
data + '\r\n0\r\n' +
this._trailer + '\r\n', encoding);
} else {
ret = this.connection.write(this._header + data, encoding);
}
} else if (Buffer.isBuffer(data)) {
if (this.chunkedEncoding) {
var chunk_size = data.length.toString(16);

// Skip expensive Buffer.byteLength() calls; only ISO-8859-1 characters
// are allowed in HTTP headers. Therefore:
//
// this._header.length == Buffer.byteLength(this._header.length)
// this._trailer.length == Buffer.byteLength(this._trailer.length)
//
var header_len = this._header.length;
var chunk_size_len = chunk_size.length;
var data_len = data.length;
var trailer_len = this._trailer.length;

var len = header_len
+ chunk_size_len
+ 2 // '\r\n'.length
+ data_len
+ 5 // '\r\n0\r\n'.length
+ trailer_len
+ 2; // '\r\n'.length

var buf = new Buffer(len);
var off = 0;

buf.write(this._header, off, header_len, 'ascii');
off += header_len;

buf.write(chunk_size, off, chunk_size_len, 'ascii');
off += chunk_size_len;

crlf_buf.copy(buf, off);
off += 2;

data.copy(buf, off);
off += data_len;

zero_chunk_buf.copy(buf, off);
off += 5;

if (trailer_len > 0) {
buf.write(this._trailer, off, trailer_len, 'ascii');
off += trailer_len;
}

crlf_buf.copy(buf, off);

ret = this.connection.write(buf);
} else {
var header_len = this._header.length;
var buf = new Buffer(header_len + data.length);
buf.write(this._header, 0, header_len, 'ascii');
data.copy(buf, header_len);
ret = this.connection.write(buf);
}
} else {
ret = this.connection.write(this._header + data, encoding);
throw new TypeError('first argument must be a string or Buffer');
}
this._headerSent = true;