use std::{
fmt,
task::{Context, Poll},
};
use http::{Request, Response, header::HeaderMap};
use tower_layer::Layer;
use tower_service::Service;
#[derive(Clone)]
pub struct SetRequestHeaderLayer {
header_map: HeaderMap,
}
impl fmt::Debug for SetRequestHeaderLayer {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("SetRequestHeaderLayer")
.field("header_map", &self.header_map)
.finish()
}
}
impl SetRequestHeaderLayer {
pub fn new(header_map: HeaderMap) -> Self {
Self { header_map }
}
}
impl<S> Layer<S> for SetRequestHeaderLayer {
type Service = SetRequestHeader<S>;
fn layer(&self, inner: S) -> Self::Service {
SetRequestHeader {
inner,
header_map: self.header_map.clone(),
}
}
}
#[derive(Clone)]
pub struct SetRequestHeader<S> {
inner: S,
header_map: HeaderMap,
}
impl<S> SetRequestHeader<S> {
pub fn apply<B>(&self, req: &mut Request<B>) {
for (key, value) in self.header_map.iter() {
req.headers_mut().insert(key, value.clone());
}
}
}
impl<S> fmt::Debug for SetRequestHeader<S>
where
S: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("SetRequestHeader")
.field("inner", &self.inner)
.field("header_map", &self.header_map)
.finish()
}
}
impl<ReqBody, ResBody, S> Service<Request<ReqBody>> for SetRequestHeader<S>
where
S: Service<Request<ReqBody>, Response = Response<ResBody>>,
{
type Response = S::Response;
type Error = S::Error;
type Future = S::Future;
#[inline]
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
self.inner.poll_ready(cx)
}
fn call(&mut self, mut req: Request<ReqBody>) -> Self::Future {
self.apply(&mut req);
self.inner.call(req)
}
}