1
1
//! http-client implementation for async-h1, with connection pooling ("Keep-Alive").
2
2
3
- #[ cfg( feature = "unstable-config" ) ]
4
3
use std:: convert:: { Infallible , TryFrom } ;
5
-
6
4
use std:: fmt:: Debug ;
7
5
use std:: net:: SocketAddr ;
8
6
use std:: sync:: Arc ;
@@ -33,19 +31,15 @@ use tcp::{TcpConnWrapper, TcpConnection};
33
31
#[ cfg( any( feature = "native-tls" , feature = "rustls" ) ) ]
34
32
use tls:: { TlsConnWrapper , TlsConnection } ;
35
33
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
-
39
34
type HttpPool = DashMap < SocketAddr , Pool < TcpStream , std:: io:: Error > > ;
40
35
#[ cfg( any( feature = "native-tls" , feature = "rustls" ) ) ]
41
36
type HttpsPool = DashMap < SocketAddr , Pool < TlsStream < TcpStream > , Error > > ;
42
37
43
- /// Async -h1 based HTTP Client, with connecton pooling ("Keep-Alive").
38
+ /// async -h1 based HTTP Client, with connection pooling ("Keep-Alive").
44
39
pub struct H1Client {
45
40
http_pools : HttpPool ,
46
41
#[ cfg( any( feature = "native-tls" , feature = "rustls" ) ) ]
47
42
https_pools : HttpsPool ,
48
- max_concurrent_connections : usize ,
49
43
config : Arc < Config > ,
50
44
}
51
45
@@ -82,10 +76,6 @@ impl Debug for H1Client {
82
76
. collect :: < Vec < String > > ( ) ,
83
77
)
84
78
. field ( "https_pools" , & https_pools)
85
- . field (
86
- "max_concurrent_connections" ,
87
- & self . max_concurrent_connections ,
88
- )
89
79
. field ( "config" , & self . config )
90
80
. finish ( )
91
81
}
@@ -104,19 +94,25 @@ impl H1Client {
104
94
http_pools : DashMap :: new ( ) ,
105
95
#[ cfg( any( feature = "native-tls" , feature = "rustls" ) ) ]
106
96
https_pools : DashMap :: new ( ) ,
107
- max_concurrent_connections : DEFAULT_MAX_CONCURRENT_CONNECTIONS ,
108
97
config : Arc :: new ( Config :: default ( ) ) ,
109
98
}
110
99
}
111
100
112
101
/// Create a new instance.
113
102
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
+
114
111
Self {
115
112
http_pools : DashMap :: new ( ) ,
116
113
#[ cfg( any( feature = "native-tls" , feature = "rustls" ) ) ]
117
114
https_pools : DashMap :: new ( ) ,
118
- max_concurrent_connections : max,
119
- config : Arc :: new ( Config :: default ( ) ) ,
115
+ config : Arc :: new ( config) ,
120
116
}
121
117
}
122
118
}
@@ -157,7 +153,6 @@ impl HttpClient for H1Client {
157
153
for ( idx, addr) in addrs. into_iter ( ) . enumerate ( ) {
158
154
let has_another_addr = idx != max_addrs_idx;
159
155
160
- #[ cfg( feature = "unstable-config" ) ]
161
156
if !self . config . http_keep_alive {
162
157
match scheme {
163
158
"http" => {
@@ -196,7 +191,7 @@ impl HttpClient for H1Client {
196
191
let manager = TcpConnection :: new ( addr, self . config . clone ( ) ) ;
197
192
let pool = Pool :: < TcpStream , std:: io:: Error > :: new (
198
193
manager,
199
- self . max_concurrent_connections ,
194
+ self . config . max_connections_per_host ,
200
195
) ;
201
196
self . http_pools . insert ( addr, pool) ;
202
197
self . http_pools . get ( & addr) . unwrap ( )
@@ -216,14 +211,11 @@ impl HttpClient for H1Client {
216
211
req. set_local_addr ( stream. local_addr ( ) . ok ( ) ) ;
217
212
218
213
let tcp_conn = client:: connect ( TcpConnWrapper :: new ( stream) , req) ;
219
- #[ cfg( feature = "unstable-config" ) ]
220
214
return if let Some ( timeout) = self . config . timeout {
221
215
async_std:: future:: timeout ( timeout, tcp_conn) . await ?
222
216
} else {
223
217
tcp_conn. await
224
218
} ;
225
- #[ cfg( not( feature = "unstable-config" ) ) ]
226
- return tcp_conn. await ;
227
219
}
228
220
#[ cfg( any( feature = "native-tls" , feature = "rustls" ) ) ]
229
221
"https" => {
@@ -233,7 +225,7 @@ impl HttpClient for H1Client {
233
225
let manager = TlsConnection :: new ( host. clone ( ) , addr, self . config . clone ( ) ) ;
234
226
let pool = Pool :: < TlsStream < TcpStream > , Error > :: new (
235
227
manager,
236
- self . max_concurrent_connections ,
228
+ self . config . max_connections_per_host ,
237
229
) ;
238
230
self . https_pools . insert ( addr, pool) ;
239
231
self . https_pools . get ( & addr) . unwrap ( )
@@ -253,14 +245,11 @@ impl HttpClient for H1Client {
253
245
req. set_local_addr ( stream. get_ref ( ) . local_addr ( ) . ok ( ) ) ;
254
246
255
247
let tls_conn = client:: connect ( TlsConnWrapper :: new ( stream) , req) ;
256
- #[ cfg( feature = "unstable-config" ) ]
257
248
return if let Some ( timeout) = self . config . timeout {
258
249
async_std:: future:: timeout ( timeout, tls_conn) . await ?
259
250
} else {
260
251
tls_conn. await
261
252
} ;
262
- #[ cfg( not( feature = "unstable-config" ) ) ]
263
- return tls_conn. await ;
264
253
}
265
254
_ => unreachable ! ( ) ,
266
255
}
@@ -272,36 +261,35 @@ impl HttpClient for H1Client {
272
261
) )
273
262
}
274
263
275
- #[ cfg_attr( feature = "docs" , doc( cfg( feature = "unstable-config" ) ) ) ]
276
- #[ cfg( feature = "unstable-config" ) ]
277
264
/// Override the existing configuration with new configuration.
278
265
///
279
266
/// Config options may not impact existing connections.
280
267
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
+
281
271
self . config = Arc :: new ( config) ;
282
272
283
273
Ok ( ( ) )
284
274
}
285
275
286
- #[ cfg_attr( feature = "docs" , doc( cfg( feature = "unstable-config" ) ) ) ]
287
- #[ cfg( feature = "unstable-config" ) ]
288
276
/// Get the current configuration.
289
277
fn config ( & self ) -> & Config {
290
278
& * self . config
291
279
}
292
280
}
293
281
294
- #[ cfg_attr( feature = "docs" , doc( cfg( feature = "unstable-config" ) ) ) ]
295
- #[ cfg( feature = "unstable-config" ) ]
296
282
impl TryFrom < Config > for H1Client {
297
283
type Error = Infallible ;
298
284
299
285
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
+
300
289
Ok ( Self {
301
290
http_pools : DashMap :: new ( ) ,
302
291
#[ cfg( any( feature = "native-tls" , feature = "rustls" ) ) ]
303
292
https_pools : DashMap :: new ( ) ,
304
- max_concurrent_connections : DEFAULT_MAX_CONCURRENT_CONNECTIONS ,
305
293
config : Arc :: new ( config) ,
306
294
} )
307
295
}
0 commit comments