use std::time::Duration;
use hyper::Request;
use hyper_util::{
client::legacy::{
Client, Client as HyperClient, ResponseFuture,
connect::{Connect, HttpConnector},
},
rt::TokioExecutor,
};
use crate::request_body::RequestBody;
pub trait HttpClient: sealed::Sealed + Send + Sync + 'static {
fn request(&self, req: Request<RequestBody>) -> ResponseFuture;
}
impl<C> HttpClient for Client<C, RequestBody>
where
C: Connect + Clone + Send + Sync + 'static,
{
fn request(&self, req: Request<RequestBody>) -> ResponseFuture {
self.request(req)
}
}
impl<C> sealed::Sealed for Client<C, RequestBody> {}
const TCP_KEEPALIVE: Duration = Duration::from_secs(60);
const POOL_IDLE_TIMEOUT: Duration = Duration::from_secs(2);
pub(crate) fn default() -> impl HttpClient {
let mut connector = HttpConnector::new();
connector.set_keepalive(Some(TCP_KEEPALIVE));
connector.enforce_http(!cfg!(any(
feature = "native-tls",
feature = "rustls-tls-aws-lc",
feature = "rustls-tls-ring",
)));
#[cfg(feature = "native-tls")]
let connector = hyper_tls::HttpsConnector::new_with_connector(connector);
#[cfg(all(feature = "rustls-tls-aws-lc", not(feature = "native-tls")))]
let connector =
prepare_hyper_rustls_connector(connector, rustls::crypto::aws_lc_rs::default_provider());
#[cfg(all(
feature = "rustls-tls-ring",
not(feature = "rustls-tls-aws-lc"),
not(feature = "native-tls"),
))]
let connector =
prepare_hyper_rustls_connector(connector, rustls::crypto::ring::default_provider());
HyperClient::builder(TokioExecutor::new())
.pool_idle_timeout(POOL_IDLE_TIMEOUT)
.build(connector)
}
#[cfg(not(feature = "native-tls"))]
#[cfg(any(feature = "rustls-tls-aws-lc", feature = "rustls-tls-ring"))]
fn prepare_hyper_rustls_connector(
connector: HttpConnector,
provider: rustls::crypto::CryptoProvider,
) -> hyper_rustls::HttpsConnector<HttpConnector> {
#[cfg(not(feature = "rustls-tls-webpki-roots"))]
#[cfg(not(feature = "rustls-tls-native-roots"))]
compile_error!(
"`rustls-tls-aws-lc` and `rustls-tls-ring` features require either \
`rustls-tls-webpki-roots` or `rustls-tls-native-roots` feature to be enabled"
);
#[cfg(feature = "rustls-tls-native-roots")]
let builder = hyper_rustls::HttpsConnectorBuilder::new()
.with_provider_and_native_roots(provider)
.unwrap();
#[cfg(all(
feature = "rustls-tls-webpki-roots",
not(feature = "rustls-tls-native-roots")
))]
let builder = hyper_rustls::HttpsConnectorBuilder::new()
.with_provider_and_webpki_roots(provider)
.unwrap();
builder
.https_or_http()
.enable_http1()
.wrap_connector(connector)
}
mod sealed {
pub trait Sealed {}
}