@@ -2,11 +2,54 @@ import axios, { AxiosInstance } from "axios";
22import { readFileSync } from "fs" ;
33import { HttpsProxyAgent , HttpsProxyAgentOptions } from "https-proxy-agent" ;
44import { ClientRequest , RequestOptions } from "agent-base" ;
5+ import { Socket } from "net" ;
6+ import http from "http" ;
7+ import https from "https" ;
58import {
69 addCookiesToRequest ,
710 storeCookiesFromResponse ,
811} from "./cookiesHelpers" ;
912
13+ const LOCAL_IPV4 = "127.0.0.1" ;
14+ const LOCAL_IPV6 = "::1" ;
15+
16+ const checkConnection = ( host : string , port : number ) : Promise < boolean > => {
17+ return new Promise ( ( resolve ) => {
18+ const socket = new Socket ( ) ;
19+ const timeout = 1000 ;
20+
21+ socket . setTimeout ( timeout ) ;
22+
23+ socket . once ( "connect" , ( ) => {
24+ socket . destroy ( ) ;
25+ resolve ( true ) ;
26+ } ) ;
27+
28+ socket . once ( "timeout" , ( ) => {
29+ socket . destroy ( ) ;
30+ resolve ( false ) ;
31+ } ) ;
32+
33+ socket . once ( "error" , ( ) => {
34+ socket . destroy ( ) ;
35+ resolve ( false ) ;
36+ } ) ;
37+
38+ socket . connect ( port , host ) ;
39+ } ) ;
40+ } ;
41+
42+
43+ const createLocalhostLookup = async ( port : number ) => {
44+ const ipv6Works = await checkConnection ( LOCAL_IPV6 , port ) . catch ( ( ) => false ) ;
45+ const targetIp = ipv6Works ? LOCAL_IPV6 : LOCAL_IPV4 ;
46+ const targetFamily = ipv6Works ? 6 : 4 ;
47+
48+ return ( _lookupHostname : string , _options : any , callback : any ) => {
49+ callback ( null , targetIp , targetFamily ) ;
50+ } ;
51+ } ;
52+
1053class PatchedHttpsProxyAgent extends HttpsProxyAgent {
1154 ca : unknown ;
1255
@@ -32,17 +75,48 @@ let proxyConfig: ProxyConfig;
3275
3376function createAxiosInstance (
3477 config : ProxyConfig ,
78+ enableRQProxy : boolean = false ,
3579 addStoredCookies : boolean = false
3680) : AxiosInstance {
37- const instance = axios . create ( {
38- proxy : false ,
39- httpAgent : new HttpsProxyAgent ( `http://${ config . ip } :${ config . port } ` ) ,
40- httpsAgent : new PatchedHttpsProxyAgent ( {
41- host : config . ip ,
42- port : config . port ,
43- ca : readFileSync ( config . rootCertPath ) ,
44- } ) ,
45- } ) ;
81+ let instance : AxiosInstance ;
82+ if ( enableRQProxy ) {
83+ instance = axios . create ( {
84+ proxy : false ,
85+ httpAgent : new HttpsProxyAgent ( `http://${ config . ip } :${ config . port } ` ) ,
86+ httpsAgent : new PatchedHttpsProxyAgent ( {
87+ host : config . ip ,
88+ port : config . port ,
89+ ca : readFileSync ( config . rootCertPath ) ,
90+ } ) ,
91+ } ) ;
92+ } else {
93+ instance = axios . create ( {
94+ proxy : false ,
95+ } ) ;
96+
97+ instance . interceptors . request . use ( async ( requestConfig ) => {
98+ const { url : requestUrl } = requestConfig ;
99+
100+ if ( ! requestUrl ) {
101+ return requestConfig ;
102+ }
103+
104+ const url = new URL ( requestUrl ) ;
105+ const { hostname, port : urlPort , protocol } = url ;
106+
107+ if ( hostname === "localhost" || hostname === LOCAL_IPV6 || hostname === LOCAL_IPV4 ) {
108+ // convert string port to integer
109+ const port = urlPort ? parseInt ( urlPort , 10 ) : protocol === "https:" ? 443 : 80 ;
110+
111+ const lookup = await createLocalhostLookup ( port ) ;
112+
113+ requestConfig . httpAgent = new http . Agent ( { lookup } ) ;
114+ requestConfig . httpsAgent = new https . Agent ( { lookup } ) ;
115+ }
116+
117+ return requestConfig ;
118+ } ) ;
119+ }
46120
47121 instance . interceptors . response . use ( storeCookiesFromResponse ) ;
48122 if ( addStoredCookies ) {
@@ -60,8 +134,12 @@ export const createOrUpdateAxiosInstance = (
60134 } ;
61135
62136 try {
63- proxiedAxios = createAxiosInstance ( proxyConfig ) ;
64- proxiedAxiosWithSessionCookies = createAxiosInstance ( proxyConfig , true ) ;
137+ proxiedAxios = createAxiosInstance ( proxyConfig , false ) ;
138+ proxiedAxiosWithSessionCookies = createAxiosInstance (
139+ proxyConfig ,
140+ false ,
141+ true
142+ ) ;
65143 } catch ( error ) {
66144 /* Do nothing */
67145 console . error ( "Error creating or updating Axios instance:" , error ) ;
0 commit comments