11//! http-client implementation for async-h1, with connection pooling ("Keep-Alive").
22
3- #[ cfg( feature = "unstable-config" ) ]
43use std:: convert:: { Infallible , TryFrom } ;
5-
64use std:: fmt:: Debug ;
75use std:: net:: SocketAddr ;
86use std:: sync:: Arc ;
@@ -33,19 +31,15 @@ use tcp::{TcpConnWrapper, TcpConnection};
3331#[ cfg( any( feature = "native-tls" , feature = "rustls" ) ) ]
3432use tls:: { TlsConnWrapper , TlsConnection } ;
3533
36- // This number is based on a few random benchmarks and see whatever gave decent perf vs resource use.
37- const DEFAULT_MAX_CONCURRENT_CONNECTIONS : usize = 50 ;
38-
3934type HttpPool = DashMap < SocketAddr , Pool < TcpStream , std:: io:: Error > > ;
4035#[ cfg( any( feature = "native-tls" , feature = "rustls" ) ) ]
4136type HttpsPool = DashMap < SocketAddr , Pool < TlsStream < TcpStream > , Error > > ;
4237
43- /// Async -h1 based HTTP Client, with connecton pooling ("Keep-Alive").
38+ /// async -h1 based HTTP Client, with connection pooling ("Keep-Alive").
4439pub struct H1Client {
4540 http_pools : HttpPool ,
4641 #[ cfg( any( feature = "native-tls" , feature = "rustls" ) ) ]
4742 https_pools : HttpsPool ,
48- max_concurrent_connections : usize ,
4943 config : Arc < Config > ,
5044}
5145
@@ -82,10 +76,6 @@ impl Debug for H1Client {
8276 . collect :: < Vec < String > > ( ) ,
8377 )
8478 . field ( "https_pools" , & https_pools)
85- . field (
86- "max_concurrent_connections" ,
87- & self . max_concurrent_connections ,
88- )
8979 . field ( "config" , & self . config )
9080 . finish ( )
9181 }
@@ -104,19 +94,25 @@ impl H1Client {
10494 http_pools : DashMap :: new ( ) ,
10595 #[ cfg( any( feature = "native-tls" , feature = "rustls" ) ) ]
10696 https_pools : DashMap :: new ( ) ,
107- max_concurrent_connections : DEFAULT_MAX_CONCURRENT_CONNECTIONS ,
10897 config : Arc :: new ( Config :: default ( ) ) ,
10998 }
11099 }
111100
112101 /// Create a new instance.
113102 pub fn with_max_connections ( max : usize ) -> Self {
103+ #[ cfg( features = "h1_client" ) ]
104+ assert ! ( max > 0 , "max_connections_per_host with h1_client must be greater than zero or it will deadlock!" ) ;
105+
106+ let config = Config {
107+ max_connections_per_host : max,
108+ ..Default :: default ( )
109+ } ;
110+
114111 Self {
115112 http_pools : DashMap :: new ( ) ,
116113 #[ cfg( any( feature = "native-tls" , feature = "rustls" ) ) ]
117114 https_pools : DashMap :: new ( ) ,
118- max_concurrent_connections : max,
119- config : Arc :: new ( Config :: default ( ) ) ,
115+ config : Arc :: new ( config) ,
120116 }
121117 }
122118}
@@ -157,7 +153,6 @@ impl HttpClient for H1Client {
157153 for ( idx, addr) in addrs. into_iter ( ) . enumerate ( ) {
158154 let has_another_addr = idx != max_addrs_idx;
159155
160- #[ cfg( feature = "unstable-config" ) ]
161156 if !self . config . http_keep_alive {
162157 match scheme {
163158 "http" => {
@@ -196,7 +191,7 @@ impl HttpClient for H1Client {
196191 let manager = TcpConnection :: new ( addr, self . config . clone ( ) ) ;
197192 let pool = Pool :: < TcpStream , std:: io:: Error > :: new (
198193 manager,
199- self . max_concurrent_connections ,
194+ self . config . max_connections_per_host ,
200195 ) ;
201196 self . http_pools . insert ( addr, pool) ;
202197 self . http_pools . get ( & addr) . unwrap ( )
@@ -216,14 +211,11 @@ impl HttpClient for H1Client {
216211 req. set_local_addr ( stream. local_addr ( ) . ok ( ) ) ;
217212
218213 let tcp_conn = client:: connect ( TcpConnWrapper :: new ( stream) , req) ;
219- #[ cfg( feature = "unstable-config" ) ]
220214 return if let Some ( timeout) = self . config . timeout {
221215 async_std:: future:: timeout ( timeout, tcp_conn) . await ?
222216 } else {
223217 tcp_conn. await
224218 } ;
225- #[ cfg( not( feature = "unstable-config" ) ) ]
226- return tcp_conn. await ;
227219 }
228220 #[ cfg( any( feature = "native-tls" , feature = "rustls" ) ) ]
229221 "https" => {
@@ -233,7 +225,7 @@ impl HttpClient for H1Client {
233225 let manager = TlsConnection :: new ( host. clone ( ) , addr, self . config . clone ( ) ) ;
234226 let pool = Pool :: < TlsStream < TcpStream > , Error > :: new (
235227 manager,
236- self . max_concurrent_connections ,
228+ self . config . max_connections_per_host ,
237229 ) ;
238230 self . https_pools . insert ( addr, pool) ;
239231 self . https_pools . get ( & addr) . unwrap ( )
@@ -253,14 +245,11 @@ impl HttpClient for H1Client {
253245 req. set_local_addr ( stream. get_ref ( ) . local_addr ( ) . ok ( ) ) ;
254246
255247 let tls_conn = client:: connect ( TlsConnWrapper :: new ( stream) , req) ;
256- #[ cfg( feature = "unstable-config" ) ]
257248 return if let Some ( timeout) = self . config . timeout {
258249 async_std:: future:: timeout ( timeout, tls_conn) . await ?
259250 } else {
260251 tls_conn. await
261252 } ;
262- #[ cfg( not( feature = "unstable-config" ) ) ]
263- return tls_conn. await ;
264253 }
265254 _ => unreachable ! ( ) ,
266255 }
@@ -272,36 +261,35 @@ impl HttpClient for H1Client {
272261 ) )
273262 }
274263
275- #[ cfg_attr( feature = "docs" , doc( cfg( feature = "unstable-config" ) ) ) ]
276- #[ cfg( feature = "unstable-config" ) ]
277264 /// Override the existing configuration with new configuration.
278265 ///
279266 /// Config options may not impact existing connections.
280267 fn set_config ( & mut self , config : Config ) -> http_types:: Result < ( ) > {
268+ #[ cfg( features = "h1_client" ) ]
269+ assert ! ( config. max_connections_per_host > 0 , "max_connections_per_host with h1_client must be greater than zero or it will deadlock!" ) ;
270+
281271 self . config = Arc :: new ( config) ;
282272
283273 Ok ( ( ) )
284274 }
285275
286- #[ cfg_attr( feature = "docs" , doc( cfg( feature = "unstable-config" ) ) ) ]
287- #[ cfg( feature = "unstable-config" ) ]
288276 /// Get the current configuration.
289277 fn config ( & self ) -> & Config {
290278 & * self . config
291279 }
292280}
293281
294- #[ cfg_attr( feature = "docs" , doc( cfg( feature = "unstable-config" ) ) ) ]
295- #[ cfg( feature = "unstable-config" ) ]
296282impl TryFrom < Config > for H1Client {
297283 type Error = Infallible ;
298284
299285 fn try_from ( config : Config ) -> Result < Self , Self :: Error > {
286+ #[ cfg( features = "h1_client" ) ]
287+ assert ! ( config. max_connections_per_host > 0 , "max_connections_per_host with h1_client must be greater than zero or it will deadlock!" ) ;
288+
300289 Ok ( Self {
301290 http_pools : DashMap :: new ( ) ,
302291 #[ cfg( any( feature = "native-tls" , feature = "rustls" ) ) ]
303292 https_pools : DashMap :: new ( ) ,
304- max_concurrent_connections : DEFAULT_MAX_CONCURRENT_CONNECTIONS ,
305293 config : Arc :: new ( config) ,
306294 } )
307295 }
0 commit comments