Skip to content

Commit b9cc423

Browse files
authored
Merge pull request #45 from Fishrock123/hyper-improvements
hyper: re-use internal client, impl Default
2 parents 2431e8e + e2c9f00 commit b9cc423

File tree

1 file changed

+43
-31
lines changed

1 file changed

+43
-31
lines changed

src/hyper.rs

Lines changed: 43 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -5,52 +5,66 @@ use futures_util::stream::TryStreamExt;
55
use http_types::headers::{HeaderName, HeaderValue};
66
use http_types::StatusCode;
77
use hyper::body::HttpBody;
8+
use hyper::client::connect::Connect;
89
use hyper_tls::HttpsConnector;
910
use std::convert::TryFrom;
11+
use std::fmt::Debug;
1012
use std::io;
1113
use std::str::FromStr;
1214

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+
1328
/// Hyper-based HTTP Client.
1429
#[derive(Debug)]
15-
pub struct HyperClient {}
30+
pub struct HyperClient(Box<dyn HyperClientObject>);
1631

1732
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.
2134
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()
2352
}
2453
}
2554

2655
#[async_trait]
2756
impl HttpClient for HyperClient {
2857
async fn send(&self, req: Request) -> Result<Response, Error> {
2958
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();
3259

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?;
4561

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)
4864
}
4965
}
5066

51-
struct HyperHttpRequest {
52-
inner: hyper::Request<hyper::Body>,
53-
}
67+
struct HyperHttpRequest(HyperRequest);
5468

5569
impl HyperHttpRequest {
5670
async fn try_from(mut value: Request) -> Result<Self, Error> {
@@ -88,17 +102,15 @@ impl HyperHttpRequest {
88102
.uri(uri)
89103
.body(body)?;
90104

91-
Ok(HyperHttpRequest { inner: request })
105+
Ok(HyperHttpRequest(request))
92106
}
93107

94108
fn into_inner(self) -> hyper::Request<hyper::Body> {
95-
self.inner
109+
self.0
96110
}
97111
}
98112

99-
struct HttpTypesResponse {
100-
inner: Response,
101-
}
113+
struct HttpTypesResponse(Response);
102114

103115
impl HttpTypesResponse {
104116
async fn try_from(value: hyper::Response<hyper::Body>) -> Result<Self, Error> {
@@ -123,11 +135,11 @@ impl HttpTypesResponse {
123135
}
124136

125137
res.set_body(body);
126-
Ok(HttpTypesResponse { inner: res })
138+
Ok(HttpTypesResponse(res))
127139
}
128140

129141
fn into_inner(self) -> Response {
130-
self.inner
142+
self.0
131143
}
132144
}
133145

0 commit comments

Comments
 (0)