blob: 6c5411e808ca5e4cc61e16e54bf755d2536da9ac [file] [log] [blame]
juliatuttle586843332017-03-27 16:22:371// Copyright 2017 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef NET_REPORTING_REPORTING_CACHE_H_
6#define NET_REPORTING_REPORTING_CACHE_H_
7
juliatuttle586843332017-03-27 16:22:378#include <memory>
Lily Chenad5dd0802020-03-10 21:58:099#include <set>
Lily Chenefb6fcf2019-04-19 04:17:5410#include <string>
juliatuttle586843332017-03-27 16:22:3711#include <vector>
12
Hans Wennborga65658a2020-04-21 08:09:4613#include "base/callback.h"
juliatuttle586843332017-03-27 16:22:3714#include "base/macros.h"
juliatuttle586843332017-03-27 16:22:3715#include "base/time/time.h"
16#include "base/values.h"
17#include "net/base/net_export.h"
Lily Chenfc92ff42019-05-06 22:59:1018#include "net/reporting/reporting_endpoint.h"
Lily Chenefb6fcf2019-04-19 04:17:5419#include "net/reporting/reporting_header_parser.h"
juliatuttle667c0bb2017-07-06 15:17:1320#include "net/reporting/reporting_report.h"
juliatuttle586843332017-03-27 16:22:3721#include "url/gurl.h"
22#include "url/origin.h"
23
24namespace net {
25
Lily Chen731a95c2019-05-06 22:27:2226class ReportingContext;
27
juliatuttle586843332017-03-27 16:22:3728// The cache holds undelivered reports and clients (per-origin endpoint
29// configurations) in memory. (It is not responsible for persisting them.)
30//
Lily Chenefb6fcf2019-04-19 04:17:5431// Each Reporting "endpoint" represents a report collector at some specified
32// URL. Endpoints are organized into named "endpoint groups", each of which
33// additionally specifes some properties such as expiration time.
34// A "client" represents the entire endpoint configuration set by an origin via
35// a Report-To header, which consists of multiple endpoint groups, each of which
36// consists of multiple endpoints. An endpoint group is keyed by its name. An
37// endpoint is unkeyed except by the client and group structure tree above it.
38//
39// The cache implementation corresponds roughly to the "Reporting cache"
40// described in the spec, except that endpoints and clients are stored in a more
41// structurally-convenient way, and endpoint failures/retry-after are tracked in
42// ReportingEndpointManager.
juliatuttle72a9ba62017-03-28 17:28:5243//
44// The cache implementation has the notion of "pending" reports. These are
45// reports that are part of an active delivery attempt, so they won't be
46// actually deallocated. Any attempt to remove a pending report wil mark it
47// "doomed", which will cause it to be deallocated once it is no longer pending.
juliatuttle586843332017-03-27 16:22:3748class NET_EXPORT ReportingCache {
49 public:
Lily Chenc5652312019-03-20 21:58:3050 class PersistentReportingStore;
51
Sam Burnett1446f0dd2019-07-16 04:19:3052 static std::unique_ptr<ReportingCache> Create(ReportingContext* context);
juliatuttle586843332017-03-27 16:22:3753
juliatuttle0c436c8c2017-06-05 16:57:0454 virtual ~ReportingCache();
juliatuttle586843332017-03-27 16:22:3755
56 // Adds a report to the cache.
57 //
58 // All parameters correspond to the desired values for the relevant fields in
59 // ReportingReport.
Lily Chen09383462020-04-09 21:39:0660 virtual void AddReport(const NetworkIsolationKey& network_isolation_key,
61 const GURL& url,
Douglas Creagerf6cb49f72018-07-19 20:14:5362 const std::string& user_agent,
Lily Chenefb6fcf2019-04-19 04:17:5463 const std::string& group_name,
juliatuttle0c436c8c2017-06-05 16:57:0464 const std::string& type,
65 std::unique_ptr<const base::Value> body,
Julia Tuttle107e30672018-03-29 18:48:4266 int depth,
juliatuttle0c436c8c2017-06-05 16:57:0467 base::TimeTicks queued,
68 int attempts) = 0;
juliatuttle586843332017-03-27 16:22:3769
70 // Gets all reports in the cache. The returned pointers are valid as long as
71 // either no calls to |RemoveReports| have happened or the reports' |pending|
72 // flag has been set to true using |SetReportsPending|. Does not return
73 // doomed reports (pending reports for which removal has been requested).
74 //
75 // (Clears any existing data in |*reports_out|.)
juliatuttle0c436c8c2017-06-05 16:57:0476 virtual void GetReports(
77 std::vector<const ReportingReport*>* reports_out) const = 0;
juliatuttle586843332017-03-27 16:22:3778
Douglas Creager0b937ec2018-04-13 13:53:0979 // Gets all reports in the cache, including pending and doomed reports, as a
80 // base::Value.
81 virtual base::Value GetReportsAsValue() const = 0;
82
Lily Chend9ab4e52020-01-03 22:04:4483 // Gets all reports in the cache that aren't pending or doomed (i.e. that are
84 // eligible for delivery), and marks returned reports as pending in
85 // preparation for a delivery attempt. The returned pointers are valid as long
86 // as the reports are still pending.
87 virtual std::vector<const ReportingReport*> GetReportsToDeliver() = 0;
juliatuttle586843332017-03-27 16:22:3788
89 // Unmarks a set of reports as pending. |reports| must be previously marked as
90 // pending.
juliatuttle0c436c8c2017-06-05 16:57:0491 virtual void ClearReportsPending(
92 const std::vector<const ReportingReport*>& reports) = 0;
juliatuttle586843332017-03-27 16:22:3793
94 // Increments |attempts| on a set of reports.
juliatuttle0c436c8c2017-06-05 16:57:0495 virtual void IncrementReportsAttempts(
96 const std::vector<const ReportingReport*>& reports) = 0;
juliatuttle586843332017-03-27 16:22:3797
Lily Chenefb6fcf2019-04-19 04:17:5498 // Records that we attempted (and possibly succeeded at) delivering
99 // |reports_delivered| reports to the specified endpoint.
Lily Chenad5dd0802020-03-10 21:58:09100 virtual void IncrementEndpointDeliveries(
101 const ReportingEndpointGroupKey& group_key,
102 const GURL& url,
103 int reports_delivered,
104 bool successful) = 0;
Douglas Creager1f0b5022018-04-10 18:19:13105
juliatuttle586843332017-03-27 16:22:37106 // Removes a set of reports. Any reports that are pending will not be removed
107 // immediately, but rather marked doomed and removed once they are no longer
108 // pending.
Yutaka Hirano1515aed2021-07-09 07:38:43109 virtual void RemoveReports(
110 const std::vector<const ReportingReport*>& reports) = 0;
juliatuttle586843332017-03-27 16:22:37111
112 // Removes all reports. Like |RemoveReports()|, pending reports are doomed
113 // until no longer pending.
Yutaka Hirano1515aed2021-07-09 07:38:43114 virtual void RemoveAllReports() = 0;
juliatuttle586843332017-03-27 16:22:37115
juliatuttle586843332017-03-27 16:22:37116 // Gets the count of reports in the cache, *including* doomed reports.
117 //
118 // Needed to ensure that doomed reports are eventually deleted, since no
119 // method provides a view of *every* report in the cache, just non-doomed
120 // ones.
juliatuttle0c436c8c2017-06-05 16:57:04121 virtual size_t GetFullReportCountForTesting() const = 0;
juliatuttle586843332017-03-27 16:22:37122
juliatuttle0c436c8c2017-06-05 16:57:04123 virtual bool IsReportPendingForTesting(
124 const ReportingReport* report) const = 0;
juliatuttle586843332017-03-27 16:22:37125
juliatuttle0c436c8c2017-06-05 16:57:04126 virtual bool IsReportDoomedForTesting(
127 const ReportingReport* report) const = 0;
Lily Chenefb6fcf2019-04-19 04:17:54128
129 // Adds a new client to the cache for |origin|, or updates the existing one
130 // to match the new header. All values are assumed to be valid as they have
131 // passed through the ReportingHeaderParser.
132 virtual void OnParsedHeader(
Lily Chenf0dd74b2020-04-07 00:25:58133 const NetworkIsolationKey& network_isolation_key,
Lily Chenefb6fcf2019-04-19 04:17:54134 const url::Origin& origin,
135 std::vector<ReportingEndpointGroup> parsed_header) = 0;
136
137 // Gets all the origins of clients in the cache.
Lily Chenad5dd0802020-03-10 21:58:09138 virtual std::set<url::Origin> GetAllOrigins() const = 0;
Lily Chenefb6fcf2019-04-19 04:17:54139
Lily Chenad5dd0802020-03-10 21:58:09140 // Remove client for the given (NIK, origin) pair, if it exists in the cache.
141 // All endpoint groups and endpoints for that client are also removed.
142 virtual void RemoveClient(const NetworkIsolationKey& network_isolation_key,
143 const url::Origin& origin) = 0;
144
145 // Remove all clients for the given |origin|, if any exists in the cache.
Lily Chenefb6fcf2019-04-19 04:17:54146 // All endpoint groups and endpoints for |origin| are also removed.
Lily Chenad5dd0802020-03-10 21:58:09147 virtual void RemoveClientsForOrigin(const url::Origin& origin) = 0;
Lily Chenefb6fcf2019-04-19 04:17:54148
149 // Remove all clients, groups, and endpoints from the cache.
150 virtual void RemoveAllClients() = 0;
151
Lily Chenad5dd0802020-03-10 21:58:09152 // Remove the endpoint group matching |group_key|, and remove
153 // all endpoints for that group. May cause the client it was associated with
154 // to be deleted if it becomes empty.
155 virtual void RemoveEndpointGroup(
156 const ReportingEndpointGroupKey& group_key) = 0;
Lily Chenefb6fcf2019-04-19 04:17:54157
158 // Remove all endpoints for with |url|, regardless of origin or group. Used
159 // when a delivery returns 410 Gone. May cause deletion of groups/clients if
160 // they become empty.
161 virtual void RemoveEndpointsForUrl(const GURL& url) = 0;
162
Sam Burnett00099fc12019-07-24 23:26:15163 // Insert endpoints and endpoint groups that have been loaded from the store.
164 //
165 // You must only call this method if context.store() was non-null when you
166 // constructed the cache and persist_clients_across_restarts in your
167 // ReportingPolicy is true.
168 virtual void AddClientsLoadedFromStore(
169 std::vector<ReportingEndpoint> loaded_endpoints,
170 std::vector<CachedReportingEndpointGroup> loaded_endpoint_groups) = 0;
171
Lily Chenefb6fcf2019-04-19 04:17:54172 // Gets endpoints that apply to a delivery for |origin| and |group|.
173 //
174 // First checks for |group| in a client exactly matching |origin|.
175 // If none exists, then checks for |group| in clients for superdomains
176 // of |origin| which have include_subdomains enabled, returning only the
177 // endpoints for the most specific applicable parent origin of |origin|. If
178 // there are multiple origins with that group within the most specific
179 // applicable superdomain, gets endpoints for that group from only one of
180 // them. The group must not be expired.
181 //
182 // For example, given the origin https://foo.bar.baz.com/, the cache
183 // would prioritize returning each potential match below over the ones below
184 // it, for groups with name |group| with include_subdomains enabled:
185 // 1. https://foo.bar.baz.com/ (exact origin match)
186 // 2. https://foo.bar.baz.com:444/ (technically, a superdomain)
187 // 3. https://bar.baz.com/, https://bar.baz.com:444/, etc. (superdomain)
188 // 4. https://baz.com/, https://baz.com:444/, etc. (superdomain)
189 // If both https://bar.baz.com/ and https://bar.baz.com:444/ had a group with
190 // name |group| with include_subdomains enabled, this method would return
191 // endpoints from that group from the earliest-inserted origin.
Lily Chenfc92ff42019-05-06 22:59:10192 virtual std::vector<ReportingEndpoint> GetCandidateEndpointsForDelivery(
Lily Chenad5dd0802020-03-10 21:58:09193 const ReportingEndpointGroupKey& group_key) = 0;
Lily Chenefb6fcf2019-04-19 04:17:54194
195 // Gets the status of all clients in the cache, including expired ones, as a
196 // base::Value.
197 virtual base::Value GetClientsAsValue() const = 0;
198
199 // Gets the total number of endpoints in the cache across all origins.
200 virtual size_t GetEndpointCount() const = 0;
201
Sam Burnettf13c06b2019-07-30 15:53:49202 // Flush the contents of the cache to disk, if applicable.
203 virtual void Flush() = 0;
204
Lily Chenad5dd0802020-03-10 21:58:09205 // Finds an endpoint for the given |group_key| and |url|, otherwise returns an
206 // invalid ReportingEndpoint.
207 virtual ReportingEndpoint GetEndpointForTesting(
208 const ReportingEndpointGroupKey& group_key,
209 const GURL& url) const = 0;
Lily Chenefb6fcf2019-04-19 04:17:54210
211 // Returns whether an endpoint group with exactly the given properties exists
212 // in the cache. If |expires| is base::Time(), it will not be checked.
213 virtual bool EndpointGroupExistsForTesting(
Lily Chenad5dd0802020-03-10 21:58:09214 const ReportingEndpointGroupKey& group_key,
Lily Chenefb6fcf2019-04-19 04:17:54215 OriginSubdomains include_subdomains,
216 base::Time expires) const = 0;
217
Lily Chenad5dd0802020-03-10 21:58:09218 // Returns whether a client for the given (NIK, Origin) exists.
219 virtual bool ClientExistsForTesting(
220 const NetworkIsolationKey& network_isolation_key,
221 const url::Origin& origin) const = 0;
222
Lily Chenefb6fcf2019-04-19 04:17:54223 // Returns number of endpoint groups.
224 virtual size_t GetEndpointGroupCountForTesting() const = 0;
225
Lily Chenad5dd0802020-03-10 21:58:09226 // Returns number of endpoint groups.
227 virtual size_t GetClientCountForTesting() const = 0;
228
Lily Chenefb6fcf2019-04-19 04:17:54229 // Sets an endpoint with the given properties in a group with the given
230 // properties, bypassing header parsing. Note that the endpoint is not
231 // guaranteed to exist in the cache after calling this function, if endpoint
232 // eviction is triggered. Unlike the AddOrUpdate*() methods used in header
233 // parsing, this method inserts or updates a single endpoint while leaving the
234 // exiting configuration for that origin intact.
Lily Chenad5dd0802020-03-10 21:58:09235 virtual void SetEndpointForTesting(const ReportingEndpointGroupKey& group_key,
Lily Chenefb6fcf2019-04-19 04:17:54236 const GURL& url,
237 OriginSubdomains include_subdomains,
238 base::Time expires,
239 int priority,
240 int weight) = 0;
juliatuttle586843332017-03-27 16:22:37241};
242
Lily Chenc5652312019-03-20 21:58:30243// Persistent storage for Reporting reports and clients.
244class NET_EXPORT ReportingCache::PersistentReportingStore {
245 public:
Lily Chen6a00fa362019-04-26 19:22:55246 using ReportingClientsLoadedCallback =
Lily Chenfc92ff42019-05-06 22:59:10247 base::OnceCallback<void(std::vector<ReportingEndpoint>,
Lily Chen6a00fa362019-04-26 19:22:55248 std::vector<CachedReportingEndpointGroup>)>;
249
Lily Chenc5652312019-03-20 21:58:30250 PersistentReportingStore() = default;
251 virtual ~PersistentReportingStore() = default;
252
Lily Chen6a00fa362019-04-26 19:22:55253 // Initializes the store and retrieves stored endpoints and endpoint groups.
254 // Called only once at startup.
255 virtual void LoadReportingClients(
256 ReportingClientsLoadedCallback loaded_callback) = 0;
257
258 // Adds an endpoint to the store.
Lily Chenfc92ff42019-05-06 22:59:10259 virtual void AddReportingEndpoint(const ReportingEndpoint& endpoint) = 0;
Lily Chen6a00fa362019-04-26 19:22:55260 // Adds an endpoint group to the store.
261 virtual void AddReportingEndpointGroup(
262 const CachedReportingEndpointGroup& group) = 0;
263
264 // Updates the access time of an endpoint group in the store.
265 virtual void UpdateReportingEndpointGroupAccessTime(
266 const CachedReportingEndpointGroup& group) = 0;
267
268 // Updates the details of an endpoint in the store.
269 virtual void UpdateReportingEndpointDetails(
Lily Chenfc92ff42019-05-06 22:59:10270 const ReportingEndpoint& endpoint) = 0;
Lily Chen6a00fa362019-04-26 19:22:55271 // Updates the details of an endpoint group in the store.
272 virtual void UpdateReportingEndpointGroupDetails(
273 const CachedReportingEndpointGroup& group) = 0;
274
275 // Deletes an endpoint from the store.
Lily Chenfc92ff42019-05-06 22:59:10276 virtual void DeleteReportingEndpoint(const ReportingEndpoint& endpoint) = 0;
Lily Chen6a00fa362019-04-26 19:22:55277 // Deletes an endpoint group from the store.
278 virtual void DeleteReportingEndpointGroup(
279 const CachedReportingEndpointGroup& group) = 0;
280
281 // TODO(chlily): methods to load, add, and delete reports will be added.
Lily Chenc5652312019-03-20 21:58:30282
283 // Flushes the store.
284 virtual void Flush() = 0;
285
286 private:
287 DISALLOW_COPY_AND_ASSIGN(PersistentReportingStore);
288};
289
juliatuttle586843332017-03-27 16:22:37290} // namespace net
291
292#endif // NET_REPORTING_REPORTING_CACHE_H_