From 13ade9181f5e6fd98db3ea0ab5872c43538ade2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8B=A5=E9=BA=92?= Date: Thu, 9 Jul 2026 16:55:03 +0800 Subject: [PATCH] fix(runtime): ignore unsupported lowercase proxy env vars --- packages/cli/tests/e2e/proxy.e2e.test.ts | 11 +---------- packages/runtime/src/proxy.ts | 24 ++++++++---------------- packages/runtime/tests/proxy.test.ts | 24 ++++++++++-------------- 3 files changed, 19 insertions(+), 40 deletions(-) diff --git a/packages/cli/tests/e2e/proxy.e2e.test.ts b/packages/cli/tests/e2e/proxy.e2e.test.ts index 80b7f0b..b92692c 100644 --- a/packages/cli/tests/e2e/proxy.e2e.test.ts +++ b/packages/cli/tests/e2e/proxy.e2e.test.ts @@ -11,7 +11,7 @@ import { cliPackageRoot } from "./helpers.ts"; const execFileAsync = promisify(execFile); /** - * 代理支持 E2E(issue #35):只验证 `setupProxyFromEnv()` 是否把代理 dispatcher + * 代理支持 E2E:只验证 `setupProxyFromEnv()` 是否把代理 dispatcher * 正确装到全局 fetch 上——设了 HTTPS_PROXY 后裸 `fetch()` 走代理,未设置时直连, * NO_PROXY 命中时跳过,非法代理值给出明确报错。 * @@ -66,11 +66,8 @@ afterAll(async () => { /** 清空所有代理相关环境变量,确保每个用例只受自身设置影响 */ const PROXY_ENV_CLEARED = { HTTPS_PROXY: "", - https_proxy: "", HTTP_PROXY: "", - http_proxy: "", NO_PROXY: "", - no_proxy: "", }; /** 以给定代理环境变量运行探针脚本,返回 { exitCode, stderr } */ @@ -97,12 +94,6 @@ describe("e2e: proxy", () => { expect(connectTargets).toContain(`${FAKE_HOST}:443`); }); - test("空字符串小写变量不屏蔽大写 HTTPS_PROXY(undici ?? 取值回归)", async () => { - connectTargets.length = 0; - await runProbe({ https_proxy: "", HTTPS_PROXY: proxyUrl }); - expect(connectTargets).toContain(`${FAKE_HOST}:443`); - }); - test("NO_PROXY 命中目标主机时不走代理", async () => { connectTargets.length = 0; await runProbe({ HTTPS_PROXY: proxyUrl, NO_PROXY: FAKE_HOST }); diff --git a/packages/runtime/src/proxy.ts b/packages/runtime/src/proxy.ts index 8c566e8..4c21ef5 100644 --- a/packages/runtime/src/proxy.ts +++ b/packages/runtime/src/proxy.ts @@ -7,30 +7,22 @@ export interface ProxyEnv { noProxy?: string; } -function pick(env: NodeJS.ProcessEnv, ...keys: string[]): string | undefined { - for (const key of keys) { - const value = env[key]?.trim(); - if (value) return value; - } - return undefined; +function pick(env: NodeJS.ProcessEnv, key: string): string | undefined { + const value = env[key]?.trim(); + return value || undefined; } -/** - * 读取代理环境变量(小写优先,与 curl 约定一致)。 - * 空白值视为未设置——undici 自身用 `??` 取值,空字符串的小写变量会屏蔽 - * 已设置的大写变量,这里统一清洗后显式传入,绕开该坑。 - */ +/** 读取代理环境变量,空白值视为未设置。 */ export function readProxyEnv(env: NodeJS.ProcessEnv = process.env): ProxyEnv { return { - httpProxy: pick(env, "http_proxy", "HTTP_PROXY"), - httpsProxy: pick(env, "https_proxy", "HTTPS_PROXY"), - noProxy: pick(env, "no_proxy", "NO_PROXY"), + httpProxy: pick(env, "HTTP_PROXY"), + httpsProxy: pick(env, "HTTPS_PROXY"), + noProxy: pick(env, "NO_PROXY"), }; } // Node 内置 fetch(undici)默认不读取代理环境变量,VPN / 公司代理环境下会 -// 绕过代理直连而被拦截(见 issue #35)。仅当用户显式设置了 HTTP_PROXY / -// HTTPS_PROXY 时才安装代理 dispatcher(同时支持 NO_PROXY),未设置时不触碰 +// 绕过代理直连而被拦截。仅当用户配置了代理时才安装 dispatcher,未配置时不触碰 // 全局 dispatcher,行为与之前完全一致。 export function setupProxyFromEnv(): void { const { httpProxy, httpsProxy, noProxy } = readProxyEnv(); diff --git a/packages/runtime/tests/proxy.test.ts b/packages/runtime/tests/proxy.test.ts index 1986459..aae11a2 100644 --- a/packages/runtime/tests/proxy.test.ts +++ b/packages/runtime/tests/proxy.test.ts @@ -17,21 +17,17 @@ test("readProxyEnv: 空白值视为未设置", () => { }); }); -test("readProxyEnv: 大小写变量均可识别,小写优先", () => { - expect(readProxyEnv({ HTTPS_PROXY: "http://upper:1" }).httpsProxy).toBe("http://upper:1"); - expect(readProxyEnv({ https_proxy: "http://lower:1" }).httpsProxy).toBe("http://lower:1"); +test("readProxyEnv: 读取代理变量", () => { expect( - readProxyEnv({ https_proxy: "http://lower:1", HTTPS_PROXY: "http://upper:1" }).httpsProxy, - ).toBe("http://lower:1"); -}); - -test("readProxyEnv: 空字符串小写变量不屏蔽已设置的大写变量", () => { - expect(readProxyEnv({ https_proxy: "", HTTPS_PROXY: "http://upper:1" }).httpsProxy).toBe( - "http://upper:1", - ); - expect(readProxyEnv({ http_proxy: "", HTTP_PROXY: "http://upper:2" }).httpProxy).toBe( - "http://upper:2", - ); + readProxyEnv({ + HTTP_PROXY: "http://proxy.example.com:8080", + HTTPS_PROXY: "http://secure-proxy.example.com:8080", + }), + ).toEqual({ + httpProxy: "http://proxy.example.com:8080", + httpsProxy: "http://secure-proxy.example.com:8080", + noProxy: undefined, + }); }); test("readProxyEnv: NO_PROXY 独立读取", () => {