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

Add referrer to navigation fetch request #23090

Merged
merged 2 commits into from Apr 26, 2019
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -12,7 +12,7 @@ use ipc_channel::ipc;
use ipc_channel::router::ROUTER;
use msg::constellation_msg::PipelineId;
use net::http_loader::{set_default_accept, set_default_accept_language};
use net_traits::request::{Destination, RequestBuilder};
use net_traits::request::{Destination, Referrer, RequestBuilder};
use net_traits::response::ResponseInit;
use net_traits::{CoreResourceMsg, FetchChannels, FetchMetadata, FetchResponseMsg};
use net_traits::{IpcSend, NetworkError, ResourceThreads};
@@ -109,7 +109,10 @@ impl NetworkListener {
.url_list
.push(metadata.final_url.clone());

self.request_builder.referrer_url = metadata.referrer.clone();
self.request_builder.referrer = metadata
.referrer
.clone()
.map(|referrer_url| Referrer::ReferrerUrl(referrer_url));
self.request_builder.referrer_policy = metadata.referrer_policy;

self.res_init = Some(ResponseInit {
@@ -783,21 +783,27 @@ fn http_network_or_cache_fetch(
done_chan: &mut DoneChannel,
context: &FetchContext,
) -> Response {
// Step 2
let mut response: Option<Response> = None;

// Step 4
let mut revalidating_flag = false;

// TODO: Implement Window enum for Request
let request_has_no_window = true;

// Step 2
// Step 5.1
let mut http_request;
let http_request = if request_has_no_window && request.redirect_mode == RedirectMode::Error {
request
} else {
// Step 3
// Step 5.2
// TODO Implement body source
http_request = request.clone();
&mut http_request
};

// Step 4
// Step 5.3
let credentials_flag = match http_request.credentials_mode {
CredentialsMode::Include => true,
CredentialsMode::CredentialsSameOrigin
@@ -810,26 +816,26 @@ fn http_network_or_cache_fetch(

let content_length_value = match http_request.body {
None => match http_request.method {
// Step 6
// Step 5.5
Method::POST | Method::PUT => Some(0),
// Step 5
// Step 5.4
_ => None,
},
// Step 7
// Step 5.6
Some(ref http_request_body) => Some(http_request_body.len() as u64),
};

// Step 8
// Step 5.7
if let Some(content_length_value) = content_length_value {
http_request
.headers
.typed_insert(ContentLength(content_length_value));
if http_request.keep_alive {
// Step 9 TODO: needs request's client object
// Step 5.8 TODO: needs request's client object
}
}

// Step 10
// Step 5.9
match http_request.referrer {
Referrer::NoReferrer => (),
Referrer::ReferrerUrl(ref http_request_referrer) => http_request
@@ -843,7 +849,7 @@ fn http_network_or_cache_fetch(
},
};

// Step 11
// Step 5.10
if cors_flag || (http_request.method != Method::GET && http_request.method != Method::HEAD) {
debug_assert_ne!(http_request.origin, Origin::Client);
if let Origin::Origin(ref url_origin) = http_request.origin {
@@ -853,7 +859,7 @@ fn http_network_or_cache_fetch(
}
}

// Step 12
// Step 5.11
if !http_request.headers.contains_key(header::USER_AGENT) {
let user_agent = context.user_agent.clone().into_owned();
http_request
@@ -862,19 +868,19 @@ fn http_network_or_cache_fetch(
}

match http_request.cache_mode {
// Step 13
// Step 5.12
CacheMode::Default if is_no_store_cache(&http_request.headers) => {
http_request.cache_mode = CacheMode::NoStore;
},

// Step 14
// Step 5.13
CacheMode::NoCache if !http_request.headers.contains_key(header::CACHE_CONTROL) => {
http_request
.headers
.typed_insert(CacheControl::new().with_max_age(Duration::from_secs(0)));
},

// Step 15
// Step 5.14
CacheMode::Reload | CacheMode::NoStore => {
// Substep 1
if !http_request.headers.contains_key(header::PRAGMA) {
@@ -892,7 +898,10 @@ fn http_network_or_cache_fetch(
_ => {},
}

// Step 16
// Step 5.15
// TODO: if necessary append `Accept-Encoding`/`identity` to headers

// Step 5.16
let current_url = http_request.current_url();
let host = Host::from(
format!(
@@ -912,7 +921,7 @@ fn http_network_or_cache_fetch(
// here, according to the fetch spec
set_default_accept_encoding(&mut http_request.headers);

// Step 17
// Step 5.17
// TODO some of this step can't be implemented yet
if credentials_flag {
// Substep 1
@@ -952,16 +961,10 @@ fn http_network_or_cache_fetch(
}
}

// Step 18
// Step 5.18
// TODO If there’s a proxy-authentication entry, use it as appropriate.

// Step 19
let mut response: Option<Response> = None;

// Step 20
let mut revalidating_flag = false;

// Step 21
// Step 5.19
if let Ok(http_cache) = context.state.http_cache.read() {
if let Some(response_from_cache) = http_cache.construct_response(&http_request, done_chan) {
let response_headers = response_from_cache.response.headers.clone();
@@ -1029,7 +1032,10 @@ fn http_network_or_cache_fetch(

wait_for_cached_response(done_chan, &mut response);

// Step 22
// Step 6
// TODO: https://infra.spec.whatwg.org/#if-aborted

// Step 7
if response.is_none() {
// Substep 1
if http_request.cache_mode == CacheMode::OnlyIfCached {
@@ -1038,7 +1044,7 @@ fn http_network_or_cache_fetch(
));
}
}
// More Step 22
// More Step 7
if response.is_none() {
// Substep 2
let forward_response =
@@ -1079,7 +1085,13 @@ fn http_network_or_cache_fetch(

let mut response = response.unwrap();

// Step 23
// Step 8
// TODO: if necessary set response's range-requested flag

// Step 9
// TODO: handle CORS not set and cross-origin blocked

// Step 10
// FIXME: Figure out what to do with request window objects
if let (Some((StatusCode::UNAUTHORIZED, _)), false, true) =
(response.status.as_ref(), cors_flag, credentials_flag)
@@ -1112,7 +1124,7 @@ fn http_network_or_cache_fetch(
);
}

// Step 24
// Step 11
if let Some((StatusCode::PROXY_AUTHENTICATION_REQUIRED, _)) = response.status.as_ref() {
// Step 1
if request_has_no_window {
@@ -1137,12 +1149,12 @@ fn http_network_or_cache_fetch(
// cors_flag, done_chan, context);
}

// Step 25
// Step 12
if authentication_fetch_flag {
// TODO Create the authentication entry for request and the given realm
}

// Step 26
// Step 13
response
}

@@ -162,7 +162,7 @@ pub struct RequestBuilder {
pub use_url_credentials: bool,
pub origin: ImmutableOrigin,
// XXXManishearth these should be part of the client object
pub referrer_url: Option<ServoUrl>,
pub referrer: Option<Referrer>,
pub referrer_policy: Option<ReferrerPolicy>,
pub pipeline_id: Option<PipelineId>,
pub redirect_mode: RedirectMode,
@@ -188,7 +188,7 @@ impl RequestBuilder {
credentials_mode: CredentialsMode::Omit,
use_url_credentials: false,
origin: ImmutableOrigin::new_opaque(),
referrer_url: None,
referrer: None,
referrer_policy: None,
pipeline_id: None,
redirect_mode: RedirectMode::Follow,
@@ -265,8 +265,8 @@ impl RequestBuilder {
self
}

pub fn referrer_url(mut self, referrer_url: Option<ServoUrl>) -> RequestBuilder {
self.referrer_url = referrer_url;
pub fn referrer(mut self, referrer: Option<Referrer>) -> RequestBuilder {
self.referrer = referrer;
self
}

@@ -313,11 +313,7 @@ impl RequestBuilder {
request.credentials_mode = self.credentials_mode;
request.use_url_credentials = self.use_url_credentials;
request.cache_mode = self.cache_mode;
request.referrer = if let Some(url) = self.referrer_url {
Referrer::ReferrerUrl(url)
} else {
Referrer::NoReferrer
};
request.referrer = self.referrer.unwrap_or(Referrer::Client);
request.referrer_policy = self.referrer_policy;
request.redirect_mode = self.redirect_mode;
let mut url_list = self.url_list;
@@ -36,7 +36,7 @@ use js::jsapi::{JSAutoCompartment, JSContext};
use js::jsval::UndefinedValue;
use js::rust::HandleValue;
use msg::constellation_msg::{PipelineId, TopLevelBrowsingContextId};
use net_traits::request::{CredentialsMode, Destination, RequestBuilder};
use net_traits::request::{CredentialsMode, Destination, Referrer, RequestBuilder};
use net_traits::{load_whole_resource, IpcSend};
use script_traits::{TimerEvent, TimerSource, WorkerGlobalScopeInit, WorkerScriptLoadOrigin};
use servo_rand::random;
@@ -305,12 +305,14 @@ impl DedicatedWorkerGlobalScope {
pipeline_id,
} = worker_load_origin;

let referrer = referrer_url.map(|referrer_url| Referrer::ReferrerUrl(referrer_url));

let request = RequestBuilder::new(worker_url.clone())
.destination(Destination::Worker)
.credentials_mode(CredentialsMode::Include)
.use_url_credentials(true)
.pipeline_id(pipeline_id)
.referrer_url(referrer_url)
.referrer(referrer)
.referrer_policy(referrer_policy)
.origin(origin);

@@ -27,6 +27,7 @@ use crate::dom::urlhelper::UrlHelper;
use crate::dom::virtualmethods::VirtualMethods;
use dom_struct::dom_struct;
use html5ever::{LocalName, Prefix};
use net_traits::request::Referrer;
use num_traits::ToPrimitive;
use servo_url::ServoUrl;
use std::default::Default;
@@ -639,7 +640,7 @@ pub fn follow_hyperlink(subject: &Element, hyperlink_suffix: Option<String>) {
// will have been done as part of Step 7 above
// in choose_browsing_context/create_auxiliary_browsing_context.

// Step 10, 11, 12, 13. TODO: if parsing the URL failed, navigate to error page.
// Step 10, 11. TODO: if parsing the URL failed, navigate to error page.
let attribute = subject.get_attribute(&ns!(), &local_name!("href")).unwrap();
let mut href = attribute.Value();
// Step 11: append a hyperlink suffix.
@@ -657,8 +658,16 @@ pub fn follow_hyperlink(subject: &Element, hyperlink_suffix: Option<String>) {
.get_attribute_by_name(DOMString::from_string(String::from("referrerpolicy")))
.and_then(|attribute: DomRoot<Attr>| (determine_policy_for_token(&attribute.Value())));

// Step 13, 14.
// Step 13
let referrer = match subject.get_attribute(&ns!(), &local_name!("rel")) {
Some(ref link_types) if link_types.Value().contains("noreferrer") => {
Referrer::NoReferrer
},
_ => Referrer::Client,
};

// Step 14
debug!("following hyperlink to {}", url);
target_window.load_url(url, replace, false, referrer_policy);
target_window.load_url(url, replace, false, referrer, referrer_policy);
};
}
@@ -55,6 +55,7 @@ use html5ever::{LocalName, Prefix};
use hyper::Method;
use mime::{self, Mime};
use net_traits::http_percent_encode;
use net_traits::request::Referrer;
use script_traits::LoadData;
use servo_rand::random;
use std::borrow::ToOwned;
@@ -400,8 +401,8 @@ impl HTMLFormElement {
let mut load_data = LoadData::new(
action_components,
None,
Some(Referrer::ReferrerUrl(target_document.url())),
target_document.get_referrer_policy(),
Some(target_document.url()),
);

// Step 22
@@ -30,6 +30,7 @@ use euclid::TypedSize2D;
use html5ever::{LocalName, Prefix};
use ipc_channel::ipc;
use msg::constellation_msg::{BrowsingContextId, PipelineId, TopLevelBrowsingContextId};
use net_traits::request::Referrer;
use profile_traits::ipc as ProfiledIpc;
use script_layout_interface::message::ReflowGoal;
use script_traits::IFrameSandboxState::{IFrameSandboxed, IFrameUnsandboxed};
@@ -269,8 +270,8 @@ impl HTMLIFrameElement {
let load_data = LoadData::new(
url,
creator_pipeline_id,
Some(Referrer::ReferrerUrl(document.url())),
document.get_referrer_policy(),
Some(document.url()),
);

let pipeline_id = self.pipeline_id();
@@ -295,8 +296,8 @@ impl HTMLIFrameElement {
let load_data = LoadData::new(
url,
pipeline_id,
Some(Referrer::ReferrerUrl(document.url().clone())),
document.get_referrer_policy(),
Some(document.url().clone()),
);
let browsing_context_id = BrowsingContextId::new();
let top_level_browsing_context_id = window.window_proxy().top_level_browsing_context_id();
@@ -64,7 +64,7 @@ use ipc_channel::router::ROUTER;
use mime::{self, Mime};
use net_traits::image::base::Image;
use net_traits::image_cache::ImageResponse;
use net_traits::request::{CredentialsMode, Destination, RequestBuilder};
use net_traits::request::{CredentialsMode, Destination, Referrer, RequestBuilder};
use net_traits::{CoreResourceMsg, FetchChannels, FetchMetadata, FetchResponseListener, Metadata};
use net_traits::{NetworkError, ResourceFetchTiming, ResourceTimingType};
use script_layout_interface::HTMLMediaData;
@@ -720,7 +720,7 @@ impl HTMLMediaElement {
.use_url_credentials(true)
.origin(document.origin().immutable().clone())
.pipeline_id(Some(self.global().pipeline_id()))
.referrer_url(Some(document.url()))
.referrer(Some(Referrer::ReferrerUrl(document.url())))
.referrer_policy(document.get_referrer_policy());

let mut current_fetch_context = self.current_fetch_context.borrow_mut();
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.