mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-03-11 22:51:00 -07:00
95 lines
2.1 KiB
TypeScript
95 lines
2.1 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright 2025 Google LLC
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
import { getErrorMessage, isNodeError } from './errors.js';
|
|
import { URL } from 'node:url';
|
|
import { Agent, ProxyAgent, setGlobalDispatcher } from 'undici';
|
|
|
|
const DEFAULT_HEADERS_TIMEOUT = 60000; // 60 seconds
|
|
const DEFAULT_BODY_TIMEOUT = 300000; // 5 minutes
|
|
|
|
// Configure default global dispatcher with higher timeouts
|
|
setGlobalDispatcher(
|
|
new Agent({
|
|
headersTimeout: DEFAULT_HEADERS_TIMEOUT,
|
|
bodyTimeout: DEFAULT_BODY_TIMEOUT,
|
|
}),
|
|
);
|
|
|
|
const PRIVATE_IP_RANGES = [
|
|
/^10\./,
|
|
/^127\./,
|
|
/^172\.(1[6-9]|2[0-9]|3[0-1])\./,
|
|
/^192\.168\./,
|
|
/^::1$/,
|
|
/^fc00:/,
|
|
/^fe80:/,
|
|
];
|
|
|
|
export class FetchError extends Error {
|
|
constructor(
|
|
message: string,
|
|
public code?: string,
|
|
options?: ErrorOptions,
|
|
) {
|
|
super(message, options);
|
|
this.name = 'FetchError';
|
|
}
|
|
}
|
|
|
|
export function isPrivateIp(url: string): boolean {
|
|
try {
|
|
const hostname = new URL(url).hostname;
|
|
return PRIVATE_IP_RANGES.some((range) => range.test(hostname));
|
|
} catch (_e) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
export async function fetchWithTimeout(
|
|
url: string,
|
|
timeout: number,
|
|
options?: RequestInit,
|
|
): Promise<Response> {
|
|
const controller = new AbortController();
|
|
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
|
|
if (options?.signal) {
|
|
if (options.signal.aborted) {
|
|
controller.abort();
|
|
} else {
|
|
options.signal.addEventListener('abort', () => controller.abort(), {
|
|
once: true,
|
|
});
|
|
}
|
|
}
|
|
|
|
try {
|
|
const response = await fetch(url, {
|
|
...options,
|
|
signal: controller.signal,
|
|
});
|
|
return response;
|
|
} catch (error) {
|
|
if (isNodeError(error) && error.code === 'ABORT_ERR') {
|
|
throw new FetchError(`Request timed out after ${timeout}ms`, 'ETIMEDOUT');
|
|
}
|
|
throw new FetchError(getErrorMessage(error), undefined, { cause: error });
|
|
} finally {
|
|
clearTimeout(timeoutId);
|
|
}
|
|
}
|
|
|
|
export function setGlobalProxy(proxy: string) {
|
|
setGlobalDispatcher(
|
|
new ProxyAgent({
|
|
uri: proxy,
|
|
headersTimeout: DEFAULT_HEADERS_TIMEOUT,
|
|
bodyTimeout: DEFAULT_BODY_TIMEOUT,
|
|
}),
|
|
);
|
|
}
|