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 referrer policy delivery via noreferrer link relation #12493

Merged
merged 2 commits into from Sep 21, 2016
Merged
Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
The table of contents is too big for display.

Always

Just for now

Next

Bring referrer policy delivery to <a> and <link> via rel attribute

  • Loading branch information
TheKK committed Sep 20, 2016
commit 55a2270e16868addccf62854f9eeafdb7e3016f1
@@ -7,7 +7,7 @@

use dom::bindings::js::JS;
use dom::document::Document;
use msg::constellation_msg::PipelineId;
use msg::constellation_msg::{PipelineId, ReferrerPolicy};
use net_traits::{PendingAsyncLoad, AsyncResponseTarget, LoadContext};
use net_traits::{ResourceThreads, IpcSend};
use std::thread;
@@ -125,24 +125,26 @@ impl DocumentLoader {
/// the future.
pub fn prepare_async_load(&mut self,
load: LoadType,
referrer: &Document) -> PendingAsyncLoad {
referrer: &Document,
referrer_policy: Option<ReferrerPolicy>) -> PendingAsyncLoad {
let context = load.to_load_context();
let url = load.url().clone();
self.add_blocking_load(load);
PendingAsyncLoad::new(context,
self.resource_threads.sender(),
url,
self.pipeline,
referrer.get_referrer_policy(),
referrer_policy.or(referrer.get_referrer_policy()),
Some(referrer.url().clone()))
}

/// Create and initiate a new network request.
pub fn load_async(&mut self,
load: LoadType,
listener: AsyncResponseTarget,
referrer: &Document) {
let pending = self.prepare_async_load(load, referrer);
referrer: &Document,
referrer_policy: Option<ReferrerPolicy>) {
let pending = self.prepare_async_load(load, referrer, referrer_policy);
pending.load_async(listener)
}

@@ -1423,14 +1423,14 @@ impl Document {
loader.add_blocking_load(load)
}

pub fn prepare_async_load(&self, load: LoadType) -> PendingAsyncLoad {
pub fn prepare_async_load(&self, load: LoadType, referrer_policy: Option<ReferrerPolicy>) -> PendingAsyncLoad {
let mut loader = self.loader.borrow_mut();
loader.prepare_async_load(load, self)
loader.prepare_async_load(load, self, referrer_policy)
}

pub fn load_async(&self, load: LoadType, listener: AsyncResponseTarget) {
pub fn load_async(&self, load: LoadType, listener: AsyncResponseTarget, referrer_policy: Option<ReferrerPolicy>) {
let mut loader = self.loader.borrow_mut();
loader.load_async(load, listener, self);
loader.load_async(load, listener, self, referrer_policy);
}

pub fn finish_load(&self, load: LoadType) {
@@ -1726,17 +1726,6 @@ impl Document {
Origin::opaque_identifier()
};

// TODO: we currently default to Some(NoReferrer) instead of None (i.e. unset)
// for an important reason. Many of the methods by which a referrer policy is communicated
// are currently unimplemented, and so in such cases we may be ignoring the desired policy.
// If the default were left unset, then in Step 7 of the Fetch algorithm we adopt
// no-referrer-when-downgrade. However, since we are potentially ignoring a stricter
// referrer policy, this might be passing too much info. Hence, we default to the
// strictest policy, which is no-referrer.
// Once other delivery methods are implemented, make the unset case really
// unset (i.e. None).
let referrer_policy = referrer_policy.or(Some(ReferrerPolicy::NoReferrer));

Document {
node: Node::new_document_node(),
window: JS::from_ref(window),
@@ -5,6 +5,7 @@
use dom::activation::Activatable;
use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::AttrBinding::AttrMethods;
use dom::bindings::codegen::Bindings::DOMTokenListBinding::DOMTokenListMethods;
use dom::bindings::codegen::Bindings::HTMLAnchorElementBinding;
use dom::bindings::codegen::Bindings::HTMLAnchorElementBinding::HTMLAnchorElementMethods;
use dom::bindings::codegen::Bindings::MouseEventBinding::MouseEventMethods;
@@ -23,6 +24,7 @@ use dom::mouseevent::MouseEvent;
use dom::node::{Node, document_from_node, window_from_node};
use dom::urlhelper::UrlHelper;
use dom::virtualmethods::VirtualMethods;
use msg::constellation_msg::ReferrerPolicy;
use num_traits::ToPrimitive;
use script_traits::MozBrowserEvent;
use std::default::Default;
@@ -536,7 +538,14 @@ impl Activatable for HTMLAnchorElement {

// Step 4.
//TODO: Download the link is `download` attribute is set.
follow_hyperlink(element, ismap_suffix);

// https://w3c.github.io/webappsec-referrer-policy/#referrer-policy-delivery
let referrer_policy = match self.RelList().Contains("noreferrer".into()) {
true => Some(ReferrerPolicy::NoReferrer),
false => None,
};

follow_hyperlink(element, ismap_suffix, referrer_policy);
}

//TODO:https://html.spec.whatwg.org/multipage/#the-a-element
@@ -550,7 +559,7 @@ fn is_current_browsing_context(target: DOMString) -> bool {
}

/// https://html.spec.whatwg.org/multipage/#following-hyperlinks-2
fn follow_hyperlink(subject: &Element, hyperlink_suffix: Option<String>) {
fn follow_hyperlink(subject: &Element, hyperlink_suffix: Option<String>, referrer_policy: Option<ReferrerPolicy>) {
// Step 1: replace.
// Step 2: source browsing context.
// Step 3: target browsing context.
@@ -587,6 +596,7 @@ fn follow_hyperlink(subject: &Element, hyperlink_suffix: Option<String>) {
}

debug!("following hyperlink to {}", url);

let window = document.window();
window.load_url(url, false);
window.load_url(url, false, referrer_policy);
}
@@ -6,6 +6,7 @@ use cssparser::Parser as CssParser;
use document_loader::LoadType;
use dom::attr::Attr;
use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::DOMTokenListBinding::DOMTokenListMethods;
use dom::bindings::codegen::Bindings::HTMLLinkElementBinding;
use dom::bindings::codegen::Bindings::HTMLLinkElementBinding::HTMLLinkElementMethods;
use dom::bindings::inheritance::Castable;
@@ -26,6 +27,7 @@ use hyper::mime::{Mime, TopLevel, SubLevel};
use hyper_serde::Serde;
use ipc_channel::ipc;
use ipc_channel::router::ROUTER;
use msg::constellation_msg::ReferrerPolicy;
use net_traits::{AsyncResponseListener, AsyncResponseTarget, Metadata, NetworkError};
use network_listener::{NetworkListener, PreInvoke};
use script_layout_interface::message::Msg;
@@ -239,7 +241,13 @@ impl HTMLLinkElement {
if self.parser_inserted.get() {
document.increment_script_blocking_stylesheet_count();
}
document.load_async(LoadType::Stylesheet(url), response_target);

let referrer_policy = match self.RelList().Contains("noreferrer".into()) {
true => Some(ReferrerPolicy::NoReferrer),
false => None,
};

document.load_async(LoadType::Stylesheet(url), response_target, referrer_policy);
}
Err(e) => debug!("Parsing url {} failed: {}", href, e)
}
@@ -519,7 +519,7 @@ impl HTMLMediaElement {

// FIXME: we're supposed to block the load event much earlier than now
let doc = document_from_node(self);
doc.load_async(LoadType::Media(url), response_target);
doc.load_async(LoadType::Media(url), response_target, None);
} else {
// TODO local resource fetch
self.queue_dedicated_media_source_failure_steps();
@@ -236,7 +236,7 @@ fn fetch_a_classic_script(script: &HTMLScriptElement,
listener.notify_action(message.to().unwrap());
});

doc.load_async(LoadType::Script(url), response_target);
doc.load_async(LoadType::Script(url), response_target, None);
}

impl HTMLScriptElement {
@@ -355,6 +355,7 @@ impl HTMLScriptElement {

// Step 18.6.
fetch_a_classic_script(self, url, encoding);

true
},
None => false,
@@ -40,7 +40,7 @@ impl Location {
setter: fn(&mut Url, USVString)) {
let mut url = self.window.get_url();
setter(&mut url, value);
self.window.load_url(url, false);
self.window.load_url(url, false, None);
}
}

@@ -51,13 +51,13 @@ impl LocationMethods for Location {
// _entry settings object_.
let base_url = self.window.get_url();
if let Ok(url) = base_url.join(&url.0) {
self.window.load_url(url, false);
self.window.load_url(url, false, None);
}
}

// https://html.spec.whatwg.org/multipage/#dom-location-reload
fn Reload(&self) {
self.window.load_url(self.get_url(), true);
self.window.load_url(self.get_url(), true, None);
}

// https://html.spec.whatwg.org/multipage/#dom-location-hash
@@ -106,7 +106,7 @@ impl LocationMethods for Location {
// https://html.spec.whatwg.org/multipage/#dom-location-href
fn SetHref(&self, value: USVString) {
if let Ok(url) = self.window.get_url().join(&value.0) {
self.window.load_url(url, false);
self.window.load_url(url, false, None);
}
}

@@ -51,7 +51,7 @@ use js::jsval::UndefinedValue;
use js::rust::CompileOptionsWrapper;
use js::rust::Runtime;
use libc;
use msg::constellation_msg::{FrameType, LoadData, PipelineId, WindowSizeType};
use msg::constellation_msg::{FrameType, LoadData, PipelineId, ReferrerPolicy, WindowSizeType};
use net_traits::ResourceThreads;
use net_traits::bluetooth_thread::BluetoothMethodMsg;
use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheThread};
@@ -1410,11 +1410,13 @@ impl Window {
}

/// Commence a new URL load which will either replace this window or scroll to a fragment.
pub fn load_url(&self, url: Url, replace: bool) {
pub fn load_url(&self, url: Url, replace: bool, referrer_policy: Option<ReferrerPolicy>) {
let doc = self.Document();
let referrer_policy = referrer_policy.or(doc.get_referrer_policy());

self.main_thread_script_chan().send(
MainThreadScriptMsg::Navigate(self.id,
LoadData::new(url, doc.get_referrer_policy(), Some(doc.url().clone())),
LoadData::new(url, referrer_policy, Some(doc.url().clone())),
replace)).unwrap();
}

ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.