mirror of https://github.com/nodejs/node.git
http: Use writev instead of the hacky hot end
parent
a58454226f
commit
ec576235f1
|
@ -460,6 +460,10 @@ var crlf_buf = new Buffer('\r\n');
|
|||
|
||||
|
||||
OutgoingMessage.prototype.end = function(data, encoding) {
|
||||
if (data && typeof data !== 'string' && !Buffer.isBuffer(data)) {
|
||||
throw new TypeError('first argument must be a string or Buffer');
|
||||
}
|
||||
|
||||
if (this.finished) {
|
||||
return false;
|
||||
}
|
||||
|
@ -473,113 +477,25 @@ OutgoingMessage.prototype.end = function(data, encoding) {
|
|||
data = false;
|
||||
}
|
||||
|
||||
if (this.connection && data)
|
||||
this.connection.cork();
|
||||
|
||||
var ret;
|
||||
|
||||
var hot = this._headerSent === false &&
|
||||
(data && data.length > 0) &&
|
||||
this.output.length === 0 &&
|
||||
this.connection &&
|
||||
this.connection.writable &&
|
||||
this.connection._httpMessage === this;
|
||||
|
||||
// The benefits of the hot-path optimization below start to fall
|
||||
// off when the buffer size gets up near 128KB, because the cost
|
||||
// of the copy is more than the cost of the extra write() call.
|
||||
// Switch to the write/end method at that point. Heuristics and
|
||||
// magic numbers are awful, but slow http responses are worse.
|
||||
if (hot && Buffer.isBuffer(data) && data.length > 120 * 1024)
|
||||
hot = false;
|
||||
|
||||
if (hot) {
|
||||
// Hot path. They're doing
|
||||
// res.writeHead();
|
||||
// res.end(blah);
|
||||
// HACKY.
|
||||
|
||||
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 {
|
||||
throw new TypeError('first argument must be a string or Buffer');
|
||||
}
|
||||
this._headerSent = true;
|
||||
|
||||
} else if (data) {
|
||||
if (data) {
|
||||
// Normal body write.
|
||||
ret = this.write(data, encoding);
|
||||
}
|
||||
|
||||
if (!hot) {
|
||||
if (this.chunkedEncoding) {
|
||||
ret = this._send('0\r\n' + this._trailer + '\r\n'); // Last chunk.
|
||||
} else {
|
||||
// Force a flush, HACK.
|
||||
ret = this._send('');
|
||||
}
|
||||
if (this.chunkedEncoding) {
|
||||
ret = this._send('0\r\n' + this._trailer + '\r\n'); // Last chunk.
|
||||
} else {
|
||||
// Force a flush, HACK.
|
||||
ret = this._send('');
|
||||
}
|
||||
|
||||
if (this.connection && data)
|
||||
this.connection.uncork();
|
||||
|
||||
this.finished = true;
|
||||
|
||||
// There is the first message on the outgoing queue, and we've sent
|
||||
|
|
Loading…
Reference in New Issue