diff --git a/lib/_http_outgoing.js b/lib/_http_outgoing.js index 7681222cf37fc6..d2a3352f080d60 100644 --- a/lib/_http_outgoing.js +++ b/lib/_http_outgoing.js @@ -112,35 +112,29 @@ OutgoingMessage.prototype.setTimeout = function(msecs, callback) { // any messages, before ever calling this. In that case, just skip // it, since something else is destroying this connection anyway. OutgoingMessage.prototype.destroy = function(error) { - if (this.socket) + if (this.socket) { + // If the socket is corked from a write, uncork it before destroying it. + if (this.socket._writableState.corked) + this.socket.uncork(); + this.socket.destroy(error); - else + } else { this.once('socket', function(socket) { socket.destroy(error); }); + } }; // This abstract either writing directly to the socket or buffering it. OutgoingMessage.prototype._send = function(data, encoding, callback) { - // This is a shameful hack to get the headers and first body chunk onto - // the same packet. Future versions of Node are going to take care of - // this at a lower level and in a more general way. + // Send the headers before the body. OutgoingMessage#write should cork + // the stream before calling #_send, batching them in the same packet. if (!this._headerSent) { - if (typeof data === 'string' && - encoding !== 'hex' && - encoding !== 'base64') { - data = this._header + data; - } else { - this.output.unshift(this._header); - this.outputEncodings.unshift('latin1'); - this.outputCallbacks.unshift(null); - this.outputSize += this._header.length; - if (typeof this._onPendingData === 'function') - this._onPendingData(this._header.length); - } + this._writeRaw(this._header, 'latin1', null); this._headerSent = true; } + return this._writeRaw(data, encoding, callback); }; @@ -461,6 +455,13 @@ OutgoingMessage.prototype.write = function(chunk, encoding, callback) { // signal the user to keep writing. if (chunk.length === 0) return true; + // By corking the socket and uncorking after a tick, we manage to + // batch writes together, i.e. the header with the body. + if (this.connection) { + this.connection.cork(); + process.nextTick(connectionCorkNT, this.connection); + } + var len, ret; if (this.chunkedEncoding) { if (typeof chunk === 'string' && @@ -477,10 +478,6 @@ OutgoingMessage.prototype.write = function(chunk, encoding, callback) { else len = chunk.length; - if (this.connection && !this.connection.corked) { - this.connection.cork(); - process.nextTick(connectionCorkNT, this.connection); - } this._send(len.toString(16), 'latin1', null); this._send(crlf_buf, null, null); this._send(chunk, encoding, null); @@ -670,12 +667,11 @@ OutgoingMessage.prototype._flushOutput = function _flushOutput(socket) { var output = this.output; var outputEncodings = this.outputEncodings; var outputCallbacks = this.outputCallbacks; - socket.cork(); + for (var i = 0; i < outputLength; i++) { ret = socket.write(output[i], outputEncodings[i], outputCallbacks[i]); } - socket.uncork(); this.output = []; this.outputEncodings = [];