Skip to content

Commit 0bbe335

Browse files
authored
[proxy-agent] Support for getProxyForUrl option (#160)
1 parent 9326064 commit 0bbe335

File tree

3 files changed

+43
-2
lines changed

3 files changed

+43
-2
lines changed

.changeset/odd-mirrors-nail.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'proxy-agent': minor
3+
---
4+
5+
Support for `getProxyForUrl` option, to provide proxy address dynamically per different URLs

packages/proxy-agent/src/index.ts

+12-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import * as https from 'https';
33
import LRUCache from 'lru-cache';
44
import { Agent, AgentConnectOpts } from 'agent-base';
55
import createDebug from 'debug';
6-
import { getProxyForUrl } from 'proxy-from-env';
6+
import { getProxyForUrl as envGetProxyForUrl } from 'proxy-from-env';
77
import { PacProxyAgent, PacProxyAgentOptions } from 'pac-proxy-agent';
88
import { HttpProxyAgent, HttpProxyAgentOptions } from 'http-proxy-agent';
99
import { HttpsProxyAgent, HttpsProxyAgentOptions } from 'https-proxy-agent';
@@ -21,6 +21,8 @@ type ValidProtocol = (typeof PROTOCOLS)[number];
2121

2222
type AgentConstructor = new (...args: never[]) => Agent;
2323

24+
type GetProxyForUrlCallback = (url: string) => string;
25+
2426
/**
2527
* Supported proxy types.
2628
*/
@@ -61,6 +63,12 @@ export type ProxyAgentOptions = HttpProxyAgentOptions<''> &
6163
* instance with the proxy agent options passed in.
6264
*/
6365
httpsAgent?: http.Agent;
66+
/**
67+
* A callback for dynamic provision of proxy for url.
68+
* Defaults to standard proxy environment variables,
69+
* see https://www.npmjs.com/package/proxy-from-env for details
70+
*/
71+
getProxyForUrl?: GetProxyForUrlCallback;
6472
};
6573

6674
/**
@@ -79,6 +87,7 @@ export class ProxyAgent extends Agent {
7987
connectOpts?: ProxyAgentOptions;
8088
httpAgent: http.Agent;
8189
httpsAgent: http.Agent;
90+
getProxyForUrl: GetProxyForUrlCallback;
8291

8392
constructor(opts?: ProxyAgentOptions) {
8493
super(opts);
@@ -87,6 +96,7 @@ export class ProxyAgent extends Agent {
8796
this.httpAgent = opts?.httpAgent || new http.Agent(opts);
8897
this.httpsAgent =
8998
opts?.httpsAgent || new https.Agent(opts as https.AgentOptions);
99+
this.getProxyForUrl = opts?.getProxyForUrl || envGetProxyForUrl;
90100
}
91101

92102
async connect(
@@ -97,7 +107,7 @@ export class ProxyAgent extends Agent {
97107
const protocol = secureEndpoint ? 'https:' : 'http:';
98108
const host = req.getHeader('host');
99109
const url = new URL(req.path, `${protocol}//${host}`).href;
100-
const proxy = getProxyForUrl(url);
110+
const proxy = this.getProxyForUrl(url);
101111

102112
if (!proxy) {
103113
debug('Proxy not enabled for URL: %o', url);

packages/proxy-agent/test/test.ts

+26
Original file line numberDiff line numberDiff line change
@@ -251,5 +251,31 @@ describe('ProxyAgent', () => {
251251
HttpsProxyAgent
252252
);
253253
});
254+
255+
it('should call provided function with getProxyForUrl option', async () => {
256+
let gotCall = false;
257+
let urlParameter = "";
258+
httpsServer.once('request', function (req, res) {
259+
res.end(JSON.stringify(req.headers));
260+
});
261+
262+
const agent = new ProxyAgent({
263+
rejectUnauthorized: false,
264+
getProxyForUrl: (u) => {
265+
gotCall = true;
266+
urlParameter = u;
267+
return httpsProxyServerUrl.href;
268+
}
269+
});
270+
const requestUrl = new URL('/test', httpsServerUrl);
271+
const res = await req(requestUrl, {
272+
agent,
273+
rejectUnauthorized: false,
274+
});
275+
const body = await json(res);
276+
assert(httpsServerUrl.host === body.host);
277+
assert(gotCall);
278+
assert(requestUrl.href === urlParameter);
279+
});
254280
});
255281
});

0 commit comments

Comments
 (0)