@@ -9,34 +9,56 @@ use dashmap::DashMap;
9
9
use deadpool:: managed:: Pool ;
10
10
use http_types:: StatusCode ;
11
11
12
- #[ cfg( feature = "native-tls" ) ]
13
- use async_native_tls:: TlsStream ;
14
- #[ cfg( feature = "rustls" ) ]
15
- use async_tls:: client:: TlsStream ;
12
+ cfg_if:: cfg_if! {
13
+ if #[ cfg( feature = "rustls" ) ] {
14
+ use async_tls:: client:: TlsStream ;
15
+ } else if #[ cfg( feature = "native-tls" ) ] {
16
+ use async_native_tls:: TlsStream ;
17
+ }
18
+ }
16
19
17
20
use super :: { async_trait, Error , HttpClient , Request , Response } ;
18
21
19
22
mod tcp;
23
+ #[ cfg( any( feature = "native-tls" , feature = "rustls" ) ) ]
20
24
mod tls;
21
25
22
26
use tcp:: { TcpConnWrapper , TcpConnection } ;
27
+ #[ cfg( any( feature = "native-tls" , feature = "rustls" ) ) ]
23
28
use tls:: { TlsConnWrapper , TlsConnection } ;
24
29
25
30
// This number is based on a few random benchmarks and see whatever gave decent perf vs resource use.
26
31
const DEFAULT_MAX_CONCURRENT_CONNECTIONS : usize = 50 ;
27
32
28
33
type HttpPool = DashMap < SocketAddr , Pool < TcpStream , std:: io:: Error > > ;
34
+ #[ cfg( any( feature = "native-tls" , feature = "rustls" ) ) ]
29
35
type HttpsPool = DashMap < SocketAddr , Pool < TlsStream < TcpStream > , Error > > ;
30
36
31
37
/// Async-h1 based HTTP Client, with connecton pooling ("Keep-Alive").
32
38
pub struct H1Client {
33
39
http_pools : HttpPool ,
40
+ #[ cfg( any( feature = "native-tls" , feature = "rustls" ) ) ]
34
41
https_pools : HttpsPool ,
35
42
max_concurrent_connections : usize ,
36
43
}
37
44
38
45
impl Debug for H1Client {
39
46
fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
47
+ let https_pools = if cfg ! ( any( feature = "native-tls" , feature = "rustls" ) ) {
48
+ self . http_pools
49
+ . iter ( )
50
+ . map ( |pool| {
51
+ let status = pool. status ( ) ;
52
+ format ! (
53
+ "Connections: {}, Available: {}, Max: {}" ,
54
+ status. size, status. available, status. max_size
55
+ )
56
+ } )
57
+ . collect :: < Vec < String > > ( )
58
+ } else {
59
+ vec ! [ ]
60
+ } ;
61
+
40
62
f. debug_struct ( "H1Client" )
41
63
. field (
42
64
"http_pools" ,
@@ -52,20 +74,7 @@ impl Debug for H1Client {
52
74
} )
53
75
. collect :: < Vec < String > > ( ) ,
54
76
)
55
- . field (
56
- "https_pools" ,
57
- & self
58
- . http_pools
59
- . iter ( )
60
- . map ( |pool| {
61
- let status = pool. status ( ) ;
62
- format ! (
63
- "Connections: {}, Available: {}, Max: {}" ,
64
- status. size, status. available, status. max_size
65
- )
66
- } )
67
- . collect :: < Vec < String > > ( ) ,
68
- )
77
+ . field ( "https_pools" , & https_pools)
69
78
. field (
70
79
"max_concurrent_connections" ,
71
80
& self . max_concurrent_connections ,
@@ -85,6 +94,7 @@ impl H1Client {
85
94
pub fn new ( ) -> Self {
86
95
Self {
87
96
http_pools : DashMap :: new ( ) ,
97
+ #[ cfg( any( feature = "native-tls" , feature = "rustls" ) ) ]
88
98
https_pools : DashMap :: new ( ) ,
89
99
max_concurrent_connections : DEFAULT_MAX_CONCURRENT_CONNECTIONS ,
90
100
}
@@ -94,6 +104,7 @@ impl H1Client {
94
104
pub fn with_max_connections ( max : usize ) -> Self {
95
105
Self {
96
106
http_pools : DashMap :: new ( ) ,
107
+ #[ cfg( any( feature = "native-tls" , feature = "rustls" ) ) ]
97
108
https_pools : DashMap :: new ( ) ,
98
109
max_concurrent_connections : max,
99
110
}
@@ -106,14 +117,17 @@ impl HttpClient for H1Client {
106
117
req. insert_header ( "Connection" , "keep-alive" ) ;
107
118
108
119
// Insert host
120
+ #[ cfg( any( feature = "native-tls" , feature = "rustls" ) ) ]
109
121
let host = req
110
122
. url ( )
111
123
. host_str ( )
112
124
. ok_or_else ( || Error :: from_str ( StatusCode :: BadRequest , "missing hostname" ) ) ?
113
125
. to_string ( ) ;
114
126
115
127
let scheme = req. url ( ) . scheme ( ) ;
116
- if scheme != "http" && scheme != "https" {
128
+ if scheme != "http"
129
+ && ( scheme != "https" || cfg ! ( not( any( feature = "native-tls" , feature = "rustls" ) ) ) )
130
+ {
117
131
return Err ( Error :: from_str (
118
132
StatusCode :: BadRequest ,
119
133
format ! ( "invalid url scheme '{}'" , scheme) ,
@@ -124,6 +138,7 @@ impl HttpClient for H1Client {
124
138
. url ( )
125
139
. socket_addrs ( || match req. url ( ) . scheme ( ) {
126
140
"http" => Some ( 80 ) ,
141
+ #[ cfg( any( feature = "native-tls" , feature = "rustls" ) ) ]
127
142
"https" => Some ( 443 ) ,
128
143
_ => None ,
129
144
} ) ?
@@ -156,6 +171,7 @@ impl HttpClient for H1Client {
156
171
req. set_local_addr ( stream. local_addr ( ) . ok ( ) ) ;
157
172
client:: connect ( TcpConnWrapper :: new ( stream) , req) . await
158
173
}
174
+ #[ cfg( any( feature = "native-tls" , feature = "rustls" ) ) ]
159
175
"https" => {
160
176
let pool_ref = if let Some ( pool_ref) = self . https_pools . get ( & addr) {
161
177
pool_ref
0 commit comments