Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
90 commits
Select commit Hold shift + click to select a range
91dda5f
deps: update undici to 6.22.0
mcollina Oct 7, 2025
7e0e86c
deps: upgrade npm to 10.9.4
npm-cli-bot Oct 7, 2025
99ea08d
repl: add isValidParentheses check before wrap input
meixg Oct 7, 2025
2237142
module: link module with a module request record
legendecas Oct 7, 2025
7a91282
src: use simdjson::pad
0hmX Aug 17, 2025
6021c3a
tools: copyedit `build-tarball.yml`
aduh95 Sep 10, 2025
ec5290f
build: do not include custom ESLint rules testing in tarball
aduh95 Sep 8, 2025
b632a1d
tools: skip test-internet workflow for draft PRs
targos Sep 11, 2025
d2a7057
lib,src: refactor assert to load error source from memory
legendecas Sep 2, 2025
12e5535
lib: add source map support for assert messages
legendecas Sep 3, 2025
bb6fd7c
src: ensure `v8::Eternal` is empty before setting it
addaleax Sep 11, 2025
9833dc6
doc: rephrase dynamic import() description
meteorqz6 Sep 12, 2025
24c2249
url: add type checking to urlToHttpOptions()
simon-id Sep 12, 2025
16c4b46
benchmark: calibrate config cluster/echo.js
meteorqz6 Sep 12, 2025
4cc84c9
node-api: make napi_delete_reference use node_api_basic_env
JeetuSuthar Sep 12, 2025
4d748ad
src: remove `std::array` overload of `FIXED_ONE_BYTE_STRING`
addaleax Aug 4, 2025
34dcb7d
src: create strings in `FIXED_ONE_BYTE_STRING` as internalized
addaleax Aug 4, 2025
e790eb6
repl: fix cpu overhead pasting big strings to the REPL
BridgeAR Sep 14, 2025
f2fbcc5
util: fix debuglog.enabled not being present with callback logger
BridgeAR Sep 14, 2025
8fd669c
doc: type improvement of file `http.md`
samuel871211 Sep 14, 2025
f88752d
url: replaced slice with at
Connormiha Sep 14, 2025
a71dd59
benchmark: calibrate config dgram multi-buffer
brunocroh Sep 14, 2025
758271a
http: optimize checkIsHttpToken for short strings
JinhyeokFang Sep 14, 2025
a33ed9b
inspector: ensure adequate memory allocation for `Binary::toBase64`
Renegade334 Sep 14, 2025
0a3a3f7
doc: add security escalation policy
UlisesGascon Sep 15, 2025
28ef564
typings: remove unused imports
meteorqz6 Sep 15, 2025
6d24b88
node-api: added SharedArrayBuffer api
mertcanaltin Sep 16, 2025
ba00875
stream: use new AsyncResource instead of bind
mcollina Sep 16, 2025
26b40ba
src: replace FIXED_ONE_BYTE_STRING with Environment-cached strings
iknoom Sep 17, 2025
36b68db
src: reduce the nearest parent package JSON cache size
michaelsmithxyz Sep 17, 2025
85818db
fs,win: do not add a second trailing slash in readdir
Flarna Sep 17, 2025
c42c120
tools: fix `tools/make-v8.sh` for clang
richardlau Sep 17, 2025
af8b5fa
http: add shouldUpgradeCallback to let servers control HTTP upgrades
pimterry Sep 17, 2025
2bf0a93
meta: add .npmrc with ignore-scripts=true
joyeecheung Sep 17, 2025
e02a562
deps: upgrade openssl sources to openssl-3.5.3
nodejs-github-bot Sep 16, 2025
48aaf98
deps: update archs files for openssl-3.5.3
nodejs-github-bot Sep 16, 2025
09bdcce
diagnostics_channel: fix race condition with diagnostics_channel and GC
uurien Sep 19, 2025
892b425
src: rename private fields to follow naming convention
iknoom Sep 20, 2025
c9cde35
src: simplify is_callable by making it a concept
tniessen Sep 20, 2025
34c686b
lib: update inspect output format for subclasses
miguelmarcondesf Sep 21, 2025
ca1942c
test: testcase demonstrating issue 59541
ericrannaud Sep 7, 2025
312b33a
vm: "afterEvaluate", evaluate() return a promise from the outer context
ericrannaud Sep 10, 2025
5bf21a4
vm: explain how to share promises between contexts w/ afterEvaluate
ericrannaud Sep 19, 2025
3a3220a
dgram: restore buffer optimization in fixBufferList
ri7116 Sep 21, 2025
d6e303d
doc: update V8 fast API guidance
Renegade334 Sep 21, 2025
53cb9f3
build: add the missing macro definitions for OpenHarmony
hqzing Sep 22, 2025
816e1be
zlib: reduce code duplication
jhofstee Sep 22, 2025
badbba2
deps: update googletest to 50b8600
nodejs-github-bot Sep 23, 2025
4808dbd
doc: fix typo in section on microtask order
tniessen Sep 23, 2025
4bc366f
doc: use "WebAssembly" instead of "Web Assembly"
tniessen Sep 24, 2025
8e182e5
src: remove unnecessary `Environment::GetCurrent()` calls
iknoom Sep 11, 2025
aed9fd5
crypto: avoid calls to `promise.catch()`
Renegade334 Sep 9, 2025
f488b2f
crypto: use async functions for non-stub Promise-returning functions
Renegade334 Sep 9, 2025
1f93913
crypto: use `return await` when returning Promises from async functions
Renegade334 Sep 9, 2025
2870a73
doc,crypto: update subtle.generateKey and subtle.importKey
panva Sep 13, 2025
095e7a8
tls: only do off-thread certificate loading on loading tls
joyeecheung Sep 11, 2025
19a7b1e
tls: load bundled and extra certificates off-thread
joyeecheung Sep 11, 2025
e4a4f63
sqlite: fix crash session extension callbacks with workers
louwers Sep 23, 2025
ddbc1aa
deps: upgrade openssl sources to openssl-3.5.4
nodejs-github-bot Oct 1, 2025
28aea13
deps: update archs files for openssl-3.5.4
nodejs-github-bot Oct 1, 2025
37c2d18
deps: update amaro to 1.1.4
pmarchini Sep 29, 2025
04590b8
meta: bump actions/setup-python from 5.6.0 to 6.0.0
dependabot[bot] Oct 5, 2025
0fedbb3
meta: bump ossf/scorecard-action from 2.4.2 to 2.4.3
dependabot[bot] Oct 4, 2025
1f3b9d6
meta: bump actions/cache from 4.2.4 to 4.3.0
dependabot[bot] Oct 4, 2025
7cd2b42
meta: bump step-security/harden-runner from 2.12.2 to 2.13.1
dependabot[bot] Oct 4, 2025
0feca0c
meta: bump actions/setup-node from 4.4.0 to 5.0.0
dependabot[bot] Oct 4, 2025
a0ba688
meta: bump actions/stale from 9.1.0 to 10.0.0
dependabot[bot] Oct 4, 2025
090ba14
meta: bump codecov/codecov-action from 5.5.0 to 5.5.1
dependabot[bot] Oct 3, 2025
c591cca
meta: bump github/codeql-action from 3.30.0 to 3.30.5
dependabot[bot] Oct 3, 2025
20a9e86
meta: move Michael to emeritus
mhdawson Oct 1, 2025
3fca564
doc: add automated migration info to deprecations
AugustinMauroy Oct 6, 2025
ca2dff6
doc: fix typo on child_process.md
nglgzz Oct 6, 2025
d37f67d
doc: remove optional title prefixes
avivkeller Oct 5, 2025
3b3b71e
doc: mark `.env` files support as stable
Hilzu Oct 3, 2025
1ddaab1
doc: mention reverse proxy and include simple example
styfle Sep 4, 2025
b3eeb3b
doc: provide alternative to `url.parse()` using WHATWG URL
styfle Sep 2, 2025
ef005d0
typings: update 'types' binding
Renegade334 Sep 24, 2025
84701ff
src: clear all linked module caches once instantiated
legendecas Jul 29, 2025
e10dc7b
module: allow overriding linked requests for a ModuleWrap
legendecas Aug 22, 2025
6277058
vm: sync-ify SourceTextModule linkage
legendecas Aug 29, 2025
1eadab8
win,tools: add description to signature
martincostello Oct 3, 2025
7067d79
test: mark sea tests flaky on macOS x64
richardlau Sep 30, 2025
686ac49
src: add percentage support to --max-old-space-size
Asaf-Federman Jul 28, 2025
42c5544
src: assert memory calc for max-old-space-size-percentage
Asaf-Federman Aug 18, 2025
660d573
test,doc: skip --max-old-space-size-percentage on 32-bit platforms
Asaf-Federman Oct 9, 2025
bedaaa1
http: support http proxy for fetch under NODE_USE_ENV_PROXY
joyeecheung Mar 20, 2025
ebec3ef
test: move http proxy tests to test/client-proxy
joyeecheung Jul 3, 2025
4210259
http,https: add built-in proxy support in http/https.request and Agent
joyeecheung Jul 1, 2025
1486fed
cli: add --use-env-proxy
joyeecheung Jul 26, 2025
54b94e1
2025-10-20, Version 22.21.0 'Jod' (LTS)
aduh95 Oct 18, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
http,https: add built-in proxy support in http/https.request and Agent
This patch implements proxy support for HTTP and HTTPS clients and
agents in the `http` and `https` built-ins`. When NODE_USE_ENV_PROXY
is set to 1, the default global agent would parse the
HTTP_PROXY/http_proxy, HTTPS_PROXY/https_proxy, NO_PROXY/no_proxy
settings from the environment variables, and proxy the requests
sent through the built-in http/https client accordingly.

To support this, `http.Agent` and `https.Agent` now accept a few new
options:

- `proxyEnv`: when it's an object, the agent would read and parse
  the HTTP_PROXY/http_proxy, HTTPS_PROXY/https_proxy, NO_PROXY/no_proxy
  properties from it, and apply them based on the protocol it uses
  to send requests. This option allows custom agents to
  reuse built-in proxy support by composing options. Global agents
  set this to `process.env` when NODE_USE_ENV_PROXY is 1.
- `defaultPort` and `protocol`: these allow setting of the default port
  and protocol of the agents. We also need these when configuring
  proxy settings and deciding whether a request should be proxied.

Implementation-wise, this adds a `ProxyConfig` internal class to handle
parsing and application of proxy configurations. The configuration
is parsed during agent construction. When requests are made,
the `createConnection()` methods on the agents would check whether
the request should be proxied. If yes, they either connect to the
proxy server (in the case of HTTP reqeusts) or establish a tunnel
(in the case of HTTPS requests) through either a TCP socket (if the
proxy uses HTTP) or a TLS socket (if the proxy uses HTTPS).

When proxying HTTPS requests through a tunnel, the connection listener
is invoked after the tunnel is established. Tunnel establishment uses
the timeout of the request options, if there is one. Otherwise it uses
the timeout of the agent.

If an error is encountered during tunnel establishment, an
ERR_PROXY_TUNNEL would be emitted on the returned socket. If the proxy
server sends a errored status code, the error would contain an
`statusCode` property. If the error is caused by timeout, the error
would contain a `proxyTunnelTimeout` property.

This implementation honors the built-in socket pool and socket limits.
Pooled sockets are still keyed by request endpoints, they are just
connected to the proxy server instead, and the persistence of the
connection can be maintained as long as the proxy server respects
connection/proxy-connection or persist by default (HTTP/1.1)

PR-URL: #58980
Refs: #57872
Refs: #8381
Refs: #15620
Reviewed-By: Matteo Collina <[email protected]>
  • Loading branch information
joyeecheung authored and aduh95 committed Oct 18, 2025
commit 42102594b1ec23bb77558e1dd43c9093b17f0961
12 changes: 12 additions & 0 deletions doc/api/errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -2527,6 +2527,18 @@ Accessing `Object.prototype.__proto__` has been forbidden using
[`Object.setPrototypeOf`][] should be used to get and set the prototype of an
object.

<a id="ERR_PROXY_INVALID_CONFIG"></a>

### `ERR_PROXY_INVALID_CONFIG`

Failed to proxy a request because the proxy configuration is invalid.

<a id="ERR_PROXY_TUNNEL"></a>

### `ERR_PROXY_TUNNEL`

Failed to establish proxy tunnel when `NODE_USE_ENV_PROXY` is enabled.

<a id="ERR_QUIC_APPLICATION_ERROR"></a>

### `ERR_QUIC_APPLICATION_ERROR`
Expand Down
114 changes: 114 additions & 0 deletions doc/api/http.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,14 @@ http.get({
<!-- YAML
added: v0.3.4
changes:
- version:
- REPLACEME
pr-url: https://github.com/nodejs/node/pull/58980
description: Add support for `proxyEnv`.
- version:
- REPLACEME
pr-url: https://github.com/nodejs/node/pull/58980
description: Add support for `defaultPort` and `protocol`.
- version:
- v22.20.0
pr-url: https://github.com/nodejs/node/pull/59315
Expand Down Expand Up @@ -188,6 +196,20 @@ changes:
**Default:** `'lifo'`.
* `timeout` {number} Socket timeout in milliseconds.
This will set the timeout when the socket is created.
* `proxyEnv` {Object|undefined} Environment variables for proxy configuration.
See [Built-in Proxy Support][] for details. **Default:** `undefined`
* `HTTP_PROXY` {string|undefined} URL for the proxy server that HTTP requests should use.
If undefined, no proxy is used for HTTP requests.
* `HTTPS_PROXY` {string|undefined} URL for the proxy server that HTTPS requests should use.
If undefined, no proxy is used for HTTPS requests.
* `NO_PROXY` {string|undefined} Patterns specifying the endpoints
that should not be routed through a proxy.
* `http_proxy` {string|undefined} Same as `HTTP_PROXY`. If both are set, `http_proxy` takes precedence.
* `https_proxy` {string|undefined} Same as `HTTPS_PROXY`. If both are set, `https_proxy` takes precedence.
* `no_proxy` {string|undefined} Same as `NO_PROXY`. If both are set, `no_proxy` takes precedence.
* `defaultPort` {number} Default port to use when the port is not specified
in requests. **Default:** `80`.
* `protocol` {string} The protocol to use for the agent. **Default:** `'http:'`.

`options` in [`socket.connect()`][] are also supported.

Expand Down Expand Up @@ -4299,6 +4321,98 @@ added:

A browser-compatible implementation of {WebSocket}.

## Built-in Proxy Support

<!-- YAML
added: REPLACEME
-->

> Stability: 1.1 - Active development

When Node.js creates the global agent, it checks the `NODE_USE_ENV_PROXY`
environment variable. If it is set to `1`, the global agent will be constructed
with `proxyEnv: process.env`, enabling proxy support based on the environment variables.

Custom agents can also be created with proxy support by passing a
`proxyEnv` option when constructing the agent. The value can be `process.env`
if they just want to inherit the configuration from the environment variables,
or an object with specific setting overriding the environment.

The following properties of the `proxyEnv` are checked to configure proxy
support.

* `HTTP_PROXY` or `http_proxy`: Proxy server URL for HTTP requests. If both are set,
`http_proxy` takes precedence.
* `HTTPS_PROXY` or `https_proxy`: Proxy server URL for HTTPS requests. If both are set,
`https_proxy` takes precedence.
* `NO_PROXY` or `no_proxy`: Comma-separated list of hosts to bypass the proxy. If both are set,
`no_proxy` takes precedence.

If the request is made to a Unix domain socket, the proxy settings will be ignored.

### Proxy URL Format

Proxy URLs can use either HTTP or HTTPS protocols:

* HTTP proxy: `http://proxy.example.com:8080`
* HTTPS proxy: `https://proxy.example.com:8080`
* Proxy with authentication: `http://username:[email protected]:8080`

