Skip to content

Commit ae24120

Browse files
committed
fixup! http: add http.setGlobalProxyFromEnv()
1 parent cc30706 commit ae24120

File tree

7 files changed

+134
-24
lines changed

7 files changed

+134
-24
lines changed

doc/api/http.md

Lines changed: 44 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4361,15 +4361,16 @@ added:
43614361
43624362
Set the maximum number of idle HTTP parsers.
43634363
4364-
## `http.setGlobalProxyFromEnv(proxyEnv)`
4364+
## `http.setGlobalProxyFromEnv([proxyEnv])`
43654365
43664366
<!-- YAML
43674367
added:
43684368
- REPLACEME
43694369
-->
43704370
43714371
* `proxyEnv` {Object} An object containing proxy configuration. This accepts the
4372-
same options as the `proxyEnv` option accepted by [`Agent`][]
4372+
same options as the `proxyEnv` option accepted by [`Agent`][]. **Default:**
4373+
`process.env`.
43734374
* Returns: {Function} A function that restores the original agent and dispatcher
43744375
settings to the state before this `http.setGlobalProxyFromEnv()` is invoked.
43754376
@@ -4466,7 +4467,47 @@ Or the `--use-env-proxy` flag.
44664467
HTTP_PROXY=http://proxy.example.com:8080 NO_PROXY=localhost,127.0.0.1 node --use-env-proxy client.js
44674468
```
44684469
4469-
To enable proxy support dynamically and globally:
4470+
To enable proxy support dynamically and globally with `process.env` (the default option of `http.setGlobalProxyFromEnv()`):
4471+
4472+
```cjs
4473+
const http = require('node:http');
4474+
4475+
// Reads proxy-related environment variables from process.env
4476+
const restore = http.setGlobalProxyFromEnv();
4477+
4478+
// Subsequent requests will use the configured proxies from environment variables
4479+
http.get('http://www.example.com', (res) => {
4480+
// This request will be proxied if HTTP_PROXY or http_proxy is set
4481+
});
4482+
4483+
fetch('https://www.example.com', (res) => {
4484+
// This request will be proxied if HTTPS_PROXY or https_proxy is set
4485+
});
4486+
4487+
// To restore the original global agent and dispatcher settings, call the returned function.
4488+
// restore();
4489+
```
4490+
4491+
```mjs
4492+
import http from 'node:http';
4493+
4494+
// Reads proxy-related environment variables from process.env
4495+
http.setGlobalProxyFromEnv();
4496+
4497+
// Subsequent requests will use the configured proxies from environment variables
4498+
http.get('http://www.example.com', (res) => {
4499+
// This request will be proxied if HTTP_PROXY or http_proxy is set
4500+
});
4501+
4502+
fetch('https://www.example.com', (res) => {
4503+
// This request will be proxied if HTTPS_PROXY or https_proxy is set
4504+
});
4505+
4506+
// To restore the original global agent and dispatcher settings, call the returned function.
4507+
// restore();
4508+
```
4509+
4510+
To enable proxy support dynamically and globally with custom settings:
44704511
44714512
```cjs
44724513
const http = require('node:http');
@@ -4506,25 +4547,6 @@ fetch('https://www.example.com', (res) => {
45064547
});
45074548
```
45084549
4509-
To clear the dynamically enabled global proxy configuration:
4510-
4511-
```cjs
4512-
const http = require('node:http');
4513-
const restore = http.setGlobalProxyFromEnv({ /* ... */ });
4514-
// Perform requests that will be proxied.
4515-
restore();
4516-
// From now on, requests will no longer be proxied.
4517-
```
4518-
4519-
```mjs
4520-
import http from 'node:http';
4521-
4522-
const restore = http.setGlobalProxyFromEnv({ /* ... */ });
4523-
// Perform requests that will be proxied.
4524-
restore();
4525-
// From now on, requests will no longer be proxied.
4526-
```
4527-
45284550
To create a custom agent with built-in proxy support:
45294551
45304552
```cjs

lib/http.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ const {
2525
ObjectDefineProperty,
2626
} = primordials;
2727

28-
const { validateInteger } = require('internal/validators');
28+
const { validateInteger, validateObject } = require('internal/validators');
2929
const httpAgent = require('_http_agent');
3030
const { ClientRequest } = require('_http_client');
3131
const { methods, parsers } = require('_http_common');
@@ -129,7 +129,8 @@ function lazyUndici() {
129129
return undici ??= require('internal/deps/undici/undici');
130130
}
131131

