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