hyperx/header/common/
referrer_policy.rs

1use std::fmt;
2
3use header::{Header, RawLike, parsing};
4
5/// `Referrer-Policy` header, part of
6/// [Referrer Policy](https://www.w3.org/TR/referrer-policy/#referrer-policy-header)
7///
8/// The `Referrer-Policy` HTTP header specifies the referrer
9/// policy that the user agent applies when determining what
10/// referrer information should be included with requests made,
11/// and with browsing contexts created from the context of the
12/// protected resource.
13///
14/// # ABNF
15///
16/// ```text
17/// Referrer-Policy: 1#policy-token
18/// policy-token   = "no-referrer" / "no-referrer-when-downgrade"
19///                  / "same-origin" / "origin"
20///                  / "origin-when-cross-origin" / "unsafe-url"
21/// ```
22///
23/// # Example values
24///
25/// * `no-referrer`
26///
27/// # Example
28///
29/// ```
30/// # extern crate http;
31/// use hyperx::header::{ReferrerPolicy, TypedHeaders};
32///
33/// let mut headers = http::HeaderMap::new();
34/// headers.encode(&ReferrerPolicy::NoReferrer);
35/// ```
36#[derive(Clone, PartialEq, Eq, Debug)]
37pub enum ReferrerPolicy {
38    /// `no-referrer`
39    NoReferrer,
40    /// `no-referrer-when-downgrade`
41    NoReferrerWhenDowngrade,
42    /// `same-origin`
43    SameOrigin,
44    /// `origin`
45    Origin,
46    /// `origin-when-cross-origin`
47    OriginWhenCrossOrigin,
48    /// `unsafe-url`
49    UnsafeUrl,
50     /// `strict-origin`
51    StrictOrigin,
52    ///`strict-origin-when-cross-origin`
53    StrictOriginWhenCrossOrigin,
54}
55
56impl Header for ReferrerPolicy {
57    fn header_name() -> &'static str {
58        static NAME: &'static str = "Referrer-Policy";
59        NAME
60    }
61
62    fn parse_header<'a, T>(raw: &'a T) -> ::Result<ReferrerPolicy>
63    where T: RawLike<'a>
64    {
65        use self::ReferrerPolicy::*;
66        // See https://www.w3.org/TR/referrer-policy/#determine-policy-for-token
67        let headers: Vec<String> = parsing::from_comma_delimited(raw)?;
68
69        for h in headers.iter().rev() {
70            let slice = &h.to_ascii_lowercase()[..];
71            match slice {
72                "no-referrer" | "never" => return Ok(NoReferrer),
73                "no-referrer-when-downgrade" | "default" => return Ok(NoReferrerWhenDowngrade),
74                "same-origin" => return Ok(SameOrigin),
75                "origin" => return Ok(Origin),
76                "origin-when-cross-origin" => return Ok(OriginWhenCrossOrigin),
77                "strict-origin" => return Ok(StrictOrigin),
78                "strict-origin-when-cross-origin" => return Ok(StrictOriginWhenCrossOrigin),
79                "unsafe-url" | "always" => return Ok(UnsafeUrl),
80                _ => continue,
81            }
82        }
83
84        Err(::Error::Header)
85    }
86
87    fn fmt_header(&self, f: &mut ::header::Formatter) -> fmt::Result {
88        f.fmt_line(self)
89    }
90}
91
92impl fmt::Display for ReferrerPolicy {
93    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
94        use self::ReferrerPolicy::*;
95        f.write_str(match *self {
96            NoReferrer => "no-referrer",
97            NoReferrerWhenDowngrade => "no-referrer-when-downgrade",
98            SameOrigin => "same-origin",
99            Origin => "origin",
100            OriginWhenCrossOrigin => "origin-when-cross-origin",
101            StrictOrigin => "strict-origin",
102            StrictOriginWhenCrossOrigin => "strict-origin-when-cross-origin",
103            UnsafeUrl => "unsafe-url",
104        })
105    }
106}
107
108#[cfg(test)]
109mod tests {
110    use super::ReferrerPolicy;
111    use header::{Header, Raw};
112
113    #[test]
114    fn test_parse_header() {
115        let r: Raw = "origin".into();
116        let a: ReferrerPolicy = Header::parse_header(&r).unwrap();
117        let b = ReferrerPolicy::Origin;
118        assert_eq!(a, b);
119
120        let r: Raw = "foobar".into();
121        let e: ::Result<ReferrerPolicy> = Header::parse_header(&r);
122        assert!(e.is_err());
123    }
124
125    #[test]
126    fn test_rightmost_header() {
127        let r: Raw = "same-origin, origin, foobar".into();
128        let a: ReferrerPolicy = Header::parse_header(&r).unwrap();
129        let b = ReferrerPolicy::Origin;
130        assert_eq!(a, b);
131    }
132}
133
134standard_header!(ReferrerPolicy, REFERRER_POLICY);