Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion lib/internal/http.js
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ class ProxyConfig {
// Follow curl's behavior: strip leading dot before matching suffixes.
if (entry[0] === '.') {
const suffix = entry.substring(1);
if (host.endsWith(suffix)) return false;
if (host === suffix || (host.endsWith(suffix) && host[host.length - suffix.length - 1] === '.')) return false;
}

// Handle wildcards like *.example.com
Expand Down
39 changes: 38 additions & 1 deletion test/client-proxy/test-http-proxy-request-no-proxy-domain.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { runProxiedRequest } from '../common/proxy-server.js';
const server = http.createServer(common.mustCall((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Hello World\n');
}, 3));
}, 5));
server.on('error', common.mustNotCall((err) => { console.error('Server error', err); }));
server.listen(0, '127.0.0.1');
await once(server, 'listening');
Expand Down Expand Up @@ -77,5 +77,42 @@ await once(proxy, 'listening');
assert.strictEqual(code, 0);
assert.strictEqual(signal, null);
}

// Test NO_PROXY with leading-dot entry should NOT match partial domain names.
// Regression test: .example.com must not match notexample.com or badexample.com.
{
const { code, signal, stderr, stdout } = await runProxiedRequest({
NODE_USE_ENV_PROXY: 1,
REQUEST_URL: `http://notexample.com:${server.address().port}/test`,
HTTP_PROXY: `http://localhost:${server.address().port}`,
RESOLVE_TO_LOCALHOST: 'notexample.com',
NO_PROXY: '.example.com',
});

// The request should go through the proxy (not bypass it),
// because notexample.com is not a subdomain of example.com.
assert.match(stdout, /Status Code: 200/);
assert.strictEqual(stderr.trim(), '');
assert.strictEqual(code, 0);
assert.strictEqual(signal, null);
}

{
const { code, signal, stderr, stdout } = await runProxiedRequest({
NODE_USE_ENV_PROXY: 1,
REQUEST_URL: `http://badexample.com:${server.address().port}/test`,
HTTP_PROXY: `http://localhost:${server.address().port}`,
RESOLVE_TO_LOCALHOST: 'badexample.com',
NO_PROXY: '.example.com',
});

// The request should go through the proxy (not bypass it),
// because badexample.com is not a subdomain of example.com.
assert.match(stdout, /Status Code: 200/);
assert.strictEqual(stderr.trim(), '');
assert.strictEqual(code, 0);
assert.strictEqual(signal, null);
}

proxy.close();
server.close();
Loading