rama/cli/
forward.rs

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