@@ -4,11 +4,12 @@ const { tspl } = require('@matteo.collina/tspl')
44const { test, after } = require ( 'node:test' )
55const diagnosticsChannel = require ( 'node:diagnostics_channel' )
66const { request, fetch, setGlobalDispatcher, getGlobalDispatcher } = require ( '..' )
7- const { InvalidArgumentError, SecureProxyConnectionError } = require ( '../lib/core/errors' )
7+ const { InvalidArgumentError, ConnectTimeoutError , SecureProxyConnectionError } = require ( '../lib/core/errors' )
88const ProxyAgent = require ( '../lib/dispatcher/proxy-agent' )
99const Pool = require ( '../lib/dispatcher/pool' )
1010const { createServer } = require ( 'node:http' )
1111const https = require ( 'node:https' )
12+ const net = require ( 'node:net' )
1213const { Socket } = require ( 'node:net' )
1314const { createProxy } = require ( 'proxy' )
1415
@@ -121,6 +122,65 @@ test('should accept string, URL and object as options', (t) => {
121122 t . doesNotThrow ( ( ) => new ProxyAgent ( { uri : 'http://example.com' } ) )
122123} )
123124
125+ test ( 'ProxyAgent forwards connectTimeout to the proxy connector' , async ( t ) => {
126+ t = tspl ( t , { plan : 4 } )
127+
128+ const originalConnect = net . connect
129+ let connect
130+ let socket
131+ const proxyAgent = new ProxyAgent ( {
132+ uri : 'http://localhost:9000' ,
133+ connectTimeout : 1e3 ,
134+ clientFactory ( _origin , options ) {
135+ connect = options . connect
136+ return {
137+ close ( ) {
138+ return Promise . resolve ( )
139+ } ,
140+ destroy ( ) {
141+ return Promise . resolve ( )
142+ }
143+ }
144+ }
145+ } )
146+
147+ try {
148+ net . connect = function ( options ) {
149+ return new net . Socket ( options )
150+ }
151+
152+ t . ok ( typeof connect === 'function' )
153+
154+ const timeout = setTimeout ( ( ) => {
155+ if ( socket && ! socket . destroyed ) {
156+ socket . destroy ( )
157+ }
158+ t . fail ( 'connectTimeout was not forwarded to the proxy connector' )
159+ } , 2e3 )
160+
161+ await new Promise ( ( resolve , reject ) => {
162+ socket = connect ( { hostname : 'localhost' , protocol : 'http:' , port : 9000 } , ( err ) => {
163+ try {
164+ t . ok ( err instanceof ConnectTimeoutError )
165+ t . strictEqual ( err . code , 'UND_ERR_CONNECT_TIMEOUT' )
166+ t . strictEqual ( err . message , 'Connect Timeout Error (attempted address: localhost:9000, timeout: 1000ms)' )
167+ clearTimeout ( timeout )
168+ resolve ( )
169+ } catch ( error ) {
170+ clearTimeout ( timeout )
171+ reject ( error )
172+ }
173+ } )
174+ } )
175+ } finally {
176+ net . connect = originalConnect
177+ if ( socket && ! socket . destroyed ) {
178+ socket . destroy ( )
179+ }
180+ await proxyAgent . close ( )
181+ }
182+ } )
183+
124184test ( 'use proxy-agent to connect through proxy (keep alive)' , async ( t ) => {
125185 t = tspl ( t , { plan : 10 } )
126186 const server = await buildServer ( )
0 commit comments