juliatuttle | 72a9ba6 | 2017-03-28 17:28:52 | [diff] [blame] | 1 | # Reporting |
| 2 | |
| 3 | Reporting is a central mechanism for sending out-of-band error reports |
| 4 | to origins from various other components (e.g. HTTP Public Key Pinning, |
| 5 | Interventions, or Content Security Policy could potentially use it). |
| 6 | |
Lily Chen | f65f5d4 | 2019-04-03 22:35:58 | [diff] [blame] | 7 | The parts of it that are exposed to the web platform are specified in the [draft |
| 8 | spec](https://w3c.github.io/reporting/). This document assumes that you've read |
| 9 | that one. |
juliatuttle | 72a9ba6 | 2017-03-28 17:28:52 | [diff] [blame] | 10 | |
| 11 | ## Reporting in Chromium |
| 12 | |
| 13 | Reporting is implemented as part of the network stack in Chromium, such |
| 14 | that it can be used by other parts of the network stack (e.g. HPKP) or |
| 15 | by non-browser embedders as well as by Chromium. |
| 16 | |
juliatuttle | 72a9ba6 | 2017-03-28 17:28:52 | [diff] [blame] | 17 | ### Inside `//net` |
| 18 | |
| 19 | * The top-level class is the *`ReportingService`*. This lives in the |
| 20 | `URLRequestContext`, and provides the high-level operations used by |
| 21 | other parts of `//net` and other components: queueing reports, |
| 22 | handling configuration headers, clearing browsing data, and so on. |
| 23 | |
Lily Chen | f65f5d4 | 2019-04-03 22:35:58 | [diff] [blame] | 24 | * A *`ReportingPolicy`* specifies a number of parameters for the Reporting |
| 25 | API, such as the maximum number of reports and endpoints to queue, the |
| 26 | time interval between delivery attempts, whether or not to persist reports |
| 27 | and clients across network changes, etc. It is used to create a |
| 28 | `ReportingService` obeying the specified parameters. |
juliatuttle | 72a9ba6 | 2017-03-28 17:28:52 | [diff] [blame] | 29 | |
Lily Chen | f65f5d4 | 2019-04-03 22:35:58 | [diff] [blame] | 30 | * Within `ReportingService` lives *`ReportingContext`*, which in turn |
| 31 | contains the inner workings of Reporting, spread across several classes: |
juliatuttle | 72a9ba6 | 2017-03-28 17:28:52 | [diff] [blame] | 32 | |
Lily Chen | f65f5d4 | 2019-04-03 22:35:58 | [diff] [blame] | 33 | * The *`ReportingCache`* stores undelivered reports and endpoint |
| 34 | configurations (aka "clients" in the spec). |
juliatuttle | 72a9ba6 | 2017-03-28 17:28:52 | [diff] [blame] | 35 | |
Lily Chen | f65f5d4 | 2019-04-03 22:35:58 | [diff] [blame] | 36 | * The *`ReportingHeaderParser`* parses `Report-To:` headers and updates |
| 37 | the cache accordingly. |
juliatuttle | 72a9ba6 | 2017-03-28 17:28:52 | [diff] [blame] | 38 | |
Lily Chen | f65f5d4 | 2019-04-03 22:35:58 | [diff] [blame] | 39 | * The *`ReportingDeliveryAgent`* reads reports from the cache, decides |
| 40 | which endpoints to deliver them to, and attempts to do so. It uses a |
| 41 | couple of helper classes: |
juliatuttle | 72a9ba6 | 2017-03-28 17:28:52 | [diff] [blame] | 42 | |
Lily Chen | f65f5d4 | 2019-04-03 22:35:58 | [diff] [blame] | 43 | * The *`ReportingUploader`* does the low-level work of delivering |
| 44 | reports: accepts a URL and JSON from the `DeliveryAgent`, creates |
| 45 | a `URLRequest`, and parses the result. It also handles sending |
| 46 | CORS preflight requests for cross-origin report uploads. |
juliatuttle | 72a9ba6 | 2017-03-28 17:28:52 | [diff] [blame] | 47 | |
Lily Chen | f65f5d4 | 2019-04-03 22:35:58 | [diff] [blame] | 48 | * The *`ReportingEndpointManager`* chooses an endpoint from the |
| 49 | cache when one is requested by the `ReportingDeliveryAgent`, and |
| 50 | manages exponential backoff (using `BackoffEntry`) for failing |
| 51 | endpoints. |
juliatuttle | 72a9ba6 | 2017-03-28 17:28:52 | [diff] [blame] | 52 | |
Lily Chen | f65f5d4 | 2019-04-03 22:35:58 | [diff] [blame] | 53 | * The *`ReportingGarbageCollector`* periodically examines the cache |
| 54 | and removes reports that have remained undelivered for too long, or |
| 55 | that have failed delivery too many times. |
juliatuttle | 72a9ba6 | 2017-03-28 17:28:52 | [diff] [blame] | 56 | |
Lily Chen | f65f5d4 | 2019-04-03 22:35:58 | [diff] [blame] | 57 | * The *`ReportingBrowsingDataRemover`* examines the cache upon request |
| 58 | and removes browsing data (reports and endpoints) of selected types |
| 59 | and origins. |
| 60 | |
| 61 | * The *`ReportingDelegate`* calls upon the `NetworkDelegate` (see below) |
| 62 | to check permissions for queueing/sending reports and setting/using |
| 63 | clients. |
| 64 | |
| 65 | * The `ReportingService` is set up in a `URLRequestContext` by passing a |
| 66 | `ReportingPolicy` to the `URLRequestContextBuilder`. This creates a |
| 67 | `ReportingService` which is owned by the `URLRequestContextStorage`. |
| 68 | |
| 69 | * `Report-To:` headers are processed by an `HttpNetworkTransaction` when they |
| 70 | are received, and passed on to the `ReportingService` to be added to the |
| 71 | cache. |
juliatuttle | 72a9ba6 | 2017-03-28 17:28:52 | [diff] [blame] | 72 | |
| 73 | ### Outside `//net` |
| 74 | |
Lily Chen | f65f5d4 | 2019-04-03 22:35:58 | [diff] [blame] | 75 | * In the network service, a `network::NetworkContext` queues reports by getting |
| 76 | the `ReportingService` from the `URLRequestContext`. |
juliatuttle | 72a9ba6 | 2017-03-28 17:28:52 | [diff] [blame] | 77 | |
Lily Chen | f65f5d4 | 2019-04-03 22:35:58 | [diff] [blame] | 78 | * The JavaScript [ReportingObserver](https://w3c.github.io/reporting/#observers) |
| 79 | interface lives [in `//third_party/blink/renderer/core/frame/`][1]. |
juliatuttle | 72a9ba6 | 2017-03-28 17:28:52 | [diff] [blame] | 80 | |
Lily Chen | f65f5d4 | 2019-04-03 22:35:58 | [diff] [blame] | 81 | * It queues reports via the `NetworkContext` using a |
| 82 | `blink::mojom::ReportingServiceProxy` (implemented [in |
| 83 | `//content/browser/net/`][2]), which can queue Intervention, Deprecation, |
Charlie Hu | cdd110d4 | 2020-11-23 23:04:32 | [diff] [blame] | 84 | CSP Violation, and Permissions Policy Violation reports. |
Lily Chen | f65f5d4 | 2019-04-03 22:35:58 | [diff] [blame] | 85 | |
| 86 | * The `ChromeNetworkDelegate` [in `//chrome/browser/net/`][3] checks permissions |
| 87 | for queueing reports and setting/using clients based on whether cookie access |
| 88 | is allowed, and checks permissions for sending reports using a |
| 89 | `ReportingPermissionsChecker`, which checks whether the user has allowed |
| 90 | report uploading via the BACKGROUND_SYNC permission. |
| 91 | |
| 92 | * Cronet can configure "preloaded" `Report-To:` headers (as well as Network |
| 93 | Error Logging headers) when initializing a `CronetURLRequestContext`, to allow |
| 94 | embedders to collect and send reports before having received a header in an |
| 95 | actual response. |
| 96 | |
| 97 | * This functionality is tested on Android by way of sending Network Error |
| 98 | Logging reports [in the Cronet Java tests][4]. |
| 99 | |
| 100 | [1]: https://chromium.googlesource.com/chromium/src/+/HEAD/third_party/blink/renderer/core/frame/reporting_observer.h |
| 101 | [2]: https://chromium.googlesource.com/chromium/src/+/HEAD/content/browser/net/reporting_service_proxy.cc |
| 102 | [3]: https://chromium.googlesource.com/chromium/src/+/HEAD/chrome/browser/net/chrome_network_delegate.h |
| 103 | [4]: https://chromium.googlesource.com/chromium/src/+/HEAD/components/cronet/android/test/javatests/src/org/chromium/net/NetworkErrorLoggingTest.java |