mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-09 14:14:32 +00:00
fix: bypass proxy for CDP localhost connections (#31219)
When HTTP_PROXY / HTTPS_PROXY / ALL_PROXY environment variables are set, CDP connections to localhost/127.0.0.1 can be incorrectly routed through the proxy (e.g. via global-agent or undici proxy dispatcher), causing browser control to fail. Fix: - New cdp-proxy-bypass module with utilities for direct localhost connections - WebSocket (ws) CDP connections: pass explicit http.Agent to bypass any global proxy agent patching - fetch-based CDP probes: wrap in withNoProxyForLocalhost() to temporarily set NO_PROXY for the duration of the call - Playwright connectOverCDP: wrap in withNoProxyForLocalhost() since Playwright reads env vars internally - 13 new tests covering getDirectAgentForCdp, hasProxyEnv, and withNoProxyForLocalhost (env save/restore, error recovery)
This commit is contained in:
committed by
Peter Steinberger
parent
1184d39e1d
commit
c96234b51d
@@ -1,6 +1,7 @@
|
||||
import WebSocket from "ws";
|
||||
import { isLoopbackHost } from "../gateway/net.js";
|
||||
import { rawDataToString } from "../infra/ws.js";
|
||||
import { getDirectAgentForCdp, withNoProxyForLocalhost } from "./cdp-proxy-bypass.js";
|
||||
import { getChromeExtensionRelayAuthHeaders } from "./extension-relay.js";
|
||||
|
||||
export { isLoopbackHost };
|
||||
@@ -122,7 +123,10 @@ async function fetchChecked(url: string, timeoutMs = 1500, init?: RequestInit):
|
||||
const t = setTimeout(ctrl.abort.bind(ctrl), timeoutMs);
|
||||
try {
|
||||
const headers = getHeadersWithAuth(url, (init?.headers as Record<string, string>) || {});
|
||||
const res = await fetch(url, { ...init, headers, signal: ctrl.signal });
|
||||
// Bypass proxy for loopback CDP connections (#31219)
|
||||
const res = await withNoProxyForLocalhost(() =>
|
||||
fetch(url, { ...init, headers, signal: ctrl.signal }),
|
||||
);
|
||||
if (!res.ok) {
|
||||
throw new Error(`HTTP ${res.status}`);
|
||||
}
|
||||
@@ -146,9 +150,12 @@ export async function withCdpSocket<T>(
|
||||
typeof opts?.handshakeTimeoutMs === "number" && Number.isFinite(opts.handshakeTimeoutMs)
|
||||
? Math.max(1, Math.floor(opts.handshakeTimeoutMs))
|
||||
: 5000;
|
||||
// Bypass proxy for loopback CDP connections (#31219)
|
||||
const agent = getDirectAgentForCdp(wsUrl);
|
||||
const ws = new WebSocket(wsUrl, {
|
||||
handshakeTimeout: handshakeTimeoutMs,
|
||||
...(Object.keys(headers).length ? { headers } : {}),
|
||||
...(agent ? { agent } : {}),
|
||||
});
|
||||
const { send, closeWithError } = createCdpSender(ws);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user