Skip to main content

fusen_rs/protocol/http/
client.rs

1use 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}