Files
hapi/cli/src/utils/proxyEnv.test.ts
T
weishuandGitHub 17439ae02c fix(cli): bypass proxy for loopback addresses at CLI entrypoint (#868)
Bun's fetch and node:http honor HTTP_PROXY/HTTPS_PROXY env vars, which can
route loopback traffic through a configured proxy (e.g. Surge/Clash). When
NO_PROXY doesn't explicitly exclude localhost, this breaks loopback
communication: SessionStart hooks fail to arrive (transcripts don't sync, web
UI stays empty), runner control client times out, and MCP server connections
fail.

Normalize NO_PROXY at the CLI entrypoint to always cover loopback
(localhost, 127.0.0.1, ::1). Child processes inherit the patched env so their
loopback traffic is covered too. Non-loopback traffic continues using the
configured proxy. Supersedes the runner control client workaround from #563.
2026-06-11 00:00:09 +08:00

37 lines
1.4 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import { ensureLoopbackProxyBypass } from './proxyEnv';
describe('ensureLoopbackProxyBypass', () => {
it('adds loopback hosts when NO_PROXY is unset', () => {
const env: NodeJS.ProcessEnv = {};
ensureLoopbackProxyBypass(env);
expect(env.NO_PROXY).toBe('localhost,127.0.0.1,::1');
expect(env.no_proxy).toBe('localhost,127.0.0.1,::1');
});
it('preserves existing entries and appends missing loopback hosts', () => {
const env: NodeJS.ProcessEnv = { NO_PROXY: 'npmjs.org' };
ensureLoopbackProxyBypass(env);
expect(env.NO_PROXY).toBe('npmjs.org,localhost,127.0.0.1,::1');
});
it('does not duplicate already-present hosts', () => {
const env: NodeJS.ProcessEnv = { NO_PROXY: 'LOCALHOST, 127.0.0.1' };
ensureLoopbackProxyBypass(env);
expect(env.NO_PROXY).toBe('LOCALHOST,127.0.0.1,::1');
});
it('reads lowercase no_proxy when NO_PROXY is unset', () => {
const env: NodeJS.ProcessEnv = { no_proxy: 'example.com,localhost,127.0.0.1,::1' };
ensureLoopbackProxyBypass(env);
expect(env.NO_PROXY).toBe('example.com,localhost,127.0.0.1,::1');
});
it('leaves a wildcard NO_PROXY untouched', () => {
const env: NodeJS.ProcessEnv = { NO_PROXY: '*' };
ensureLoopbackProxyBypass(env);
expect(env.NO_PROXY).toBe('*');
expect(env.no_proxy).toBeUndefined();
});
});