





























@@ -19,12 +19,25 @@ import {
1919SsrFBlockedError,
2020type SsrFPolicy,
2121} from "./ssrf.js";
22+import { _globalUndiciStreamTimeoutMs } from "./undici-global-dispatcher.js";
2223import {
2324createHttp1Agent,
2425createHttp1EnvHttpProxyAgent,
2526createHttp1ProxyAgent,
2627} from "./undici-runtime.js";
272829+function resolveDispatcherTimeoutMs(fromParams: number | undefined): number | undefined {
30+if (fromParams !== undefined) {
31+return fromParams;
32+}
33+// Fall back to module-level bridge set by ensureGlobalUndiciStreamTimeouts
34+// (avoids reading Undici's non-public `.options` field)
35+if (_globalUndiciStreamTimeoutMs !== undefined) {
36+return _globalUndiciStreamTimeoutMs;
37+}
38+return undefined;
39+}
40+2841type FetchLike = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
29423043export const GUARDED_FETCH_MODE = {
@@ -125,6 +138,7 @@ function assertExplicitProxySupportsPinnedDns(
125138126139function createPolicyDispatcherWithoutPinnedDns(
127140dispatcherPolicy?: PinnedDispatcherPolicy,
141+timeoutMs?: number,
128142): Dispatcher | null {
129143if (!dispatcherPolicy) {
130144return null;
@@ -133,23 +147,28 @@ function createPolicyDispatcherWithoutPinnedDns(
133147if (dispatcherPolicy.mode === "direct") {
134148return createHttp1Agent(
135149dispatcherPolicy.connect ? { connect: { ...dispatcherPolicy.connect } } : undefined,
150+timeoutMs,
136151);
137152}
138153139154if (dispatcherPolicy.mode === "env-proxy") {
140-return createHttp1EnvHttpProxyAgent({
141- ...(dispatcherPolicy.connect ? { connect: { ...dispatcherPolicy.connect } } : {}),
142- ...(dispatcherPolicy.proxyTls ? { proxyTls: { ...dispatcherPolicy.proxyTls } } : {}),
143-});
155+return createHttp1EnvHttpProxyAgent(
156+{
157+ ...(dispatcherPolicy.connect ? { connect: { ...dispatcherPolicy.connect } } : {}),
158+ ...(dispatcherPolicy.proxyTls ? { proxyTls: { ...dispatcherPolicy.proxyTls } } : {}),
159+},
160+timeoutMs,
161+);
144162}
145163146164const proxyUrl = dispatcherPolicy.proxyUrl.trim();
147-return dispatcherPolicy.proxyTls
148- ? createHttp1ProxyAgent({
149-uri: proxyUrl,
150-requestTls: { ...dispatcherPolicy.proxyTls },
151-})
152- : createHttp1ProxyAgent({ uri: proxyUrl });
165+if (dispatcherPolicy.proxyTls) {
166+return createHttp1ProxyAgent(
167+{ uri: proxyUrl, requestTls: { ...dispatcherPolicy.proxyTls } },
168+timeoutMs,
169+);
170+}
171+return createHttp1ProxyAgent({ uri: proxyUrl }, timeoutMs);
153172}
154173155174async function assertExplicitProxyAllowed(
@@ -337,25 +356,31 @@ export async function fetchWithSsrFGuard(params: GuardedFetchOptions): Promise<G
337356await assertExplicitProxyAllowed(params.dispatcherPolicy, params.lookupFn, params.policy);
338357const canUseTrustedEnvProxy =
339358mode === GUARDED_FETCH_MODE.TRUSTED_ENV_PROXY && hasProxyEnvConfigured();
359+const timeoutMs = resolveDispatcherTimeoutMs(params.timeoutMs);
340360if (canUseTrustedEnvProxy) {
341-dispatcher = createHttp1EnvHttpProxyAgent();
361+dispatcher = createHttp1EnvHttpProxyAgent(undefined, timeoutMs);
342362} else if (usesTrustedExplicitProxyMode) {
343363// Explicit proxy targets are still checked against the caller's hostname
344364// policy, but the proxy does the DNS resolution for the final target.
345365assertHostnameAllowedWithPolicy(parsedUrl.hostname, params.policy);
346-dispatcher = createPolicyDispatcherWithoutPinnedDns(params.dispatcherPolicy);
366+dispatcher = createPolicyDispatcherWithoutPinnedDns(params.dispatcherPolicy, timeoutMs);
347367} else if (params.pinDns === false) {
348368await resolvePinnedHostnameWithPolicy(parsedUrl.hostname, {
349369lookupFn: params.lookupFn,
350370policy: params.policy,
351371});
352-dispatcher = createPolicyDispatcherWithoutPinnedDns(params.dispatcherPolicy);
372+dispatcher = createPolicyDispatcherWithoutPinnedDns(params.dispatcherPolicy, timeoutMs);
353373} else {
354374const pinned = await resolvePinnedHostnameWithPolicy(parsedUrl.hostname, {
355375lookupFn: params.lookupFn,
356376policy: params.policy,
357377});
358-dispatcher = createPinnedDispatcher(pinned, params.dispatcherPolicy, params.policy);
378+dispatcher = createPinnedDispatcher(
379+pinned,
380+params.dispatcherPolicy,
381+params.policy,
382+timeoutMs,
383+);
359384}
360385361386const init: DispatcherAwareRequestInit = {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。