Repository navigation
fix(cli): 联网命令遵循 HTTP(S)_PROXY / NO_PROXY(0.9.1) - #30
Conversation
Node 内置 fetch 不读代理环境变量(除非以 NODE_USE_ENV_PROXY 启动),挂代理的机器上 pull / publish / hosts upload 等一律 "fetch failed"。检测到代理变量时用 undici 的 EnvHttpProxyAgent 设为全局 dispatcher;没有代理变量时不加载 undici。 undici 取 7.x:8.x 要求 Node >=22.19,而 F-Droid 构建机(Debian trixie)是 Node 20。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Reviewer's Guide该 PR 使用 undici 7.x 的 EnvHttpProxyAgent,在 CLI 执行联网命令前按需接管全局 fetch,使其遵循 HTTP(S)_PROXY 和 NO_PROXY,同时通过本地 CONNECT 代理测试验证转发,并将相关包版本发布为 0.9.1。 Sequence diagram for CLI proxy-aware fetchsequenceDiagram
participant User
participant CLI as tinyui CLI
participant ProxySetup as useEnvProxy
participant Fetch as global fetch
participant Proxy as HTTP(S) proxy
participant Server as Updates server
User->>CLI: run networking command
CLI->>ProxySetup: useEnvProxy()
alt HTTP_PROXY or HTTPS_PROXY is set
ProxySetup->>ProxySetup: import("undici")
ProxySetup->>ProxySetup: setGlobalDispatcher(new EnvHttpProxyAgent(...))
end
CLI->>Fetch: fetch(updates request)
alt request matches NO_PROXY
Fetch->>Server: direct HTTPS request
else request uses proxy
Fetch->>Proxy: CONNECT / proxied request
Proxy->>Server: forward request
Server-->>Proxy: response
Proxy-->>Fetch: response
end
Fetch-->>CLI: response
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configuration
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
CodeSeer 审查
结论:批准
摘要
本次改动为 CLI 在检测到 HTTP(S)_PROXY 时安装 undici 的 EnvHttpProxyAgent,使全局 fetch 同时遵循 NO_PROXY,并补充了代理转发测试与文档说明。bin.ts 在命令执行前完成初始化,未设置代理变量时不会动态加载 undici。同步将 core、native 和 CLI 版本更新为 0.9.1,并重新生成运行时字节码。
按规则不审的文件
pnpm-lock.yaml:lock 文件
整个 PR 至 ead8589 · gpt-5.6-terra
There was a problem hiding this comment.
Hey - I've found 3 issues
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="packages/cli/src/proxy.ts" line_range="15-18" />
<code_context>
+ const httpProxy = env.HTTP_PROXY ?? env.http_proxy;
+ const httpsProxy = env.HTTPS_PROXY ?? env.https_proxy;
+ const noProxy = env.NO_PROXY ?? env.no_proxy;
+ setGlobalDispatcher(new EnvHttpProxyAgent({
+ ...(httpProxy !== undefined && { httpProxy }),
+ ...(httpsProxy !== undefined && { httpsProxy }),
+ ...(noProxy !== undefined && { noProxy }),
+ }));
+ return true;
</code_context>
<issue_to_address>
**Loopback requests leak tokens**
When a proxy is configured and an authenticated command targets an allowed loopback HTTP URL that `NO_PROXY` does not exclude, `EnvHttpProxyAgent` sends the request through the proxy, so local Wrangler commands fail to reach the server and the proxy can read bearer tokens. Add loopback hosts to the default `NO_PROXY` exclusions.
Ensure localhost and loopback addresses are excluded from proxying even when `NO_PROXY` is unset or does not list them.
</issue_to_address>
### Comment 2
<location path="packages/cli/src/bin.ts" line_range="394" />
<code_context>
return argv.includes("--help") || argv.includes("-h") ? 0 : 2;
}
const { values, positionals } = parseArgs({ args: argv, allowPositionals: true, options: command.options });
+ await useEnvProxy();
return command.run(values, positionals);
}
</code_context>
<issue_to_address>
**Offline commands fail**
When a proxy variable contains a malformed URL and the user invokes an offline command, `useEnvProxy()` constructs `EnvHttpProxyAgent` before `command.run`, so the malformed URL throws and commands such as `build`, `bundle`, and `schema` do not run.
Bypass proxy initialization for commands that do not make network requests.
</issue_to_address>
### Comment 3
<location path="packages/cli/src/proxy.ts" line_range="12" />
<code_context>
+export async function useEnvProxy(env: NodeJS.ProcessEnv = process.env): Promise<boolean> {
+ if (!PROXY_ENV.some((name) => env[name])) return false;
+ const { EnvHttpProxyAgent, setGlobalDispatcher } = await import("undici");
+ const httpProxy = env.HTTP_PROXY ?? env.http_proxy;
+ const httpsProxy = env.HTTPS_PROXY ?? env.https_proxy;
+ const noProxy = env.NO_PROXY ?? env.no_proxy;
</code_context>
<issue_to_address>
**Configured proxy is ignored**
When an uppercase proxy or `NO_PROXY` variable is empty while its lowercase counterpart is configured, `??` selects the empty uppercase value instead of the configured lowercase value, so `EnvHttpProxyAgent` receives an empty proxy URL or `noProxy` list and requests use the wrong routing behavior.
Treat empty uppercase values as unset when falling back to lowercase environment variables.
</issue_to_address>Sourcery assessment
Needs a human reviewer. 3 findings to address first, and the change reroutes authenticated CLI requests through environment-selected proxies and introduces a new networking dependency; if the proxy handling is wrong, update tokens or publish operations could be exposed or sent to an unintended intermediary. Reverting stops future rerouting, but any credential exposure or externally performed request that already occurred cannot be undone.
Blocking findings: packages/cli/src/proxy.ts:18, packages/cli/src/bin.ts:394, packages/cli/src/proxy.ts:12
| setGlobalDispatcher(new EnvHttpProxyAgent({ | ||
| ...(httpProxy !== undefined && { httpProxy }), | ||
| ...(httpsProxy !== undefined && { httpsProxy }), | ||
| ...(noProxy !== undefined && { noProxy }), |
There was a problem hiding this comment.
🟡 Medium · Loopback requests leak tokens
When a proxy is configured and an authenticated command targets an allowed loopback HTTP URL that NO_PROXY does not exclude, EnvHttpProxyAgent sends the request through the proxy, so local Wrangler commands fail to reach the server and the proxy can read bearer tokens. Add loopback hosts to the default NO_PROXY exclusions.
Ensure localhost and loopback addresses are excluded from proxying even when NO_PROXY is unset or does not list them.
Prompt for AI agents
In `packages/cli/src/proxy.ts` at lines 15-18:
**Loopback requests leak tokens**
When a proxy is configured and an authenticated command targets an allowed loopback HTTP URL that `NO_PROXY` does not exclude, `EnvHttpProxyAgent` sends the request through the proxy, so local Wrangler commands fail to reach the server and the proxy can read bearer tokens. Add loopback hosts to the default `NO_PROXY` exclusions.
Ensure localhost and loopback addresses are excluded from proxying even when `NO_PROXY` is unset or does not list them.| return argv.includes("--help") || argv.includes("-h") ? 0 : 2; | ||
| } | ||
| const { values, positionals } = parseArgs({ args: argv, allowPositionals: true, options: command.options }); | ||
| await useEnvProxy(); |
There was a problem hiding this comment.
🟡 Medium · Offline commands fail
When a proxy variable contains a malformed URL and the user invokes an offline command, useEnvProxy() constructs EnvHttpProxyAgent before command.run, so the malformed URL throws and commands such as build, bundle, and schema do not run.
Bypass proxy initialization for commands that do not make network requests.
Prompt for AI agents
In `packages/cli/src/bin.ts` at line 394:
**Offline commands fail**
When a proxy variable contains a malformed URL and the user invokes an offline command, `useEnvProxy()` constructs `EnvHttpProxyAgent` before `command.run`, so the malformed URL throws and commands such as `build`, `bundle`, and `schema` do not run.
Bypass proxy initialization for commands that do not make network requests.| export async function useEnvProxy(env: NodeJS.ProcessEnv = process.env): Promise<boolean> { | ||
| if (!PROXY_ENV.some((name) => env[name])) return false; | ||
| const { EnvHttpProxyAgent, setGlobalDispatcher } = await import("undici"); | ||
| const httpProxy = env.HTTP_PROXY ?? env.http_proxy; |
There was a problem hiding this comment.
🟡 Medium · Configured proxy is ignored
When an uppercase proxy or NO_PROXY variable is empty while its lowercase counterpart is configured, ?? selects the empty uppercase value instead of the configured lowercase value, so EnvHttpProxyAgent receives an empty proxy URL or noProxy list and requests use the wrong routing behavior.
Treat empty uppercase values as unset when falling back to lowercase environment variables.
Prompt for AI agents
In `packages/cli/src/proxy.ts` at line 12:
**Configured proxy is ignored**
When an uppercase proxy or `NO_PROXY` variable is empty while its lowercase counterpart is configured, `??` selects the empty uppercase value instead of the configured lowercase value, so `EnvHttpProxyAgent` receives an empty proxy URL or `noProxy` list and requests use the wrong routing behavior.
Treat empty uppercase values as unset when falling back to lowercase environment variables.* fix(cli): 代理按审查意见收紧——回环直连、无法解析时不中断、空大写变量回退小写 #30 的 Sourcery 审查指出的三处(0.9.1 已发出): - 本机回环地址始终加入 NO_PROXY:本地实例经代理不可达,明文 http 下 token 会经过代理 - 代理变量无法解析时提示并直连,不再让 build / bundle / schema 等离线命令失败 - `??` 改 `||`:HTTP_PROXY="" 不再遮住已配置的 http_proxy 每条各有测试;改回旧写法时对应测试失败。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore: 版本号 0.9.2 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(cli): 代理初始化失败时装回直连 dispatcher,与「直连」提示一致 CodeSeer 审查 #31:先装过有效代理、再遇到无法解析的设置时,旧代理仍在生效。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
问题
Node 内置
fetch不读HTTPS_PROXY等代理环境变量(除非进程以NODE_USE_ENV_PROXY启动),挂代理的机器上tinyui pull/publish/hosts upload一律报fetch failed。TrendingAI 的发版冒烟就因此拉不到内置包。改动
packages/cli/src/proxy.ts:检测到代理变量时,用 undici 的EnvHttpProxyAgent(同时遵循NO_PROXY)设为全局 dispatcher;没有代理变量时不 import undici。bin.ts在执行命令前调用。CONNECT的代理,断言全局fetch经由它转发。RuntimeBytecode.kt随之重新生成。quickjs-kmp 不变(仍 0.1.2)。验证
NODE_USE_ENV_PROXY,新 CLItinyui pull成功;同命令 0.9.0 报fetch failed。🤖 Generated with Claude Code
Summary by Sourcery
Enable reliable proxied network access for CLI commands while preserving direct connections when no proxy is configured.
New Features:
Bug Fixes:
Enhancements:
Documentation:
Tests:
Chores: