Skip to main content

tower_http/set_header/request/
single_header.rs

1//! Set a single header on the request.
2//!
3//! See the root [`crate::set_header::request`] module for full documentation and usage examples.
4//!
5use http::{header::HeaderName, Request, Response};
6use std::{
7    fmt,
8    task::{Context, Poll},
9};
10use tower_layer::Layer;
11use tower_service::Service;
12
13use crate::set_header::{InsertHeaderMode, MakeHeaderValue};
14
15/// Layer that applies [`SetRequestHeader`] which adds a request header.
16///
17/// See [`SetRequestHeader`] for more details.
18pub struct SetRequestHeaderLayer<M> {
19    header_name: HeaderName,
20    make: M,
21    mode: InsertHeaderMode,
22}
23
24impl<M> fmt::Debug for SetRequestHeaderLayer<M> {
25    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
26        f.debug_struct("SetRequestHeaderLayer")
27            .field("header_name", &self.header_name)
28            .field("mode", &self.mode)
29            .field("make", &std::any::type_name::<M>())
30            .finish()
31    }
32}
33
34impl<M> SetRequestHeaderLayer<M> {
35    /// Create a new [`SetRequestHeaderLayer`].
36    ///
37    /// If a previous value exists for the same header, it is removed and replaced with the new
38    /// header value.
39    pub fn overriding(header_name: HeaderName, make: M) -> Self {
40        Self::new(header_name, make, InsertHeaderMode::Override)
41    }
42
43    /// Create a new [`SetRequestHeaderLayer`].
44    ///
45    /// The new header is always added, preserving any existing values. If previous values exist,
46    /// the header will have multiple values.
47    pub fn appending(header_name: HeaderName, make: M) -> Self {
48        Self::new(header_name, make, InsertHeaderMode::Append)
49    }
50
51    /// Create a new [`SetRequestHeaderLayer`].
52    ///
53    /// If a previous value exists for the header, the new value is not inserted.
54    pub fn if_not_present(header_name: HeaderName, make: M) -> Self {
55        Self::new(header_name, make, InsertHeaderMode::IfNotPresent)
56    }
57
58    fn new(header_name: HeaderName, make: M, mode: InsertHeaderMode) -> Self {
59        Self {
60            make,
61            header_name,
62            mode,
63        }
64    }
65}
66
67impl<S, M> Layer<S> for SetRequestHeaderLayer<M>
68where
69    M: Clone,
70{
71    type Service = SetRequestHeader<S, M>;
72
73    fn layer(&self, inner: S) -> Self::Service {
74        SetRequestHeader {
75            inner,
76            header_name: self.header_name.clone(),
77            make: self.make.clone(),
78            mode: self.mode,
79        }
80    }
81}
82
83impl<M> Clone for SetRequestHeaderLayer<M>
84where
85    M: Clone,
86{
87    fn clone(&self) -> Self {
88        Self {
89            make: self.make.clone(),
90            header_name: self.header_name.clone(),
91            mode: self.mode,
92        }
93    }
94}
95
96/// Middleware that sets a header on the request.
97#[derive(Clone)]
98pub struct SetRequestHeader<S, M> {
99    inner: S,
100    header_name: HeaderName,
101    make: M,
102    mode: InsertHeaderMode,
103}
104
105impl<S, M> SetRequestHeader<S, M> {
106    /// Create a new [`SetRequestHeader`].
107    ///
108    /// If a previous value exists for the same header, it is removed and replaced with the new
109    /// header value.
110    pub fn overriding(inner: S, header_name: HeaderName, make: M) -> Self {
111        Self::new(inner, header_name, make, InsertHeaderMode::Override)
112    }
113
114    /// Create a new [`SetRequestHeader`].
115    ///
116    /// The new header is always added, preserving any existing values. If previous values exist,
117    /// the header will have multiple values.
118    pub fn appending(inner: S, header_name: HeaderName, make: M) -> Self {
119        Self::new(inner, header_name, make, InsertHeaderMode::Append)
120    }
121
122    /// Create a new [`SetRequestHeader`].
123    ///
124    /// If a previous value exists for the header, the new value is not inserted.
125    pub fn if_not_present(inner: S, header_name: HeaderName, make: M) -> Self {
126        Self::new(inner, header_name, make, InsertHeaderMode::IfNotPresent)
127    }
128
129    fn new(inner: S, header_name: HeaderName, make: M, mode: InsertHeaderMode) -> Self {
130        Self {
131            inner,
132            header_name,
133            make,
134            mode,
135        }
136    }
137
138    define_inner_service_accessors!();
139}
140
141impl<S, M> fmt::Debug for SetRequestHeader<S, M>
142where
143    S: fmt::Debug,
144{
145    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
146        f.debug_struct("SetRequestHeader")
147            .field("inner", &self.inner)
148            .field("header_name", &self.header_name)
149            .field("mode", &self.mode)
150            .field("make", &std::any::type_name::<M>())
151            .finish()
152    }
153}
154
155impl<ReqBody, ResBody, S, M> Service<Request<ReqBody>> for SetRequestHeader<S, M>
156where
157    S: Service<Request<ReqBody>, Response = Response<ResBody>>,
158    M: MakeHeaderValue<Request<ReqBody>>,
159{
160    type Response = S::Response;
161    type Error = S::Error;
162    type Future = S::Future;
163
164    #[inline]
165    fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
166        self.inner.poll_ready(cx)
167    }
168
169    fn call(&mut self, mut req: Request<ReqBody>) -> Self::Future {
170        self.mode.apply(&self.header_name, &mut req, &mut self.make);
171        self.inner.call(req)
172    }
173}