import { URL } from 'url';
export function getProxyForUrl(url: string): URL {
const parsedUrl = new URL(url);
let protocol = parsedUrl.protocol;
let hostname = parsedUrl.host;
if (typeof hostname !== 'string' || !hostname || typeof protocol !== 'string') {
return null;
}
setProxyVars();
protocol = protocol.split(':', 1)[0];
hostname = hostname.replace(/:\d*$/, '');
let parsedPort = parseInt(parsedUrl.port, 10) || 0;
if (!parsedPort) parsedPort = protocol === 'https:' ? 443 : 80;
if (!shouldProxy(hostname, parsedPort)) {
return null;
}
let proxy =
getEnv(`npm_config_${protocol}_proxy`) ||
getEnv(`${protocol}_proxy`) ||
getEnv('npm_config_proxy') ||
getEnv('all_proxy');
if (proxy && proxy.indexOf('://') === -1) {
proxy = `${protocol}://${proxy}`;
}
if (!proxy) return null;
return new URL(proxy);
}
function shouldProxy(hostname: string, port: number): boolean {
const NO_PROXY = (getEnv('npm_config_no_proxy') || getEnv('no_proxy')).toLowerCase();
if (!NO_PROXY) {
return true;
}
if (NO_PROXY === '*') {
return false;
}
for (const proxy of NO_PROXY.split(/[,\s]/)) {
if (!proxy) continue;
const parsedProxy = proxy.match(/^(.+):(\d+)$/);
let parsedProxyHostname = parsedProxy ? parsedProxy[1] : proxy;
const parsedProxyPort = parsedProxy ? parseInt(parsedProxy[2], 10) : 0;
if (parsedProxyPort && parsedProxyPort !== port) {
continue;
}
if (!parsedProxyHostname.startsWith('.') && !parsedProxyHostname.startsWith('*')) {
if (hostname === parsedProxyHostname) {
return false;
}
}
if (parsedProxyHostname.startsWith('*')) {
parsedProxyHostname = parsedProxyHostname.slice(1);
}
if (!hostname.endsWith(parsedProxyHostname)) {
return false;
}
}
return true;
}
function getEnv(key: string): string {
return process.env[key.toLowerCase()] || process.env[key.toUpperCase()] || '';
}
function setProxyVars(): void {
const NPM_HTTPS_PROXY = process.env.npm_config_https_proxy || process.env.npm_config_proxy;
const NPM_HTTP_PROXY = process.env.npm_config_http_proxy || process.env.npm_config_proxy;
const NPM_NO_PROXY = process.env.npm_config_no_proxy;
if (NPM_HTTPS_PROXY) process.env.HTTPS_PROXY = NPM_HTTPS_PROXY;
if (NPM_HTTP_PROXY) process.env.HTTP_PROXY = NPM_HTTP_PROXY;
if (NPM_NO_PROXY) process.env.NO_PROXY = NPM_NO_PROXY;
}