rocket_http_community/header/
proxy_proto.rs

1use std::fmt;
2
3use uncased::{AsUncased, UncasedStr};
4
5/// Parsed [`Config::proxy_proto_header`] value: identifies a forwarded HTTP
6/// protocol (aka [X-Forwarded-Proto]).
7///
8/// The value of the header with name [`Config::proxy_proto_header`] is parsed
9/// case-insensitively into this `enum`. For a given request, the parsed value,
10/// if the header was present, can be retrieved via [`Request::proxy_proto()`]
11/// or directly as a [request guard]. That value is used to determine whether a
12/// request's context is likely secure ([`Request::context_is_likely_secure()`])
13/// which in-turn is used to determine whether the `Secure` cookie flag is set
14/// by default when [cookies are added] to a `CookieJar`.
15///
16/// [X-Forwarded-Proto]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto
17/// [`Config::proxy_proto_header`]: ../../rocket/struct.Config.html#structfield.proxy_proto_header
18/// [`Request::proxy_proto()`]: ../../rocket/request/struct.Request.html#method.proxy_proto
19/// [`Request::context_is_likely_secure()`]: ../../rocket/request/struct.Request.html#method.context_is_likely_secure
20/// [cookies are added]: ../..//rocket/http/struct.CookieJar.html#method.add
21/// [request guard]: ../../rocket/request/trait.FromRequest.html#provided-implementations
22#[derive(Clone, Debug, Eq, PartialEq)]
23pub enum ProxyProto<'a> {
24    /// `"http"`: Hypertext Transfer Protocol.
25    Http,
26    /// `"https"`: Hypertext Transfer Protocol Secure.
27    Https,
28    /// Any protocol name other than `"http"` or `"https"`.
29    Unknown(&'a UncasedStr),
30}
31
32impl ProxyProto<'_> {
33    /// Returns `true` if `self` is `ProxyProto::Https` and `false` otherwise.
34    ///
35    /// # Example
36    ///
37    /// ```rust
38    /// use rocket::http::ProxyProto;
39    ///
40    /// assert!(ProxyProto::Https.is_https());
41    /// assert!(!ProxyProto::Http.is_https());
42    /// ```
43    pub fn is_https(&self) -> bool {
44        self == &ProxyProto::Https
45    }
46}
47
48impl<'a> From<&'a str> for ProxyProto<'a> {
49    fn from(value: &'a str) -> ProxyProto<'a> {
50        match value.as_uncased() {
51            v if v == "http" => ProxyProto::Http,
52            v if v == "https" => ProxyProto::Https,
53            v => ProxyProto::Unknown(v),
54        }
55    }
56}
57
58impl fmt::Display for ProxyProto<'_> {
59    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
60        f.write_str(match *self {
61            ProxyProto::Http => "http",
62            ProxyProto::Https => "https",
63            ProxyProto::Unknown(s) => s.as_str(),
64        })
65    }
66}