1 use crate::transport::BoxFuture; 2 use http::uri::Authority; 3 use http::uri::Scheme; 4 use http::{Request, Uri}; 5 use std::task::{Context, Poll}; 6 use tower_service::Service; 7 8 #[derive(Debug)] 9 pub(crate) struct AddOrigin<T> { 10 inner: T, 11 scheme: Option<Scheme>, 12 authority: Option<Authority>, 13 } 14 15 impl<T> AddOrigin<T> { new(inner: T, origin: Uri) -> Self16 pub(crate) fn new(inner: T, origin: Uri) -> Self { 17 let http::uri::Parts { 18 scheme, authority, .. 19 } = origin.into_parts(); 20 21 Self { 22 inner, 23 scheme, 24 authority, 25 } 26 } 27 } 28 29 impl<T, ReqBody> Service<Request<ReqBody>> for AddOrigin<T> 30 where 31 T: Service<Request<ReqBody>>, 32 T::Future: Send + 'static, 33 T::Error: Into<crate::Error>, 34 { 35 type Response = T::Response; 36 type Error = crate::Error; 37 type Future = BoxFuture<'static, Result<Self::Response, Self::Error>>; 38 poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>39 fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { 40 self.inner.poll_ready(cx).map_err(Into::into) 41 } 42 call(&mut self, req: Request<ReqBody>) -> Self::Future43 fn call(&mut self, req: Request<ReqBody>) -> Self::Future { 44 if self.scheme.is_none() || self.authority.is_none() { 45 let err = crate::transport::Error::new_invalid_uri(); 46 return Box::pin(async move { Err::<Self::Response, _>(err.into()) }); 47 } 48 49 // Split the request into the head and the body. 50 let (mut head, body) = req.into_parts(); 51 52 // Update the the request URI 53 head.uri = { 54 // Split the request URI into parts. 55 let mut uri: http::uri::Parts = head.uri.into(); 56 // Update the URI parts, setting hte scheme and authority 57 uri.scheme = self.scheme.clone(); 58 uri.authority = self.authority.clone(); 59 60 http::Uri::from_parts(uri).expect("valid uri") 61 }; 62 63 let request = Request::from_parts(head, body); 64 65 let fut = self.inner.call(request); 66 67 Box::pin(async move { fut.await.map_err(Into::into) }) 68 } 69 } 70