Implement initial version of ReportingObserver (#37905)

The specification moved around lately with how it defines its reports
and report bodies. They became dictionaries, but are currently missing
some fields [1].

Most tests won't be passing yet, since the `Reporting-Endpoints` header
isn't used yet. In fact, the specification leaves it up to the browser
to figure out when to run this task [2]. I am not sure if there some
background scheduling we can do here.

Confirmed with content-security-policy/reporting-api/
report-to-directive-allowed-in-meta.https.sub.html that the callback is
invoked. The test doesn't pass, since
the `describe_scripted_caller` is empty for HTML elements. Thus the
`source_file` is empty, whereas it should be equivalent to the current
document URL.

Part of #37328

Signed-off-by: Tim van der Lippe <tvanderlippe@gmail.com>

[1]: https://github.com/w3c/reporting/issues/286
[2]: https://w3c.github.io/reporting/#report-delivery
This commit is contained in:
Tim van der Lippe 2025-07-07 12:43:30 +02:00 committed by GitHub
parent 3d4868592a
commit fcb2a4cd95
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 551 additions and 101 deletions

View file

@ -36,6 +36,7 @@ use crate::dom::bindings::cell::{DomRefCell, Ref};
use crate::dom::bindings::codegen::Bindings::ImageBitmapBinding::{
ImageBitmapOptions, ImageBitmapSource,
};
use crate::dom::bindings::codegen::Bindings::ReportingObserverBinding::Report;
use crate::dom::bindings::codegen::Bindings::RequestBinding::RequestInit;
use crate::dom::bindings::codegen::Bindings::VoidFunctionBinding::VoidFunction;
use crate::dom::bindings::codegen::Bindings::WorkerBinding::WorkerType;
@ -56,6 +57,7 @@ use crate::dom::globalscope::GlobalScope;
use crate::dom::idbfactory::IDBFactory;
use crate::dom::performance::Performance;
use crate::dom::promise::Promise;
use crate::dom::reportingobserver::ReportingObserver;
use crate::dom::trustedscripturl::TrustedScriptURL;
use crate::dom::trustedtypepolicyfactory::TrustedTypePolicyFactory;
use crate::dom::types::ImageBitmap;
@ -139,6 +141,12 @@ pub(crate) struct WorkerGlobalScope {
#[no_trace]
insecure_requests_policy: InsecureRequestsPolicy,
/// <https://w3c.github.io/reporting/#windoworworkerglobalscope-registered-reporting-observer-list>
reporting_observer_list: DomRefCell<Vec<DomRoot<ReportingObserver>>>,
/// <https://w3c.github.io/reporting/#windoworworkerglobalscope-reports>
report_list: DomRefCell<Vec<Report>>,
}
impl WorkerGlobalScope {
@ -196,6 +204,8 @@ impl WorkerGlobalScope {
timer_scheduler: RefCell::default(),
insecure_requests_policy,
trusted_types: Default::default(),
reporting_observer_list: Default::default(),
report_list: Default::default(),
}
}
@ -259,6 +269,35 @@ impl WorkerGlobalScope {
self.policy_container.borrow_mut().set_csp_list(csp_list);
}
pub(crate) fn append_reporting_observer(&self, reporting_observer: DomRoot<ReportingObserver>) {
self.reporting_observer_list
.borrow_mut()
.push(reporting_observer);
}
pub(crate) fn remove_reporting_observer(&self, reporting_observer: &ReportingObserver) {
if let Some(index) = self
.reporting_observer_list
.borrow()
.iter()
.position(|observer| &**observer == reporting_observer)
{
self.reporting_observer_list.borrow_mut().remove(index);
}
}
pub(crate) fn registered_reporting_observers(&self) -> Vec<DomRoot<ReportingObserver>> {
self.reporting_observer_list.borrow().clone()
}
pub(crate) fn append_report(&self, report: Report) {
self.report_list.borrow_mut().push(report);
}
pub(crate) fn buffered_reports(&self) -> Vec<Report> {
self.report_list.borrow().clone()
}
/// Get a mutable reference to the [`TimerScheduler`] for this [`ServiceWorkerGlobalScope`].
pub(crate) fn timer_scheduler(&self) -> RefMut<TimerScheduler> {
self.timer_scheduler.borrow_mut()