132-
function setGlobalProxyFromEnv(env) {
132+
function setGlobalProxyFromEnv(env = process.env) {
133+
validateObject(env, 'proxyEnv');
133134
const httpProxy = parseProxyUrl(env, 'http:');
134135
const httpsProxy = parseProxyUrl(env, 'https:');
135136
const noProxy = env.no_proxy || env.NO_PROXY;
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Tests that http.setGlobalProxyFromEnv() without arguments uses process.env.
2+
3+
import '../common/index.mjs';
4+
import assert from 'node:assert';
5+
import { startTestServers, checkProxiedFetch } from '../common/proxy-server.js';
6+
7+
const { proxyLogs, proxyUrl, shutdown, httpEndpoint: { serverHost, requestUrl } } = await startTestServers({
8+
httpEndpoint: true,
9+
});
10+
11+
// Test that calling setGlobalProxyFromEnv() without arguments uses process.env
12+
await checkProxiedFetch({
13+
FETCH_URL: requestUrl,
14+
// Set the proxy in the environment instead of passing it to SET_GLOBAL_PROXY
15+
http_proxy: proxyUrl,
16+
SET_GLOBAL_PROXY_DEFAULT: '1', // Signal to call without arguments
17+
}, {
18+
stdout: 'Hello world',
19+
});
20+
21+
shutdown();
22+
23+
// FIXME(undici:4083): undici currently always tunnels the request over
24+
// CONNECT if proxyTunnel is not explicitly set to false.
25+
const expectedLogs = [{
26+
method: 'CONNECT',
27+
url: serverHost,
28+
headers: {
29+
'connection': 'close',
30+
'host': serverHost,
31+
'proxy-connection': 'keep-alive',
32+
},
33+
}];
34+
35+
assert.deepStrictEqual(proxyLogs, expectedLogs);
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Tests that http.setGlobalProxyFromEnv() without arguments uses process.env.
2+
3+
import '../common/index.mjs';
4+
import assert from 'node:assert';
5+
import { startTestServers, checkProxiedRequest } from '../common/proxy-server.js';
6+
7+
const { proxyLogs, proxyUrl, shutdown, httpEndpoint: { serverHost, requestUrl } } = await startTestServers({
8+
httpEndpoint: true,
9+
});
10+
11+
// Test that calling setGlobalProxyFromEnv() without arguments uses process.env
12+
await checkProxiedRequest({
13+
REQUEST_URL: requestUrl,
14+
// Set the proxy in the environment instead of passing it to SET_GLOBAL_PROXY
15+
http_proxy: proxyUrl,
16+
SET_GLOBAL_PROXY_DEFAULT: '1', // Signal to call without arguments
17+
}, {
18+
stdout: 'Hello world',
19+
});
20+
21+
shutdown();
22+
23+
const expectedLogs = [{
24+
method: 'GET',
25+
url: requestUrl,
26+
headers: {
27+
'connection': 'keep-alive',
28+
'proxy-connection': 'keep-alive',
29+
'host': serverHost,
30+
},
31+
}];
32+
33+
assert.deepStrictEqual(proxyLogs, expectedLogs);
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Tests that http.setGlobalProxyFromEnv() validates that proxyEnv is an object.
2+
3+
import '../common/index.mjs';
4+
import assert from 'node:assert';
5+
import http from 'node:http';
6+
7+
for (const invalidInput of [42, 'string', null, [], true]) {
8+
assert.throws(
9+
() => http.setGlobalProxyFromEnv(invalidInput),
10+
{
11+
code: 'ERR_INVALID_ARG_TYPE',
12+
name: 'TypeError',
13+
},
14+
);
15+
}

test/fixtures/fetch-and-log.mjs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ let restore;
44
if (process.env.SET_GLOBAL_PROXY) {
55
const config = JSON.parse(process.env.SET_GLOBAL_PROXY);
66
restore = http.setGlobalProxyFromEnv(config);
7+
} else if (process.env.SET_GLOBAL_PROXY_DEFAULT) {
8+
restore = http.setGlobalProxyFromEnv();
79
}
810

911
const response = await fetch(process.env.FETCH_URL);

test/fixtures/request-and-log.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ let restore;
22
if (process.env.SET_GLOBAL_PROXY) {
33
const config = JSON.parse(process.env.SET_GLOBAL_PROXY);
44
restore = require('http').setGlobalProxyFromEnv(config);
5+
} else if (process.env.SET_GLOBAL_PROXY_DEFAULT) {
6+
restore = require('http').setGlobalProxyFromEnv();
57
}
68

79
const url = process.env.REQUEST_URL;

0 commit comments

Comments
 (0)