Skip to content

Commit 181fe18

Browse files
committed
hyper: avoid leaking generics into HttpClient
Avoid leaking Hyper generics into HttpClient by hiding it behind a dynamic trait object pointer.
1 parent 46395ab commit 181fe18

File tree

1 file changed

+27
-9
lines changed

1 file changed

+27
-9
lines changed

src/hyper.rs

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,29 @@ use http_types::headers::{HeaderName, HeaderValue};
66
use http_types::StatusCode;
77
use hyper::body::HttpBody;
88
use hyper::client::connect::Connect;
9-
use hyper::client::HttpConnector;
109
use hyper_tls::HttpsConnector;
1110
use std::convert::TryFrom;
1211
use std::fmt::Debug;
1312
use std::io;
1413
use std::str::FromStr;
1514
use std::sync::Arc;
1615

16+
// Avoid leaking Hyper generics into HttpClient by hiding it behind a dynamic trait object pointer.
17+
trait HyperClientObject: Debug + Send + Sync + 'static {
18+
fn dyn_request(&self, req: hyper::Request<hyper::Body>) -> hyper::client::ResponseFuture;
19+
}
20+
21+
impl<C: Clone + Connect + Debug + Send + Sync + 'static> HyperClientObject for hyper::Client<C> {
22+
fn dyn_request(&self, req: hyper::Request<hyper::Body>) -> hyper::client::ResponseFuture {
23+
self.request(req)
24+
}
25+
}
26+
1727
/// Hyper-based HTTP Client.
18-
#[derive(Clone, Debug)]
19-
pub struct HyperClient<C: Clone + Connect + Debug + Send + Sync + 'static>(Arc<hyper::Client<C>>);
28+
#[derive(Debug)]
29+
pub struct HyperClient(Arc<dyn HyperClientObject>);
2030

21-
impl HyperClient<HttpsConnector<HttpConnector>> {
31+
impl HyperClient {
2232
/// Create a new client instance.
2333
pub fn new() -> Self {
2434
let https = HttpsConnector::new();
@@ -27,25 +37,33 @@ impl HyperClient<HttpsConnector<HttpConnector>> {
2737
}
2838
}
2939

30-
impl<C: Clone + Connect + Debug + Send + Sync + 'static> HyperClient<C> {
40+
impl Clone for HyperClient {
41+
fn clone(&self) -> Self {
42+
Self(self.0.clone())
43+
}
44+
}
45+
46+
impl HyperClient {
3147
/// Create from externally initialized and configured client.
32-
pub fn from_client(client: hyper::Client<C>) -> Self {
48+
pub fn from_client<C: Clone + Connect + Debug + Send + Sync + 'static>(
49+
client: hyper::Client<C>,
50+
) -> Self {
3351
Self(Arc::new(client))
3452
}
3553
}
3654

37-
impl Default for HyperClient<HttpsConnector<HttpConnector>> {
55+
impl Default for HyperClient {
3856
fn default() -> Self {
3957
Self::new()
4058
}
4159
}
4260

4361
#[async_trait]
44-
impl<C: Clone + Connect + Debug + Send + Sync + 'static> HttpClient for HyperClient<C> {
62+
impl HttpClient for HyperClient {
4563
async fn send(&self, req: Request) -> Result<Response, Error> {
4664
let req = HyperHttpRequest::try_from(req).await?.into_inner();
4765

48-
let response = self.0.request(req).await?;
66+
let response = self.0.dyn_request(req).await?;
4967

5068
let res = HttpTypesResponse::try_from(response).await?.into_inner();
5169
Ok(res)

0 commit comments

Comments
 (0)