### `NO_PROXY` Format

The `NO_PROXY` environment variable supports several formats:

* `*` - Bypass proxy for all hosts
* `example.com` - Exact host name match
* `.example.com` - Domain suffix match (matches `sub.example.com`)
* `*.example.com` - Wildcard domain match
* `192.168.1.100` - Exact IP address match
* `192.168.1.1-192.168.1.100` - IP address range
* `example.com:8080` - Hostname with specific port

Multiple entries should be separated by commas.

### Example

Starting a Node.js process with proxy support enabled for all requests sent
through the default global agent:

```console
NODE_USE_ENV_PROXY=1 HTTP_PROXY=http://proxy.example.com:8080 NO_PROXY=localhost,127.0.0.1 node client.js
```

To create a custom agent with built-in proxy support:

```cjs
const http = require('node:http');

// Creating a custom agent with custom proxy support.
const agent = new http.Agent({ proxyEnv: { HTTP_PROXY: 'http://proxy.example.com:8080' } });

http.request({
hostname: 'www.example.com',
port: 80,
path: '/',
agent,
}, (res) => {
// This request will be proxied through proxy.example.com:8080 using the HTTP protocol.
console.log(`STATUS: ${res.statusCode}`);
});
```

Alternatively, the following also works:

```cjs
const http = require('node:http');
// Use lower-cased option name.
const agent1 = new http.Agent({ proxyEnv: { http_proxy: 'http://proxy.example.com:8080' } });
// Use values inherited from the environment variables, if the process is started with
// HTTP_PROXY=http://proxy.example.com:8080 this will use the proxy server specified
// in process.env.HTTP_PROXY.
const agent2 = new http.Agent({ proxyEnv: process.env });
```

