diff --git a/components/constellation/constellation.rs b/components/constellation/constellation.rs index 2ded8ee5925..ffe135e0355 100644 --- a/components/constellation/constellation.rs +++ b/components/constellation/constellation.rs @@ -131,7 +131,7 @@ use media::{GLPlayerThreads, WindowGLContext}; use net_traits::pub_domains::reg_host; use net_traits::request::{Referrer, RequestBuilder}; use net_traits::storage_thread::{StorageThreadMsg, StorageType}; -use net_traits::{self, FetchResponseMsg, IpcSend, ResourceThreads}; +use net_traits::{self, FetchResponseMsg, IpcSend, ReferrerPolicy, ResourceThreads}; use profile_traits::{mem, time}; use script_layout_interface::{LayoutFactory, ScriptThreadFactory}; use script_traits::CompositorEvent::{MouseButtonEvent, MouseMoveEvent}; @@ -1413,7 +1413,7 @@ where url, None, Referrer::NoReferrer, - None, + ReferrerPolicy::EmptyString, None, ); let ctx_id = BrowsingContextId::from(top_level_browsing_context_id); @@ -3033,7 +3033,7 @@ where url, None, Referrer::NoReferrer, - None, + ReferrerPolicy::EmptyString, None, ); let sandbox = IFrameSandboxState::IFrameUnsandboxed; diff --git a/components/net/fetch/methods.rs b/components/net/fetch/methods.rs index 2e99f5f3314..f7934fc6b41 100644 --- a/components/net/fetch/methods.rs +++ b/components/net/fetch/methods.rs @@ -28,8 +28,8 @@ use net_traits::request::{ }; use net_traits::response::{Response, ResponseBody, ResponseType}; use net_traits::{ - FetchTaskTarget, NetworkError, ResourceAttribute, ResourceFetchTiming, ResourceTimeValue, - ResourceTimingType, + FetchTaskTarget, NetworkError, ReferrerPolicy, ResourceAttribute, ResourceFetchTiming, + ResourceTimeValue, ResourceTimingType, }; use rustls::Certificate; use serde::{Deserialize, Serialize}; @@ -278,18 +278,16 @@ pub async fn main_fetch( // Step 8: If request’s referrer policy is the empty string, then set request’s referrer policy // to request’s policy container’s referrer policy. - request.referrer_policy = request - .referrer_policy - .or(Some(policy_container.referrer_policy)); - - assert!(request.referrer_policy.is_some()); + if request.referrer_policy == ReferrerPolicy::EmptyString { + request.referrer_policy = policy_container.get_referrer_policy(); + } let referrer_url = match mem::replace(&mut request.referrer, Referrer::NoReferrer) { Referrer::NoReferrer => None, Referrer::ReferrerUrl(referrer_source) | Referrer::Client(referrer_source) => { request.headers.remove(header::REFERER); determine_requests_referrer( - request.referrer_policy.unwrap(), + request.referrer_policy, referrer_source, request.current_url(), ) diff --git a/components/net/http_loader.rs b/components/net/http_loader.rs index 2ebf2bdc738..ad74820012f 100644 --- a/components/net/http_loader.rs +++ b/components/net/http_loader.rs @@ -313,7 +313,7 @@ pub fn determine_requests_referrer( current_url: ServoUrl, ) -> Option { match referrer_policy { - ReferrerPolicy::NoReferrer => None, + ReferrerPolicy::EmptyString | ReferrerPolicy::NoReferrer => None, ReferrerPolicy::Origin => strip_url_for_use_as_referrer(referrer_source, true), ReferrerPolicy::UnsafeUrl => strip_url_for_use_as_referrer(referrer_source, false), ReferrerPolicy::StrictOrigin => strict_origin(referrer_source, current_url), @@ -831,7 +831,9 @@ pub async fn http_fetch( // response is guaranteed to be something by now let mut response = response.unwrap(); - // Step 5 + // TODO: Step 5: cross-origin resource policy check + + // Step 6 if response .actual_response() .status @@ -986,12 +988,12 @@ pub async fn http_redirect_fetch( ResourceTimeValue::RedirectStart, )); // updates start_time only if redirect_start is nonzero (implying TAO) - // Step 5 + // Step 7: If request’s redirect count is 20, then return a network error. if request.redirect_count >= 20 { return Response::network_error(NetworkError::Internal("Too many redirects".into())); } - // Step 6 + // Step 8: Increase request’s redirect count by 1. request.redirect_count += 1; // Step 7 @@ -1002,6 +1004,7 @@ pub async fn http_redirect_fetch( request.current_url() ), }; + let has_credentials = has_credentials(&location_url); if request.mode == RequestMode::CorsMode && !same_origin && has_credentials { @@ -1010,24 +1013,25 @@ pub async fn http_redirect_fetch( )); } - // Step 8 + // Step 9 + if cors_flag && location_url.origin() != request.current_url().origin() { + request.origin = Origin::Origin(ImmutableOrigin::new_opaque()); + } + + // Step 10 if cors_flag && has_credentials { return Response::network_error(NetworkError::Internal("Credentials check failed".into())); } - // Step 9 + // Step 11: If internalResponse’s status is not 303, request’s body is non-null, and request’s + // body’s source is null, then return a network error. if response.actual_response().status != StatusCode::SEE_OTHER && request.body.as_ref().is_some_and(|b| b.source_is_null()) { return Response::network_error(NetworkError::Internal("Request body is not done".into())); } - // Step 10 - if cors_flag && location_url.origin() != request.current_url().origin() { - request.origin = Origin::Origin(ImmutableOrigin::new_opaque()); - } - - // Step 11 + // Step 12 if response .actual_response() .status @@ -1040,10 +1044,10 @@ pub async fn http_redirect_fetch( request.method != Method::GET) }) { - // Step 11.1 + // Step 12.1 request.method = Method::GET; request.body = None; - // Step 11.2 + // Step 12.2 for name in &[ CONTENT_ENCODING, CONTENT_LANGUAGE, @@ -1075,13 +1079,7 @@ pub async fn http_redirect_fetch( request.url_list.push(location_url); // Step 19: Invoke set request’s referrer policy on redirect on request and internalResponse. - if let Some(referrer_policy) = response - .actual_response() - .headers - .typed_get::() - { - request.referrer_policy = Some(referrer_policy.into()); - } + set_requests_referrer_policy_on_redirect(request, response.actual_response()); // Step 20: Let recursive be true. // Step 21: If request’s redirect mode is "manual", then... @@ -2364,15 +2362,13 @@ fn append_a_request_origin_header(request: &mut Request) { // Step 4.1 If request’s mode is not "cors", then switch on request’s referrer policy: if request.mode != RequestMode::CorsMode { match request.referrer_policy { - Some(ReferrerPolicy::NoReferrer) => { + ReferrerPolicy::NoReferrer => { // Set serializedOrigin to `null`. serialized_origin = headers::Origin::NULL; }, - Some( - ReferrerPolicy::NoReferrerWhenDowngrade | - ReferrerPolicy::StrictOrigin | - ReferrerPolicy::StrictOriginWhenCrossOrigin, - ) => { + ReferrerPolicy::NoReferrerWhenDowngrade | + ReferrerPolicy::StrictOrigin | + ReferrerPolicy::StrictOriginWhenCrossOrigin => { // If request’s origin is a tuple origin, its scheme is "https", and // request’s current URL’s scheme is not "https", then set serializedOrigin to `null`. if let ImmutableOrigin::Tuple(scheme, _, _) = &request_origin { @@ -2381,7 +2377,7 @@ fn append_a_request_origin_header(request: &mut Request) { } } }, - Some(ReferrerPolicy::SameOrigin) => { + ReferrerPolicy::SameOrigin => { // If request’s origin is not same origin with request’s current URL’s origin, // then set serializedOrigin to `null`. if *request_origin != request.current_url().origin() { @@ -2507,3 +2503,18 @@ fn set_the_sec_fetch_user_header(r: &mut Request) { // Step 5. Set a structured field value `Sec-Fetch-User`/header in r’s header list. r.headers.typed_insert(header); } + +/// +fn set_requests_referrer_policy_on_redirect(request: &mut Request, response: &Response) { + // Step 1: Let policy be the result of executing § 8.1 Parse a referrer policy from a + // Referrer-Policy header on actualResponse. + let referrer_policy: ReferrerPolicy = response + .headers + .typed_get::() + .into(); + + // Step 2: If policy is not the empty string, then set request’s referrer policy to policy. + if referrer_policy != ReferrerPolicy::EmptyString { + request.referrer_policy = referrer_policy; + } +} diff --git a/components/net/tests/fetch.rs b/components/net/tests/fetch.rs index 81321770a4e..796015941b2 100644 --- a/components/net/tests/fetch.rs +++ b/components/net/tests/fetch.rs @@ -322,7 +322,7 @@ fn test_cors_preflight_fetch() { let target_url = url.clone().join("a.html").unwrap(); let mut request = RequestBuilder::new(url, Referrer::ReferrerUrl(target_url)).build(); - request.referrer_policy = Some(ReferrerPolicy::Origin); + request.referrer_policy = ReferrerPolicy::Origin; request.use_cors_preflight = true; request.mode = RequestMode::CorsMode; let fetch_response = fetch(&mut request, None); diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 29b7b73d5b3..5baa48c4e33 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -371,9 +371,6 @@ pub struct Document { /// The document's origin. #[no_trace] origin: MutableOrigin, - /// - #[no_trace] - referrer_policy: Cell>, /// referrer: Option, /// @@ -3295,7 +3292,6 @@ impl Document { source: DocumentSource, doc_loader: DocumentLoader, referrer: Option, - referrer_policy: Option, status_code: Option, canceller: FetchCanceller, ) -> Document { @@ -3401,7 +3397,6 @@ impl Document { https_state: Cell::new(HttpsState::None), origin, referrer, - referrer_policy: Cell::new(referrer_policy), target_element: MutNullableDom::new(None), policy_container: DomRefCell::new(PolicyContainer::default()), last_click_info: DomRefCell::new(None), @@ -3580,7 +3575,6 @@ impl Document { source: DocumentSource, doc_loader: DocumentLoader, referrer: Option, - referrer_policy: Option, status_code: Option, canceller: FetchCanceller, can_gc: CanGc, @@ -3598,7 +3592,6 @@ impl Document { source, doc_loader, referrer, - referrer_policy, status_code, canceller, can_gc, @@ -3619,7 +3612,6 @@ impl Document { source: DocumentSource, doc_loader: DocumentLoader, referrer: Option, - referrer_policy: Option, status_code: Option, canceller: FetchCanceller, can_gc: CanGc, @@ -3637,7 +3629,6 @@ impl Document { source, doc_loader, referrer, - referrer_policy, status_code, canceller, )), @@ -3762,7 +3753,6 @@ impl Document { DocumentLoader::new(&self.loader()), None, None, - None, Default::default(), can_gc, ); @@ -3847,13 +3837,14 @@ impl Document { } } - pub fn set_referrer_policy(&self, policy: Option) { - self.referrer_policy.set(policy); + pub fn set_referrer_policy(&self, policy: ReferrerPolicy) { + self.policy_container + .borrow_mut() + .set_referrer_policy(policy); } - //TODO - default still at no-referrer - pub fn get_referrer_policy(&self) -> Option { - self.referrer_policy.get() + pub fn get_referrer_policy(&self) -> ReferrerPolicy { + self.policy_container.borrow().get_referrer_policy() } pub fn set_target_element(&self, node: Option<&Element>, can_gc: CanGc) { @@ -4301,7 +4292,6 @@ impl DocumentMethods for Document { docloader, None, None, - None, Default::default(), can_gc, )) @@ -5621,18 +5611,17 @@ fn update_with_current_instant(marker: &Cell>) { } /// -pub fn determine_policy_for_token(token: &str) -> Option { +pub fn determine_policy_for_token(token: &str) -> ReferrerPolicy { match_ignore_ascii_case! { token, - "never" | "no-referrer" => Some(ReferrerPolicy::NoReferrer), - "no-referrer-when-downgrade" => Some(ReferrerPolicy::NoReferrerWhenDowngrade), - "origin" => Some(ReferrerPolicy::Origin), - "same-origin" => Some(ReferrerPolicy::SameOrigin), - "strict-origin" => Some(ReferrerPolicy::StrictOrigin), - "default" | "strict-origin-when-cross-origin" => Some(ReferrerPolicy::StrictOriginWhenCrossOrigin), - "origin-when-cross-origin" => Some(ReferrerPolicy::OriginWhenCrossOrigin), - "always" | "unsafe-url" => Some(ReferrerPolicy::UnsafeUrl), - "" => Some(ReferrerPolicy::default()), - _ => None, + "never" | "no-referrer" => ReferrerPolicy::NoReferrer, + "no-referrer-when-downgrade" => ReferrerPolicy::NoReferrerWhenDowngrade, + "origin" => ReferrerPolicy::Origin, + "same-origin" => ReferrerPolicy::SameOrigin, + "strict-origin" => ReferrerPolicy::StrictOrigin, + "default" | "strict-origin-when-cross-origin" => ReferrerPolicy::StrictOriginWhenCrossOrigin, + "origin-when-cross-origin" => ReferrerPolicy::OriginWhenCrossOrigin, + "always" | "unsafe-url" => ReferrerPolicy::UnsafeUrl, + _ => ReferrerPolicy::EmptyString, } } diff --git a/components/script/dom/domimplementation.rs b/components/script/dom/domimplementation.rs index 7a75fce1ae4..13b9d14ffe6 100644 --- a/components/script/dom/domimplementation.rs +++ b/components/script/dom/domimplementation.rs @@ -159,7 +159,6 @@ impl DOMImplementationMethods for DOMImplementation { loader, None, None, - None, Default::default(), can_gc, ); diff --git a/components/script/dom/domparser.rs b/components/script/dom/domparser.rs index aeeb4f0488c..c40ed43fd7e 100644 --- a/components/script/dom/domparser.rs +++ b/components/script/dom/domparser.rs @@ -86,7 +86,6 @@ impl DOMParserMethods for DOMParser { loader, None, None, - None, Default::default(), can_gc, ); @@ -108,7 +107,6 @@ impl DOMParserMethods for DOMParser { loader, None, None, - None, Default::default(), can_gc, ); diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index b26917c4028..251f088c6ed 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -4539,11 +4539,11 @@ pub fn reflect_referrer_policy_attribute(element: &Element) -> DOMString { DOMString::new() } -pub(crate) fn referrer_policy_for_element(element: &Element) -> Option { +pub(crate) fn referrer_policy_for_element(element: &Element) -> ReferrerPolicy { element .get_attribute_by_name(DOMString::from_string(String::from("referrerpolicy"))) - .and_then(|attribute: DomRoot| determine_policy_for_token(&attribute.Value())) - .or_else(|| document_from_node(element).get_referrer_policy()) + .map(|attribute: DomRoot| determine_policy_for_token(&attribute.Value())) + .unwrap_or(document_from_node(element).get_referrer_policy()) } pub(crate) fn cors_setting_for_element(element: &Element) -> Option { diff --git a/components/script/dom/globalscope.rs b/components/script/dom/globalscope.rs index ac6a2b07b1e..70ace0ba1e7 100644 --- a/components/script/dom/globalscope.rs +++ b/components/script/dom/globalscope.rs @@ -2426,7 +2426,7 @@ impl GlobalScope { } /// Get the Referrer Policy for this global scope. - pub fn get_referrer_policy(&self) -> Option { + pub fn get_referrer_policy(&self) -> ReferrerPolicy { if let Some(window) = self.downcast::() { let document = window.Document(); @@ -2435,7 +2435,7 @@ impl GlobalScope { if let Some(worker) = self.downcast::() { let policy_container = worker.policy_container().to_owned(); - return Some(policy_container.referrer_policy); + return policy_container.get_referrer_policy(); } unreachable!(); } diff --git a/components/script/dom/htmlimageelement.rs b/components/script/dom/htmlimageelement.rs index b8cb5d15f62..61f4400a554 100644 --- a/components/script/dom/htmlimageelement.rs +++ b/components/script/dom/htmlimageelement.rs @@ -336,7 +336,7 @@ pub(crate) fn image_fetch_request( referrer: Referrer, pipeline_id: PipelineId, cors_setting: Option, - referrer_policy: Option, + referrer_policy: ReferrerPolicy, from_picture_or_srcset: FromPictureOrSrcSet, ) -> RequestBuilder { let mut request = @@ -1523,12 +1523,13 @@ fn get_correct_referrerpolicy_from_raw_token(token: &DOMString) -> DOMString { // so it should remain unchanged. DOMString::new() } else { - match determine_policy_for_token(token) { - Some(policy) => DOMString::from_string(policy.to_string()), - // If the policy is set to an incorrect value, then it should be - // treated as an invalid value default (empty string). - None => DOMString::new(), + let policy = determine_policy_for_token(token); + + if policy == ReferrerPolicy::EmptyString { + return DOMString::new(); } + + DOMString::from_string(policy.to_string()) } } diff --git a/components/script/dom/htmllinkelement.rs b/components/script/dom/htmllinkelement.rs index b709a1cc203..140471071a8 100644 --- a/components/script/dom/htmllinkelement.rs +++ b/components/script/dom/htmllinkelement.rs @@ -76,7 +76,7 @@ struct LinkProcessingOptions { integrity: String, link_type: String, cross_origin: Option, - referrer_policy: Option, + referrer_policy: ReferrerPolicy, policy_container: PolicyContainer, source_set: Option<()>, base_url: ServoUrl, @@ -502,12 +502,12 @@ impl StylesheetOwner for HTMLLinkElement { self.parser_inserted.get() } - fn referrer_policy(&self) -> Option { + fn referrer_policy(&self) -> ReferrerPolicy { if self.RelList().Contains("noreferrer".into()) { - return Some(ReferrerPolicy::NoReferrer); + return ReferrerPolicy::NoReferrer; } - None + ReferrerPolicy::EmptyString } fn set_origin_clean(&self, origin_clean: bool) { diff --git a/components/script/dom/htmlstyleelement.rs b/components/script/dom/htmlstyleelement.rs index 9639d80546a..5f93eba9044 100644 --- a/components/script/dom/htmlstyleelement.rs +++ b/components/script/dom/htmlstyleelement.rs @@ -266,8 +266,8 @@ impl StylesheetOwner for HTMLStyleElement { self.parser_inserted.get() } - fn referrer_policy(&self) -> Option { - None + fn referrer_policy(&self) -> ReferrerPolicy { + ReferrerPolicy::EmptyString } fn set_origin_clean(&self, origin_clean: bool) { diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index 4d3037dd55e..3267204fda4 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -2305,7 +2305,6 @@ impl Node { DocumentSource::NotFromParser, loader, None, - None, document.status_code(), Default::default(), can_gc, diff --git a/components/script/dom/request.rs b/components/script/dom/request.rs index 2c6fb480c86..e205f3b3342 100644 --- a/components/script/dom/request.rs +++ b/components/script/dom/request.rs @@ -267,7 +267,7 @@ impl RequestMethods for Request { // Step 13.4 request.referrer = global.get_referrer(); // Step 13.5 - request.referrer_policy = None; + request.referrer_policy = MsgReferrerPolicy::EmptyString; } // Step 14 @@ -303,7 +303,7 @@ impl RequestMethods for Request { // Step 15 if let Some(init_referrerpolicy) = init.referrerPolicy.as_ref() { let init_referrer_policy = (*init_referrerpolicy).into(); - request.referrer_policy = Some(init_referrer_policy); + request.referrer_policy = init_referrer_policy; } // Step 16 @@ -564,11 +564,7 @@ impl RequestMethods for Request { // https://fetch.spec.whatwg.org/#dom-request-referrerpolicy fn ReferrerPolicy(&self) -> ReferrerPolicy { - self.request - .borrow() - .referrer_policy - .map(|m| m.into()) - .unwrap_or(ReferrerPolicy::_empty) + self.request.borrow().referrer_policy.into() } // https://fetch.spec.whatwg.org/#dom-request-mode @@ -825,6 +821,7 @@ impl From for MsgReferrerPolicy { impl From for ReferrerPolicy { fn from(policy: MsgReferrerPolicy) -> Self { match policy { + MsgReferrerPolicy::EmptyString => ReferrerPolicy::_empty, MsgReferrerPolicy::NoReferrer => ReferrerPolicy::No_referrer, MsgReferrerPolicy::NoReferrerWhenDowngrade => { ReferrerPolicy::No_referrer_when_downgrade diff --git a/components/script/dom/servoparser/mod.rs b/components/script/dom/servoparser/mod.rs index 852575b4de7..aa181a3e074 100644 --- a/components/script/dom/servoparser/mod.rs +++ b/components/script/dom/servoparser/mod.rs @@ -215,7 +215,6 @@ impl ServoParser { loader, None, None, - None, Default::default(), can_gc, ); diff --git a/components/script/dom/servoparser/prefetch.rs b/components/script/dom/servoparser/prefetch.rs index a96872590a3..750af5c5f48 100644 --- a/components/script/dom/servoparser/prefetch.rs +++ b/components/script/dom/servoparser/prefetch.rs @@ -76,7 +76,7 @@ struct PrefetchSink { #[no_trace] referrer: Referrer, #[no_trace] - referrer_policy: Option, + referrer_policy: ReferrerPolicy, #[no_trace] resource_threads: ResourceThreads, prefetching: Cell, @@ -203,10 +203,10 @@ impl PrefetchSink { ServoUrl::parse_with_base(Some(base), &attr.value).ok() } - fn get_referrer_policy(&self, tag: &Tag, name: LocalName) -> Option { + fn get_referrer_policy(&self, tag: &Tag, name: LocalName) -> ReferrerPolicy { self.get_attr(tag, name) - .and_then(|attr| determine_policy_for_token(&attr.value)) - .or(self.referrer_policy) + .map(|attr| determine_policy_for_token(&attr.value)) + .unwrap_or(self.referrer_policy) } fn get_cors_settings(&self, tag: &Tag, name: LocalName) -> Option { diff --git a/components/script/dom/workerglobalscope.rs b/components/script/dom/workerglobalscope.rs index 258d58e6cf6..f441f4265c6 100644 --- a/components/script/dom/workerglobalscope.rs +++ b/components/script/dom/workerglobalscope.rs @@ -277,8 +277,7 @@ impl WorkerGlobalScopeMethods for WorkerGlobalScope { .parser_metadata(ParserMetadata::NotParserInserted) .use_url_credentials(true) .origin(global_scope.origin().immutable().clone()) - .pipeline_id(Some(self.upcast::().pipeline_id())) - .referrer_policy(None); + .pipeline_id(Some(self.upcast::().pipeline_id())); let (url, source) = match fetch::load_whole_resource( request, diff --git a/components/script/dom/xmldocument.rs b/components/script/dom/xmldocument.rs index f7da09c8d51..627e0427a6a 100644 --- a/components/script/dom/xmldocument.rs +++ b/components/script/dom/xmldocument.rs @@ -55,7 +55,6 @@ impl XMLDocument { doc_loader, None, None, - None, Default::default(), ), } diff --git a/components/script/dom/xmlhttprequest.rs b/components/script/dom/xmlhttprequest.rs index 401157ce5a8..da2cffe4cb6 100644 --- a/components/script/dom/xmlhttprequest.rs +++ b/components/script/dom/xmlhttprequest.rs @@ -168,7 +168,7 @@ pub struct XMLHttpRequest { #[no_trace] referrer: Referrer, #[no_trace] - referrer_policy: Option, + referrer_policy: ReferrerPolicy, canceller: DomRefCell, } @@ -1533,7 +1533,6 @@ impl XMLHttpRequest { docloader, None, None, - None, Default::default(), can_gc, ) diff --git a/components/script/script_module.rs b/components/script/script_module.rs index 14c85722512..eedb00f1799 100644 --- a/components/script/script_module.rs +++ b/components/script/script_module.rs @@ -12,6 +12,7 @@ use std::sync::{Arc, Mutex}; use std::{mem, ptr}; use encoding_rs::UTF_8; +use headers::{HeaderMapExt, ReferrerPolicy as ReferrerPolicyHeader}; use html5ever::local_name; use hyper_serde::Serde; use indexmap::IndexSet; @@ -1189,6 +1190,19 @@ impl FetchResponseListener for ModuleContext { return Err(NetworkError::Internal("No MIME type".into())); } + // Step 13.4: Let referrerPolicy be the result of parsing the `Referrer-Policy` header + // given response. + let referrer_policy = meta + .headers + .and_then(|headers| headers.typed_get::()) + .into(); + + // Step 13.5: If referrerPolicy is not the empty string, set options's referrer policy + // to referrerPolicy. + if referrer_policy != ReferrerPolicy::EmptyString { + self.options.referrer_policy = referrer_policy; + } + // Step 10. let (source_text, _, _) = UTF_8.decode(&self.data); Ok(ScriptOrigin::external( @@ -1364,7 +1378,7 @@ pub struct ScriptFetchOptions { #[no_trace] pub parser_metadata: ParserMetadata, #[no_trace] - pub referrer_policy: Option, + pub referrer_policy: ReferrerPolicy, } impl ScriptFetchOptions { @@ -1376,7 +1390,7 @@ impl ScriptFetchOptions { referrer: global.get_referrer(), parser_metadata: ParserMetadata::NotParserInserted, credentials_mode: CredentialsMode::CredentialsSameOrigin, - referrer_policy: None, + referrer_policy: ReferrerPolicy::EmptyString, } } @@ -1741,6 +1755,7 @@ fn fetch_single_module_script( .parser_metadata(options.parser_metadata) .integrity_metadata(options.integrity_metadata.clone()) .credentials_mode(options.credentials_mode) + .referrer_policy(options.referrer_policy) .mode(mode); let context = Arc::new(Mutex::new(ModuleContext { diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index 3d000e23cd5..0057a86d872 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -69,7 +69,7 @@ use net_traits::request::{ }; use net_traits::storage_thread::StorageType; use net_traits::{ - FetchMetadata, FetchResponseListener, FetchResponseMsg, Metadata, NetworkError, ReferrerPolicy, + FetchMetadata, FetchResponseListener, FetchResponseMsg, Metadata, NetworkError, ResourceFetchTiming, ResourceThreads, ResourceTimingType, }; use percent_encoding::percent_decode; @@ -3822,12 +3822,6 @@ impl ScriptThread { .as_ref() .map(|referrer| referrer.clone().into_string()); - let referrer_policy = metadata - .headers - .as_deref() - .and_then(|h| h.typed_get::()) - .map(ReferrerPolicy::from); - let document = Document::new( &window, HasBrowsingContext::Yes, @@ -3840,11 +3834,18 @@ impl ScriptThread { DocumentSource::FromParser, loader, referrer, - referrer_policy, Some(metadata.status.raw_code()), incomplete.canceller, can_gc, ); + + let referrer_policy = metadata + .headers + .as_deref() + .and_then(|h| h.typed_get::()) + .into(); + + document.set_referrer_policy(referrer_policy); document.set_ready_state(DocumentReadyState::Loading, can_gc); self.documents diff --git a/components/script/stylesheet_loader.rs b/components/script/stylesheet_loader.rs index 590918606b3..20cfc1f2f37 100644 --- a/components/script/stylesheet_loader.rs +++ b/components/script/stylesheet_loader.rs @@ -52,9 +52,8 @@ pub trait StylesheetOwner { /// trigger a document-load-blocking load). fn parser_inserted(&self) -> bool; - /// Which referrer policy should loads triggered by this owner follow, or - /// `None` for the default. - fn referrer_policy(&self) -> Option; + /// Which referrer policy should loads triggered by this owner follow + fn referrer_policy(&self) -> ReferrerPolicy; /// Notes that a new load is pending to finish. fn increment_pending_loads_count(&self); @@ -335,9 +334,7 @@ impl<'a> StylesheetLoader<'a> { .upcast::() .as_stylesheet_owner() .expect("Stylesheet not loaded by