From 8d92c9c90351cb195ff8bb3c61da483d61db39e7 Mon Sep 17 00:00:00 2001 From: Ferenc Hammerl <31069338+fhammerl@users.noreply.github.com> Date: Wed, 1 Mar 2023 13:45:12 +0000 Subject: [PATCH] Bypass proxy on loopback IPs --- packages/http-client/__tests__/proxy.test.ts | 26 ++++++++++++++------ packages/http-client/src/proxy.ts | 10 ++++++++ 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/packages/http-client/__tests__/proxy.test.ts b/packages/http-client/__tests__/proxy.test.ts index ccbceec2..368e0d29 100644 --- a/packages/http-client/__tests__/proxy.test.ts +++ b/packages/http-client/__tests__/proxy.test.ts @@ -223,19 +223,29 @@ describe('proxy', () => { expect(_proxyConnects).toEqual(['httpbin.org:443']) }) - it('HttpClient does basic https get request when bypass proxy', async () => { - process.env['https_proxy'] = _proxyUrl - process.env['no_proxy'] = 'httpbin.org' +it('HttpClient bypasses proxy for loopback addresses (localhost, ::1, 127.*)', async () => { + // setup a server listening on localhost:8091 + var server = http.createServer(function (request, response) { + response.writeHead(200); + request.pipe(response); + }); + await server.listen(8091) + try { + process.env['http_proxy'] = _proxyUrl const httpClient = new httpm.HttpClient() const res: httpm.HttpClientResponse = await httpClient.get( - 'https://httpbin.org/get' + 'http://localhost:8091' ) expect(res.message.statusCode).toBe(200) const body: string = await res.readBody() - const obj = JSON.parse(body) - expect(obj.url).toBe('https://httpbin.org/get') - expect(_proxyConnects).toHaveLength(0) - }) + expect(body).toEqual(''); + // proxy at _proxyUrl was ignored + expect(_proxyConnects).toEqual(undefined) + } + finally { + await server.close() + } +}) it('proxyAuth not set in tunnel agent when authentication is not provided', async () => { process.env['https_proxy'] = 'http://127.0.0.1:8080' diff --git a/packages/http-client/src/proxy.ts b/packages/http-client/src/proxy.ts index e4e43a54..e4a3e49a 100644 --- a/packages/http-client/src/proxy.ts +++ b/packages/http-client/src/proxy.ts @@ -25,6 +25,11 @@ export function checkBypass(reqUrl: URL): boolean { return false } + const reqHost = reqUrl.hostname + if (isLoopbackAddress(reqHost)) { + return true + } + const noProxy = process.env['no_proxy'] || process.env['NO_PROXY'] || '' if (!noProxy) { return false @@ -66,3 +71,8 @@ export function checkBypass(reqUrl: URL): boolean { return false } + +function isLoopbackAddress(host: string): boolean { + const hostUpper = host.toUpperCase() + return hostUpper === 'LOCALHOST' || hostUpper.startsWith('127.') || hostUpper.startsWith('::1') +}