diff --git a/lib/_http_client.js b/lib/_http_client.js index b81ffa1cefc573..5048794f274397 100644 --- a/lib/_http_client.js +++ b/lib/_http_client.js @@ -44,6 +44,7 @@ const { const net = require('net'); const url = require('url'); const assert = require('internal/assert'); +const { once } = require('internal/util'); const { _checkIsHttpToken: checkIsHttpToken, debug, @@ -240,8 +241,6 @@ function ClientRequest(input, options, cb) { this.host = host; this.protocol = protocol; - let called = false; - if (this.agent) { // If there is an agent we should default to Connection:keep-alive, // but only if the Agent will actually reuse the connection! @@ -305,18 +304,6 @@ function ClientRequest(input, options, cb) { options.headers); } - const oncreate = (err, socket) => { - if (called) - return; - called = true; - if (err) { - process.nextTick(() => this.emit('error', err)); - return; - } - this.onSocket(socket); - this._deferToConnect(null, null, () => this._flush()); - }; - // initiate connection if (this.agent) { this.agent.addRequest(this, options); @@ -325,20 +312,27 @@ function ClientRequest(input, options, cb) { this._last = true; this.shouldKeepAlive = false; if (typeof options.createConnection === 'function') { - const newSocket = options.createConnection(options, oncreate); - if (newSocket && !called) { - called = true; - this.onSocket(newSocket); - } else { - return; + const oncreate = once((err, socket) => { + if (err) { + process.nextTick(() => this.emit('error', err)); + } else { + this.onSocket(socket); + } + }); + + try { + const newSocket = options.createConnection(options, oncreate); + if (newSocket) { + oncreate(null, newSocket); + } + } catch (err) { + oncreate(err); } } else { debug('CLIENT use net.createConnection', options); this.onSocket(net.createConnection(options)); } } - - this._deferToConnect(null, null, () => this._flush()); } ObjectSetPrototypeOf(ClientRequest.prototype, OutgoingMessage.prototype); ObjectSetPrototypeOf(ClientRequest, OutgoingMessage); @@ -826,6 +820,7 @@ function onSocketNT(req, socket, err) { _destroy(req, null, err); } else { tickOnSocket(req, socket); + req._flush(); } }