mirror of
https://github.com/nodejs/node.git
synced 2025-08-15 13:48:44 +02:00
cli: add --use-env-proxy
This does the same as NODE_USE_ENV_PROXY. When both are set, like other options that can be configured from both sides, the CLI flag takes precedence. PR-URL: https://github.com/nodejs/node/pull/59151 Fixes: https://github.com/nodejs/node/issues/59100 Reviewed-By: Ilyas Shabi <ilyasshabi94@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
This commit is contained in:
parent
5e1a4fa3e4
commit
0259df9faf
16 changed files with 347 additions and 30 deletions
|
@ -78,8 +78,6 @@ if (!common.isWindows) {
|
|||
REQUEST_URL: requestUrl,
|
||||
http_proxy: `http://localhost:${proxy.address().port}`,
|
||||
HTTP_PROXY: `http://localhost:${proxy2.address().port}`,
|
||||
}, {
|
||||
stdout: 'Hello world',
|
||||
});
|
||||
assert.deepStrictEqual(logs, expectedLogs);
|
||||
assert.strictEqual(stderr.trim(), '');
|
||||
|
|
|
@ -92,8 +92,6 @@ if (!common.isWindows) {
|
|||
https_proxy: `http://localhost:${proxy.address().port}`,
|
||||
HTTPS_PROXY: `http://localhost:${proxy2.address().port}`,
|
||||
NODE_EXTRA_CA_CERTS: fixtures.path('keys', 'fake-startcom-root-cert.pem'),
|
||||
}, {
|
||||
stdout: 'Hello world',
|
||||
});
|
||||
assert.deepStrictEqual(logs, expectedLogs);
|
||||
assert.strictEqual(stderr.trim(), '');
|
||||
|
|
75
test/client-proxy/test-use-env-proxy-cli-http.mjs
Normal file
75
test/client-proxy/test-use-env-proxy-cli-http.mjs
Normal file
|
@ -0,0 +1,75 @@
|
|||
// This tests that --use-env-proxy works the same as NODE_USE_ENV_PROXY=1
|
||||
// for HTTP requests using the built-in http module and fetch API.
|
||||
|
||||
import * as common from '../common/index.mjs';
|
||||
import assert from 'node:assert';
|
||||
import http from 'node:http';
|
||||
import { once } from 'events';
|
||||
import { createProxyServer, runProxiedRequest, checkProxiedFetch } from '../common/proxy-server.js';
|
||||
|
||||
// Start a minimal proxy server.
|
||||
const { proxy, logs } = createProxyServer();
|
||||
proxy.listen(0);
|
||||
await once(proxy, 'listening');
|
||||
|
||||
delete process.env.NODE_USE_ENV_PROXY; // Ensure the environment variable is not set.
|
||||
|
||||
// Start a HTTP server to process the final request.
|
||||
const server = http.createServer(common.mustCall((req, res) => {
|
||||
res.end('Hello world');
|
||||
}, 2));
|
||||
server.on('error', common.mustNotCall((err) => { console.error('Server error', err); }));
|
||||
server.listen(0);
|
||||
await once(server, 'listening');
|
||||
|
||||
const serverHost = `localhost:${server.address().port}`;
|
||||
const requestUrl = `http://${serverHost}/test`;
|
||||
|
||||
// Tests --use-env-proxy works with http builtins.
|
||||
{
|
||||
const { code, signal, stderr, stdout } = await runProxiedRequest({
|
||||
REQUEST_URL: requestUrl,
|
||||
HTTP_PROXY: `http://localhost:${proxy.address().port}`,
|
||||
}, ['--use-env-proxy']);
|
||||
assert.strictEqual(stderr.trim(), '');
|
||||
assert.match(stdout, /Hello world/);
|
||||
assert.strictEqual(code, 0);
|
||||
assert.strictEqual(signal, null);
|
||||
assert.deepStrictEqual(logs, [{
|
||||
method: 'GET',
|
||||
url: requestUrl,
|
||||
headers: {
|
||||
'connection': 'keep-alive',
|
||||
'proxy-connection': 'keep-alive',
|
||||
'host': serverHost,
|
||||
},
|
||||
}]);
|
||||
}
|
||||
|
||||
// Tests --use-env-proxy works with fetch and http.
|
||||
{
|
||||
logs.splice(0, logs.length);
|
||||
await checkProxiedFetch({
|
||||
FETCH_URL: requestUrl,
|
||||
HTTP_PROXY: `http://localhost:${proxy.address().port}`,
|
||||
}, {
|
||||
stdout: 'Hello world',
|
||||
}, ['--use-env-proxy']);
|
||||
|
||||
// FIXME(undici:4083): undici currently always tunnels the request over
|
||||
// CONNECT if proxyTunnel is not explicitly set to false, but what we
|
||||
// need is for it to be automatically false for HTTP requests to be
|
||||
// consistent with curl.
|
||||
assert.deepStrictEqual(logs, [{
|
||||
method: 'CONNECT',
|
||||
url: serverHost,
|
||||
headers: {
|
||||
'connection': 'close',
|
||||
'proxy-connection': 'keep-alive',
|
||||
'host': serverHost,
|
||||
},
|
||||
}]);
|
||||
}
|
||||
|
||||
server.close();
|
||||
proxy.close();
|
81
test/client-proxy/test-use-env-proxy-cli-https.mjs
Normal file
81
test/client-proxy/test-use-env-proxy-cli-https.mjs
Normal file
|
@ -0,0 +1,81 @@
|
|||
// This tests that --use-env-proxy works the same as NODE_USE_ENV_PROXY=1
|
||||
// for HTTPS requests using the built-in https module and fetch API.
|
||||
|
||||
import * as common from '../common/index.mjs';
|
||||
import fixtures from '../common/fixtures.js';
|
||||
import assert from 'node:assert';
|
||||
import { once } from 'events';
|
||||
import { createProxyServer, runProxiedRequest, checkProxiedFetch } from '../common/proxy-server.js';
|
||||
|
||||
if (!common.hasCrypto) {
|
||||
common.skip('missing crypto');
|
||||
}
|
||||
|
||||
// https must be dynamically imported so that builds without crypto support
|
||||
// can skip it.
|
||||
const { default: https } = await import('node:https');
|
||||
|
||||
// Start a minimal proxy server.
|
||||
const { proxy, logs } = createProxyServer();
|
||||
proxy.listen(0);
|
||||
await once(proxy, 'listening');
|
||||
|
||||
delete process.env.NODE_USE_ENV_PROXY; // Ensure the environment variable is not set.
|
||||
// Start a HTTPS server to process the final request.
|
||||
const server = https.createServer({
|
||||
cert: fixtures.readKey('agent8-cert.pem'),
|
||||
key: fixtures.readKey('agent8-key.pem'),
|
||||
}, common.mustCall((req, res) => {
|
||||
res.end('Hello world');
|
||||
}, 2));
|
||||
server.on('error', common.mustNotCall((err) => { console.error('Server error', err); }));
|
||||
server.listen(0);
|
||||
await once(server, 'listening');
|
||||
|
||||
const serverHost = `localhost:${server.address().port}`;
|
||||
const requestUrl = `https://${serverHost}/test`;
|
||||
|
||||
// Tests --use-env-proxy works with https builtins.
|
||||
{
|
||||
const { code, signal, stderr, stdout } = await runProxiedRequest({
|
||||
REQUEST_URL: requestUrl,
|
||||
HTTPS_PROXY: `http://localhost:${proxy.address().port}`,
|
||||
NODE_EXTRA_CA_CERTS: fixtures.path('keys', 'fake-startcom-root-cert.pem'),
|
||||
}, ['--use-env-proxy']);
|
||||
assert.strictEqual(stderr.trim(), '');
|
||||
assert.match(stdout, /Hello world/);
|
||||
assert.strictEqual(code, 0);
|
||||
assert.strictEqual(signal, null);
|
||||
assert.deepStrictEqual(logs, [{
|
||||
method: 'CONNECT',
|
||||
url: serverHost,
|
||||
headers: {
|
||||
'proxy-connection': 'keep-alive',
|
||||
'host': serverHost,
|
||||
},
|
||||
}]);
|
||||
}
|
||||
|
||||
// Tests --use-env-proxy works with fetch and https.
|
||||
{
|
||||
logs.splice(0, logs.length);
|
||||
await checkProxiedFetch({
|
||||
FETCH_URL: `https://${serverHost}/test`,
|
||||
HTTPS_PROXY: `http://localhost:${proxy.address().port}`,
|
||||
NODE_EXTRA_CA_CERTS: fixtures.path('keys', 'fake-startcom-root-cert.pem'),
|
||||
}, {
|
||||
stdout: 'Hello world',
|
||||
}, ['--use-env-proxy']);
|
||||
assert.deepStrictEqual(logs, [{
|
||||
method: 'CONNECT',
|
||||
url: serverHost,
|
||||
headers: {
|
||||
'connection': 'close',
|
||||
'proxy-connection': 'keep-alive',
|
||||
'host': serverHost,
|
||||
},
|
||||
}]);
|
||||
}
|
||||
|
||||
server.close();
|
||||
proxy.close();
|
117
test/client-proxy/test-use-env-proxy-precedence.mjs
Normal file
117
test/client-proxy/test-use-env-proxy-precedence.mjs
Normal file
|
@ -0,0 +1,117 @@
|
|||
// This tests the precedence and interaction between --use-env-proxy CLI flag
|
||||
// and NODE_USE_ENV_PROXY environment variable when both are set.
|
||||
|
||||
import * as common from '../common/index.mjs';
|
||||
import assert from 'node:assert';
|
||||
import http from 'node:http';
|
||||
import { once } from 'events';
|
||||
import { createProxyServer, runProxiedRequest } from '../common/proxy-server.js';
|
||||
|
||||
// Start a proxy server for testing
|
||||
const { proxy, logs } = createProxyServer();
|
||||
proxy.listen(0);
|
||||
await once(proxy, 'listening');
|
||||
|
||||
// Start a HTTP server to process the final request
|
||||
const server = http.createServer(common.mustCall((req, res) => {
|
||||
res.end('Hello world');
|
||||
}, 4));
|
||||
server.on('error', common.mustNotCall((err) => { console.error('Server error', err); }));
|
||||
server.listen(0);
|
||||
await once(server, 'listening');
|
||||
|
||||
const serverHost = `localhost:${server.address().port}`;
|
||||
const requestUrl = `http://${serverHost}/test`;
|
||||
|
||||
delete process.env.NODE_USE_ENV_PROXY; // Ensure the environment variable is not set.
|
||||
// NODE_USE_ENV_PROXY=1 and --use-env-proxy can be used at the same time.
|
||||
{
|
||||
const { code, signal, stderr, stdout } = await runProxiedRequest({
|
||||
NODE_USE_ENV_PROXY: '1',
|
||||
REQUEST_URL: requestUrl,
|
||||
HTTP_PROXY: `http://localhost:${proxy.address().port}`,
|
||||
}, ['--use-env-proxy']);
|
||||
|
||||
assert.strictEqual(stderr.trim(), '');
|
||||
assert.match(stdout, /Hello world/);
|
||||
assert.strictEqual(code, 0);
|
||||
assert.strictEqual(signal, null);
|
||||
|
||||
// Should use the proxy
|
||||
assert.strictEqual(logs.length, 1);
|
||||
assert.deepStrictEqual(logs[0], {
|
||||
method: 'GET',
|
||||
url: requestUrl,
|
||||
headers: {
|
||||
'connection': 'keep-alive',
|
||||
'proxy-connection': 'keep-alive',
|
||||
'host': serverHost,
|
||||
},
|
||||
});
|
||||
|
||||
logs.splice(0, logs.length);
|
||||
}
|
||||
|
||||
// NODE_USE_ENV_PROXY=0 and --no-use-env-proxy can be used at the same time.
|
||||
{
|
||||
const { code, signal, stderr, stdout } = await runProxiedRequest({
|
||||
NODE_USE_ENV_PROXY: '0',
|
||||
REQUEST_URL: requestUrl,
|
||||
HTTP_PROXY: `http://localhost:${proxy.address().port}`,
|
||||
}, ['--no-use-env-proxy']);
|
||||
|
||||
assert.strictEqual(stderr.trim(), '');
|
||||
assert.match(stdout, /Hello world/);
|
||||
assert.strictEqual(code, 0);
|
||||
assert.strictEqual(signal, null);
|
||||
|
||||
// Should NOT use the proxy
|
||||
assert.strictEqual(logs.length, 0);
|
||||
}
|
||||
|
||||
// --use-env-proxy CLI flag takes precedence over NODE_USE_ENV_PROXY=0.
|
||||
{
|
||||
const { code, signal, stderr, stdout } = await runProxiedRequest({
|
||||
NODE_USE_ENV_PROXY: '0',
|
||||
REQUEST_URL: requestUrl,
|
||||
HTTP_PROXY: `http://localhost:${proxy.address().port}`,
|
||||
}, ['--use-env-proxy']);
|
||||
|
||||
assert.strictEqual(stderr.trim(), '');
|
||||
assert.match(stdout, /Hello world/);
|
||||
assert.strictEqual(code, 0);
|
||||
assert.strictEqual(signal, null);
|
||||
|
||||
// Should use the proxy because CLI flag takes precedence
|
||||
assert.strictEqual(logs.length, 1);
|
||||
assert.deepStrictEqual(logs[0], {
|
||||
method: 'GET',
|
||||
url: requestUrl,
|
||||
headers: {
|
||||
'connection': 'keep-alive',
|
||||
'proxy-connection': 'keep-alive',
|
||||
'host': serverHost,
|
||||
},
|
||||
});
|
||||
|
||||
logs.splice(0, logs.length);
|
||||
}
|
||||
|
||||
// --no-use-env-proxy CLI flag disables the proxy even if NODE_USE_ENV_PROXY=1.
|
||||
{
|
||||
const { code, signal, stderr, stdout } = await runProxiedRequest({
|
||||
NODE_USE_ENV_PROXY: '1',
|
||||
REQUEST_URL: requestUrl,
|
||||
HTTP_PROXY: `http://localhost:${proxy.address().port}`,
|
||||
}, ['--no-use-env-proxy']);
|
||||
|
||||
// Should NOT use the proxy because CLI flag takes precedence.
|
||||
assert.strictEqual(stderr.trim(), '');
|
||||
assert.match(stdout, /Hello world/);
|
||||
assert.strictEqual(code, 0);
|
||||
assert.strictEqual(signal, null);
|
||||
assert.strictEqual(logs.length, 0);
|
||||
}
|
||||
|
||||
proxy.close();
|
||||
server.close();
|
|
@ -142,11 +142,11 @@ function spawnPromisified(...args) {
|
|||
});
|
||||
}
|
||||
|
||||
exports.checkProxiedFetch = async function(envExtension, expectation) {
|
||||
exports.checkProxiedFetch = async function(envExtension, expectation, cliArgsExtension = []) {
|
||||
const fixtures = require('./fixtures');
|
||||
const { code, signal, stdout, stderr } = await spawnPromisified(
|
||||
process.execPath,
|
||||
[fixtures.path('fetch-and-log.mjs')], {
|
||||
[...cliArgsExtension, fixtures.path('fetch-and-log.mjs')], {
|
||||
env: {
|
||||
...process.env,
|
||||
...envExtension,
|
||||
|
@ -166,11 +166,11 @@ exports.checkProxiedFetch = async function(envExtension, expectation) {
|
|||
});
|
||||
};
|
||||
|
||||
exports.runProxiedRequest = async function(envExtension) {
|
||||
exports.runProxiedRequest = async function(envExtension, cliArgsExtension = []) {
|
||||
const fixtures = require('./fixtures');
|
||||
return spawnPromisified(
|
||||
process.execPath,
|
||||
[fixtures.path('request-and-log.js')], {
|
||||
[...cliArgsExtension, fixtures.path('request-and-log.js')], {
|
||||
env: {
|
||||
...process.env,
|
||||
...envExtension,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue