diff --git a/lib/_http_client.js b/lib/_http_client.js index 676ed3b2c50aaa..183233e494c108 100644 --- a/lib/_http_client.js +++ b/lib/_http_client.js @@ -66,7 +66,7 @@ const { } = require('internal/dtrace'); const INVALID_PATH_REGEX = /[^\u0021-\u00ff]/; -const kOnSocket = Symbol('kOnSocket'); +const kError = Symbol('kError'); function validateHost(host, name) { if (host !== null && host !== undefined && typeof host !== 'string') { @@ -358,28 +358,17 @@ ClientRequest.prototype.destroy = function destroy(err) { this.res._dump(); } - if (!this.socket) { - this.once(kOnSocket, (socket) => { - if (this.agent) { - socket.emit('free'); - } else { - socket.destroy(); - } - - if (!this.aborted && !err) { - err = connResetException('socket hang up'); - } - - if (err) { - this.emit('error', err); - } - this.emit('close'); - }); - } else { + // In the event that we don't have a socket, we will pop out of + // the request queue through handling in onSocket. + if (this.socket) { + // in-progress this.socket.destroy(err); + } else if (err) { + this[kError] = err; } }; + function emitAbortNT(req) { req.emit('abort'); } @@ -710,12 +699,6 @@ function emitFreeNT(req) { } function tickOnSocket(req, socket) { - req.emit(kOnSocket, socket); - - if (req.destroyed) { - return; - } - const parser = parsers.alloc(); req.socket = socket; parser.initialize(HTTPParser.RESPONSE, @@ -776,9 +759,30 @@ function listenSocketTimeout(req) { } ClientRequest.prototype.onSocket = function onSocket(socket) { - process.nextTick(tickOnSocket, this, socket); + process.nextTick(onSocketNT, this, socket); }; +function onSocketNT(req, socket) { + if (req.destroyed) { + // If we were aborted while waiting for a socket, skip the whole thing. + if (!req.agent) { + socket.destroy(req[kError]); + } else { + socket.emit('free'); + let err = req[kError]; + if (!req.aborted && !err) { + err = connResetException('socket hang up'); + } + if (err) { + req.emit('error', err); + } + req.emit('close'); + } + } else { + tickOnSocket(req, socket); + } +} + ClientRequest.prototype._deferToConnect = _deferToConnect; function _deferToConnect(method, arguments_, cb) { // This function is for calls that need to happen once the socket is