From ecf23dcd9e805ca43a738dbd266f6c2a25b45601 Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Wed, 7 Aug 2024 15:22:14 +0200 Subject: [PATCH] Pass `req` to `getProxyForUrl` callback This allows more flexibility in the callback, e.g. for inspecting request headers before deciding on a given proxy. --- .changeset/sixty-carpets-cross.md | 5 +++++ packages/proxy-agent/src/index.ts | 8 ++++---- packages/proxy-agent/test/test.ts | 5 ++++- 3 files changed, 13 insertions(+), 5 deletions(-) create mode 100644 .changeset/sixty-carpets-cross.md diff --git a/.changeset/sixty-carpets-cross.md b/.changeset/sixty-carpets-cross.md new file mode 100644 index 00000000..2dd6a905 --- /dev/null +++ b/.changeset/sixty-carpets-cross.md @@ -0,0 +1,5 @@ +--- +'proxy-agent': minor +--- + +Include ClientRequest in getProxyForUrl parameters for additional flexibility diff --git a/packages/proxy-agent/src/index.ts b/packages/proxy-agent/src/index.ts index 496e185a..83612e5b 100644 --- a/packages/proxy-agent/src/index.ts +++ b/packages/proxy-agent/src/index.ts @@ -22,7 +22,7 @@ type ValidProtocol = (typeof PROTOCOLS)[number]; type AgentConstructor = new (...args: never[]) => Agent; -type GetProxyForUrlCallback = (url: string) => string | Promise; +type GetProxyForUrlCallback = (url: string, req: http.ClientRequest) => string | Promise; /** * Supported proxy types. @@ -69,7 +69,7 @@ export type ProxyAgentOptions = HttpProxyAgentOptions<''> & * Defaults to standard proxy environment variables, * see https://www.npmjs.com/package/proxy-from-env for details */ - getProxyForUrl?: GetProxyForUrlCallback; + getProxyForUrl: GetProxyForUrlCallback; }; /** @@ -90,7 +90,7 @@ export class ProxyAgent extends Agent { httpsAgent: http.Agent; getProxyForUrl: GetProxyForUrlCallback; - constructor(opts?: ProxyAgentOptions) { + constructor(opts: ProxyAgentOptions) { super(opts); debug('Creating new ProxyAgent instance: %o', opts); this.connectOpts = opts; @@ -115,7 +115,7 @@ export class ProxyAgent extends Agent { : 'http:'; const host = req.getHeader('host'); const url = new URL(req.path, `${protocol}//${host}`).href; - const proxy = await this.getProxyForUrl(url); + const proxy = await this.getProxyForUrl(url, req); if (!proxy) { debug('Proxy not enabled for URL: %o', url); diff --git a/packages/proxy-agent/test/test.ts b/packages/proxy-agent/test/test.ts index 2544d182..8e8f0f4b 100644 --- a/packages/proxy-agent/test/test.ts +++ b/packages/proxy-agent/test/test.ts @@ -266,15 +266,17 @@ describe('ProxyAgent', () => { it('should call provided function with getProxyForUrl option', async () => { let gotCall = false; let urlParameter = ''; + let reqParameter: http.ClientRequest | undefined; httpsServer.once('request', function (req, res) { res.end(JSON.stringify(req.headers)); }); const agent = new ProxyAgent({ rejectUnauthorized: false, - getProxyForUrl: (u) => { + getProxyForUrl: (u, r) => { gotCall = true; urlParameter = u; + reqParameter = r; return httpsProxyServerUrl.href; }, }); @@ -287,6 +289,7 @@ describe('ProxyAgent', () => { assert(httpsServerUrl.host === body.host); assert(gotCall); assert(requestUrl.href === urlParameter); + assert(reqParameter?.constructor.name === 'ClientRequest'); }); it('should call provided function with asynchronous getProxyForUrl option', async () => {