[Built-in Proxy Support]: #built-in-proxy-support
[RFC 8187]: https://www.rfc-editor.org/rfc/rfc8187.txt
[`'ERR_HTTP_CONTENT_LENGTH_MISMATCH'`]: errors.md#err_http_content_length_mismatch
[`'checkContinue'`]: #event-checkcontinue
Expand Down
8 changes: 8 additions & 0 deletions doc/api/https.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,14 @@ An [`Agent`][] object for HTTPS similar to [`http.Agent`][]. See

<!-- YAML
changes:
- version:
- REPLACEME
pr-url: https://github.com/nodejs/node/pull/58980
description: Add support for `proxyEnv`.
- version:
- REPLACEME
pr-url: https://github.com/nodejs/node/pull/58980
description: Add support for `defaultPort` and `protocol`.
- version: v12.5.0
pr-url: https://github.com/nodejs/node/pull/28209
description: do not automatically set servername if the target host was
Expand Down
110 changes: 95 additions & 15 deletions lib/_http_agent.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,17 @@ const EventEmitter = require('events');
let debug = require('internal/util/debuglog').debuglog('http', (fn) => {
debug = fn;
});
const {
parseProxyConfigFromEnv,
kProxyConfig,
checkShouldUseProxy,
kWaitForProxyTunnel,
filterEnvForProxies,
} = require('internal/http');
const { AsyncResource } = require('async_hooks');
const { async_id_symbol } = require('internal/async_hooks').symbols;
const {
getLazy,
kEmptyObject,
once,
} = require('internal/util');
Expand All @@ -46,6 +54,7 @@ const {
validateOneOf,
validateString,
} = require('internal/validators');
const assert = require('internal/assert');

