mirror of
https://github.com/tiennm99/ccs.git
synced 2026-08-06 18:22:08 +00:00
fix(cliproxy): add NO_PROXY support and error handling for proxy URLs
- Add shouldBypassProxy() to respect NO_PROXY/no_proxy env var - Supports exact match, wildcard (*), and domain suffix patterns - Add try-catch for malformed proxy URLs with graceful fallback - Extract getHostname() helper for URL parsing
This commit is contained in:
@@ -35,8 +35,44 @@ function getProxyUrl(isHttps: boolean): string | undefined {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a hostname should bypass the proxy based on NO_PROXY/no_proxy env var.
|
||||||
|
* Supports: exact match, wildcard (*), and domain suffix (.example.com)
|
||||||
|
* @param hostname The hostname to check
|
||||||
|
* @returns true if the hostname should bypass the proxy
|
||||||
|
*/
|
||||||
|
function shouldBypassProxy(hostname: string): boolean {
|
||||||
|
const noProxy = process.env.no_proxy || process.env.NO_PROXY;
|
||||||
|
if (!noProxy) return false;
|
||||||
|
|
||||||
|
const noProxyList = noProxy.split(',').map((s) => s.trim().toLowerCase());
|
||||||
|
const host = hostname.toLowerCase();
|
||||||
|
|
||||||
|
return noProxyList.some((pattern) => {
|
||||||
|
if (pattern === '*') return true;
|
||||||
|
if (pattern.startsWith('.')) {
|
||||||
|
return host.endsWith(pattern) || host === pattern.slice(1);
|
||||||
|
}
|
||||||
|
return host === pattern || host.endsWith('.' + pattern);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract hostname from URL.
|
||||||
|
* @param url The URL to parse
|
||||||
|
* @returns Hostname or empty string if invalid
|
||||||
|
*/
|
||||||
|
function getHostname(url: string): string {
|
||||||
|
try {
|
||||||
|
return new URL(url).hostname;
|
||||||
|
} catch {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create appropriate proxy agent based on URL protocol.
|
* Create appropriate proxy agent based on URL protocol.
|
||||||
|
* Respects NO_PROXY/no_proxy for bypassing specific hosts.
|
||||||
* @param url Target URL to determine protocol
|
* @param url Target URL to determine protocol
|
||||||
* @returns Proxy agent or false (no agent/pooling disabled)
|
* @returns Proxy agent or false (no agent/pooling disabled)
|
||||||
*/
|
*/
|
||||||
@@ -48,11 +84,23 @@ function getProxyAgent(url: string): http.Agent | https.Agent | false {
|
|||||||
return false; // No proxy configured, disable connection pooling for clean exit
|
return false; // No proxy configured, disable connection pooling for clean exit
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use appropriate agent based on target URL protocol
|
// Check if this host should bypass the proxy
|
||||||
if (isHttps) {
|
const hostname = getHostname(url);
|
||||||
return new HttpsProxyAgent(proxyUrl);
|
if (hostname && shouldBypassProxy(hostname)) {
|
||||||
|
return false; // Bypass proxy for this host
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create proxy agent with error handling for malformed URLs
|
||||||
|
try {
|
||||||
|
if (isHttps) {
|
||||||
|
return new HttpsProxyAgent(proxyUrl);
|
||||||
|
}
|
||||||
|
return new HttpProxyAgent(proxyUrl);
|
||||||
|
} catch {
|
||||||
|
// Invalid proxy URL, fall back to direct connection
|
||||||
|
console.error(`[cliproxy] Invalid proxy URL: ${proxyUrl}`);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return new HttpProxyAgent(proxyUrl);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Default configuration for downloader */
|
/** Default configuration for downloader */
|
||||||
|
|||||||
Reference in New Issue
Block a user