Skip to content

Commit fdf9847

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 5703470 commit fdf9847

File tree

1 file changed

+27
-10
lines changed

1 file changed

+27
-10
lines changed

src/hyper.rs

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,46 +6,63 @@ 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();
2535
let client = hyper::Client::builder().build(https);
2636
Self(Arc::new(client))
2737
}
28-
}
2938

30-
impl<C: Clone + Connect + Debug + Send + Sync + 'static> HyperClient<C> {
3139
/// Create from externally initialized and configured client.
32-
pub fn from_client(client: hyper::Client<C>) -> Self {
40+
pub fn from_client<C>(client: hyper::Client<C>) -> Self
41+
where
42+
C: Clone + Connect + Debug + Send + Sync + 'static,
43+
{
3344
Self(Arc::new(client))
3445
}
3546
}
3647

37-
impl Default for HyperClient<HttpsConnector<HttpConnector>> {
48+
impl Clone for HyperClient {
49+
fn clone(&self) -> Self {
50+
Self(self.0.clone())
51+
}
52+
}
53+
54+
impl Default for HyperClient {
3855
fn default() -> Self {
3956
Self::new()
4057
}
4158
}
4259

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

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

5067
let res = HttpTypesResponse::try_from(response).await?.into_inner();
5168
Ok(res)

0 commit comments

Comments
 (0)