fusen_rs/protocol/http/
client.rs1use http::{Request, Response, Version};
2use http_body_util::combinators::BoxBody;
3use hyper::body::Incoming;
4use hyper_tls::HttpsConnector;
5use hyper_util::client::legacy::{Client, connect::HttpConnector};
6use std::{convert::Infallible, time::Duration};
7
8use crate::error::FusenError;
9pub type HttpSocket = Client<HttpsConnector<HttpConnector>, BoxBody<bytes::Bytes, Infallible>>;
10
11pub enum HttpVersion {
12 H1,
13 H2,
14}
15
16#[derive(Debug)]
17pub struct HttpClient {
18 pub http1_client: HttpSocket,
19 pub http2_client: HttpSocket,
20}
21
22impl Default for HttpClient {
23 fn default() -> Self {
24 Self::new()
25 }
26}
27
28impl HttpClient {
29 pub fn new() -> Self {
30 let mut connector = HttpConnector::new();
31 connector.set_keepalive(Some(Duration::from_secs(1800)));
32 connector.enforce_http(false);
33 Self {
34 http1_client: Client::builder(hyper_util::rt::TokioExecutor::new())
35 .build(HttpsConnector::new_with_connector(connector.clone())),
36 http2_client: Client::builder(hyper_util::rt::TokioExecutor::new())
37 .http2_only(true)
38 .build(HttpsConnector::new_with_connector(connector)),
39 }
40 }
41 pub async fn send_http_request(
42 &self,
43 request: Request<BoxBody<bytes::Bytes, Infallible>>,
44 ) -> Result<Response<Incoming>, FusenError> {
45 let http_client = match request.version() {
46 Version::HTTP_2 => &self.http2_client,
47 _ => &self.http1_client,
48 };
49 send_http_request(http_client, request).await
50 }
51}
52
53async fn send_http_request(
54 client: &Client<HttpsConnector<HttpConnector>, BoxBody<bytes::Bytes, Infallible>>,
55 request: Request<BoxBody<bytes::Bytes, Infallible>>,
56) -> Result<Response<Incoming>, FusenError> {
57 let response = client
58 .request(request)
59 .await
60 .map_err(|error| FusenError::Error(Box::new(error)))?;
61 Ok(response)
62}