mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-04-17 08:41:19 -07:00
feat(core): use experiment flags for default fetch timeouts (#24261)
This commit is contained in:
@@ -4,21 +4,37 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import { updateGlobalFetchTimeouts } from './fetch.js';
|
||||
import { describe, it, expect, vi, beforeEach, afterAll } from 'vitest';
|
||||
import {
|
||||
isPrivateIp,
|
||||
isPrivateIpAsync,
|
||||
isAddressPrivate,
|
||||
fetchWithTimeout,
|
||||
} from './fetch.js';
|
||||
import * as dnsPromises from 'node:dns/promises';
|
||||
import type { LookupAddress, LookupAllOptions } from 'node:dns';
|
||||
import ipaddr from 'ipaddr.js';
|
||||
|
||||
const { setGlobalDispatcher, Agent, ProxyAgent } = vi.hoisted(() => ({
|
||||
setGlobalDispatcher: vi.fn(),
|
||||
Agent: vi.fn(),
|
||||
ProxyAgent: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock('undici', () => ({
|
||||
setGlobalDispatcher,
|
||||
Agent,
|
||||
ProxyAgent,
|
||||
}));
|
||||
|
||||
vi.mock('node:dns/promises', () => ({
|
||||
lookup: vi.fn(),
|
||||
}));
|
||||
|
||||
// Import after mocks are established
|
||||
const {
|
||||
isPrivateIp,
|
||||
isPrivateIpAsync,
|
||||
isAddressPrivate,
|
||||
fetchWithTimeout,
|
||||
setGlobalProxy,
|
||||
} = await import('./fetch.js');
|
||||
|
||||
// Mock global fetch
|
||||
const originalFetch = global.fetch;
|
||||
global.fetch = vi.fn();
|
||||
@@ -183,4 +199,19 @@ describe('fetch utils', () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('setGlobalProxy', () => {
|
||||
it('should configure ProxyAgent with experiment flag timeout', () => {
|
||||
const proxyUrl = 'http://proxy.example.com';
|
||||
updateGlobalFetchTimeouts(45773134);
|
||||
setGlobalProxy(proxyUrl);
|
||||
|
||||
expect(ProxyAgent).toHaveBeenCalledWith({
|
||||
uri: proxyUrl,
|
||||
headersTimeout: 45773134,
|
||||
bodyTimeout: 45773134,
|
||||
});
|
||||
expect(setGlobalDispatcher).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -10,9 +10,6 @@ import { Agent, ProxyAgent, setGlobalDispatcher } from 'undici';
|
||||
import ipaddr from 'ipaddr.js';
|
||||
import { lookup } from 'node:dns/promises';
|
||||
|
||||
const DEFAULT_HEADERS_TIMEOUT = 300000; // 5 minutes
|
||||
const DEFAULT_BODY_TIMEOUT = 300000; // 5 minutes
|
||||
|
||||
export class FetchError extends Error {
|
||||
constructor(
|
||||
message: string,
|
||||
@@ -31,14 +28,36 @@ export class PrivateIpError extends Error {
|
||||
}
|
||||
}
|
||||
|
||||
let defaultTimeout = 300000; // 5 minutes
|
||||
let currentProxy: string | undefined = undefined;
|
||||
|
||||
// Configure default global dispatcher with higher timeouts
|
||||
setGlobalDispatcher(
|
||||
new Agent({
|
||||
headersTimeout: DEFAULT_HEADERS_TIMEOUT,
|
||||
bodyTimeout: DEFAULT_BODY_TIMEOUT,
|
||||
headersTimeout: defaultTimeout,
|
||||
bodyTimeout: defaultTimeout,
|
||||
}),
|
||||
);
|
||||
|
||||
export function updateGlobalFetchTimeouts(timeoutMs: number) {
|
||||
if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
|
||||
throw new RangeError(
|
||||
`Invalid timeout value: ${timeoutMs}. Must be a positive finite number.`,
|
||||
);
|
||||
}
|
||||
defaultTimeout = timeoutMs;
|
||||
if (currentProxy) {
|
||||
setGlobalProxy(currentProxy);
|
||||
} else {
|
||||
setGlobalDispatcher(
|
||||
new Agent({
|
||||
headersTimeout: defaultTimeout,
|
||||
bodyTimeout: defaultTimeout,
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitizes a hostname by stripping IPv6 brackets if present.
|
||||
*/
|
||||
@@ -191,11 +210,12 @@ export async function fetchWithTimeout(
|
||||
}
|
||||
|
||||
export function setGlobalProxy(proxy: string) {
|
||||
currentProxy = proxy;
|
||||
setGlobalDispatcher(
|
||||
new ProxyAgent({
|
||||
uri: proxy,
|
||||
headersTimeout: DEFAULT_HEADERS_TIMEOUT,
|
||||
bodyTimeout: DEFAULT_BODY_TIMEOUT,
|
||||
headersTimeout: defaultTimeout,
|
||||
bodyTimeout: defaultTimeout,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user