xref: /aosp_15_r20/external/cronet/net/reporting/README.md (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker# Reporting
2*6777b538SAndroid Build Coastguard Worker
3*6777b538SAndroid Build Coastguard WorkerReporting is a central mechanism for sending out-of-band error reports
4*6777b538SAndroid Build Coastguard Workerto origins from various other components (e.g. HTTP Public Key Pinning,
5*6777b538SAndroid Build Coastguard WorkerInterventions, or Content Security Policy could potentially use it).
6*6777b538SAndroid Build Coastguard Worker
7*6777b538SAndroid Build Coastguard WorkerThe parts of it that are exposed to the web platform are specified in three
8*6777b538SAndroid Build Coastguard Workerdocuments:
9*6777b538SAndroid Build Coastguard Worker * The original API implemented in Chrome (Reporting V0) can be found at
10*6777b538SAndroid Build Coastguard Worker     [https://www.w3.org/TR/2018/WD-reporting-1-20180925/].
11*6777b538SAndroid Build Coastguard Worker * The newer API is split into two parts. Document and worker-level reporting
12*6777b538SAndroid Build Coastguard Worker     (Reporting V1) is specified in the [draft reporting spec]
13*6777b538SAndroid Build Coastguard Worker     (https://w3c.github.io/reporting/), while Network-level reporting is
14*6777b538SAndroid Build Coastguard Worker     specified in the [draft network reporting spec]
15*6777b538SAndroid Build Coastguard Worker     (https://w3c.github.io/reporting/network-reporting.html).
16*6777b538SAndroid Build Coastguard Worker
17*6777b538SAndroid Build Coastguard WorkerThis document assumes that you've read those ones.
18*6777b538SAndroid Build Coastguard Worker
19*6777b538SAndroid Build Coastguard Worker## Reporting in Chromium
20*6777b538SAndroid Build Coastguard Worker
21*6777b538SAndroid Build Coastguard WorkerReporting is implemented as part of the network stack in Chromium, such
22*6777b538SAndroid Build Coastguard Workerthat it can be used by other parts of the network stack (e.g. HPKP) or
23*6777b538SAndroid Build Coastguard Workerby non-browser embedders as well as by Chromium.
24*6777b538SAndroid Build Coastguard Worker
25*6777b538SAndroid Build Coastguard Worker### Inside `//net`
26*6777b538SAndroid Build Coastguard Worker
27*6777b538SAndroid Build Coastguard Worker* The top-level class is the *`ReportingService`*. This lives in the
28*6777b538SAndroid Build Coastguard Worker  `URLRequestContext`, and provides the high-level operations used by
29*6777b538SAndroid Build Coastguard Worker  other parts of `//net` and other components: queueing reports,
30*6777b538SAndroid Build Coastguard Worker  handling configuration headers, clearing browsing data, and so on.
31*6777b538SAndroid Build Coastguard Worker
32*6777b538SAndroid Build Coastguard Worker    * A *`ReportingPolicy`* specifies a number of parameters for the Reporting
33*6777b538SAndroid Build Coastguard Worker      API, such as the maximum number of reports and endpoints to queue, the
34*6777b538SAndroid Build Coastguard Worker      time interval between delivery attempts, whether or not to persist reports
35*6777b538SAndroid Build Coastguard Worker      and clients across network changes, etc. It is used to create a
36*6777b538SAndroid Build Coastguard Worker      `ReportingService` obeying the specified parameters.
37*6777b538SAndroid Build Coastguard Worker
38*6777b538SAndroid Build Coastguard Worker    * Within `ReportingService` lives *`ReportingContext`*, which in turn
39*6777b538SAndroid Build Coastguard Worker      contains the inner workings of Reporting, spread across several classes:
40*6777b538SAndroid Build Coastguard Worker
41*6777b538SAndroid Build Coastguard Worker        * The *`ReportingCache`* stores undelivered reports and endpoint
42*6777b538SAndroid Build Coastguard Worker          configurations (aka "clients" in the V0 spec, and the named endpoint
43*6777b538SAndroid Build Coastguard Worker          per reporting source in the V1 spec).
44*6777b538SAndroid Build Coastguard Worker
45*6777b538SAndroid Build Coastguard Worker        * The *`ReportingHeaderParser`* parses `Report-To:` and
46*6777b538SAndroid Build Coastguard Worker          `Reporting-Endpoints' headers and updates the cache accordingly.
47*6777b538SAndroid Build Coastguard Worker
48*6777b538SAndroid Build Coastguard Worker        * The *`ReportingDeliveryAgent`* reads reports from the cache, decides
49*6777b538SAndroid Build Coastguard Worker          which endpoints to deliver them to, and attempts to do so. It uses a
50*6777b538SAndroid Build Coastguard Worker          couple of helper classes:
51*6777b538SAndroid Build Coastguard Worker
52*6777b538SAndroid Build Coastguard Worker            * The *`ReportingUploader`* does the low-level work of delivering
53*6777b538SAndroid Build Coastguard Worker              reports: accepts a URL and JSON from the `DeliveryAgent`, creates
54*6777b538SAndroid Build Coastguard Worker              a `URLRequest`, and parses the result. It also handles sending
55*6777b538SAndroid Build Coastguard Worker              CORS preflight requests for cross-origin report uploads.
56*6777b538SAndroid Build Coastguard Worker
57*6777b538SAndroid Build Coastguard Worker            * The *`ReportingEndpointManager`* chooses an endpoint from the
58*6777b538SAndroid Build Coastguard Worker              cache when one is requested by the `ReportingDeliveryAgent`, and
59*6777b538SAndroid Build Coastguard Worker              manages exponential backoff (using `BackoffEntry`) for failing
60*6777b538SAndroid Build Coastguard Worker              endpoints.
61*6777b538SAndroid Build Coastguard Worker
62*6777b538SAndroid Build Coastguard Worker        * The *`ReportingGarbageCollector`* periodically examines the cache
63*6777b538SAndroid Build Coastguard Worker          and removes reports that have remained undelivered for too long, or
64*6777b538SAndroid Build Coastguard Worker          that have failed delivery too many times.
65*6777b538SAndroid Build Coastguard Worker
66*6777b538SAndroid Build Coastguard Worker        * The *`ReportingBrowsingDataRemover`* examines the cache upon request
67*6777b538SAndroid Build Coastguard Worker          and removes browsing data (reports and endpoints) of selected types
68*6777b538SAndroid Build Coastguard Worker          and origins.
69*6777b538SAndroid Build Coastguard Worker
70*6777b538SAndroid Build Coastguard Worker        * The *`ReportingDelegate`* calls upon the `NetworkDelegate` (see below)
71*6777b538SAndroid Build Coastguard Worker          to check permissions for queueing/sending reports and setting/using
72*6777b538SAndroid Build Coastguard Worker          clients.
73*6777b538SAndroid Build Coastguard Worker
74*6777b538SAndroid Build Coastguard Worker* The `ReportingService` is set up in a `URLRequestContext` by passing a
75*6777b538SAndroid Build Coastguard Worker  `ReportingPolicy` to the `URLRequestContextBuilder`. This creates a
76*6777b538SAndroid Build Coastguard Worker  `ReportingService` which is owned by the `URLRequestContext`.
77*6777b538SAndroid Build Coastguard Worker
78*6777b538SAndroid Build Coastguard Worker* `Report-To:` headers are processed by an `HttpNetworkTransaction` when they
79*6777b538SAndroid Build Coastguard Worker  are received, and passed on to the `ReportingService` to be added to the
80*6777b538SAndroid Build Coastguard Worker  cache.
81*6777b538SAndroid Build Coastguard Worker
82*6777b538SAndroid Build Coastguard Worker* `Reporting-Endpoints:` headers are initially parsed by
83*6777b538SAndroid Build Coastguard Worker  `PopulateParsedHeaders`, where the raw header data is run through the
84*6777b538SAndroid Build Coastguard Worker  Structured Headers parser. If valid, this structure is stored on the network
85*6777b538SAndroid Build Coastguard Worker  response until a reporting source can be associated with it, and is then
86*6777b538SAndroid Build Coastguard Worker  passed through the `ReportingService` to be further validated and added to the
87*6777b538SAndroid Build Coastguard Worker  cache.
88*6777b538SAndroid Build Coastguard Worker
89*6777b538SAndroid Build Coastguard Worker* A reporting source, used only by V1 reports, is a `base::UnguessableToken`
90*6777b538SAndroid Build Coastguard Worker  associated with the document (or worker eventually) which configures reporting
91*6777b538SAndroid Build Coastguard Worker  using a `Reporting-Endpoints:` header. This same token must be passed into
92*6777b538SAndroid Build Coastguard Worker  the `ReportingService` when a report is queued for the correct endpoint to be
93*6777b538SAndroid Build Coastguard Worker  found. Since the `ReportingService` in `//net` does not know anything about
94*6777b538SAndroid Build Coastguard Worker  documents or workers, it tracks configurations and reports using this source
95*6777b538SAndroid Build Coastguard Worker  token. Any object creating such a token is responsible for informing the
96*6777b538SAndroid Build Coastguard Worker  `ReportingService` when the token will no longer be used (when the document
97*6777b538SAndroid Build Coastguard Worker  is destroyed, for instance.) This will cause any outstanding reports for that
98*6777b538SAndroid Build Coastguard Worker  token to be sent, and the configuration removed from the cache.
99*6777b538SAndroid Build Coastguard Worker
100*6777b538SAndroid Build Coastguard Worker### Outside `//net`
101*6777b538SAndroid Build Coastguard Worker
102*6777b538SAndroid Build Coastguard Worker* In the network service, a `network::NetworkContext` queues reports by getting
103*6777b538SAndroid Build Coastguard Worker  the `ReportingService` from the `URLRequestContext`.
104*6777b538SAndroid Build Coastguard Worker
105*6777b538SAndroid Build Coastguard Worker* The JavaScript [ReportingObserver](https://w3c.github.io/reporting/#observers)
106*6777b538SAndroid Build Coastguard Worker  interface lives [in `//third_party/blink/renderer/core/frame/`][1].
107*6777b538SAndroid Build Coastguard Worker
108*6777b538SAndroid Build Coastguard Worker    * It queues reports via the `NetworkContext` using a
109*6777b538SAndroid Build Coastguard Worker      `blink::mojom::ReportingServiceProxy` (implemented [in
110*6777b538SAndroid Build Coastguard Worker      `//content/browser/network/`][2]), which can queue Intervention, Deprecation,
111*6777b538SAndroid Build Coastguard Worker      CSP Violation, and Permissions Policy Violation reports.
112*6777b538SAndroid Build Coastguard Worker
113*6777b538SAndroid Build Coastguard Worker* The `ChromeNetworkDelegate` [in `//chrome/browser/net/`][3] checks permissions
114*6777b538SAndroid Build Coastguard Worker  for queueing reports and setting/using clients based on whether cookie access
115*6777b538SAndroid Build Coastguard Worker  is allowed, and checks permissions for sending reports using a
116*6777b538SAndroid Build Coastguard Worker  `ReportingPermissionsChecker`, which checks whether the user has allowed
117*6777b538SAndroid Build Coastguard Worker  report uploading via the BACKGROUND_SYNC permission.
118*6777b538SAndroid Build Coastguard Worker
119*6777b538SAndroid Build Coastguard Worker* Cronet can configure "preloaded" `Report-To:` headers (as well as Network
120*6777b538SAndroid Build Coastguard Worker  Error Logging headers) when initializing a `CronetURLRequestContext`, to allow
121*6777b538SAndroid Build Coastguard Worker  embedders to collect and send reports before having received a header in an
122*6777b538SAndroid Build Coastguard Worker  actual response.
123*6777b538SAndroid Build Coastguard Worker
124*6777b538SAndroid Build Coastguard Worker    * This functionality is tested on Android by way of sending Network Error
125*6777b538SAndroid Build Coastguard Worker      Logging reports [in the Cronet Java tests][4].
126*6777b538SAndroid Build Coastguard Worker
127*6777b538SAndroid Build Coastguard Worker## Differences between V0 and V1 reporting
128*6777b538SAndroid Build Coastguard Worker
129*6777b538SAndroid Build Coastguard WorkerThe original V0 reporting API included support for the `Report-To` header only,
130*6777b538SAndroid Build Coastguard Workerwhich configures endpoint groups which apply to an entire origin. This is still
131*6777b538SAndroid Build Coastguard Workerrequired for Network Error Logging, as those reports are not associated with
132*6777b538SAndroid Build Coastguard Workerany successful document load.
133*6777b538SAndroid Build Coastguard Worker
134*6777b538SAndroid Build Coastguard WorkerAll V0 reports destined for the same endpoint group may be bundled together for
135*6777b538SAndroid Build Coastguard Workerdelivery, regardless of their source (subject to NAK isolation).
136*6777b538SAndroid Build Coastguard Worker
137*6777b538SAndroid Build Coastguard WorkerV1 reporting drops the `Report-To` header in favor of `Reporting-Endpoints`,
138*6777b538SAndroid Build Coastguard Workerwhich configures named endpoints (single URLs) which are only valid for the
139*6777b538SAndroid Build Coastguard Workernetwork resource with which the header was sent. (In general, this means
140*6777b538SAndroid Build Coastguard Workerdocuments and workers, since other resources do not currently generate reports.
141*6777b538SAndroid Build Coastguard WorkerChrome ignores any `Reporting-Endpoints` headers on those responses.) The V1 API
142*6777b538SAndroid Build Coastguard Workerdoes not support multiple weighted URLs for an endpoint, or failover between
143*6777b538SAndroid Build Coastguard Workerthem.
144*6777b538SAndroid Build Coastguard Worker
145*6777b538SAndroid Build Coastguard WorkerV1 reports from the same source may be bundled together in a single delivery,
146*6777b538SAndroid Build Coastguard Workerbut must be delivered separtely from other reports, even those coming from a
147*6777b538SAndroid Build Coastguard Workerdifferent `Document` object at the same URL.
148*6777b538SAndroid Build Coastguard Worker
149*6777b538SAndroid Build Coastguard Worker## Supporting both V0 and V1 reporting in the same codebase
150*6777b538SAndroid Build Coastguard Worker
151*6777b538SAndroid Build Coastguard WorkerChrome cannot yet drop support for NEL, and therefore for the `Report-To`
152*6777b538SAndroid Build Coastguard Workerheader. Until we can, it is possible for reports to be sent to endpoints
153*6777b538SAndroid Build Coastguard Workerconfigured with either header. NEL reports can only go to those endpoint groups
154*6777b538SAndroid Build Coastguard Workerconfigured with `Report-To`.
155*6777b538SAndroid Build Coastguard Worker
156*6777b538SAndroid Build Coastguard WorkerTo support both mechanisms simultaneously, we do the following:
157*6777b538SAndroid Build Coastguard Worker
158*6777b538SAndroid Build Coastguard Worker* V1 endpoints are stored in the cache along with V0 endpoint groups. Separate
159*6777b538SAndroid Build Coastguard Worker  maps are kept of (origin -> endpoint groups) and (source token -> endpoints).
160*6777b538SAndroid Build Coastguard Worker
161*6777b538SAndroid Build Coastguard Worker* All reports which can be associated with a specific source (currently all
162*6777b538SAndroid Build Coastguard Worker  reports except for NEL, which requires origin-scoped V0 configuration) must be
163*6777b538SAndroid Build Coastguard Worker  queued with that source's reporting source token.
164*6777b538SAndroid Build Coastguard Worker
165*6777b538SAndroid Build Coastguard Worker* When a report is to be delivered, the `ReportingDeliveryAgent` will first
166*6777b538SAndroid Build Coastguard Worker  attempt to find a matching V1 endpoint for the source. Only if that is
167*6777b538SAndroid Build Coastguard Worker  unsuccessful, because the source is null, or because the named endpoint is not
168*6777b538SAndroid Build Coastguard Worker  configured, will it fall back to searching for a matching V0 named endpoint
169*6777b538SAndroid Build Coastguard Worker  group.
170*6777b538SAndroid Build Coastguard Worker
171*6777b538SAndroid Build Coastguard Worker[1]: https://chromium.googlesource.com/chromium/src/+/HEAD/third_party/blink/renderer/core/frame/reporting_observer.h
172*6777b538SAndroid Build Coastguard Worker[2]: https://chromium.googlesource.com/chromium/src/+/HEAD/content/browser/network/reporting_service_proxy.cc
173*6777b538SAndroid Build Coastguard Worker[3]: https://chromium.googlesource.com/chromium/src/+/HEAD/chrome/browser/net/chrome_network_delegate.h
174*6777b538SAndroid Build Coastguard Worker[4]: https://chromium.googlesource.com/chromium/src/+/HEAD/components/cronet/android/test/javatests/src/org/chromium/net/NetworkErrorLoggingTest.java
175