From dc4766573af9bd31d57fede5b9ef0ffa56fe44ab Mon Sep 17 00:00:00 2001 From: Garrett Squire Date: Thu, 6 Oct 2016 13:18:57 -0700 Subject: [PATCH] feat(headers): support multiple values for Referrer-Policy header Closes #882 --- src/header/common/referrer_policy.rs | 33 ++++++++++++++++++---------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/src/header/common/referrer_policy.rs b/src/header/common/referrer_policy.rs index 46f4deb624..beb5242ddc 100644 --- a/src/header/common/referrer_policy.rs +++ b/src/header/common/referrer_policy.rs @@ -54,19 +54,23 @@ impl Header for ReferrerPolicy { fn parse_header(raw: &[Vec]) -> ::Result { use self::ReferrerPolicy::*; - parsing::from_one_raw_str(raw).and_then(|s: String| { - let slice = &s.to_ascii_lowercase()[..]; - // See https://www.w3.org/TR/referrer-policy/#determine-policy-for-token + // See https://www.w3.org/TR/referrer-policy/#determine-policy-for-token + let headers: Vec = try!(parsing::from_comma_delimited(raw)); + + for h in headers.iter().rev() { + let slice = &h.to_ascii_lowercase()[..]; match slice { - "no-referrer" | "never" => Ok(NoReferrer), - "no-referrer-when-downgrade" | "default" => Ok(NoReferrerWhenDowngrade), - "same-origin" => Ok(SameOrigin), - "origin" => Ok(Origin), - "origin-when-cross-origin" => Ok(OriginWhenCrossOrigin), - "unsafe-url" | "always" => Ok(UnsafeUrl), - _ => Err(::Error::Header), + "no-referrer" | "never" => return Ok(NoReferrer), + "no-referrer-when-downgrade" | "default" => return Ok(NoReferrerWhenDowngrade), + "same-origin" => return Ok(SameOrigin), + "origin" => return Ok(Origin), + "origin-when-cross-origin" => return Ok(OriginWhenCrossOrigin), + "unsafe-url" | "always" => return Ok(UnsafeUrl), + _ => continue, } - }) + } + + Err(::Error::Header) } } @@ -92,3 +96,10 @@ fn test_parse_header() { let e: ::Result = Header::parse_header([b"foobar".to_vec()].as_ref()); assert!(e.is_err()); } + +#[test] +fn test_rightmost_header() { + let a: ReferrerPolicy = Header::parse_header(&["same-origin, origin, foobar".into()]).unwrap(); + let b = ReferrerPolicy::Origin; + assert_eq!(a, b); +}