Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement meta referrer policy delivery (2) #11422

Closed
wants to merge 2 commits into from
Closed
Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Next

Add meta-referrer support

  • Loading branch information
rebstar6 committed May 27, 2016
commit eaf44859bb6d311154e2cf824f8f28d68b3227da
@@ -352,7 +352,7 @@ pub enum FrameType {

/// [Policies](https://w3c.github.io/webappsec-referrer-policy/#referrer-policy-states)
/// for providing a referrer header for a request
#[derive(HeapSizeOf, Clone, Deserialize, Serialize)]
#[derive(HeapSizeOf, Clone, Deserialize, Serialize, Debug, Copy)]
pub enum ReferrerPolicy {
NoReferrer,
NoRefWhenDowngrade,
@@ -592,7 +592,9 @@ pub fn modify_request_headers(headers: &mut Headers,
user_agent: &str,
cookie_jar: &Arc<RwLock<CookieStorage>>,
auth_cache: &Arc<RwLock<AuthCache>>,
load_data: &LoadData) {
load_data: &LoadData,
referrer_url: &mut Option<Url>) {

// Ensure that the host header is set from the original url
let host = Host {
hostname: url.host_str().unwrap().to_owned(),
@@ -613,10 +615,12 @@ pub fn modify_request_headers(headers: &mut Headers,
set_default_accept(headers);
set_default_accept_encoding(headers);

if let Some(referer_val) = determine_request_referrer(headers,
load_data.referrer_policy.clone(),
load_data.referrer_url.clone(),
url.clone()) {
*referrer_url = determine_request_referrer(headers,
load_data.referrer_policy.clone(),
referrer_url.clone(),
url.clone());

if let Some(referer_val) = referrer_url.clone() {
headers.set(Referer(referer_val.into_string()));
}

@@ -804,6 +808,8 @@ pub fn load<A, B>(load_data: &LoadData,
let mut doc_url = load_data.url.clone();
let mut redirected_to = HashSet::new();
let mut method = load_data.method.clone();
// URL of referrer - to be updated with redirects
let mut referrer_url = load_data.referrer_url.clone();

let mut new_auth_header: Option<Authorization<Basic>> = None;

@@ -874,7 +880,7 @@ pub fn load<A, B>(load_data: &LoadData,

modify_request_headers(&mut request_headers, &doc_url,
&user_agent, &http_state.cookie_jar,
&http_state.auth_cache, &load_data);
&http_state.auth_cache, &load_data, &mut referrer_url);

//if there is a new auth header then set the request headers with it
if let Some(ref auth_header) = new_auth_header {
@@ -140,7 +140,7 @@ impl LoadData {
credentials_flag: true,
context: context,
referrer_policy: load_origin.referrer_policy(),
referrer_url: load_origin.referrer_url(),
referrer_url: load_origin.referrer_url().clone(),
source: load_origin.request_source()
}
}
@@ -237,7 +237,7 @@ pub struct Document {
/// The document's origin.
origin: Origin,
/// https://w3c.github.io/webappsec-referrer-policy/#referrer-policy-states
referrer_policy: Option<ReferrerPolicy>,
referrer_policy: Cell<Option<ReferrerPolicy>>,
}

#[derive(JSTraceable, HeapSizeOf)]
@@ -1702,7 +1702,7 @@ impl Document {
touchpad_pressure_phase: Cell::new(TouchpadPressurePhase::BeforeClick),
origin: origin,
//TODO - setting this for now so no Referer header set
referrer_policy: Some(ReferrerPolicy::NoReferrer),
referrer_policy: Cell::new(Some(ReferrerPolicy::NoReferrer)),
}
}

@@ -1832,9 +1832,13 @@ impl Document {
}
}

//TODO - for now, returns no-referrer for all until reading in the value
pub fn set_referrer_policy(&self, policy: Option<ReferrerPolicy>) {
self.referrer_policy.set(policy);
}

//TODO - default still at no-referrer
pub fn get_referrer_policy(&self) -> Option<ReferrerPolicy> {
return self.referrer_policy.clone();
return self.referrer_policy.get();
}
}

@@ -2793,6 +2797,12 @@ impl DocumentMethods for Document {

// https://html.spec.whatwg.org/multipage/#documentandelementeventhandlers
document_and_element_event_handlers!();

// https://html.spec.whatwg.org/multipage/#dom-document-referrer
fn Referrer(&self) -> DOMString {
//TODO - unimplemented, for ref pol tests
DOMString::new()
}
}

fn update_with_current_time_ms(marker: &Cell<u64>) {
@@ -2803,6 +2813,20 @@ fn update_with_current_time_ms(marker: &Cell<u64>) {
}
}

/// https://w3c.github.io/webappsec-referrer-policy/#determine-policy-for-token
pub fn determine_policy_for_token(token: &str) -> Option<ReferrerPolicy> {
let lower = token.to_lowercase();
return match lower.as_ref() {
"never" | "no-referrer" => Some(ReferrerPolicy::NoReferrer),
"default" | "no-referrer-when-downgrade" => Some(ReferrerPolicy::NoRefWhenDowngrade),
"origin" => Some(ReferrerPolicy::OriginOnly),
"origin-when-cross-origin" => Some(ReferrerPolicy::OriginWhenCrossOrigin),
"always" | "unsafe-url" => Some(ReferrerPolicy::UnsafeUrl),
"" => Some(ReferrerPolicy::NoReferrer),
_ => None,
}
}

pub struct DocumentProgressHandler {
addr: Trusted<Document>
}
@@ -148,8 +148,9 @@ impl HTMLIFrameElement {
pub fn process_the_iframe_attributes(&self) {
let url = self.get_url();

// TODO - loaddata here should have referrer info (not None, None)
self.navigate_or_reload_child_browsing_context(Some(LoadData::new(url, None, None)));
let document = document_from_node(self);
self.navigate_or_reload_child_browsing_context(
Some(LoadData::new(url, document.get_referrer_policy(), Some(document.url().clone()))));
}

#[allow(unsafe_code)]
@@ -4,12 +4,13 @@

use dom::attr::AttrValue;
use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods;
use dom::bindings::codegen::Bindings::HTMLMetaElementBinding;
use dom::bindings::codegen::Bindings::HTMLMetaElementBinding::HTMLMetaElementMethods;
use dom::bindings::inheritance::Castable;
use dom::bindings::js::{Root, RootedReference};
use dom::bindings::str::DOMString;
use dom::document::Document;
use dom::document::{Document, determine_policy_for_token};
use dom::element::Element;
use dom::htmlelement::HTMLElement;
use dom::node::{Node, document_from_node};
@@ -59,6 +60,10 @@ impl HTMLMetaElement {
if name == "viewport" {
self.apply_viewport();
}

if name == "referrer" {
self.apply_referrer();
}
}
}

@@ -85,6 +90,28 @@ impl HTMLMetaElement {
}
}
}

/// https://html.spec.whatwg.org/multipage/#meta-referrer
fn apply_referrer(&self) {
/*todo - I think this chould only run if document's policy hasnt yet
been set. unclear - see:
https://html.spec.whatwg.org/multipage/#meta-referrer
https://w3c.github.io/webappsec-referrer-policy/#set-referrer-policy
*/
let doc = document_from_node(self);
if let Some(head) = doc.GetHead() {
if head.upcast::<Node>().is_parent_of(self.upcast::<Node>()) {
let element = self.upcast::<Element>();
if let Some(content) = element.get_attribute(&ns!(), &atom!("content")).r() {
let content = content.value();
let content_val = content.trim();
if !content_val.is_empty() {
doc.set_referrer_policy(determine_policy_for_token(content_val));
}
}
}
}
}
}

impl HTMLMetaElementMethods for HTMLMetaElement {
@@ -82,7 +82,7 @@ partial /*sealed*/ interface Document {
[/*PutForwards=href, */Unforgeable]
readonly attribute Location? location;
readonly attribute DOMString domain;
// readonly attribute DOMString referrer;
readonly attribute DOMString referrer;
[Throws]
attribute DOMString cookie;
readonly attribute DOMString lastModified;
@@ -148,10 +148,14 @@ pub struct XMLHttpRequest {
fetch_time: Cell<i64>,
generation_id: Cell<GenerationId>,
response_status: Cell<Result<(), ()>>,
referrer_url: Option<Url>,
referrer_policy: Option<ReferrerPolicy>,
}

impl XMLHttpRequest {
fn new_inherited(global: GlobalRef) -> XMLHttpRequest {
//TODO - will this panic (outside of the scope of the ref policy tests)?
let current_doc = global.as_window().Document();
XMLHttpRequest {
eventtarget: XMLHttpRequestEventTarget::new_inherited(),
ready_state: Cell::new(XMLHttpRequestState::Unsent),
@@ -183,6 +187,8 @@ impl XMLHttpRequest {
fetch_time: Cell::new(0),
generation_id: Cell::new(GenerationId(0)),
response_status: Cell::new(Ok(())),
referrer_url: Some(current_doc.url().clone()),
referrer_policy: current_doc.get_referrer_policy(),
}
}
pub fn new(global: GlobalRef) -> Root<XMLHttpRequest> {
@@ -297,10 +303,10 @@ impl XMLHttpRequest {

impl LoadOrigin for XMLHttpRequest {
fn referrer_url(&self) -> Option<Url> {
None
return self.referrer_url.clone();
}
fn referrer_policy(&self) -> Option<ReferrerPolicy> {
None
return self.referrer_policy;
}
fn request_source(&self) -> RequestSource {
if self.sync.get() {
@@ -592,11 +598,12 @@ impl XMLHttpRequestMethods for XMLHttpRequest {

// Step 5
let global = self.global();
//TODO - set referrer_policy/referrer_url in load_data

let mut load_data =
LoadData::new(LoadContext::Browsing,
self.request_url.borrow().clone().unwrap(),
self);

if load_data.url.origin().ne(&global.r().get_url().origin()) {
load_data.credentials_flag = self.WithCredentials();
}
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.