reqwest_middleware/
req_init.rs

1use crate::RequestBuilder;
2
3/// When attached to a [`ClientWithMiddleware`] (generally using [`with_init`]), it is run
4/// whenever the client starts building a request, in the order it was attached.
5///
6/// # Example
7///
8/// ```
9/// use reqwest_middleware::{RequestInitialiser, RequestBuilder};
10///
11/// struct AuthInit;
12///
13/// impl RequestInitialiser for AuthInit {
14///     fn init(&self, req: RequestBuilder) -> RequestBuilder {
15///         req.bearer_auth("my_auth_token")
16///     }
17/// }
18/// ```
19///
20/// [`ClientWithMiddleware`]: crate::ClientWithMiddleware
21/// [`with_init`]: crate::ClientBuilder::with_init
22pub trait RequestInitialiser: 'static + Send + Sync {
23    fn init(&self, req: RequestBuilder) -> RequestBuilder;
24}
25
26impl<F> RequestInitialiser for F
27where
28    F: Send + Sync + 'static + Fn(RequestBuilder) -> RequestBuilder,
29{
30    fn init(&self, req: RequestBuilder) -> RequestBuilder {
31        (self)(req)
32    }
33}
34
35/// A middleware that inserts the value into the [`Extensions`](http::Extensions) during the call.
36///
37/// This is a good way to inject extensions to middleware deeper in the stack
38///
39/// ```
40/// use reqwest::{Client, Request, Response};
41/// use reqwest_middleware::{ClientBuilder, Middleware, Next, Result, Extension};
42/// use http::Extensions;
43///
44/// #[derive(Clone)]
45/// struct LogName(&'static str);
46/// struct LoggingMiddleware;
47///
48/// #[async_trait::async_trait]
49/// impl Middleware for LoggingMiddleware {
50///     async fn handle(
51///         &self,
52///         req: Request,
53///         extensions: &mut Extensions,
54///         next: Next<'_>,
55///     ) -> Result<Response> {
56///         // get the log name or default to "unknown"
57///         let name = extensions
58///             .get()
59///             .map(|&LogName(name)| name)
60///             .unwrap_or("unknown");
61///         println!("[{name}] Request started {req:?}");
62///         let res = next.run(req, extensions).await;
63///         println!("[{name}] Result: {res:?}");
64///         res
65///     }
66/// }
67///
68/// async fn run() {
69///     let reqwest_client = Client::builder().build().unwrap();
70///     let client = ClientBuilder::new(reqwest_client)
71///         .with_init(Extension(LogName("my-client")))
72///         .with(LoggingMiddleware)
73///         .build();
74///     let resp = client.get("https://truelayer.com").send().await.unwrap();
75///     println!("TrueLayer page HTML: {}", resp.text().await.unwrap());
76/// }
77/// ```
78pub struct Extension<T>(pub T);
79
80impl<T: Send + Sync + Clone + 'static> RequestInitialiser for Extension<T> {
81    fn init(&self, req: RequestBuilder) -> RequestBuilder {
82        req.with_extension(self.0.clone())
83    }
84}