From cfce4c7fd511e9ecd6b3f475f5a5bf0867f9bbd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ramon=20R=C3=BCttimann?= Date: Fri, 14 Oct 2022 13:09:45 +0200 Subject: [PATCH] fix: do not proxy traffic to sockets This commit implements a proxy-exception for traffic targeting local sockets instead of a "host:port" combination. If such traffic would be forwarded through the proxy, the socket destination info would be lost, while a "localhost:80" destination would be added. This means that the proxy cannot handle such requests correctly either way, which makes sending traffic to the proxy pointless. Because of that, if the agent receives traffic destined for a socket, it will simply use the fallback agent to handle that traffic. --- src/classes/Agent.ts | 13 +++++++++ .../factories/createGlobalProxyAgent.ts | 27 +++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/src/classes/Agent.ts b/src/classes/Agent.ts index 9d2d5aea..07e45a8a 100644 --- a/src/classes/Agent.ts +++ b/src/classes/Agent.ts @@ -80,6 +80,19 @@ abstract class Agent { requestUrl = this.protocol + '//' + (configuration.hostname ?? configuration.host) + (configuration.port === 80 ?? configuration.port === 443 ? '' : ':' + configuration.port) + request.path; } + // If a request should go to a local socket, proxying it through an HTTP + // server does not make sense as the information about the target socket + // will be lost and the proxy won't be able to correctly handle the request. + if (configuration.socketPath) { + log.trace({ + destination: configuration.socketPath, + }, "not proxying request; destination is a socket"); + + // @ts-expect-error seems like we are using wrong type for fallbackAgent. + this.fallbackAgent.addRequest(request, configuration); + return; + } + if (!this.isProxyConfigured()) { log.trace({ destination: requestUrl, diff --git a/test/global-agent/factories/createGlobalProxyAgent.ts b/test/global-agent/factories/createGlobalProxyAgent.ts index 15c3e40b..095ac4eb 100644 --- a/test/global-agent/factories/createGlobalProxyAgent.ts +++ b/test/global-agent/factories/createGlobalProxyAgent.ts @@ -307,6 +307,33 @@ serial('forwards requests matching NO_PROXY', async (t) => { t.is(response.body, 'DIRECT'); }); +serial('forwards requests that go to a socket', async (t) => { + const globalProxyAgent = createGlobalProxyAgent(); + + // not relevant as traffic shouldn't go through proxy + globalProxyAgent.HTTP_PROXY = 'localhost:10324'; + + var server = http.createServer(function (req, res) { + res.writeHead(200); + res.write('OK'); + res.end(); + }); + + t.teardown(() => { + server.close(); + }); + server.listen('/tmp/test.sock'); + + const response: HttpResponseType = await new Promise((resolve) => { + http.get({ + socketPath: '/tmp/test.sock', + path: '/endpoint', + }, createHttpResponseResolver(resolve) + ); + }); + t.is(response.body, 'OK'); +}); + serial('proxies HTTP request (using http.get(host))', async (t) => { const globalProxyAgent = createGlobalProxyAgent();