Update FetchTaskTarget to propagate CSP violations. (#36409)

It also updates the FetchResponseListener to process CSP violations to
ensure that iframe elements (amongst others) properly generate the CSP
events. These iframe elements are used in the Trusted Types tests
themselves and weren't propagating the violations before.

However, the tests themselves are still not passing since they also use
Websockets, which currently aren't using the fetch machinery itself.
That is fixed as part of [1].

[1]: https://github.com/servo/servo/issues/35028

---------

Signed-off-by: Tim van der Lippe <tvanderlippe@gmail.com>
Signed-off-by: Josh Matthews <josh@joshmatthews.net>
Co-authored-by: Josh Matthews <josh@joshmatthews.net>
This commit is contained in:
Tim van der Lippe 2025-04-13 22:54:59 +02:00 committed by GitHub
parent 5d84acc06e
commit 85e4a2b5c7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
146 changed files with 511 additions and 612 deletions

View file

@ -18,6 +18,7 @@ use js::jsval::UndefinedValue;
use js::rust::{CustomAutoRooter, CustomAutoRooterGuard, HandleValue};
use net_traits::IpcSend;
use net_traits::image_cache::ImageCache;
use net_traits::policy_container::PolicyContainer;
use net_traits::request::{
CredentialsMode, Destination, InsecureRequestsPolicy, ParserMetadata, Referrer, RequestBuilder,
RequestMode,
@ -347,6 +348,7 @@ impl DedicatedWorkerGlobalScope {
control_receiver: Receiver<DedicatedWorkerControlMsg>,
context_sender: Sender<ThreadSafeJSContext>,
insecure_requests_policy: InsecureRequestsPolicy,
policy_container: PolicyContainer,
) -> JoinHandle<()> {
let serialized_worker_url = worker_url.to_string();
let webview_id = WebViewId::installed();
@ -388,6 +390,7 @@ impl DedicatedWorkerGlobalScope {
.referrer_policy(referrer_policy)
.insecure_requests_policy(insecure_requests_policy)
.has_trustworthy_ancestor_origin(current_global_ancestor_trustworthy)
.policy_container(policy_container)
.origin(origin);
let runtime = unsafe {

View file

@ -8,6 +8,7 @@ use std::str::{Chars, FromStr};
use std::sync::{Arc, Mutex};
use std::time::Duration;
use content_security_policy as csp;
use dom_struct::dom_struct;
use headers::ContentType;
use http::header::{self, HeaderName, HeaderValue};
@ -431,6 +432,11 @@ impl FetchResponseListener for EventSourceContext {
fn submit_resource_timing(&mut self) {
network_listener::submit_timing(self, CanGc::note())
}
fn process_csp_violations(&mut self, _request_id: RequestId, violations: Vec<csp::Violation>) {
let global = &self.resource_timing_global();
global.report_csp_violations(violations);
}
}
impl ResourceTimingListener for EventSourceContext {
@ -562,6 +568,7 @@ impl EventSourceMethods<crate::DomTypeHolder> for EventSource {
global.get_referrer(),
global.insecure_requests_policy(),
global.has_trustworthy_ancestor_or_current_origin(),
global.policy_container(),
)
.origin(global.origin().immutable().clone())
.pipeline_id(Some(global.pipeline_id()));

View file

@ -21,7 +21,9 @@ use constellation_traits::{
BlobData, BlobImpl, BroadcastMsg, FileBlob, MessagePortImpl, MessagePortMsg, PortMessageTask,
ScriptToConstellationChan, ScriptToConstellationMessage,
};
use content_security_policy::{CheckResult, CspList, PolicyDisposition};
use content_security_policy::{
CheckResult, CspList, PolicyDisposition, Violation, ViolationResource,
};
use crossbeam_channel::Sender;
use devtools_traits::{PageError, ScriptToDevtoolsControlMsg};
use dom_struct::dom_struct;
@ -3310,6 +3312,24 @@ impl GlobalScope {
}
unreachable!();
}
pub(crate) fn report_csp_violations(&self, violations: Vec<Violation>) {
for violation in violations {
let sample = match violation.resource {
ViolationResource::Inline { .. } | ViolationResource::Url(_) => None,
ViolationResource::TrustedTypePolicy { sample } => Some(sample),
};
let report = CSPViolationReportBuilder::default()
.resource("eval".to_owned())
.sample(sample)
.effective_directive(violation.directive.name)
.build(self);
let task = CSPViolationReportTask::new(self, report);
self.task_manager()
.dom_manipulation_task_source()
.queue(task);
}
}
}
/// Returns the Rust global scope from a JS global object.

View file

@ -10,6 +10,7 @@ use std::sync::Arc;
use std::{char, mem};
use app_units::{AU_PER_PX, Au};
use content_security_policy as csp;
use cssparser::{Parser, ParserInput};
use dom_struct::dom_struct;
use euclid::Point2D;
@ -294,6 +295,11 @@ impl FetchResponseListener for ImageContext {
fn submit_resource_timing(&mut self) {
network_listener::submit_timing(self, CanGc::note())
}
fn process_csp_violations(&mut self, _request_id: RequestId, violations: Vec<csp::Violation>) {
let global = &self.resource_timing_global();
global.report_csp_violations(violations);
}
}
impl ResourceTimingListener for ImageContext {
@ -416,15 +422,17 @@ impl HTMLImageElement {
// https://html.spec.whatwg.org/multipage/#update-the-image-data steps 17-20
// This function is also used to prefetch an image in `script::dom::servoparser::prefetch`.
let global = document.global();
let mut request = create_a_potential_cors_request(
Some(window.webview_id()),
img_url.clone(),
Destination::Image,
cors_setting_for_element(self.upcast()),
None,
document.global().get_referrer(),
global.get_referrer(),
document.insecure_requests_policy(),
document.has_trustworthy_ancestor_or_current_origin(),
global.policy_container(),
)
.origin(document.origin().immutable().clone())
.pipeline_id(Some(document.global().pipeline_id()))

View file

@ -7,6 +7,7 @@ use std::cell::Cell;
use std::default::Default;
use base::id::WebViewId;
use content_security_policy as csp;
use cssparser::{Parser as CssParser, ParserInput};
use dom_struct::dom_struct;
use embedder_traits::EmbedderMsg;
@ -706,9 +707,9 @@ impl LinkProcessingOptions {
Referrer::NoReferrer,
self.insecure_requests_policy,
self.has_trustworthy_ancestor_origin,
self.policy_container,
)
.integrity_metadata(self.integrity)
.policy_container(self.policy_container)
.cryptographic_nonce_metadata(self.cryptographic_nonce_metadata)
.referrer_policy(self.referrer_policy);
@ -788,6 +789,11 @@ impl FetchResponseListener for PrefetchContext {
fn submit_resource_timing(&mut self) {
submit_timing(self, CanGc::note())
}
fn process_csp_violations(&mut self, _request_id: RequestId, violations: Vec<csp::Violation>) {
let global = &self.resource_timing_global();
global.report_csp_violations(violations);
}
}
impl ResourceTimingListener for PrefetchContext {

View file

@ -10,6 +10,7 @@ use std::time::{Duration, Instant};
use std::{f64, mem};
use compositing_traits::{CrossProcessCompositorApi, ImageUpdate, SerializableImageData};
use content_security_policy as csp;
use dom_struct::dom_struct;
use embedder_traits::resources::{self, Resource as EmbedderResource};
use embedder_traits::{MediaPositionState, MediaSessionEvent, MediaSessionPlaybackState};
@ -892,15 +893,17 @@ impl HTMLMediaElement {
};
let cors_setting = cors_setting_for_element(self.upcast());
let global = self.global();
let request = create_a_potential_cors_request(
Some(document.webview_id()),
url.clone(),
destination,
cors_setting,
None,
self.global().get_referrer(),
global.get_referrer(),
document.insecure_requests_policy(),
document.has_trustworthy_ancestor_or_current_origin(),
global.policy_container(),
)
.headers(headers)
.origin(document.origin().immutable().clone())
@ -2903,6 +2906,11 @@ impl FetchResponseListener for HTMLMediaElementFetchListener {
fn submit_resource_timing(&mut self) {
network_listener::submit_timing(self, CanGc::note())
}
fn process_csp_violations(&mut self, _request_id: RequestId, violations: Vec<csp::Violation>) {
let global = &self.resource_timing_global();
global.report_csp_violations(violations);
}
}
impl ResourceTimingListener for HTMLMediaElementFetchListener {

View file

@ -21,6 +21,7 @@ use ipc_channel::ipc;
use js::jsval::UndefinedValue;
use js::rust::{CompileOptionsWrapper, HandleObject, Stencil, transform_str_to_source_text};
use net_traits::http_status::HttpStatus;
use net_traits::policy_container::PolicyContainer;
use net_traits::request::{
CorsSettings, CredentialsMode, Destination, InsecureRequestsPolicy, ParserMetadata,
RequestBuilder, RequestId,
@ -536,6 +537,11 @@ impl FetchResponseListener for ClassicContext {
fn submit_resource_timing(&mut self) {
network_listener::submit_timing(self, CanGc::note())
}
fn process_csp_violations(&mut self, _request_id: RequestId, violations: Vec<csp::Violation>) {
let global = &self.resource_timing_global();
global.report_csp_violations(violations);
}
}
impl ResourceTimingListener for ClassicContext {
@ -569,6 +575,7 @@ pub(crate) fn script_fetch_request(
options: ScriptFetchOptions,
insecure_requests_policy: InsecureRequestsPolicy,
has_trustworthy_ancestor_origin: bool,
policy_container: PolicyContainer,
) -> RequestBuilder {
// We intentionally ignore options' credentials_mode member for classic scripts.
// The mode is initialized by create_a_potential_cors_request.
@ -581,6 +588,7 @@ pub(crate) fn script_fetch_request(
options.referrer,
insecure_requests_policy,
has_trustworthy_ancestor_origin,
policy_container,
)
.origin(origin)
.pipeline_id(Some(pipeline_id))
@ -601,15 +609,17 @@ fn fetch_a_classic_script(
) {
// Step 1, 2.
let doc = script.owner_document();
let global = script.global();
let request = script_fetch_request(
doc.webview_id(),
url.clone(),
cors_setting,
doc.origin().immutable().clone(),
script.global().pipeline_id(),
global.pipeline_id(),
options.clone(),
doc.insecure_requests_policy(),
doc.has_trustworthy_ancestor_origin(),
global.policy_container(),
);
let request = doc.prepare_request(request);

View file

@ -5,6 +5,7 @@
use std::cell::Cell;
use std::sync::Arc;
use content_security_policy as csp;
use dom_struct::dom_struct;
use euclid::default::Size2D;
use html5ever::{LocalName, Prefix, local_name, namespace_url, ns};
@ -416,6 +417,11 @@ impl FetchResponseListener for PosterFrameFetchContext {
fn submit_resource_timing(&mut self) {
network_listener::submit_timing(self, CanGc::note())
}
fn process_csp_violations(&mut self, _request_id: RequestId, violations: Vec<csp::Violation>) {
let global = &self.resource_timing_global();
global.report_csp_violations(violations);
}
}
impl ResourceTimingListener for PosterFrameFetchContext {

View file

@ -7,6 +7,7 @@ use std::rc::Rc;
use std::sync::{Arc, Mutex};
use std::time::{SystemTime, UNIX_EPOCH};
use content_security_policy as csp;
use content_security_policy::Destination;
use dom_struct::dom_struct;
use embedder_traits::{
@ -791,6 +792,11 @@ impl FetchResponseListener for ResourceFetchListener {
fn submit_resource_timing(&mut self) {
network_listener::submit_timing(self, CanGc::note())
}
fn process_csp_violations(&mut self, _request_id: RequestId, violations: Vec<csp::Violation>) {
let global = &self.resource_timing_global();
global.report_csp_violations(violations);
}
}
impl ResourceTimingListener for ResourceFetchListener {
@ -821,6 +827,7 @@ impl Notification {
global.get_referrer(),
global.insecure_requests_policy(),
global.has_trustworthy_ancestor_or_current_origin(),
global.policy_container(),
)
.origin(global.origin().immutable().clone())
.pipeline_id(Some(global.pipeline_id()))

View file

@ -1068,6 +1068,16 @@ impl FetchResponseListener for ParserContext {
CanGc::note(),
);
}
fn process_csp_violations(&mut self, _request_id: RequestId, violations: Vec<csp::Violation>) {
let parser = match self.parser.as_ref() {
Some(parser) => parser.root(),
None => return,
};
let document = &parser.document;
let global = &document.global();
global.report_csp_violations(violations);
}
}
impl PreInvoke for ParserContext {}

View file

@ -15,6 +15,7 @@ use html5ever::tokenizer::{
use html5ever::{Attribute, LocalName, local_name};
use js::jsapi::JSTracer;
use markup5ever::TokenizerResult;
use net_traits::policy_container::PolicyContainer;
use net_traits::request::{
CorsSettings, CredentialsMode, InsecureRequestsPolicy, ParserMetadata, Referrer,
};
@ -60,13 +61,14 @@ unsafe impl CustomTraceable for PrefetchSink {
impl Tokenizer {
pub(crate) fn new(document: &Document) -> Self {
let global = document.global();
let sink = PrefetchSink {
origin: document.origin().immutable().clone(),
pipeline_id: document.global().pipeline_id(),
pipeline_id: global.pipeline_id(),
webview_id: document.webview_id(),
base_url: RefCell::new(None),
document_url: document.url(),
referrer: document.global().get_referrer(),
referrer: global.get_referrer(),
referrer_policy: document.get_referrer_policy(),
resource_threads: document.loader().resource_threads().clone(),
// Initially we set prefetching to false, and only set it
@ -75,6 +77,7 @@ impl Tokenizer {
prefetching: Cell::new(false),
insecure_requests_policy: document.insecure_requests_policy(),
has_trustworthy_ancestor_origin: document.has_trustworthy_ancestor_or_current_origin(),
policy_container: global.policy_container(),
};
let options = Default::default();
let inner = TraceableTokenizer(HtmlTokenizer::new(sink, options));
@ -108,6 +111,8 @@ struct PrefetchSink {
#[no_trace]
insecure_requests_policy: InsecureRequestsPolicy,
has_trustworthy_ancestor_origin: bool,
#[no_trace]
policy_container: PolicyContainer,
}
/// The prefetch tokenizer produces trivial results
@ -150,6 +155,7 @@ impl TokenSink for PrefetchSink {
},
self.insecure_requests_policy,
self.has_trustworthy_ancestor_origin,
self.policy_container.clone(),
);
let _ = self
.resource_threads
@ -169,6 +175,7 @@ impl TokenSink for PrefetchSink {
self.referrer.clone(),
self.insecure_requests_policy,
self.has_trustworthy_ancestor_origin,
self.policy_container.clone(),
)
.origin(self.origin.clone())
.pipeline_id(Some(self.pipeline_id))
@ -204,6 +211,7 @@ impl TokenSink for PrefetchSink {
self.referrer.clone(),
self.insecure_requests_policy,
self.has_trustworthy_ancestor_origin,
self.policy_container.clone(),
)
.origin(self.origin.clone())
.pipeline_id(Some(self.pipeline_id))

View file

@ -7,6 +7,7 @@ use std::cell::Cell;
use std::ptr;
use constellation_traits::BlobImpl;
use content_security_policy::Violation;
use dom_struct::dom_struct;
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
use ipc_channel::router::ROUTER;
@ -266,6 +267,7 @@ impl WebSocketMethods<crate::DomTypeHolder> for WebSocket {
.service_workers_mode(ServiceWorkersMode::None)
.credentials_mode(CredentialsMode::Include)
.cache_mode(CacheMode::NoCache)
.policy_container(global.policy_container())
.redirect_mode(RedirectMode::Error);
let channels = FetchChannels::WebSocket {
@ -280,6 +282,13 @@ impl WebSocketMethods<crate::DomTypeHolder> for WebSocket {
ROUTER.add_typed_route(
dom_event_receiver.to_ipc_receiver(),
Box::new(move |message| match message.unwrap() {
WebSocketNetworkEvent::ReportCSPViolations(violations) => {
let task = ReportCSPViolationTask {
websocket: address.clone(),
violations,
};
task_source.queue(task);
},
WebSocketNetworkEvent::ConnectionEstablished { protocol_in_use } => {
let open_thread = ConnectionEstablishedTask {
address: address.clone(),
@ -454,6 +463,18 @@ impl WebSocketMethods<crate::DomTypeHolder> for WebSocket {
}
}
struct ReportCSPViolationTask {
websocket: Trusted<WebSocket>,
violations: Vec<Violation>,
}
impl TaskOnce for ReportCSPViolationTask {
fn run_once(self) {
let global = self.websocket.root().global();
global.report_csp_violations(self.violations);
}
}
/// Task queued when *the WebSocket connection is established*.
/// <https://html.spec.whatwg.org/multipage/#feedback-from-the-protocol:concept-websocket-established>
struct ConnectionEstablishedTask {

View file

@ -243,6 +243,7 @@ impl WorkerMethods<crate::DomTypeHolder> for Worker {
control_receiver,
context_sender,
global.insecure_requests_policy(),
global.policy_container(),
);
let context = context_receiver

View file

@ -11,6 +11,7 @@ use std::sync::{Arc, Mutex};
use std::time::{Duration, Instant};
use constellation_traits::BlobImpl;
use content_security_policy as csp;
use dom_struct::dom_struct;
use encoding_rs::{Encoding, UTF_8};
use headers::{ContentLength, ContentType, HeaderMapExt};
@ -143,6 +144,11 @@ impl FetchResponseListener for XHRContext {
fn submit_resource_timing(&mut self) {
network_listener::submit_timing(self, CanGc::note())
}
fn process_csp_violations(&mut self, _request_id: RequestId, violations: Vec<csp::Violation>) {
let global = &self.resource_timing_global();
global.report_csp_violations(violations);
}
}
impl ResourceTimingListener for XHRContext {
@ -671,8 +677,9 @@ impl XMLHttpRequestMethods<crate::DomTypeHolder> for XMLHttpRequest {
None => None,
};
let global = self.global();
let mut request = RequestBuilder::new(
self.global().webview_id(),
global.webview_id(),
self.request_url.borrow().clone().unwrap(),
self.referrer.clone(),
)
@ -686,11 +693,12 @@ impl XMLHttpRequestMethods<crate::DomTypeHolder> for XMLHttpRequest {
.use_cors_preflight(self.upload_listener.get())
.credentials_mode(credentials_mode)
.use_url_credentials(use_url_credentials)
.origin(self.global().origin().immutable().clone())
.origin(global.origin().immutable().clone())
.referrer_policy(self.referrer_policy)
.insecure_requests_policy(self.global().insecure_requests_policy())
.has_trustworthy_ancestor_origin(self.global().has_trustworthy_ancestor_or_current_origin())
.pipeline_id(Some(self.global().pipeline_id()));
.insecure_requests_policy(global.insecure_requests_policy())
.has_trustworthy_ancestor_origin(global.has_trustworthy_ancestor_or_current_origin())
.policy_container(global.policy_container())
.pipeline_id(Some(global.pipeline_id()));
// step 4 (second half)
if let Some(content_type) = content_type {

View file

@ -6,8 +6,9 @@ use std::rc::Rc;
use std::sync::{Arc, Mutex};
use base::id::WebViewId;
use content_security_policy as csp;
use ipc_channel::ipc;
use net_traits::policy_container::RequestPolicyContainer;
use net_traits::policy_container::{PolicyContainer, RequestPolicyContainer};
use net_traits::request::{
CorsSettings, CredentialsMode, Destination, InsecureRequestsPolicy, Referrer,
Request as NetTraitsRequest, RequestBuilder, RequestId, RequestMode, ServiceWorkersMode,
@ -309,6 +310,11 @@ impl FetchResponseListener for FetchContext {
network_listener::submit_timing(self, CanGc::note())
}
}
fn process_csp_violations(&mut self, _request_id: RequestId, violations: Vec<csp::Violation>) {
let global = &self.resource_timing_global();
global.report_csp_violations(violations);
}
}
impl ResourceTimingListener for FetchContext {
@ -352,8 +358,9 @@ pub(crate) fn load_whole_resource(
let mut metadata = None;
loop {
match action_receiver.recv().unwrap() {
FetchResponseMsg::ProcessRequestBody(..) | FetchResponseMsg::ProcessRequestEOF(..) => {
},
FetchResponseMsg::ProcessRequestBody(..) |
FetchResponseMsg::ProcessRequestEOF(..) |
FetchResponseMsg::ProcessCspViolations(..) => {},
FetchResponseMsg::ProcessResponse(_, Ok(m)) => {
metadata = Some(match m {
FetchMetadata::Unfiltered(m) => m,
@ -385,6 +392,7 @@ pub(crate) fn create_a_potential_cors_request(
referrer: Referrer,
insecure_requests_policy: InsecureRequestsPolicy,
has_trustworthy_ancestor_origin: bool,
policy_container: PolicyContainer,
) -> RequestBuilder {
RequestBuilder::new(webview_id, url, referrer)
// https://html.spec.whatwg.org/multipage/#create-a-potential-cors-request
@ -405,4 +413,5 @@ pub(crate) fn create_a_potential_cors_request(
.use_url_credentials(true)
.insecure_requests_policy(insecure_requests_policy)
.has_trustworthy_ancestor_origin(has_trustworthy_ancestor_origin)
.policy_container(policy_container)
}

View file

@ -8,6 +8,7 @@
use std::sync::Arc;
use content_security_policy as csp;
use net_traits::image_cache::{ImageCache, PendingImageId};
use net_traits::request::{Destination, RequestBuilder as FetchRequestInit, RequestId};
use net_traits::{
@ -77,6 +78,11 @@ impl FetchResponseListener for LayoutImageContext {
fn submit_resource_timing(&mut self) {
network_listener::submit_timing(self, CanGc::note())
}
fn process_csp_violations(&mut self, _request_id: RequestId, violations: Vec<csp::Violation>) {
let global = &self.resource_timing_global();
global.report_csp_violations(violations);
}
}
impl ResourceTimingListener for LayoutImageContext {

View file

@ -11,6 +11,7 @@ use std::str::FromStr;
use std::sync::{Arc, Mutex};
use std::{mem, ptr};
use content_security_policy as csp;
use encoding_rs::UTF_8;
use headers::{HeaderMapExt, ReferrerPolicy as ReferrerPolicyHeader};
use html5ever::local_name;
@ -1273,6 +1274,11 @@ impl FetchResponseListener for ModuleContext {
fn submit_resource_timing(&mut self) {
network_listener::submit_timing(self, CanGc::note())
}
fn process_csp_violations(&mut self, _request_id: RequestId, violations: Vec<csp::Violation>) {
let global = &self.resource_timing_global();
global.report_csp_violations(violations);
}
}
impl ResourceTimingListener for ModuleContext {

View file

@ -41,6 +41,7 @@ use constellation_traits::{
JsEvalResult, LoadData, LoadOrigin, NavigationHistoryBehavior, ScriptToConstellationChan,
ScriptToConstellationMessage, ScrollState, StructuredSerializedData, WindowSizeType,
};
use content_security_policy::{self as csp};
use crossbeam_channel::unbounded;
use devtools_traits::{
CSSError, DevtoolScriptControlMsg, DevtoolsPageInfo, NavigationState,
@ -3420,8 +3421,11 @@ impl ScriptThread {
FetchResponseMsg::ProcessResponseEOF(request_id, eof) => {
self.handle_fetch_eof(pipeline_id, request_id, eof)
},
FetchResponseMsg::ProcessRequestBody(..) => {},
FetchResponseMsg::ProcessRequestEOF(..) => {},
FetchResponseMsg::ProcessCspViolations(request_id, violations) => {
self.handle_csp_violations(pipeline_id, request_id, violations)
},
FetchResponseMsg::ProcessRequestBody(..) | FetchResponseMsg::ProcessRequestEOF(..) => {
},
}
}
@ -3477,6 +3481,12 @@ impl ScriptThread {
}
}
fn handle_csp_violations(&self, id: PipelineId, _: RequestId, violations: Vec<csp::Violation>) {
if let Some(global) = self.documents.borrow().find_global(id) {
global.report_csp_violations(violations);
}
}
fn handle_navigation_redirect(&self, id: PipelineId, metadata: &Metadata) {
// TODO(mrobinson): This tries to accomplish some steps from
// <https://html.spec.whatwg.org/multipage/#process-a-navigate-fetch>, but it's

View file

@ -5,6 +5,7 @@
use std::io::{Read, Seek, Write};
use std::sync::atomic::AtomicBool;
use content_security_policy as csp;
use cssparser::SourceLocation;
use encoding_rs::UTF_8;
use mime::{self, Mime};
@ -282,6 +283,11 @@ impl FetchResponseListener for StylesheetContext {
fn submit_resource_timing(&mut self) {
network_listener::submit_timing(self, CanGc::note())
}
fn process_csp_violations(&mut self, _request_id: RequestId, violations: Vec<csp::Violation>) {
let global = &self.resource_timing_global();
global.report_csp_violations(violations);
}
}
impl ResourceTimingListener for StylesheetContext {
@ -353,15 +359,17 @@ impl StylesheetLoader<'_> {
}
// https://html.spec.whatwg.org/multipage/#default-fetch-and-process-the-linked-resource
let global = self.elem.global();
let request = create_a_potential_cors_request(
Some(document.webview_id()),
url.clone(),
Destination::Style,
cors_setting,
None,
self.elem.global().get_referrer(),
global.get_referrer(),
document.insecure_requests_policy(),
document.has_trustworthy_ancestor_or_current_origin(),
global.policy_container(),
)
.origin(document.origin().immutable().clone())
.pipeline_id(Some(self.elem.global().pipeline_id()))