reqwest_chain/
middleware.rs1use crate::chainable::{ChainMiddleware, Chainer};
4use anyhow::anyhow;
5use http::Extensions;
6use reqwest_middleware::reqwest::{Request, Response};
7use reqwest_middleware::{Error, Middleware, Next, Result};
8
9#[async_trait::async_trait]
10impl<T, S> Middleware for ChainMiddleware<T>
11where
12 T: Chainer<State = S> + Send + Sync + 'static,
13 S: Send + Sync + Default + 'static,
14{
15 async fn handle(
16 &self,
17 req: Request,
18 extensions: &mut Extensions,
19 next: Next<'_>,
20 ) -> Result<Response> {
21 execute_with_chain(self.inner(), req, next, extensions).await
26 }
27}
28
29async fn execute_with_chain<'a, T, S>(
32 chain_middleware: &'a T,
33 mut request: Request,
34 next: Next<'a>,
35 ext: &'a mut Extensions,
36) -> Result<Response>
37where
38 T: Chainer<State = S> + Sync,
39 S: Default,
40{
41 let mut request_state = S::default();
42 let mut n_past_retries = 0;
43 let max_chain_length = chain_middleware.max_chain_length();
44 loop {
45 if n_past_retries >= max_chain_length {
46 return Err(Error::Middleware(anyhow!(
47 "Maximum chain length {max_chain_length} exceeded"
48 )));
49 };
50
51 let duplicate_request = request.try_clone().ok_or_else(|| {
56 Error::Middleware(anyhow!(
57 "Request object is not clonable. Are you passing a streaming body?".to_string()
58 ))
59 })?;
60 let result = next.clone().run(duplicate_request, ext).await;
61
62 let action = chain_middleware
63 .chain(result, &mut request_state, &mut request)
64 .await?;
65 if let Some(response) = action {
66 return Ok(response);
67 } else {
68 n_past_retries += 1;
69 }
70 }
71}