



























@@ -40,8 +40,19 @@ const ALL_PROXY_ENV_KEYS = [
4040 ...NO_PROXY_ENV_KEYS,
4141 ...PROXY_ACTIVE_KEYS,
4242] as const;
43+const GATEWAY_CONTROL_PLANE_PROXY_BYPASS_ENV_KEYS = [
44+ ...ALL_PROXY_ENV_KEYS,
45+"all_proxy",
46+"ALL_PROXY",
47+] as const;
4348type ProxyEnvKey = (typeof ALL_PROXY_ENV_KEYS)[number];
4449type ProxyEnvSnapshot = Record<ProxyEnvKey, string | undefined>;
50+type GatewayControlPlaneProxyBypassEnvKey =
51+(typeof GATEWAY_CONTROL_PLANE_PROXY_BYPASS_ENV_KEYS)[number];
52+type GatewayControlPlaneProxyBypassEnvSnapshot = Record<
53+GatewayControlPlaneProxyBypassEnvKey,
54+string | undefined
55+>;
4556type NodeHttpStackSnapshot = {
4657httpRequest: typeof http.request;
4758httpGet: typeof http.get;
@@ -116,6 +127,39 @@ function restoreProxyEnv(snapshot: ProxyEnvSnapshot): void {
116127}
117128}
118129130+function captureGatewayControlPlaneProxyBypassEnv(): GatewayControlPlaneProxyBypassEnvSnapshot {
131+const snapshot = {} as GatewayControlPlaneProxyBypassEnvSnapshot;
132+for (const key of GATEWAY_CONTROL_PLANE_PROXY_BYPASS_ENV_KEYS) {
133+snapshot[key] = process.env[key];
134+}
135+return snapshot;
136+}
137+138+function restoreGatewayControlPlaneProxyBypassEnv(
139+snapshot: GatewayControlPlaneProxyBypassEnvSnapshot,
140+): void {
141+for (const key of GATEWAY_CONTROL_PLANE_PROXY_BYPASS_ENV_KEYS) {
142+const value = snapshot[key];
143+if (value === undefined) {
144+delete process.env[key];
145+} else {
146+process.env[key] = value;
147+}
148+}
149+}
150+151+function withoutGatewayControlPlaneProxyEnv<T>(run: () => T): T {
152+const snapshot = captureGatewayControlPlaneProxyBypassEnv();
153+for (const key of GATEWAY_CONTROL_PLANE_PROXY_BYPASS_ENV_KEYS) {
154+delete process.env[key];
155+}
156+try {
157+return run();
158+} finally {
159+restoreGatewayControlPlaneProxyBypassEnv(snapshot);
160+}
161+}
162+119163function restoreGlobalAgentRuntime(snapshot: ProxyEnvSnapshot): void {
120164if (
121165typeof global === "undefined" ||
@@ -371,7 +415,12 @@ function isGatewayLoopbackControlPlaneUrl(value: string): boolean {
371415) {
372416return false;
373417}
374-return isLoopbackIpAddress(url.hostname);
418+return isGatewayControlPlaneLoopbackHost(url.hostname);
419+}
420+421+function isGatewayControlPlaneLoopbackHost(hostname: string): boolean {
422+const normalizedHost = hostname.trim().toLowerCase().replace(/\.+$/, "");
423+return normalizedHost === "localhost" || isLoopbackIpAddress(hostname);
375424}
376425377426export function dangerouslyBypassManagedProxyForGatewayLoopbackControlPlane<T>(
@@ -384,38 +433,40 @@ export function dangerouslyBypassManagedProxyForGatewayLoopbackControlPlane<T>(
384433385434const snapshot = nodeHttpStackSnapshot;
386435if (!snapshot) {
387-return run();
436+return withoutGatewayControlPlaneProxyEnv(run);
388437}
389438390439// Security-sensitive: this temporarily removes managed proxy hooks for the
391440// synchronous Gateway loopback WebSocket constructor only. Do not reuse this
392441// helper for provider, plugin, user WebUI, model server, or arbitrary egress.
393-const activeStack = captureNodeHttpStack();
394-const globalRecord = global as Record<string, unknown>;
395-try {
396-http.request = snapshot.httpRequest;
397-http.get = snapshot.httpGet;
398-http.globalAgent = snapshot.httpGlobalAgent;
399-https.request = snapshot.httpsRequest;
400-https.get = snapshot.httpsGet;
401-https.globalAgent = snapshot.httpsGlobalAgent;
402-if (snapshot.hadGlobalAgent) {
403-globalRecord["GLOBAL_AGENT"] = snapshot.globalAgent;
404-} else {
405-delete globalRecord["GLOBAL_AGENT"];
406-}
407-return run();
408-} finally {
409-http.request = activeStack.httpRequest;
410-http.get = activeStack.httpGet;
411-http.globalAgent = activeStack.httpGlobalAgent;
412-https.request = activeStack.httpsRequest;
413-https.get = activeStack.httpsGet;
414-https.globalAgent = activeStack.httpsGlobalAgent;
415-if (activeStack.hadGlobalAgent) {
416-globalRecord["GLOBAL_AGENT"] = activeStack.globalAgent;
417-} else {
418-delete globalRecord["GLOBAL_AGENT"];
442+return withoutGatewayControlPlaneProxyEnv(() => {
443+const activeStack = captureNodeHttpStack();
444+const globalRecord = global as Record<string, unknown>;
445+try {
446+http.request = snapshot.httpRequest;
447+http.get = snapshot.httpGet;
448+http.globalAgent = snapshot.httpGlobalAgent;
449+https.request = snapshot.httpsRequest;
450+https.get = snapshot.httpsGet;
451+https.globalAgent = snapshot.httpsGlobalAgent;
452+if (snapshot.hadGlobalAgent) {
453+globalRecord["GLOBAL_AGENT"] = snapshot.globalAgent;
454+} else {
455+delete globalRecord["GLOBAL_AGENT"];
456+}
457+return run();
458+} finally {
459+http.request = activeStack.httpRequest;
460+http.get = activeStack.httpGet;
461+http.globalAgent = activeStack.httpGlobalAgent;
462+https.request = activeStack.httpsRequest;
463+https.get = activeStack.httpsGet;
464+https.globalAgent = activeStack.httpsGlobalAgent;
465+if (activeStack.hadGlobalAgent) {
466+globalRecord["GLOBAL_AGENT"] = activeStack.globalAgent;
467+} else {
468+delete globalRecord["GLOBAL_AGENT"];
469+}
419470}
420-}
471+});
421472}
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。