




























@@ -1,6 +1,5 @@
11import type { Dispatcher } from "undici";
22import { logWarn } from "../../logger.js";
3-import { captureHttpExchange } from "../../proxy-capture/runtime.js";
43import { buildTimeoutAbortSignal } from "../../utils/fetch-timeout.js";
54import { hasProxyEnvConfigured, shouldUseEnvHttpProxyForUrl } from "./proxy-env.js";
65import { retainSafeHeadersForCrossOriginRedirect as retainSafeRedirectHeaders } from "./redirect-headers.js";
@@ -95,6 +94,11 @@ type GuardedFetchPresetOptions = Omit<
9594>;
96959796const DEFAULT_MAX_REDIRECTS = 3;
97+const OPENCLAW_DEBUG_PROXY_ENABLED = "OPENCLAW_DEBUG_PROXY_ENABLED";
98+99+function isTruthyEnvValue(value: string | undefined): boolean {
100+return value === "1" || value === "true" || value === "yes" || value === "on";
101+}
9810299103export function withStrictGuardedFetchMode(params: GuardedFetchPresetOptions): GuardedFetchOptions {
100104return { ...params, mode: GUARDED_FETCH_MODE.STRICT };
@@ -232,6 +236,36 @@ export function retainSafeHeadersForCrossOriginRedirectHeaders(
232236return retainSafeRedirectHeaders(headers);
233237}
234238239+async function captureGuardedFetchExchange(params: {
240+url: string;
241+method: string;
242+requestHeaders?: Headers | Record<string, string> | undefined;
243+requestBody?: BodyInit | Buffer | string | null;
244+response: Response;
245+transport?: "http" | "sse";
246+capture: GuardedFetchOptions["capture"];
247+auditContext?: string;
248+}): Promise<void> {
249+if (params.capture === false || !isTruthyEnvValue(process.env[OPENCLAW_DEBUG_PROXY_ENABLED])) {
250+return;
251+}
252+const { captureHttpExchange } = await import("../../proxy-capture/runtime.js");
253+captureHttpExchange({
254+url: params.url,
255+method: params.method,
256+requestHeaders: params.requestHeaders,
257+requestBody: params.requestBody,
258+response: params.response,
259+transport: params.transport,
260+flowId: params.capture?.flowId,
261+meta: {
262+captureOrigin: "guarded-fetch",
263+ ...(params.auditContext ? { auditContext: params.auditContext } : {}),
264+ ...params.capture?.meta,
265+},
266+});
267+}
268+235269function retainSafeHeadersForCrossOriginRedirect(init?: RequestInit): RequestInit | undefined {
236270if (!init?.headers) {
237271return init;
@@ -433,23 +467,17 @@ export async function fetchWithSsrFGuard(params: GuardedFetchOptions): Promise<G
433467 ? await fetchWithRuntimeDispatcher(parsedUrl.toString(), init)
434468 : await defaultFetch(parsedUrl.toString(), init);
435469436-if (params.capture !== false) {
437-captureHttpExchange({
438-url: parsedUrl.toString(),
439-method: currentInit?.method ?? "GET",
440-requestHeaders: currentInit?.headers as Headers | Record<string, string> | undefined,
441-requestBody:
442-(currentInit as (RequestInit & { body?: BodyInit | null }) | undefined)?.body ?? null,
443- response,
444-transport: "http",
445-flowId: params.capture?.flowId,
446-meta: {
447-captureOrigin: "guarded-fetch",
448- ...(params.auditContext ? { auditContext: params.auditContext } : {}),
449- ...params.capture?.meta,
450-},
451-});
452-}
470+await captureGuardedFetchExchange({
471+url: parsedUrl.toString(),
472+method: currentInit?.method ?? "GET",
473+requestHeaders: currentInit?.headers as Headers | Record<string, string> | undefined,
474+requestBody:
475+(currentInit as (RequestInit & { body?: BodyInit | null }) | undefined)?.body ?? null,
476+ response,
477+transport: "http",
478+capture: params.capture,
479+auditContext: params.auditContext,
480+});
453481454482if (isRedirectStatus(response.status)) {
455483const location = response.headers.get("location");
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。