const kOnKeylog = Symbol('onkeylog');
const kRequestOptions = Symbol('requestOptions');
Expand Down Expand Up @@ -83,11 +92,11 @@ function Agent(options) {

EventEmitter.call(this);

this.defaultPort = 80;
this.protocol = 'http:';

this.options = { __proto__: null, ...options };

this.defaultPort = this.options.defaultPort || 80;
this.protocol = this.options.protocol || 'http:';

if (this.options.noDelay === undefined)
this.options.noDelay = true;

Expand All @@ -103,6 +112,11 @@ function Agent(options) {
this.scheduling = this.options.scheduling || 'lifo';
this.maxTotalSockets = this.options.maxTotalSockets;
this.totalSocketCount = 0;
const proxyEnv = this.options.proxyEnv;
if (typeof proxyEnv === 'object' && proxyEnv !== null) {
this[kProxyConfig] = parseProxyConfigFromEnv(proxyEnv, this.protocol, this.keepAlive);
debug(`new ${this.protocol} agent with proxy config`, this[kProxyConfig]);
}

this.agentKeepAliveTimeoutBuffer =
typeof this.options.agentKeepAliveTimeoutBuffer === 'number' &&
Expand Down Expand Up @@ -206,9 +220,40 @@ function maybeEnableKeylog(eventName) {
}
}

const lazyTLS = getLazy(() => require('tls'));

Agent.defaultMaxSockets = Infinity;

Agent.prototype.createConnection = net.createConnection;
// See ProxyConfig in internal/http.js for how the connection should be handled
// when the agent is configured to use a proxy server.
Agent.prototype.createConnection = function createConnection(...args) {
const normalized = net._normalizeArgs(args);
const options = normalized[0];
const cb = normalized[1];

// Check if this specific request should bypass the proxy
const shouldUseProxy = checkShouldUseProxy(this[kProxyConfig], options);
debug(`http createConnection should use proxy for ${options.host}:${options.port}:`, shouldUseProxy);
if (!shouldUseProxy) { // Forward to net.createConnection if no proxying is needed.
return net.createConnection(...args);
}

// Create a copy of the shared proxy connection options and connect
// to the proxy server instead of the endpoint. For Agent.prototype.createConnection
// which is used by the http agent, this is enough
const connectOptions = {
...this[kProxyConfig].proxyConnectionOptions,
};
const proxyProtocol = this[kProxyConfig].protocol;
if (proxyProtocol === 'http:') {
return net.connect(connectOptions, cb);
} else if (proxyProtocol === 'https:') {
return lazyTLS().connect(connectOptions, cb);
}
// This should be unreachable because proxy config should be null for other protocols.
assert.fail(`Unexpected proxy protocol ${proxyProtocol}`);

};

// Get the key for a given set of request options
Agent.prototype.getName = function getName(options = kEmptyObject) {
Expand All @@ -233,6 +278,16 @@ Agent.prototype.getName = function getName(options = kEmptyObject) {
return name;
};

function handleSocketAfterProxy(err, req) {
if (err.code === 'ERR_PROXY_TUNNEL') {
if (err.proxyTunnelTimeout) {
req.emit('timeout'); // Propagate the timeout from the tunnel to the request.
} else {
req.emit('error', err);
}
}
}

Agent.prototype.addRequest = function addRequest(req, options, port/* legacy */,
localAddress/* legacy */) {
// Legacy API: addRequest(req, host, port, localAddress)
Expand All @@ -245,6 +300,7 @@ Agent.prototype.addRequest = function addRequest(req, options, port/* legacy */,
};
}

// Here the agent options will override per-request options.
options = { __proto__: null, ...options, ...this.options };
if (options.socketPath)
options.path = options.socketPath;
Expand All @@ -270,20 +326,24 @@ Agent.prototype.addRequest = function addRequest(req, options, port/* legacy */,
const freeLen = freeSockets ? freeSockets.length : 0;
const sockLen = freeLen + this.sockets[name].length;

// Reusing a socket from the pool.
if (socket) {
asyncResetHandle(socket);
this.reuseSocket(socket, req);
setRequestSocket(this, req, socket);
this.sockets[name].push(socket);
} else if (sockLen < this.maxSockets &&
this.totalSocketCount < this.maxTotalSockets) {
debug('call onSocket', sockLen, freeLen);
// If we are under maxSockets create a new one.
this.createSocket(req, options, (err, socket) => {
if (err)
if (err) {
handleSocketAfterProxy(err, req);
debug('call onSocket', sockLen, freeLen);
req.onSocket(socket, err);
else
setRequestSocket(this, req, socket);
return;
}

setRequestSocket(this, req, socket);
});
} else {
debug('wait for socket');
Expand All @@ -300,16 +360,23 @@ Agent.prototype.addRequest = function addRequest(req, options, port/* legacy */,
};

Agent.prototype.createSocket = function createSocket(req, options, cb) {
// Here the agent options will override per-request options.
options = { __proto__: null, ...options, ...this.options };
if (options.socketPath)
options.path = options.socketPath;

normalizeServerName(options, req);

// Make sure per-request timeout is respected.
const timeout = req.timeout || this.options.timeout || undefined;
if (timeout) {
options.timeout = timeout;
}

const name = this.getName(options);
options._agentKey = name;

debug('createConnection', name, options);
debug('createConnection', name);
options.encoding = null;

const oncreate = once((err, s) => {
Expand All @@ -327,8 +394,15 @@ Agent.prototype.createSocket = function createSocket(req, options, cb) {
options.keepAlive = this.keepAlive;
options.keepAliveInitialDelay = this.keepAliveMsecs;
}

const newSocket = this.createConnection(options, oncreate);
if (newSocket)
// In the case where we are proxying through a tunnel for HTTPS, only add
// the socket to the pool and install/invoke the listeners after
// the tunnel is successfully established, so that actual operations
// on the socket all go through the tunnel. Errors emitted during
// tunnel establishment will be handled in the createConnection method
// in lib/https.js.
if (newSocket && !newSocket[kWaitForProxyTunnel])
oncreate(null, newSocket);
};

Expand Down Expand Up @@ -462,10 +536,13 @@ Agent.prototype.removeSocket = function removeSocket(s, options) {
req[kRequestOptions] = undefined;
// If we have pending requests and a socket gets closed make a new one
this.createSocket(req, options, (err, socket) => {
if (err)
req.onSocket(socket, err);
else
socket.emit('free');
if (err) {
handleSocketAfterProxy(err, req);
req.onSocket(null, err);
return;
}

socket.emit('free');
});
}

Expand Down Expand Up @@ -549,5 +626,8 @@ function asyncResetHandle(socket) {

module.exports = {
Agent,
globalAgent: new Agent({ keepAlive: true, scheduling: 'lifo', timeout: 5000 }),
globalAgent: new Agent({
keepAlive: true, scheduling: 'lifo', timeout: 5000,
proxyEnv: process.env.NODE_USE_ENV_PROXY ? filterEnvForProxies(process.env) : undefined,
}),
};
Loading
Loading