Repository navigation
fix(apiv2): honor NO_PROXY when an HTTPS_PROXY is configured - #11328
wahajahmed010 wants to merge 1 commit into
Conversation
Replace undici.ProxyAgent with undici.EnvHttpProxyAgent when a proxy URI is detected, and read NO_PROXY/no_proxy from the environment. Previously every request was sent through the proxy, including localhost calls between emulators; in this case the proxy URI may not resolve to a host that can reach 127.0.0.1, and the request would fail with ECONNREFUSED (or worse, hit an unrelated external server). Closes firebase#11249
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
There was a problem hiding this comment.
Code Review
This pull request replaces ProxyAgent with EnvHttpProxyAgent from undici in src/apiv2.ts to ensure that NO_PROXY/no_proxy environment variables are properly honored, and adds a corresponding unit test in src/apiv2.spec.ts. The reviewer suggests extracting a shared helper getEnvVar to handle environment variable retrieval and filter out literal 'undefined' or 'null' strings, which prevents potential issues when checking fallback variables. Additionally, the reviewer recommends using this helper to separately configure httpProxy and httpsProxy rather than forcing both to use the same proxy URI.
| function noProxyFromEnv(): string { | ||
| const env = process.env.NO_PROXY || process.env.no_proxy || ""; | ||
| return env === "undefined" || env === "null" ? "" : env; | ||
| } |
There was a problem hiding this comment.
If process.env.NO_PROXY is set to the literal string "undefined", the expression process.env.NO_PROXY || process.env.no_proxy will evaluate to "undefined", which prevents a potentially valid process.env.no_proxy from being used.\n\nAdditionally, to adhere to the repository style guide's rule on Survey prior art & harmonize utilities (lines 28-30), we should extract a shared helper to retrieve environment variables while filtering out "undefined" and "null" strings. This helper can then be reused by both proxyURIFromEnv and noProxyFromEnv.
function getEnvVar(keys: string[]): string | undefined {\n for (const key of keys) {\n const val = process.env[key];\n if (val && val !== \"undefined\" && val !== \"null\") {\n return val;\n }\n }\n return undefined;\n}\n\nfunction noProxyFromEnv(): string {\n return getEnvVar([\"NO_PROXY\", \"no_proxy\"]) || \"\";\n}References
- Survey prior art & harmonize utilities: Extract and unify shared helpers when logic is duplicated or warrants a new common utility. (link)
| fetchOptions.dispatcher = new EnvHttpProxyAgent({ | ||
| httpProxy: proxyURI, | ||
| httpsProxy: proxyURI, | ||
| noProxy: noProxyFromEnv(), | ||
| }); |
There was a problem hiding this comment.
Currently, both httpProxy and httpsProxy are set to the same proxyURI (which prefers HTTPS_PROXY over HTTP_PROXY). In environments where separate proxies are configured for HTTP and HTTPS, this forces HTTP requests to go through the HTTPS proxy.\n\nSince we are using EnvHttpProxyAgent, we can leverage the getEnvVar helper to pass the correct proxy for each protocol individually.
fetchOptions.dispatcher = new EnvHttpProxyAgent({\n httpProxy: getEnvVar([\"HTTP_PROXY\", \"http_proxy\"]),\n httpsProxy: getEnvVar([\"HTTPS_PROXY\", \"https_proxy\"]),\n noProxy: noProxyFromEnv(),\n });
Description
When
HTTPS_PROXY(orHTTP_PROXY) is set, every request the CLI makes goes throughnew undici.ProxyAgent({ uri: proxyURI }). That agent does not honorNO_PROXY/no_proxy, so requests between emulators on127.0.0.1are also proxied. Behind a corporate or sandbox proxy, the Functions emulator then fails to register its Firestore trigger andemulators:start/emulators:execerrors out withECONNREFUSED.This PR swaps
undici.ProxyAgentforundici.EnvHttpProxyAgent, which is built on top ofProxyAgentand applies the sameNO_PROXY/no_proxyrules as Node.js and other CLIs. The proxy URI is passed as bothhttpProxyandhttpsProxy;noProxyis read from the same environment variables that other Node tools consult.Fixes #11249
Scenarios Tested
HTTPS_PROXY=http://127.0.0.1:52672andNO_PROXY=127.0.0.1, a request tohttp://127.0.0.1:52673succeeds and reaches the target server.NO_PROXY, requests are still proxied (existing behavior preserved).src/apiv2.spec.tscontinue to pass (41/41 passing). One new test was added that asserts theNO_PROXYbypass branch.tsc --project tsconfig.compile.jsonis clean (0 errors).Sample Commands