diff --git a/packages/core/src/config/config.ts b/packages/core/src/config/config.ts index b25690092..2cdaf6bc7 100644 --- a/packages/core/src/config/config.ts +++ b/packages/core/src/config/config.ts @@ -748,9 +748,9 @@ export class Config { initializeTelemetry(this); } - const normalizedProxy = normalizeProxyUrl(this.getProxy()); - if (normalizedProxy) { - setGlobalDispatcher(new ProxyAgent(normalizedProxy)); + const proxyUrl = this.getProxy(); + if (proxyUrl) { + setGlobalDispatcher(new ProxyAgent(proxyUrl)); } this.geminiClient = new GeminiClient(this); this.chatRecordingService = this.chatRecordingEnabled @@ -1719,7 +1719,7 @@ export class Config { } getProxy(): string | undefined { - return this.proxy; + return normalizeProxyUrl(this.proxy); } getWorkingDir(): string { diff --git a/packages/core/src/utils/proxyUtils.test.ts b/packages/core/src/utils/proxyUtils.test.ts index 7f7a54373..4f971aec5 100644 --- a/packages/core/src/utils/proxyUtils.test.ts +++ b/packages/core/src/utils/proxyUtils.test.ts @@ -78,27 +78,28 @@ describe('normalizeProxyUrl', () => { expect(normalizeProxyUrl('http://[::1]:8080')).toBe('http://[::1]:8080'); }); - it('should not modify URL that already has socks:// prefix', () => { - expect(normalizeProxyUrl('socks://proxy.example.com:1080')).toBe( - 'socks://proxy.example.com:1080', + // SOCKS proxy tests - should throw error since undici doesn't support SOCKS + it('should throw error for socks:// proxy URL', () => { + expect(() => normalizeProxyUrl('socks://proxy.example.com:1080')).toThrow( + 'SOCKS proxy is not supported', ); }); - it('should not modify URL that already has socks4:// prefix', () => { - expect(normalizeProxyUrl('socks4://proxy.example.com:1080')).toBe( - 'socks4://proxy.example.com:1080', + it('should throw error for socks4:// proxy URL', () => { + expect(() => normalizeProxyUrl('socks4://proxy.example.com:1080')).toThrow( + 'SOCKS proxy is not supported', ); }); - it('should not modify URL that already has socks5:// prefix', () => { - expect(normalizeProxyUrl('socks5://proxy.example.com:1080')).toBe( - 'socks5://proxy.example.com:1080', + it('should throw error for socks5:// proxy URL', () => { + expect(() => normalizeProxyUrl('socks5://proxy.example.com:1080')).toThrow( + 'SOCKS proxy is not supported', ); }); - it('should handle SOCKS:// prefix (case insensitive)', () => { - expect(normalizeProxyUrl('SOCKS5://proxy.example.com:1080')).toBe( - 'SOCKS5://proxy.example.com:1080', + it('should throw error for SOCKS5:// proxy URL (case insensitive)', () => { + expect(() => normalizeProxyUrl('SOCKS5://proxy.example.com:1080')).toThrow( + 'SOCKS proxy is not supported', ); }); }); diff --git a/packages/core/src/utils/proxyUtils.ts b/packages/core/src/utils/proxyUtils.ts index 30e42654d..322cd5311 100644 --- a/packages/core/src/utils/proxyUtils.ts +++ b/packages/core/src/utils/proxyUtils.ts @@ -11,8 +11,13 @@ * This function adds the "http://" prefix if missing, since HTTP proxies are * the most common default. * + * Note: Only HTTP and HTTPS proxies are supported. SOCKS proxies (socks://, + * socks4://, socks5://) are NOT supported because the underlying undici library + * does not support them. See: https://github.com/nodejs/undici/issues/2224 + * * @param proxyUrl - The proxy URL to normalize * @returns The normalized proxy URL with protocol prefix, or undefined if input is undefined/empty + * @throws Error if a SOCKS proxy URL is provided */ export function normalizeProxyUrl( proxyUrl: string | undefined, @@ -27,11 +32,20 @@ export function normalizeProxyUrl( } // Check if the URL already has a protocol prefix - // Support http, https, socks, socks4, socks5 protocols - if (/^(https?|socks[45]?):\/\//i.test(trimmed)) { + // Only support http and https protocols (undici limitation) + if (/^https?:\/\//i.test(trimmed)) { return trimmed; } + // Reject SOCKS proxies - undici does not support them + if (/^socks[45]?:\/\//i.test(trimmed)) { + throw new Error( + `SOCKS proxy is not supported. The underlying HTTP client (undici) only supports HTTP and HTTPS proxies. ` + + `Please use an HTTP/HTTPS proxy instead, or set up a SOCKS-to-HTTP proxy converter. ` + + `See: https://github.com/nodejs/undici/issues/2224`, + ); + } + // Add http:// prefix for proxy URLs without protocol // HTTP is the default for most proxy configurations return `http://${trimmed}`;