Skip to content

Commit 46395ab

Browse files
committed
hyper: Clone & Default, re-use internal client
- Makes HyperClient impl Clone and Default - Re-uses the internal hyper client for pooling and alloc efficiency - Adds HyperClient::from_client() - Always uses the HttpsConnector (has internal http fallback) Required for hyper-client in Surf: http-rs/surf#234
1 parent 3cfd120 commit 46395ab

File tree

1 file changed

+28
-24
lines changed

1 file changed

+28
-24
lines changed

src/hyper.rs

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,46 +5,50 @@ 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;
9+
use hyper::client::HttpConnector;
810
use hyper_tls::HttpsConnector;
911
use std::convert::TryFrom;
12+
use std::fmt::Debug;
1013
use std::io;
1114
use std::str::FromStr;
15+
use std::sync::Arc;
1216

1317
/// Hyper-based HTTP Client.
14-
#[derive(Debug)]
15-
pub struct HyperClient {}
18+
#[derive(Clone, Debug)]
19+
pub struct HyperClient<C: Clone + Connect + Debug + Send + Sync + 'static>(Arc<hyper::Client<C>>);
1620

17-
impl HyperClient {
18-
/// Create a new client.
19-
///
20-
/// There is no specific benefit to reusing instances of this client.
21+
impl HyperClient<HttpsConnector<HttpConnector>> {
22+
/// Create a new client instance.
2123
pub fn new() -> Self {
22-
HyperClient {}
24+
let https = HttpsConnector::new();
25+
let client = hyper::Client::builder().build(https);
26+
Self(Arc::new(client))
27+
}
28+
}
29+
30+
impl<C: Clone + Connect + Debug + Send + Sync + 'static> HyperClient<C> {
31+
/// Create from externally initialized and configured client.
32+
pub fn from_client(client: hyper::Client<C>) -> Self {
33+
Self(Arc::new(client))
34+
}
35+
}
36+
37+
impl Default for HyperClient<HttpsConnector<HttpConnector>> {
38+
fn default() -> Self {
39+
Self::new()
2340
}
2441
}
2542

2643
#[async_trait]
27-
impl HttpClient for HyperClient {
44+
impl<C: Clone + Connect + Debug + Send + Sync + 'static> HttpClient for HyperClient<C> {
2845
async fn send(&self, req: Request) -> Result<Response, Error> {
2946
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();
3247

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-
}?;
48+
let response = self.0.request(req).await?;
4549

46-
let resp = HttpTypesResponse::try_from(response).await?.into_inner();
47-
Ok(resp)
50+
let res = HttpTypesResponse::try_from(response).await?.into_inner();
51+
Ok(res)
4852
}
4953
}
5054

0 commit comments

Comments
 (0)