cogo_http/header/common/
referrer_policy.rs

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