blob: 49100b80047a342d322cd742c2655661235c377a [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 Chenefb6fcf2019-04-19 04:17:549#include <string>
juliatuttle586843332017-03-27 16:22:3710#include <vector>
11
12#include "base/macros.h"
13#include "base/stl_util.h"
14#include "base/time/time.h"
15#include "base/values.h"
16#include "net/base/net_export.h"
17#include "net/reporting/reporting_client.h"
Lily Chenefb6fcf2019-04-19 04:17:5418#include "net/reporting/reporting_context.h"
19#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
juliatuttle586843332017-03-27 16:22:3726// The cache holds undelivered reports and clients (per-origin endpoint
27// configurations) in memory. (It is not responsible for persisting them.)
28//
Lily Chenefb6fcf2019-04-19 04:17:5429// Each Reporting "endpoint" represents a report collector at some specified
30// URL. Endpoints are organized into named "endpoint groups", each of which
31// additionally specifes some properties such as expiration time.
32// A "client" represents the entire endpoint configuration set by an origin via
33// a Report-To header, which consists of multiple endpoint groups, each of which
34// consists of multiple endpoints. An endpoint group is keyed by its name. An
35// endpoint is unkeyed except by the client and group structure tree above it.
36//
37// The cache implementation corresponds roughly to the "Reporting cache"
38// described in the spec, except that endpoints and clients are stored in a more
39// structurally-convenient way, and endpoint failures/retry-after are tracked in
40// ReportingEndpointManager.
juliatuttle72a9ba62017-03-28 17:28:5241//
42// The cache implementation has the notion of "pending" reports. These are
43// reports that are part of an active delivery attempt, so they won't be
44// actually deallocated. Any attempt to remove a pending report wil mark it
45// "doomed", which will cause it to be deallocated once it is no longer pending.
juliatuttle586843332017-03-27 16:22:3746class NET_EXPORT ReportingCache {
47 public:
Lily Chenc5652312019-03-20 21:58:3048 class PersistentReportingStore;
49
juliatuttle0c436c8c2017-06-05 16:57:0450 static std::unique_ptr<ReportingCache> Create(ReportingContext* context);
juliatuttle586843332017-03-27 16:22:3751
juliatuttle0c436c8c2017-06-05 16:57:0452 virtual ~ReportingCache();
juliatuttle586843332017-03-27 16:22:3753
54 // Adds a report to the cache.
55 //
56 // All parameters correspond to the desired values for the relevant fields in
57 // ReportingReport.
juliatuttle0c436c8c2017-06-05 16:57:0458 virtual void AddReport(const GURL& url,
Douglas Creagerf6cb49f72018-07-19 20:14:5359 const std::string& user_agent,
Lily Chenefb6fcf2019-04-19 04:17:5460 const std::string& group_name,
juliatuttle0c436c8c2017-06-05 16:57:0461 const std::string& type,
62 std::unique_ptr<const base::Value> body,
Julia Tuttle107e30672018-03-29 18:48:4263 int depth,
juliatuttle0c436c8c2017-06-05 16:57:0464 base::TimeTicks queued,
65 int attempts) = 0;
juliatuttle586843332017-03-27 16:22:3766
67 // Gets all reports in the cache. The returned pointers are valid as long as
68 // either no calls to |RemoveReports| have happened or the reports' |pending|
69 // flag has been set to true using |SetReportsPending|. Does not return
70 // doomed reports (pending reports for which removal has been requested).
71 //
72 // (Clears any existing data in |*reports_out|.)
juliatuttle0c436c8c2017-06-05 16:57:0473 virtual void GetReports(
74 std::vector<const ReportingReport*>* reports_out) const = 0;
juliatuttle586843332017-03-27 16:22:3775
Douglas Creager0b937ec2018-04-13 13:53:0976 // Gets all reports in the cache, including pending and doomed reports, as a
77 // base::Value.
78 virtual base::Value GetReportsAsValue() const = 0;
79
Douglas Creager66494e12018-03-05 22:21:0080 // Gets all reports in the cache that aren't pending. The returned pointers
81 // are valid as long as either no calls to |RemoveReports| have happened or
82 // the reports' |pending| flag has been set to true using |SetReportsPending|.
83 //
84 // (Clears any existing data in |*reports_out|.)
85 virtual void GetNonpendingReports(
86 std::vector<const ReportingReport*>* reports_out) const = 0;
87
juliatuttle586843332017-03-27 16:22:3788 // Marks a set of reports as pending. |reports| must not already be marked as
89 // pending.
juliatuttle0c436c8c2017-06-05 16:57:0490 virtual void SetReportsPending(
91 const std::vector<const ReportingReport*>& reports) = 0;
juliatuttle586843332017-03-27 16:22:3792
93 // Unmarks a set of reports as pending. |reports| must be previously marked as
94 // pending.
juliatuttle0c436c8c2017-06-05 16:57:0495 virtual void ClearReportsPending(
96 const std::vector<const ReportingReport*>& reports) = 0;
juliatuttle586843332017-03-27 16:22:3797
98 // Increments |attempts| on a set of reports.
juliatuttle0c436c8c2017-06-05 16:57:0499 virtual void IncrementReportsAttempts(
100 const std::vector<const ReportingReport*>& reports) = 0;
juliatuttle586843332017-03-27 16:22:37101
Lily Chenefb6fcf2019-04-19 04:17:54102 // Records that we attempted (and possibly succeeded at) delivering
103 // |reports_delivered| reports to the specified endpoint.
Douglas Creagere13028c2018-07-02 18:08:27104 virtual void IncrementEndpointDeliveries(const url::Origin& origin,
Lily Chenefb6fcf2019-04-19 04:17:54105 const std::string& group_name,
106 const GURL& url,
Douglas Creagere13028c2018-07-02 18:08:27107 int reports_delivered,
108 bool successful) = 0;
Douglas Creager1f0b5022018-04-10 18:19:13109
juliatuttle586843332017-03-27 16:22:37110 // Removes a set of reports. Any reports that are pending will not be removed
111 // immediately, but rather marked doomed and removed once they are no longer
112 // pending.
juliatuttle667c0bb2017-07-06 15:17:13113 virtual void RemoveReports(const std::vector<const ReportingReport*>& reports,
114 ReportingReport::Outcome outcome) = 0;
juliatuttle586843332017-03-27 16:22:37115
116 // Removes all reports. Like |RemoveReports()|, pending reports are doomed
117 // until no longer pending.
juliatuttle667c0bb2017-07-06 15:17:13118 virtual void RemoveAllReports(ReportingReport::Outcome outcome) = 0;
juliatuttle586843332017-03-27 16:22:37119
juliatuttle586843332017-03-27 16:22:37120 // Gets the count of reports in the cache, *including* doomed reports.
121 //
122 // Needed to ensure that doomed reports are eventually deleted, since no
123 // method provides a view of *every* report in the cache, just non-doomed
124 // ones.
juliatuttle0c436c8c2017-06-05 16:57:04125 virtual size_t GetFullReportCountForTesting() const = 0;
juliatuttle586843332017-03-27 16:22:37126
juliatuttle0c436c8c2017-06-05 16:57:04127 virtual bool IsReportPendingForTesting(
128 const ReportingReport* report) const = 0;
juliatuttle586843332017-03-27 16:22:37129
juliatuttle0c436c8c2017-06-05 16:57:04130 virtual bool IsReportDoomedForTesting(
131 const ReportingReport* report) const = 0;
Lily Chenefb6fcf2019-04-19 04:17:54132
133 // Adds a new client to the cache for |origin|, or updates the existing one
134 // to match the new header. All values are assumed to be valid as they have
135 // passed through the ReportingHeaderParser.
136 virtual void OnParsedHeader(
137 const url::Origin& origin,
138 std::vector<ReportingEndpointGroup> parsed_header) = 0;
139
140 // Gets all the origins of clients in the cache.
141 virtual std::vector<url::Origin> GetAllOrigins() const = 0;
142
143 // Remove client for the given |origin|, if it exists in the cache.
144 // All endpoint groups and endpoints for |origin| are also removed.
145 virtual void RemoveClient(const url::Origin& origin) = 0;
146
147 // Remove all clients, groups, and endpoints from the cache.
148 virtual void RemoveAllClients() = 0;
149
150 // Remove the endpoint group named |name| for the given |origin|, and remove
151 // all endpoints for that group. May cause the client for |origin| to be
152 // deleted if it becomes empty.
153 virtual void RemoveEndpointGroup(const url::Origin& origin,
154 const std::string& group_name) = 0;
155
156 // Remove all endpoints for with |url|, regardless of origin or group. Used
157 // when a delivery returns 410 Gone. May cause deletion of groups/clients if
158 // they become empty.
159 virtual void RemoveEndpointsForUrl(const GURL& url) = 0;
160
161 // Gets endpoints that apply to a delivery for |origin| and |group|.
162 //
163 // First checks for |group| in a client exactly matching |origin|.
164 // If none exists, then checks for |group| in clients for superdomains
165 // of |origin| which have include_subdomains enabled, returning only the
166 // endpoints for the most specific applicable parent origin of |origin|. If
167 // there are multiple origins with that group within the most specific
168 // applicable superdomain, gets endpoints for that group from only one of
169 // them. The group must not be expired.
170 //
171 // For example, given the origin https://foo.bar.baz.com/, the cache
172 // would prioritize returning each potential match below over the ones below
173 // it, for groups with name |group| with include_subdomains enabled:
174 // 1. https://foo.bar.baz.com/ (exact origin match)
175 // 2. https://foo.bar.baz.com:444/ (technically, a superdomain)
176 // 3. https://bar.baz.com/, https://bar.baz.com:444/, etc. (superdomain)
177 // 4. https://baz.com/, https://baz.com:444/, etc. (superdomain)
178 // If both https://bar.baz.com/ and https://bar.baz.com:444/ had a group with
179 // name |group| with include_subdomains enabled, this method would return
180 // endpoints from that group from the earliest-inserted origin.
181 virtual std::vector<ReportingClient> GetCandidateEndpointsForDelivery(
182 const url::Origin& origin,
183 const std::string& group_name) = 0;
184
185 // Gets the status of all clients in the cache, including expired ones, as a
186 // base::Value.
187 virtual base::Value GetClientsAsValue() const = 0;
188
189 // Gets the total number of endpoints in the cache across all origins.
190 virtual size_t GetEndpointCount() const = 0;
191
192 // Finds an endpoint for the given |origin|, |group_name|, and |url|,
193 // otherwise returns an invalid ReportingClient.
194 virtual ReportingClient GetEndpointForTesting(const url::Origin& origin,
195 const std::string& group_name,
196 const GURL& url) const = 0;
197
198 // Returns whether an endpoint group with exactly the given properties exists
199 // in the cache. If |expires| is base::Time(), it will not be checked.
200 virtual bool EndpointGroupExistsForTesting(
201 const url::Origin& origin,
202 const std::string& group_name,
203 OriginSubdomains include_subdomains,
204 base::Time expires) const = 0;
205
206 // Returns number of endpoint groups.
207 virtual size_t GetEndpointGroupCountForTesting() const = 0;
208
209 // Sets an endpoint with the given properties in a group with the given
210 // properties, bypassing header parsing. Note that the endpoint is not
211 // guaranteed to exist in the cache after calling this function, if endpoint
212 // eviction is triggered. Unlike the AddOrUpdate*() methods used in header
213 // parsing, this method inserts or updates a single endpoint while leaving the
214 // exiting configuration for that origin intact.
215 virtual void SetEndpointForTesting(const url::Origin& origin,
216 const std::string& group_name,
217 const GURL& url,
218 OriginSubdomains include_subdomains,
219 base::Time expires,
220 int priority,
221 int weight) = 0;
juliatuttle586843332017-03-27 16:22:37222};
223
Lily Chenc5652312019-03-20 21:58:30224// Persistent storage for Reporting reports and clients.
225class NET_EXPORT ReportingCache::PersistentReportingStore {
226 public:
227 PersistentReportingStore() = default;
228 virtual ~PersistentReportingStore() = default;
229
230 // TODO(chlily): methods to load, add, update, delete, etc. will be added.
231
232 // Flushes the store.
233 virtual void Flush() = 0;
234
235 private:
236 DISALLOW_COPY_AND_ASSIGN(PersistentReportingStore);
237};
238
juliatuttle586843332017-03-27 16:22:37239} // namespace net
240
241#endif // NET_REPORTING_REPORTING_CACHE_H_