Skip to main content

rama/cli/
forward.rs

1use crate::error::BoxError;
2use rama_core::error::ErrorExt as _;
3use rama_utils::macros::match_ignore_ascii_case_str;
4use std::str::FromStr;
5
6#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
7/// Kind of fowarder to use, to help you forward the client Ip information.
8///
9/// Useful in case your service is behind a load balancer.
10pub enum ForwardKind {
11    /// [`Forwarded`] header.
12    ///
13    /// [`Forwarded`]: crate::net::forwarded::Forwarded
14    Forwarded,
15    /// [`X-Forwarded-For`] header.
16    ///
17    /// [`X-Forwarded-For`]: crate::http::headers::forwarded::XForwardedFor
18    XForwardedFor,
19    /// [`X-Client-Ip`] header.
20    ///
21    /// [`X-Client-Ip`]: crate::http::headers::forwarded::XClientIp
22    XClientIp,
23    /// [`Client-Ip`] header.
24    ///
25    /// [`Client-Ip`]: crate::http::headers::forwarded::ClientIp
26    ClientIp,
27    /// [`X-Real-Ip`] header.
28    ///
29    /// [`X-Real-Ip`]: crate::http::headers::forwarded::XRealIp
30    XRealIp,
31    /// [`Cf-Connecting-Ip`] header.
32    ///
33    /// [`Cf-Connecting-Ip`]: crate::http::headers::forwarded::CFConnectingIp
34    CFConnectingIp,
35    /// [`True-Client-Ip`] header.
36    ///
37    /// [`True-Client-Ip`]: crate::http::headers::forwarded::TrueClientIp
38    TrueClientIp,
39    /// [`HaProxy`] protocol (transport layer).
40    ///
41    /// [`HaProxy`]: crate::proxy::haproxy
42    HaProxy,
43}
44
45impl<'a> TryFrom<&'a str> for ForwardKind {
46    type Error = BoxError;
47
48    fn try_from(value: &'a str) -> Result<Self, Self::Error> {
49        match_ignore_ascii_case_str! {
50            match(value) {
51                "forwarded" => Ok(Self::Forwarded),
52                "x-forwarded-for" => Ok(Self::XForwardedFor),
53                "x-client-ip" => Ok(Self::XClientIp),
54                "x-real-ip" => Ok(Self::XRealIp),
55                "cf-connecting-ip" => Ok(Self::CFConnectingIp),
56                "true-client-ip" => Ok(Self::TrueClientIp),
57                "haproxy" => Ok(Self::HaProxy),
58                _ => Err(BoxError::from("unknown forward kind").context_str_field("str", value)),
59            }
60        }
61    }
62}
63
64impl TryFrom<String> for ForwardKind {
65    type Error = BoxError;
66
67    fn try_from(value: String) -> Result<Self, Self::Error> {
68        value.as_str().try_into()
69    }
70}
71
72impl FromStr for ForwardKind {
73    type Err = BoxError;
74
75    fn from_str(s: &str) -> Result<Self, Self::Err> {
76        s.try_into()
77    }
78}