rama_http/layer/rewrite_uri/
service.rs1use std::fmt;
2
3use crate::Request;
4use rama_core::{Service, telemetry::tracing};
5use rama_net::http::uri::{UriMatchError, UriMatchReplace};
6use rama_utils::macros::define_inner_service_accessors;
7use std::borrow::Cow;
8
9pub struct RewriteUriService<R, S> {
18 match_replace: R,
19 inner: S,
20}
21
22impl<R, S> fmt::Debug for RewriteUriService<R, S>
23where
24 R: fmt::Debug,
25 S: fmt::Debug,
26{
27 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
28 f.debug_struct("RewriteUriService")
29 .field("match_replace", &self.match_replace)
30 .field("inner", &self.inner)
31 .finish()
32 }
33}
34
35impl<R, S> Clone for RewriteUriService<R, S>
36where
37 R: Clone,
38 S: Clone,
39{
40 fn clone(&self) -> Self {
41 Self {
42 match_replace: self.match_replace.clone(),
43 inner: self.inner.clone(),
44 }
45 }
46}
47
48impl<R, S> RewriteUriService<R, S> {
49 pub fn new(match_replace: R, service: S) -> Self {
51 Self {
52 match_replace,
53 inner: service,
54 }
55 }
56}
57
58impl<R, S> RewriteUriService<R, S> {
59 define_inner_service_accessors!();
60
61 #[must_use]
63 pub fn match_replace_ref(&self) -> &R {
64 &self.match_replace
65 }
66
67 #[must_use]
69 pub fn match_replace_mut(&mut self) -> &mut R {
70 &mut self.match_replace
71 }
72}
73
74impl<ReqBody, R, S> Service<Request<ReqBody>> for RewriteUriService<R, S>
75where
76 S: Service<Request<ReqBody>>,
77 R: UriMatchReplace + Send + Sync + 'static,
78 ReqBody: Send + 'static,
79{
80 type Output = S::Output;
81 type Error = S::Error;
82
83 async fn serve(&self, mut req: Request<ReqBody>) -> Result<Self::Output, Self::Error> {
84 let full_uri = req.request_uri();
85 if let Ok(uri) = self
86 .match_replace
87 .match_replace_uri(Cow::Owned(full_uri))
88 .inspect_err(|err| match err {
89 UriMatchError::NoMatch(uri) => {
90 tracing::trace!("no match found for uri: {uri}; ignore")
91 }
92 UriMatchError::Unexpected(err) => {
93 tracing::trace!("unexpected error while trying to match uri: {err}; ignore")
94 }
95 })
96 {
97 *req.uri_mut() = uri.into_owned()
98 }
99 self.inner.serve(req).await
100 }
101}