diff --git a/lib/_http_incoming.js b/lib/_http_incoming.js index 067a4cda3e39..ecd0d5e95179 100644 --- a/lib/_http_incoming.js +++ b/lib/_http_incoming.js @@ -299,6 +299,13 @@ IncomingMessage.prototype._destroy = function _destroy(err, cb) { cleanup(); process.nextTick(onError, this, e || err, cb); }); + } else if (err == null && !this.aborted) { + // The message was received completely and is being destroyed cleanly: + // complete the destroy synchronously. 'close' is still emitted on a + // later tick by the stream machinery. The deferral below only exists + // so that 'error' listeners attached right after destroy(err) still + // receive the error, which cannot matter when there is no error. + cb(); } else { process.nextTick(onError, this, err, cb); } @@ -512,7 +519,14 @@ IncomingMessage.prototype._dump = function _dump() { // If there is buffered data, it may trigger 'data' events. // Remove 'data' event listeners explicitly. this.removeAllListeners('data'); - this.resume(); + if (this.complete && !this.destroyed && this.readableLength === 0) { + // The message was fully received and never read: there is nothing to + // pull off the wire. Go straight to the 'end' emission instead of + // paying for the resume() and flow() scheduling machinery. + this.read(0); + } else { + this.resume(); + } } };