@@ -32,6 +32,7 @@ use tokio_rustls::TlsConnector;
32
32
33
33
use super :: HttpClient ;
34
34
use super :: RequestClient ;
35
+ use super :: ThrottledClient ;
35
36
use crate :: proxy;
36
37
use crate :: stats:: HttpNetworkStats ;
37
38
use crate :: x2p;
@@ -66,6 +67,7 @@ pub struct HttpClientBuilder {
66
67
supports_vpnless : bool ,
67
68
http2 : bool ,
68
69
timeout_config : Option < TimeoutConfig > ,
70
+ max_concurrent_requests : usize ,
69
71
}
70
72
71
73
impl HttpClientBuilder {
@@ -104,6 +106,10 @@ impl HttpClientBuilder {
104
106
supports_vpnless : false ,
105
107
http2 : true ,
106
108
timeout_config : None ,
109
+ // Semi-arbitrary sensible default: big enough to ensure good utilization of a typical
110
+ // internet link, small enough that we won't run out of FDs or make a server think we're
111
+ // DoSing them.
112
+ max_concurrent_requests : 32 ,
107
113
} )
108
114
}
109
115
@@ -214,6 +220,11 @@ impl HttpClientBuilder {
214
220
self . supports_vpnless
215
221
}
216
222
223
+ pub fn with_max_concurrent_requests ( & mut self , max_concurrent_requests : usize ) -> & mut Self {
224
+ self . max_concurrent_requests = max_concurrent_requests;
225
+ self
226
+ }
227
+
217
228
fn build_inner ( & self ) -> Arc < dyn RequestClient > {
218
229
match ( self . proxies . as_slice ( ) , & self . timeout_config ) {
219
230
// Construct x2p unix socket client.
@@ -226,7 +237,10 @@ impl HttpClientBuilder {
226
237
timeout_config. to_connector ( hyper_unix_connector:: UnixClient ) ;
227
238
let proxy_connector =
228
239
build_proxy_connector ( & [ unix_socket. clone ( ) ] , timeout_connector, None ) ;
229
- Arc :: new ( hyper:: Client :: builder ( ) . build :: < _ , Body > ( proxy_connector) )
240
+ Arc :: new ( ThrottledClient :: new (
241
+ hyper:: Client :: builder ( ) . build :: < _ , Body > ( proxy_connector) ,
242
+ self . max_concurrent_requests ,
243
+ ) )
230
244
}
231
245
#[ cfg( unix) ]
232
246
( proxies @ [ _, ..] , None ) if let Some ( unix_socket) = find_unix_proxy ( proxies) => {
@@ -235,7 +249,10 @@ impl HttpClientBuilder {
235
249
hyper_unix_connector:: UnixClient ,
236
250
None ,
237
251
) ;
238
- Arc :: new ( hyper:: Client :: builder ( ) . build :: < _ , Body > ( proxy_connector) )
252
+ Arc :: new ( ThrottledClient :: new (
253
+ hyper:: Client :: builder ( ) . build :: < _ , Body > ( proxy_connector) ,
254
+ self . max_concurrent_requests ,
255
+ ) )
239
256
}
240
257
241
258
// Construct x2p http proxy client.
@@ -245,14 +262,20 @@ impl HttpClientBuilder {
245
262
http_connector. enforce_http ( true ) ;
246
263
let timeout_connector = timeout_config. to_connector ( http_connector) ;
247
264
let proxy_connector = build_proxy_connector ( proxies, timeout_connector, None ) ;
248
- Arc :: new ( hyper:: Client :: builder ( ) . build :: < _ , Body > ( proxy_connector) )
265
+ Arc :: new ( ThrottledClient :: new (
266
+ hyper:: Client :: builder ( ) . build :: < _ , Body > ( proxy_connector) ,
267
+ self . max_concurrent_requests ,
268
+ ) )
249
269
}
250
270
( proxies @ [ _, ..] , None ) if self . supports_vpnless => {
251
271
let mut http_connector = HttpConnector :: new ( ) ;
252
272
// When talking to local x2pagent proxy, only http is supported.
253
273
http_connector. enforce_http ( true ) ;
254
274
let proxy_connector = build_proxy_connector ( proxies, http_connector, None ) ;
255
- Arc :: new ( hyper:: Client :: builder ( ) . build :: < _ , Body > ( proxy_connector) )
275
+ Arc :: new ( ThrottledClient :: new (
276
+ hyper:: Client :: builder ( ) . build :: < _ , Body > ( proxy_connector) ,
277
+ self . max_concurrent_requests ,
278
+ ) )
256
279
}
257
280
258
281
// Proxied http client with TLS.
@@ -265,24 +288,36 @@ impl HttpClientBuilder {
265
288
timeout_connector,
266
289
Some ( self . tls_config . clone ( ) ) ,
267
290
) ;
268
- Arc :: new ( hyper:: Client :: builder ( ) . build :: < _ , Body > ( proxy_connector) )
291
+ Arc :: new ( ThrottledClient :: new (
292
+ hyper:: Client :: builder ( ) . build :: < _ , Body > ( proxy_connector) ,
293
+ self . max_concurrent_requests ,
294
+ ) )
269
295
}
270
296
( proxies @ [ _, ..] , None ) => {
271
297
let https_connector = build_https_connector ( self . tls_config . clone ( ) , self . http2 ) ;
272
298
let proxy_connector =
273
299
build_proxy_connector ( proxies, https_connector, Some ( self . tls_config . clone ( ) ) ) ;
274
- Arc :: new ( hyper:: Client :: builder ( ) . build :: < _ , Body > ( proxy_connector) )
300
+ Arc :: new ( ThrottledClient :: new (
301
+ hyper:: Client :: builder ( ) . build :: < _ , Body > ( proxy_connector) ,
302
+ self . max_concurrent_requests ,
303
+ ) )
275
304
}
276
305
277
306
// Client with TLS only.
278
307
( [ ] , Some ( timeout_config) ) => {
279
308
let https_connector = build_https_connector ( self . tls_config . clone ( ) , self . http2 ) ;
280
309
let timeout_connector = timeout_config. to_connector ( https_connector) ;
281
- Arc :: new ( hyper:: Client :: builder ( ) . build :: < _ , Body > ( timeout_connector) )
310
+ Arc :: new ( ThrottledClient :: new (
311
+ hyper:: Client :: builder ( ) . build :: < _ , Body > ( timeout_connector) ,
312
+ self . max_concurrent_requests ,
313
+ ) )
282
314
}
283
315
( [ ] , None ) => {
284
316
let https_connector = build_https_connector ( self . tls_config . clone ( ) , self . http2 ) ;
285
- Arc :: new ( hyper:: Client :: builder ( ) . build :: < _ , Body > ( https_connector) )
317
+ Arc :: new ( ThrottledClient :: new (
318
+ hyper:: Client :: builder ( ) . build :: < _ , Body > ( https_connector) ,
319
+ self . max_concurrent_requests ,
320
+ ) )
286
321
}
287
322
}
288
323
}
0 commit comments