@@ -5,52 +5,66 @@ use futures_util::stream::TryStreamExt;
5
5
use http_types:: headers:: { HeaderName , HeaderValue } ;
6
6
use http_types:: StatusCode ;
7
7
use hyper:: body:: HttpBody ;
8
+ use hyper:: client:: connect:: Connect ;
8
9
use hyper_tls:: HttpsConnector ;
9
10
use std:: convert:: TryFrom ;
11
+ use std:: fmt:: Debug ;
10
12
use std:: io;
11
13
use std:: str:: FromStr ;
12
14
15
+ type HyperRequest = hyper:: Request < hyper:: Body > ;
16
+
17
+ // Avoid leaking Hyper generics into HttpClient by hiding it behind a dynamic trait object pointer.
18
+ trait HyperClientObject : Debug + Send + Sync + ' static {
19
+ fn dyn_request ( & self , req : hyper:: Request < hyper:: Body > ) -> hyper:: client:: ResponseFuture ;
20
+ }
21
+
22
+ impl < C : Clone + Connect + Debug + Send + Sync + ' static > HyperClientObject for hyper:: Client < C > {
23
+ fn dyn_request ( & self , req : HyperRequest ) -> hyper:: client:: ResponseFuture {
24
+ self . request ( req)
25
+ }
26
+ }
27
+
13
28
/// Hyper-based HTTP Client.
14
29
#[ derive( Debug ) ]
15
- pub struct HyperClient { }
30
+ pub struct HyperClient ( Box < dyn HyperClientObject > ) ;
16
31
17
32
impl HyperClient {
18
- /// Create a new client.
19
- ///
20
- /// There is no specific benefit to reusing instances of this client.
33
+ /// Create a new client instance.
21
34
pub fn new ( ) -> Self {
22
- HyperClient { }
35
+ let https = HttpsConnector :: new ( ) ;
36
+ let client = hyper:: Client :: builder ( ) . build ( https) ;
37
+ Self ( Box :: new ( client) )
38
+ }
39
+
40
+ /// Create from externally initialized and configured client.
41
+ pub fn from_client < C > ( client : hyper:: Client < C > ) -> Self
42
+ where
43
+ C : Clone + Connect + Debug + Send + Sync + ' static ,
44
+ {
45
+ Self ( Box :: new ( client) )
46
+ }
47
+ }
48
+
49
+ impl Default for HyperClient {
50
+ fn default ( ) -> Self {
51
+ Self :: new ( )
23
52
}
24
53
}
25
54
26
55
#[ async_trait]
27
56
impl HttpClient for HyperClient {
28
57
async fn send ( & self , req : Request ) -> Result < Response , Error > {
29
58
let req = HyperHttpRequest :: try_from ( req) . await ?. into_inner ( ) ;
30
- // UNWRAP: Scheme guaranteed to be "http" or "https" as part of conversion
31
- let scheme = req. uri ( ) . scheme_str ( ) . unwrap ( ) ;
32
59
33
- let response = match scheme {
34
- "http" => {
35
- let client = hyper:: Client :: builder ( ) . build_http :: < hyper:: Body > ( ) ;
36
- client. request ( req) . await
37
- }
38
- "https" => {
39
- let https = HttpsConnector :: new ( ) ;
40
- let client = hyper:: Client :: builder ( ) . build :: < _ , hyper:: Body > ( https) ;
41
- client. request ( req) . await
42
- }
43
- _ => unreachable ! ( ) ,
44
- } ?;
60
+ let response = self . 0 . dyn_request ( req) . await ?;
45
61
46
- let resp = HttpTypesResponse :: try_from ( response) . await ?. into_inner ( ) ;
47
- Ok ( resp )
62
+ let res = HttpTypesResponse :: try_from ( response) . await ?. into_inner ( ) ;
63
+ Ok ( res )
48
64
}
49
65
}
50
66
51
- struct HyperHttpRequest {
52
- inner : hyper:: Request < hyper:: Body > ,
53
- }
67
+ struct HyperHttpRequest ( HyperRequest ) ;
54
68
55
69
impl HyperHttpRequest {
56
70
async fn try_from ( mut value : Request ) -> Result < Self , Error > {
@@ -88,17 +102,15 @@ impl HyperHttpRequest {
88
102
. uri ( uri)
89
103
. body ( body) ?;
90
104
91
- Ok ( HyperHttpRequest { inner : request } )
105
+ Ok ( HyperHttpRequest ( request) )
92
106
}
93
107
94
108
fn into_inner ( self ) -> hyper:: Request < hyper:: Body > {
95
- self . inner
109
+ self . 0
96
110
}
97
111
}
98
112
99
- struct HttpTypesResponse {
100
- inner : Response ,
101
- }
113
+ struct HttpTypesResponse ( Response ) ;
102
114
103
115
impl HttpTypesResponse {
104
116
async fn try_from ( value : hyper:: Response < hyper:: Body > ) -> Result < Self , Error > {
@@ -123,11 +135,11 @@ impl HttpTypesResponse {
123
135
}
124
136
125
137
res. set_body ( body) ;
126
- Ok ( HttpTypesResponse { inner : res } )
138
+ Ok ( HttpTypesResponse ( res) )
127
139
}
128
140
129
141
fn into_inner ( self ) -> Response {
130
- self . inner
142
+ self . 0
131
143
}
132
144
}
133
145
0 commit comments