From 9cb1c0ae8b38173193bae9b86fa6f143d85eb4ec Mon Sep 17 00:00:00 2001 From: Erick Guan <297343+erickguan@users.noreply.github.com> Date: Sun, 26 Jul 2026 22:01:16 +0800 Subject: [PATCH] Allow Chrome using http proxy --- Readme.md | 4 ++++ src/common/puppeteer.ts | 50 +++++++++++++++++++++++++++-------------- 2 files changed, 37 insertions(+), 17 deletions(-) diff --git a/Readme.md b/Readme.md index 2345b6ef..f363c272 100644 --- a/Readme.md +++ b/Readme.md @@ -238,6 +238,10 @@ If for some reason you don't want to use Docker to run this tool you can run it ## Proxy configuration Network proxies are configured via the `*_PROXY` and `NO_PROXY` environment variables. Details on the environment variables available from [proxy-from-env](https://github.com/Rob--W/proxy-from-env#environment-variables), and the kinds of proxies avaiable from [proxy-agent](https://github.com/TooTallNate/proxy-agents/tree/main/packages/proxy-agent#maps-proxy-protocols-to-httpagent-implementations). + +Set `EPICGAMES_FREEGAMES_NODE_USE_PROXY_CHROME=true` to make Chrome use the proxy server specified by `HTTPS_PROXY`. If `HTTPS_PROXY` is unset, Chrome uses `ALL_PROXY` instead. This setting affects Chrome only; Node.js requests keep their existing proxy behavior. + +The application forwards the selected proxy value unchanged to Chrome with `--proxy-server`. It does not parse or normalize the value, apply `NO_PROXY`, or configure proxy authentication. Use a proxy server format Chrome accepts, and do not include credentials because Chrome exposes the argument in its process command line. ## Miscellaneous diff --git a/src/common/puppeteer.ts b/src/common/puppeteer.ts index 1be50397..0bb963dd 100644 --- a/src/common/puppeteer.ts +++ b/src/common/puppeteer.ts @@ -78,22 +78,38 @@ export function getDevtoolsUrl(page: Page): string { return `devtools://devtools/bundled/inspector.html?ws=${wsEndpoint.host}/devtools/page/${targetId}`; } -export const getLaunchArgs = async (): Promise[0]> => ({ - executablePath: await executablePath(), - headless: true, - protocolTimeout: 0, // https://github.com/puppeteer/puppeteer/issues/9927 - args: [ - '--disable-web-security', // For accessing iframes - '--disable-features=IsolateOrigins,site-per-process', // For accessing iframes - '--no-sandbox', // For Docker root user - '--disable-dev-shm-usage', // https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md#tips - '--no-zygote', // https://github.com/puppeteer/puppeteer/issues/1825#issuecomment-636478077 - '--disable-gpu', // https://github.com/puppeteer/puppeteer/issues/12189#issuecomment-2264825572 - // For debugging in Docker - // '--remote-debugging-port=3001', - // '--remote-debugging-address=0.0.0.0', // Change devtools url to localhost - ], -}); +const getProxyEnvironmentVariable = (name: string): string | undefined => + [process.env[name.toLowerCase()], process.env[name.toUpperCase()]].find(Boolean); + +const CHROME_PROXY_ENABLED_ENVIRONMENT_VARIABLE = 'EPICGAMES_FREEGAMES_NODE_USE_PROXY_CHROME'; + +const getChromeProxyServer = (): string | undefined => { + if (process.env[CHROME_PROXY_ENABLED_ENVIRONMENT_VARIABLE]?.toLowerCase() !== 'true') { + return undefined; + } + return getProxyEnvironmentVariable('https_proxy') ?? getProxyEnvironmentVariable('all_proxy'); +}; + +export const getLaunchArgs = async (): Promise[0]> => { + const chromeProxyServer = getChromeProxyServer(); + return { + executablePath: await executablePath(), + headless: true, + protocolTimeout: 0, // https://github.com/puppeteer/puppeteer/issues/9927 + args: [ + '--disable-web-security', // For accessing iframes + '--disable-features=IsolateOrigins,site-per-process', // For accessing iframes + '--no-sandbox', // For Docker root user + '--disable-dev-shm-usage', // https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md#tips + '--no-zygote', // https://github.com/puppeteer/puppeteer/issues/1825#issuecomment-636478077 + '--disable-gpu', // https://github.com/puppeteer/puppeteer/issues/12189#issuecomment-2264825572 + ...(chromeProxyServer ? [`--proxy-server=${chromeProxyServer}`] : []), + // For debugging in Docker + // '--remote-debugging-port=3001', + // '--remote-debugging-address=0.0.0.0', // Change devtools url to localhost + ], + }; +}; /** * This is a hacky solution to retry a function if it doesn't return within a timeout. @@ -183,7 +199,7 @@ export const safeNewPage = async (browser: Browser, L: Logger): Promise => }; /** - * Launcha new browser within a wrapper that will retry if it hangs for 30 seconds + * Launch a new browser within a wrapper that will retry if it hangs for 30 seconds */ export const safeLaunchBrowser = async (L: Logger): Promise => { L.debug('Launching a new browser');