Skip to content

Commit b76a02c

Browse files
committed
feat(headers): Add Referrer-Policy header
1 parent a10edc6 commit b76a02c

File tree

2 files changed

+96
-0
lines changed

2 files changed

+96
-0
lines changed

src/header/common/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ pub use self::prefer::{Prefer, Preference};
4848
pub use self::preference_applied::PreferenceApplied;
4949
pub use self::range::{Range, ByteRangeSpec};
5050
pub use self::referer::Referer;
51+
pub use self::referrer_policy::ReferrerPolicy;
5152
pub use self::server::Server;
5253
pub use self::set_cookie::SetCookie;
5354
pub use self::strict_transport_security::StrictTransportSecurity;
@@ -410,6 +411,7 @@ mod prefer;
410411
mod preference_applied;
411412
mod range;
412413
mod referer;
414+
mod referrer_policy;
413415
mod server;
414416
mod set_cookie;
415417
mod strict_transport_security;

src/header/common/referrer_policy.rs

+94
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
use std::fmt;
2+
use std::ascii::AsciiExt;
3+
4+
use header::{Header, HeaderFormat, parsing};
5+
6+
/// `Referrer-Policy` header, part of
7+
/// [Referrer Policy](https://www.w3.org/TR/referrer-policy/#referrer-policy-header)
8+
///
9+
/// The `Referrer-Policy` HTTP header specifies the referrer
10+
/// policy that the user agent applies when determining what
11+
/// referrer information should be included with requests made,
12+
/// and with browsing contexts created from the context of the
13+
/// protected resource.
14+
///
15+
/// # ABNF
16+
/// ```plain
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+
/// * `no-referrer`
25+
///
26+
/// # Example
27+
/// ```
28+
/// use hyper::header::{Headers, ReferrerPolicy};
29+
///
30+
/// let mut headers = Headers::new();
31+
/// headers.set(ReferrerPolicy::NoReferrer);
32+
/// ```
33+
#[derive(Clone, PartialEq, Eq, Debug)]
34+
pub enum ReferrerPolicy {
35+
/// `no-referrer`
36+
NoReferrer,
37+
/// `no-referrer-when-downgrade`
38+
NoReferrerWhenDowngrade,
39+
/// `same-origin`
40+
SameOrigin,
41+
/// `origin`
42+
Origin,
43+
/// `origin-when-cross-origin`
44+
OriginWhenCrossOrigin,
45+
/// `unsafe-url`
46+
UnsafeUrl,
47+
}
48+
49+
impl Header for ReferrerPolicy {
50+
fn header_name() -> &'static str {
51+
static NAME: &'static str = "Referrer-Policy";
52+
NAME
53+
}
54+
55+
fn parse_header(raw: &[Vec<u8>]) -> ::Result<ReferrerPolicy> {
56+
use self::ReferrerPolicy::*;
57+
parsing::from_one_raw_str(raw).and_then(|s: String| {
58+
let slice = &s.to_ascii_lowercase()[..];
59+
// See https://www.w3.org/TR/referrer-policy/#determine-policy-for-token
60+
match slice {
61+
"no-referrer" | "never" => Ok(NoReferrer),
62+
"no-referrer-when-downgrade" | "default" => Ok(NoReferrerWhenDowngrade),
63+
"same-origin" => Ok(SameOrigin),
64+
"origin" => Ok(Origin),
65+
"origin-when-cross-origin" => Ok(OriginWhenCrossOrigin),
66+
"unsafe-url" | "always" => Ok(UnsafeUrl),
67+
_ => Err(::Error::Header),
68+
}
69+
})
70+
}
71+
}
72+
73+
impl HeaderFormat for ReferrerPolicy {
74+
fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result {
75+
use self::ReferrerPolicy::*;
76+
f.write_str(match *self {
77+
NoReferrer => "no-referrer",
78+
NoReferrerWhenDowngrade => "no-referrer-when-downgrade",
79+
SameOrigin => "same-origin",
80+
Origin => "origin",
81+
OriginWhenCrossOrigin => "origin-when-cross-origin",
82+
UnsafeUrl => "unsafe-url",
83+
})
84+
}
85+
}
86+
87+
#[test]
88+
fn test_parse_header() {
89+
let a: ReferrerPolicy = Header::parse_header([b"origin".to_vec()].as_ref()).unwrap();
90+
let b = ReferrerPolicy::Origin;
91+
assert_eq!(a, b);
92+
let e: ::Result<ReferrerPolicy> = Header::parse_header([b"foobar".to_vec()].as_ref());
93+
assert!(e.is_err());
94+
}

0 commit comments

Comments
 (0)