rama_http/layer/
dpi_proxy_credential.rs1use crate::Request;
7use crate::headers::{HeaderMapExt, ProxyAuthorization};
8use rama_core::extensions::ExtensionsRef;
9use rama_core::telemetry::tracing;
10use rama_core::{Layer, Service};
11use rama_http_types::proxy::is_req_http_proxy_connect;
12use rama_net::user::credentials::DpiProxyCredential;
13use rama_net::user::{Basic, Bearer, ProxyCredential};
14use rama_utils::macros::define_inner_service_accessors;
15
16#[derive(Debug, Clone, Default)]
17#[non_exhaustive]
18pub struct DpiProxyCredentialExtractorLayer;
20
21impl DpiProxyCredentialExtractorLayer {
22 #[inline(always)]
23 pub const fn new() -> Self {
25 Self
26 }
27}
28
29impl<S> Layer<S> for DpiProxyCredentialExtractorLayer {
30 type Service = DpiProxyCredentialExtractor<S>;
31
32 #[inline(always)]
33 fn layer(&self, inner: S) -> Self::Service {
34 DpiProxyCredentialExtractor::new(inner)
35 }
36}
37
38#[derive(Debug, Clone)]
39pub struct DpiProxyCredentialExtractor<S> {
45 inner: S,
46}
47
48impl<S> DpiProxyCredentialExtractor<S> {
49 #[inline(always)]
50 pub const fn new(inner: S) -> Self {
52 Self { inner }
53 }
54
55 define_inner_service_accessors!();
56}
57
58impl<S, ReqBody> Service<Request<ReqBody>> for DpiProxyCredentialExtractor<S>
59where
60 S: Service<Request<ReqBody>>,
61 ReqBody: Send + 'static,
62{
63 type Output = S::Output;
64 type Error = S::Error;
65
66 async fn serve(&self, req: Request<ReqBody>) -> Result<Self::Output, Self::Error> {
67 if is_req_http_proxy_connect(&req) {
68 tracing::trace!("DpiProxyCredentialExtractor: try to extract proxy authorization data");
69
70 if let Some(ProxyAuthorization::<Basic>(credentials)) = req.headers().typed_get() {
71 tracing::debug!(
72 "DpiProxyCredentialExtractor: extracted Basic proxy auth: inserted in req extensions"
73 );
74 req.extensions()
75 .insert(DpiProxyCredential(ProxyCredential::Basic(credentials)));
76 } else if let Some(ProxyAuthorization::<Bearer>(token)) = req.headers().typed_get() {
77 tracing::debug!(
78 "DpiProxyCredentialExtractor: extracted Bearer proxy auth: inserted in req extensions"
79 );
80 req.extensions()
81 .insert(DpiProxyCredential(ProxyCredential::Bearer(token)));
82 }
83 }
84
85 self.inner.serve(req).await
86 }
87}