@@ -2,7 +2,7 @@ import net from "net";
22import child_process from "child_process" ;
33import fs from "fs" ;
44
5- import { Agent , Dispatcher , ProxyAgent } from "undici" ;
5+ import { Agent , Dispatcher , interceptors , ProxyAgent } from "undici" ;
66import yaml from "js-yaml" ;
77
88import { logger } from "./logger.js" ;
@@ -22,8 +22,13 @@ const SSH_WAIT_TIMEOUT = 30000;
2222type ProxyEntry = {
2323 proxyUrl : string ;
2424 dispatcher : Dispatcher ;
25+ redirectDispatcher : Dispatcher ;
2526} ;
2627
28+ const defaultDispatcher = new Agent ( ) ;
29+
30+ const defaultRedirectDispatcher = addRedirectInterceptor ( defaultDispatcher ) ;
31+
2732export type ProxyServerConfig = {
2833 matchHosts ?: Record < string , string > ;
2934 proxies ?: Record <
@@ -192,7 +197,7 @@ export async function initSingleProxy(
192197 detached : boolean ,
193198 sshProxyPrivateKeyFile ?: string ,
194199 sshProxyKnownHostsFile ?: string ,
195- ) : Promise < { proxyUrl : string ; dispatcher : Dispatcher } > {
200+ ) : Promise < ProxyEntry > {
196201 logger . debug ( "Initing proxy" , {
197202 url : getSafeProxyString ( proxyUrl ) ,
198203 localPort,
@@ -215,18 +220,37 @@ export async function initSingleProxy(
215220 } ;
216221
217222 const dispatcher = createDispatcher ( proxyUrl , agentOpts ) ;
218- return { proxyUrl, dispatcher } ;
223+ const redirectDispatcher = addRedirectInterceptor ( dispatcher ) ;
224+ return { proxyUrl, dispatcher, redirectDispatcher } ;
219225}
220226
221- export function getProxyDispatcher ( url : string ) {
227+ export function addRedirectInterceptor ( dispatcher : Dispatcher ) {
228+ // match fetch() max redirects if not doing manual redirects
229+ // https://fetch.spec.whatwg.org/#http-redirect-fetch
230+ const redirector = interceptors . redirect ( { maxRedirections : 20 } ) ;
231+ return dispatcher . compose ( redirector ) ;
232+ }
233+
234+ export function getProxyDispatcher ( url : string , withRedirect = true ) {
222235 // find url match by regex first
223- for ( const [ rx , { dispatcher } ] of proxyMap . entries ( ) ) {
236+ for ( const [ rx , { dispatcher, redirectDispatcher } ] of proxyMap . entries ( ) ) {
224237 if ( rx && url . match ( rx ) ) {
225- return dispatcher ;
238+ return withRedirect ? redirectDispatcher : dispatcher ;
226239 }
227240 }
228- // if default proxy set, return default dispatcher, otherwise no dispatcher
229- return defaultProxyEntry ? defaultProxyEntry . dispatcher : undefined ;
241+
242+ // if default proxy set, return dispatcher from default proxy, otherwise a default dispatcher
243+ if ( defaultProxyEntry ) {
244+ return withRedirect
245+ ? defaultProxyEntry . redirectDispatcher
246+ : defaultProxyEntry . dispatcher ;
247+ } else {
248+ return getDefaultDispatcher ( withRedirect ) ;
249+ }
250+ }
251+
252+ export function getDefaultDispatcher ( withRedirect = true ) {
253+ return withRedirect ? defaultRedirectDispatcher : defaultDispatcher ;
230254}
231255
232256export function createDispatcher (
0 commit comments