Add CLI for request proxy Closes #364, #377, #1756
| @@ -76,6 +76,10 @@ const DEFAULT_AVOID_LOCALHOST = false; | |||
| 76 | const DEFAULT_AUTORUN_HOSTNAME = 'auto'; | 76 | const DEFAULT_AUTORUN_HOSTNAME = 'auto'; |
| 77 | const DEFAULT_AUTORUN_PORT = -1; | 77 | const DEFAULT_AUTORUN_PORT = -1; |
| 78 | 78 | ||
| 79 | const DEFAULT_PROXY_ENABLED = false; | ||
| 80 | const DEFAULT_PROXY_URL = ''; | ||
| 81 | const DEFAULT_PROXY_BYPASS = []; | ||
| 82 | |||
| 79 | const cliArguments = yargs(hideBin(process.argv)) | 83 | const cliArguments = yargs(hideBin(process.argv)) |
| 80 | .usage('Usage: <your-start-script> <command> [options]') | 84 | .usage('Usage: <your-start-script> <command> [options]') |
| 81 | .option('enableIPv6', { | 85 | .option('enableIPv6', { |
| @@ -146,6 +150,18 @@ const cliArguments = yargs(hideBin(process.argv)) | |||
| 146 | type: 'boolean', | 150 | type: 'boolean', |
| 147 | default: null, | 151 | default: null, |
| 148 | describe: 'Enables basic authentication', | 152 | describe: 'Enables basic authentication', |
| 153 | }).option('requestProxyEnabled', { | ||
| 154 | type: 'boolean', | ||
| 155 | default: null, | ||
| 156 | describe: 'Enables request proxy', | ||
| 157 | }).option('requestProxyUrl', { | ||
| 158 | type: 'string', | ||
| 159 | default: null, | ||
| 160 | describe: 'Request proxy URL', | ||
| 161 | }).option('requestProxyBypasss', { | ||
| 162 | type: 'array', | ||
| 163 | default: null, | ||
| 164 | describe: 'Request proxy bypass', | ||
| 149 | }).parseSync(); | 165 | }).parseSync(); |
| 150 | 166 | ||
| 151 | // change all relative paths | 167 | // change all relative paths |
| @@ -182,6 +198,10 @@ const dnsPreferIPv6 = cliArguments.dnsPreferIPv6 ?? getConfigValue('dnsPreferIPv | |||
| 182 | 198 | ||
| 183 | const avoidLocalhost = cliArguments.avoidLocalhost ?? getConfigValue('avoidLocalhost', DEFAULT_AVOID_LOCALHOST); | 199 | const avoidLocalhost = cliArguments.avoidLocalhost ?? getConfigValue('avoidLocalhost', DEFAULT_AVOID_LOCALHOST); |
| 184 | 200 | ||
| 201 | const proxyEnabled = cliArguments.requestProxyEnabled ?? getConfigValue('requestProxy.enabled', DEFAULT_PROXY_ENABLED); | ||
| 202 | const proxyUrl = cliArguments.requestProxyUrl ?? getConfigValue('requestProxy.url', DEFAULT_PROXY_URL); | ||
| 203 | const proxyBypass = cliArguments.requestProxyBypass ?? getConfigValue('requestProxy.bypass', DEFAULT_PROXY_BYPASS); | ||
| 204 | |||
| 185 | if (dnsPreferIPv6) { | 205 | if (dnsPreferIPv6) { |
| 186 | // Set default DNS resolution order to IPv6 first | 206 | // Set default DNS resolution order to IPv6 first |
| 187 | dns.setDefaultResultOrder('ipv6first'); | 207 | dns.setDefaultResultOrder('ipv6first'); |
| @@ -665,7 +685,7 @@ const preSetupTasks = async function () { | |||
| 665 | }); | 685 | }); |
| 666 | 686 | ||
| 667 | // Add request proxy. | 687 | // Add request proxy. |
| 668 | initRequestProxy(); | 688 | initRequestProxy({ enabled: proxyEnabled, url: proxyUrl, bypass: proxyBypass }); |
| 669 | }; | 689 | }; |
| 670 | 690 | ||
| 671 | /** | 691 | /** |
| @@ -1,40 +1,44 @@ | |||
| 1 | const http = require('node:http'); | 1 | const http = require('node:http'); |
| 2 | const https = require('node:https'); | 2 | const https = require('node:https'); |
| 3 | 3 | ||
| 4 | const { getConfigValue, isValidUrl, color } = require('./util.js'); | 4 | const { isValidUrl, color } = require('./util.js'); |
| 5 | 5 | ||
| 6 | const LOG_HEADER = '[Request Proxy]'; | 6 | const LOG_HEADER = '[Request Proxy]'; |
| 7 | 7 | ||
| 8 | function initRequestProxy() { | 8 | /** |
| 9 | * Initialize request proxy. | ||
| 10 | * @param {ProxySettings} settings Proxy settings. | ||
| 11 | * @typedef {object} ProxySettings | ||
| 12 | * @property {boolean} enabled Whether proxy is enabled. | ||
| 13 | * @property {string} url Proxy URL. | ||
| 14 | * @property {string[]} bypass List of URLs to bypass proxy. | ||
| 15 | */ | ||
| 16 | function initRequestProxy({ enabled, url, bypass }) { | ||
| 9 | try { | 17 | try { |
| 10 | const { ProxyAgent } = require('proxy-agent'); | 18 | const { ProxyAgent } = require('proxy-agent'); |
| 11 | const proxyEnabled = getConfigValue('requestProxy.enabled', false); | ||
| 12 | 19 | ||
| 13 | // No proxy is enabled, so return | 20 | // No proxy is enabled, so return |
| 14 | if (!proxyEnabled) { | 21 | if (!enabled) { |
| 15 | return; | 22 | return; |
| 16 | } | 23 | } |
| 17 | 24 | ||
| 18 | const proxyUrl = getConfigValue('requestProxy.url', ''); | 25 | if (!url) { |
| 19 | |||
| 20 | if (!proxyUrl) { | ||
| 21 | console.error(color.red(LOG_HEADER), 'No proxy URL provided'); | 26 | console.error(color.red(LOG_HEADER), 'No proxy URL provided'); |
| 22 | return; | 27 | return; |
| 23 | } | 28 | } |
| 24 | 29 | ||
| 25 | if (!isValidUrl(proxyUrl)) { | 30 | if (!isValidUrl(url)) { |
| 26 | console.error(color.red(LOG_HEADER), 'Invalid proxy URL provided'); | 31 | console.error(color.red(LOG_HEADER), 'Invalid proxy URL provided'); |
| 27 | return; | 32 | return; |
| 28 | } | 33 | } |
| 29 | 34 | ||
| 30 | // ProxyAgent uses proxy-from-env under the hood | 35 | // ProxyAgent uses proxy-from-env under the hood |
| 31 | // Reference: https://github.com/Rob--W/proxy-from-env | 36 | // Reference: https://github.com/Rob--W/proxy-from-env |
| 32 | process.env.all_proxy = proxyUrl; | 37 | process.env.all_proxy = url; |
| 33 | 38 | ||
| 34 | const proxyBypass = getConfigValue('requestProxy.bypass', []); | ||
| 35 | 39 | ||
| 36 | if (Array.isArray(proxyBypass) && proxyBypass.length > 0) { | 40 | if (Array.isArray(bypass) && bypass.length > 0) { |
| 37 | process.env.no_proxy = proxyBypass.join(','); | 41 | process.env.no_proxy = bypass.join(','); |
| 38 | } | 42 | } |
| 39 | 43 | ||
| 40 | const proxyAgent = new ProxyAgent(); | 44 | const proxyAgent = new ProxyAgent(); |
| @@ -42,7 +46,7 @@ function initRequestProxy() { | |||
| 42 | https.globalAgent = proxyAgent; | 46 | https.globalAgent = proxyAgent; |
| 43 | 47 | ||
| 44 | console.log(); | 48 | console.log(); |
| 45 | console.log(color.green(LOG_HEADER), 'Proxy URL is used:', color.blue(proxyUrl)); | 49 | console.log(color.green(LOG_HEADER), 'Proxy URL is used:', color.blue(url)); |
| 46 | console.log(); | 50 | console.log(); |
| 47 | } catch (error) { | 51 | } catch (error) { |
| 48 | console.error(color.red(LOG_HEADER), 'Failed to initialize request proxy:', error); | 52 | console.error(color.red(LOG_HEADER), 'Failed to initialize request proxy:', error); |