Repository navigation
[Bug][http-proxy][0.2.1-alpha.2] A blank proxy variable makes every Node child connect directly while the host proxies #9373
Replies: 1 comment
|
这条成立,而且因果链可以一句话读完 —— 只依赖 1. 一条成文契约,被父进程遵守、被子进程违反契约在
主进程侧确实按它实现了 —— for (const name of [lower, lower.toUpperCase()]) {
const value = env.get(name)?.value.trim()
if (value !== undefined && value !== '') return { value, name }
}
return undefined
但子进程侧只判 const named = field !== 'noProxy' && names.some(name => inherited[name] !== undefined)
for (const name of names) overlay[name] = named ? inherited[name] : resolved空串 2. 二次伤害:空串把
|
Uh oh!
There was an error while loading. Please reload this page.
Summary
With a proxy exported and one proxy variable exported but empty, the host process proxies correctly, but every Node child spawned through
scrubbedParentEnv()connects directly, with no diagnostic. Examples of the second variable:http_proxy=besideHTTP_PROXY=http://proxy:8080, orHTTPS_PROXY=besideHTTP_PROXY. Those children include stdio MCP servers, subagent CLIs, and any otherdsh-subprocessspawn. On a network that only allows egress through the proxy, those children fail to reach the network, or reach it around a corporate proxy.The package documents the opposite: README L50 says the policy reads the variables "with a blank value treated as unset".
readEnvdoes exactly that for this process, but the child-environment overlay does not.Shells often leave such empty exports behind, for example
export http_proxy=$CORP_PROXYwith the variable unset, or a proxy toggle that clears only one casing.Environment
d743267388(currentmaster)NODE_USE_ENV_PROXYsupport (22.21+, 24+) behaves the same.http_proxy=/HTTP_PROXYpair folds into one variable, butHTTPS_PROXY=alone reproduces there too.Reproduction
The host's own requests go through the proxy, but each child environment contains
HTTPS_PROXY=and noNODE_USE_ENV_PROXY, so the MCP server connects directly. The same happens withhttp_proxy=plusHTTP_PROXY=http://127.0.0.1:3128.As a unit test, the case added to
packages/util/http-proxy/tests/install.spec.ts:On
d743267388it fails withexpected undefined to be '1'. A spawnednode -e "http.get('http://origin.test/')"with the overlay applied never reaches the proxy, while the parent'sproxyRouteFor()reportsproxied: true.Root cause
install.tsL271-L277:inheritedis the snapshot of what the user exported. An empty string is!== undefined, so it claims the scheme and is copied to the child verbatim.isSupportedProxyUrl('')isfalse, so the refused-value guard intended for SOCKS URLs kept forcurlthen withholdsNODE_USE_ENV_PROXY, and a child Node ignores every proxy variable. In thehttp_proxy=case, the empty lowercase name would also shadow the uppercase one for tools that read lowercase first.Fix
Branch:
heaven999b/deepseek-harness@fix/http-proxy-blank-env(compare with master) (one commit,fix(http-proxy): treat blank proxy variables as unset for children).packages/util/http-proxy/src/install.ts: read inherited names the way resolution does. A blank (whitespace-only) value is unset: it no longer claims its scheme, and the blank name is removed from the child (undefinedin the overlay). The child receives the other casing's value when the user set one; otherwise it receives the resolved value, the same as a scheme named in neither casing. The flag stays. Non-blank values still pass through exactly as written, and refused values such as SOCKS URLs still withhold the flag.proxyEnvironmentForChild()and README / README.zh (+ i18n record): state that blank values are unset for children too.tests/install.spec.ts: a regression case for both shapes, with assertions that hold whether or not the platform folds the two casings.Verification
d743267388(expected undefined to be '1') and passes with the fix.vitest run packages/util/http-proxy/tests --coverage --coverage.include='packages/util/http-proxy/src/**/*.ts': 3 files, 90 tests passed; everysrcfile at 100% statements/branches/functions/lines.vitest run packages/subprocess/subprocess/tests/egress.spec.ts(thescrubbedParentEnv()consumer): 5/5 passed.tsc -b packages/util/http-proxy/tsconfig.jsonandtsc -b tsconfig.host.json(includes the specs): clean. Staged oxlint,verify-translation-pairing,verify-md-wrapandgit diff --check: pass.nodeprocess with the overlay applied; run on5badb15009, andinstall.ts/policy.tsare unchanged ind743267388) now reaches the fake proxy in both scenarios:child http status 200; proxy saw=["GET http://origin.test/a"]. Before the fix, the proxy saw nothing.Related
[::1]in the childNO_PROXY. Different defect, same overlay.NODE_USE_ENV_PROXYin children.All reactions