diff --git a/packages/safe-chain/src/registryProxy/tunnelRequestHandler.js b/packages/safe-chain/src/registryProxy/tunnelRequestHandler.js index 6a66afd..33a427c 100644 --- a/packages/safe-chain/src/registryProxy/tunnelRequestHandler.js +++ b/packages/safe-chain/src/registryProxy/tunnelRequestHandler.js @@ -1,5 +1,4 @@ import * as net from "net"; -import { getProxyForUrl } from "proxy-from-env"; import { ui } from "../environment/userInteraction.js"; /** @@ -10,13 +9,20 @@ import { ui } from "../environment/userInteraction.js"; * @returns {void} */ export function tunnelRequest(req, clientSocket, head) { - // req.url in a CONNECT request is usually "hostname:port" - // We assume HTTPS for CONNECT requests to ensure we check HTTPS_PROXY - const proxyUrl = getProxyForUrl(`https://${req.url}`); + const httpsProxy = process.env.HTTPS_PROXY || process.env.https_proxy; - if (proxyUrl) { - // If a proxy is returned, it means we should use it (NO_PROXY check passed) - tunnelRequestViaProxy(req, clientSocket, head, proxyUrl); + if (httpsProxy) { + // If an HTTPS proxy is set, tunnel the request via the proxy + // This is the system proxy, not the safe-chain proxy + // The package manager will run via the safe-chain proxy + // The safe-chain proxy will then send the request to the system proxy + // Typical flow: package manager -> safe-chain proxy -> system proxy -> destination + + // There are 2 processes involved in this: + // 1. Safe-chain process: has HTTPS_PROXY set to system proxy + // 2. Package manager process: has HTTPS_PROXY set to safe-chain proxy + + tunnelRequestViaProxy(req, clientSocket, head, httpsProxy); } else { tunnelRequestToDestination(req, clientSocket, head); } @@ -149,4 +155,3 @@ function tunnelRequestViaProxy(req, clientSocket, head, proxyUrl) { }); } - diff --git a/test/e2e/proxy-tunneling.e2e.spec.js b/test/e2e/proxy-tunneling.e2e.spec.js index c1c1216..d05d836 100644 --- a/test/e2e/proxy-tunneling.e2e.spec.js +++ b/test/e2e/proxy-tunneling.e2e.spec.js @@ -58,28 +58,4 @@ describe("E2E: Safe chain proxy tunneling", () => { assert.ok(success, "curl should successfully connect to example.com via the authenticated proxy"); }); - - it("should respect NO_PROXY and bypass upstream proxy", async () => { - // 1. Setup a test script - const setupShell = await container.openShell("zsh"); - await setupShell.runCommand('npm pkg set scripts.test-curl="curl -v -I https://www.example.com"'); - - // 2. Set a BROKEN upstream proxy, but exclude example.com via NO_PROXY - const testShell = await container.openShell("zsh"); - await testShell.runCommand('export HTTPS_PROXY="http://non-existent-proxy:1234"'); - await testShell.runCommand('export NO_PROXY="www.example.com"'); - - // 3. Run the script - // If safe-chain ignores NO_PROXY, it will try to use the broken proxy and fail - // If it respects NO_PROXY, it will connect directly (which works in the container) - const { output } = await testShell.runCommand("npm run test-curl"); - - const success = output.includes("HTTP/2 200") || output.includes("HTTP/1.1 200"); - - if (!success) { - console.log("NO_PROXY Test failed. Output:", output); - } - - assert.ok(success, "curl should bypass the broken proxy for NO_PROXY domains"); - }); });