rama_net/
transport.rs

1//! transport net logic
2//!
3//! See [`TransportContext`] for the centerpiece of this module.
4
5use crate::http::RequestContext;
6use crate::{Protocol, address::Authority};
7use rama_core::{Context, error::OpaqueError};
8use rama_http_types::{Request, Version, dep::http::request::Parts as HttpParts};
9
10#[derive(Debug, Clone, PartialEq, Eq)]
11/// The context as relevant to the transport layer,
12/// often used when operating on Tcp/Udp/Tls.
13pub struct TransportContext {
14    /// the protocol used on the transport layer. One of the infamous two.
15    pub protocol: TransportProtocol,
16
17    /// The [`Protocol`] of the application layer, if known.
18    pub app_protocol: Option<Protocol>,
19
20    /// The [`Version`] if the application layer is http.
21    pub http_version: Option<Version>,
22
23    /// The authority of the target,
24    /// from where this comes depends on the kind of
25    /// request it originates from.
26    pub authority: Authority,
27}
28
29#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
30/// The protocol used for the transport layer.
31pub enum TransportProtocol {
32    /// The `tcp` protocol.
33    Tcp,
34    /// The `udp` protocol.
35    Udp,
36}
37
38/// Utility trait to support trait bounds where you wish
39/// to turn combined types into a [`TransportContext`],
40/// not expressible with [`Into`].
41///
42/// e.g. `&Request: Into<TransportContext>` would not work if it needs also [`Context`] and be a ref.
43pub trait TryRefIntoTransportContext<State> {
44    /// The error that can happen when trying to turn the self reference into the TransportContext.
45    type Error;
46
47    /// Try to turn the reference to self within the given context into the TransportContext.
48    fn try_ref_into_transport_ctx(
49        &self,
50        ctx: &Context<State>,
51    ) -> Result<TransportContext, Self::Error>;
52}
53
54impl<State, Body> TryFrom<(&Context<State>, &Request<Body>)> for TransportContext {
55    type Error = OpaqueError;
56
57    fn try_from(
58        (ctx, req): (&Context<State>, &Request<Body>),
59    ) -> Result<TransportContext, Self::Error> {
60        Ok(match ctx.get::<RequestContext>() {
61            Some(req_ctx) => req_ctx.into(),
62            None => {
63                let req_ctx = RequestContext::try_from((ctx, req))?;
64                req_ctx.into()
65            }
66        })
67    }
68}
69
70impl<State> TryFrom<(&Context<State>, &HttpParts)> for TransportContext {
71    type Error = OpaqueError;
72
73    fn try_from(
74        (ctx, parts): (&Context<State>, &HttpParts),
75    ) -> Result<TransportContext, Self::Error> {
76        Ok(match ctx.get::<RequestContext>() {
77            Some(req_ctx) => req_ctx.into(),
78            None => {
79                let req_ctx = RequestContext::try_from((ctx, parts))?;
80                req_ctx.into()
81            }
82        })
83    }
84}