diff --git a/lib/_http_incoming.js b/lib/_http_incoming.js index c1ff5c8dd22536..d09683c9a8f1b1 100644 --- a/lib/_http_incoming.js +++ b/lib/_http_incoming.js @@ -33,7 +33,6 @@ const { } = primordials; const { Readable, finished } = require('stream'); -const { kDestroy, destroy } = require('internal/stream') const kHeaders = Symbol('kHeaders'); const kHeadersCount = Symbol('kHeadersCount'); @@ -173,14 +172,6 @@ IncomingMessage.prototype._read = function _read(n) { readStart(this.socket); }; -IncomingMessage.prototype[kDestroy] = function (err) { - if (!err && !this.res.destroyed) { - this.socket = null - } - - this.destroy(err) -} - // It's possible that the socket will be destroyed, and removed from // any messages, before ever calling this. In that case, just skip // it, since something else is destroying this connection anyway. diff --git a/lib/_http_server.js b/lib/_http_server.js index 8ada9e8cfe987a..81e64e268ce94f 100644 --- a/lib/_http_server.js +++ b/lib/_http_server.js @@ -68,8 +68,10 @@ const { const { IncomingMessage } = require('_http_incoming'); const { connResetException, - codes + codes, + AbortError } = require('internal/errors'); +const { kDestroy } = require('internal/stream'); const { ERR_HTTP_REQUEST_TIMEOUT, ERR_HTTP_HEADERS_SENT, @@ -361,6 +363,23 @@ function writeHead(statusCode, reason, obj) { // Docs-only deprecated: DEP0063 ServerResponse.prototype.writeHeader = ServerResponse.prototype.writeHead; +class ServerRequest extends IncomingMessage { + [kDestroy] (err) { + if (!this.res.destroyed) { + this._destroy = (err, cb) => { + if (!this.readableEnded || !this.complete) { + this.aborted = true; + this.emit('aborted'); + } + + cb(err) + }; + } + + this.destroy(err); + } +} + function Server(options, requestListener) { if (!(this instanceof Server)) return new Server(options, requestListener); @@ -373,7 +392,7 @@ function Server(options, requestListener) { throw new ERR_INVALID_ARG_TYPE('options', 'object', options); } - this[kIncomingMessage] = options.IncomingMessage || IncomingMessage; + this[kIncomingMessage] = options.IncomingMessage || options.ServerRequest || ServerRequest; this[kServerResponse] = options.ServerResponse || ServerResponse; const maxHeaderSize = options.maxHeaderSize; @@ -997,6 +1016,7 @@ module.exports = { STATUS_CODES, Server, ServerResponse, + ServerRequest, _connectionListener: connectionListener, kServerResponse }; diff --git a/lib/internal/streams/destroy.js b/lib/internal/streams/destroy.js index 88f8d67614b136..14868a961e097e 100644 --- a/lib/internal/streams/destroy.js +++ b/lib/internal/streams/destroy.js @@ -5,6 +5,7 @@ const { codes: { ERR_MULTIPLE_CALLBACK, }, + AbortError, } = require('internal/errors'); const { FunctionPrototypeCall, @@ -374,8 +375,12 @@ function destroyer(stream, err) { return } + if (!err && (stream.readable || stream.writable)) { + err = new AbortError(); + } + if (typeof stream[kDestroy] === 'function') { - stream[kDestroy](); + stream[kDestroy](err); } else if (isRequest(stream)) { stream.abort(); } else if (isRequest(stream.req)) { @@ -406,6 +411,7 @@ module.exports = { kDestroy, construct, destroyer, + destroy2, destroy, undestroy, errorOrDestroy