rama_http/layer/dns/dns_resolve/
service.rs

1use super::DnsResolveMode;
2use crate::{HeaderName, Request};
3use rama_core::{error::OpaqueError, Context, Service};
4use rama_utils::macros::define_inner_service_accessors;
5use std::fmt;
6
7/// Service to support configuring the DNS resolve mode.
8///
9/// By default DNS resolving is expected to only be done
10/// if it is needed (e.g. because we need to know the IP).
11/// Configuring this to be used as eager (when requested) is
12/// a way to have requested the intent
13/// to reoslve DNS even if it is not needed.
14///
15/// See `Dns` (`rama_core`) and [`DnsResolveMode`] for more information.
16pub struct DnsResolveModeService<S> {
17    inner: S,
18    header_name: HeaderName,
19}
20
21impl<S> DnsResolveModeService<S> {
22    /// Create a new instance of the [`DnsResolveModeService`].
23    pub const fn new(inner: S, header_name: HeaderName) -> Self {
24        Self { inner, header_name }
25    }
26
27    define_inner_service_accessors!();
28}
29
30impl<S: fmt::Debug> fmt::Debug for DnsResolveModeService<S> {
31    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
32        f.debug_struct("DnsResolveModeService")
33            .field("inner", &self.inner)
34            .finish()
35    }
36}
37
38impl<S: Clone> Clone for DnsResolveModeService<S> {
39    fn clone(&self) -> Self {
40        DnsResolveModeService {
41            inner: self.inner.clone(),
42            header_name: self.header_name.clone(),
43        }
44    }
45}
46
47impl<State, Body, S> Service<State, Request<Body>> for DnsResolveModeService<S>
48where
49    State: Clone + Send + Sync + 'static,
50    Body: Send + Sync + 'static,
51    S: Service<
52        State,
53        Request<Body>,
54        Error: Into<rama_core::error::BoxError> + Send + Sync + 'static,
55    >,
56{
57    type Response = S::Response;
58    type Error = OpaqueError;
59
60    async fn serve(
61        &self,
62        mut ctx: Context<State>,
63        request: Request<Body>,
64    ) -> Result<Self::Response, Self::Error> {
65        if let Some(header_value) = request.headers().get(&self.header_name) {
66            let dns_resolve_mode: DnsResolveMode = header_value.try_into()?;
67            ctx.insert(dns_resolve_mode);
68        }
69
70        self.inner
71            .serve(ctx, request)
72            .await
73            .map_err(|err| OpaqueError::from_boxed(err.into()))
74    }
75}