soph_http/support/
http.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
use crate::{config, Http, HttpResult};
use reqwest_middleware::{ClientBuilder, ClientWithMiddleware};
use std::{net::IpAddr, str::FromStr, time::Duration};

impl Http {
    pub fn try_from_config(config: config::Http) -> HttpResult<Self> {
        let mut reqwest_client = reqwest::Client::builder();

        if let Some(timeout) = config.timeout {
            reqwest_client = reqwest_client.timeout(Duration::from_millis(timeout));
        }

        if let Some(pool_idle_timeout) = config.pool_idle_timeout {
            reqwest_client =
                reqwest_client.pool_idle_timeout(Duration::from_millis(pool_idle_timeout));
        }

        if let Some(pool_max_idle_per_host) = config.pool_max_idle_per_host {
            reqwest_client = reqwest_client.pool_max_idle_per_host(pool_max_idle_per_host);
        }

        if let Some(local_address) = config.local_address {
            reqwest_client = reqwest_client.local_address(IpAddr::from_str(&local_address).ok());
        }

        if let Some(tcp_keepalive) = config.tcp_keepalive {
            reqwest_client = reqwest_client.tcp_keepalive(Duration::from_millis(tcp_keepalive));
        }

        #[allow(unused_mut)]
        let mut client = ClientBuilder::new(reqwest_client.build()?);

        #[cfg(feature = "tracing")]
        {
            client = client.with(reqwest_tracing::TracingMiddleware::default());
        }

        #[cfg(feature = "retry")]
        {
            client = client.with(reqwest_retry::RetryTransientMiddleware::new_with_policy(
                reqwest_retry::policies::ExponentialBackoff::builder()
                    .build_with_max_retries(config.max_retry),
            ));
        }

        Ok(Self {
            inner: client.build(),
        })
    }
}

impl std::ops::Deref for Http {
    type Target = ClientWithMiddleware;

    fn deref(&self) -> &Self::Target {
        &self.inner
    }
}