http_api_isahc_client/
lib.rs1pub use http_api_client;
2pub use isahc;
3
4use core::time::Duration;
5
6pub use http_api_client::Client;
7#[cfg(any(
8 feature = "with-sleep-via-tokio",
9 feature = "with-sleep-via-async-timer",
10 feature = "with-sleep-via-async-io"
11))]
12pub use http_api_client::RetryableClient;
13use http_api_client::{async_trait, Body, Request, Response};
14use isahc::{
15 config::Configurable as _, AsyncReadResponseExt as _, Error as IsahcError,
16 HttpClient as IsahcHttpClient,
17};
18
19#[derive(Debug, Clone)]
20pub struct IsahcClient {
21 pub http_client: IsahcHttpClient,
22 pub body_buf_default_capacity: usize,
23}
24
25impl IsahcClient {
26 pub fn new() -> Result<Self, IsahcError> {
27 Ok(Self::with(
28 IsahcHttpClient::builder()
29 .connect_timeout(Duration::from_secs(5))
30 .timeout(Duration::from_secs(30))
31 .build()?,
32 ))
33 }
34
35 pub fn with(http_client: IsahcHttpClient) -> Self {
36 Self {
37 http_client,
38 body_buf_default_capacity: 4 * 1024,
39 }
40 }
41}
42
43#[async_trait]
44impl Client for IsahcClient {
45 type RespondError = IsahcError;
46
47 async fn respond(&self, request: Request<Body>) -> Result<Response<Body>, Self::RespondError> {
48 let res = self.http_client.send_async(request).await?;
49 let (head, body) = res.into_parts();
50
51 let mut body_buf = Vec::with_capacity(
52 body.len().unwrap_or(self.body_buf_default_capacity as u64) as usize,
53 );
54
55 let mut res = Response::from_parts(head, body);
56 res.copy_to(&mut body_buf).await?;
57
58 let (head, _) = res.into_parts();
59 let res = Response::from_parts(head, body_buf);
60
61 Ok(res)
62 }
63}
64
65#[cfg(all(
66 feature = "with-sleep-via-tokio",
67 not(feature = "with-sleep-via-async-timer"),
68 not(feature = "with-sleep-via-async-io")
69))]
70#[async_trait]
71impl RetryableClient for IsahcClient {
72 async fn sleep(&self, dur: Duration) {
73 async_sleep::sleep::<async_sleep::impl_tokio::Sleep>(dur).await;
74 }
75}
76
77#[cfg(all(
78 not(feature = "with-sleep-via-tokio"),
79 feature = "with-sleep-via-async-timer",
80 not(feature = "with-sleep-via-async-io")
81))]
82#[async_trait]
83impl RetryableClient for IsahcClient {
84 async fn sleep(&self, dur: Duration) {
85 async_sleep::sleep::<async_sleep::impl_async_timer::PlatformTimer>(dur).await;
86 }
87}
88
89#[cfg(all(
90 not(feature = "with-sleep-via-tokio"),
91 not(feature = "with-sleep-via-async-timer"),
92 feature = "with-sleep-via-async-io"
93))]
94#[async_trait]
95impl RetryableClient for IsahcClient {
96 async fn sleep(&self, dur: Duration) {
97 async_sleep::sleep::<async_sleep::impl_async_io::Timer>(dur).await;
98 }
99}