(env: Env = process.env)
| 84 | * `HTTPS_PROXY`, then `HTTP_PROXY`. `socks://` is an alias for `socks5://`. |
| 85 | */ |
| 86 | export function resolveSocksProxy(env: Env = process.env): SocksProxyConfig | undefined { |
| 87 | const candidates = [ |
| 88 | firstNonBlank(env, ['all_proxy', 'ALL_PROXY']), |
| 89 | firstNonBlank(env, ['https_proxy', 'HTTPS_PROXY']), |
| 90 | firstNonBlank(env, ['http_proxy', 'HTTP_PROXY']), |
| 91 | ]; |
| 92 | for (const value of candidates) { |
| 93 | if (value === undefined) continue; |
| 94 | const scheme = schemeOf(value); |
| 95 | if (scheme === undefined || !SOCKS_SCHEMES.has(scheme)) continue; |
| 96 | let url: URL; |
| 97 | try { |
| 98 | url = new URL(value); |
| 99 | } catch { |
| 100 | continue; |
| 101 | } |
| 102 | const config: SocksProxyConfig = { |
| 103 | type: scheme === 'socks4' || scheme === 'socks4a' ? 4 : 5, |
| 104 | // Strip IPv6 brackets: the `socks` client wants the bare address (`::1`), |
| 105 | // not the URL's bracketed `[::1]`, which it would treat as a hostname. |
| 106 | host: url.hostname.replaceAll(/^\[|\]$/g, ''), |
| 107 | port: url.port ? Number(url.port) : 1080, |
| 108 | ...(url.username ? { userId: decodeURIComponent(url.username) } : {}), |
| 109 | ...(url.password ? { password: decodeURIComponent(url.password) } : {}), |
| 110 | }; |
| 111 | return config; |
| 112 | } |
| 113 | return undefined; |
| 114 | } |
| 115 | |
| 116 | /** True when any HTTP(S) or SOCKS proxy variable is set to a usable value. */ |
| 117 | export function isProxyConfigured(env: Env = process.env): boolean { |
no test coverage detected