blob: 18ed839144836feb50814fdcd3718848c4b46044 [file] [log] [blame]
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef NET_REPORTING_REPORTING_CACHE_H_
#define NET_REPORTING_REPORTING_CACHE_H_
#include <memory>
#include <vector>
#include "base/macros.h"
#include "base/stl_util.h"
#include "base/time/time.h"
#include "base/values.h"
#include "net/base/net_export.h"
#include "net/reporting/reporting_client.h"
#include "net/reporting/reporting_report.h"
#include "url/gurl.h"
#include "url/origin.h"
namespace net {
class ReportingContext;
// The cache holds undelivered reports and clients (per-origin endpoint
// configurations) in memory. (It is not responsible for persisting them.)
//
// This corresponds roughly to the "Reporting cache" in the spec, except that
// endpoints and clients are stored in a more structurally-convenient way, and
// endpoint failures/retry-after are tracked in ReportingEndpointManager.
//
// The cache implementation has the notion of "pending" reports. These are
// reports that are part of an active delivery attempt, so they won't be
// actually deallocated. Any attempt to remove a pending report wil mark it
// "doomed", which will cause it to be deallocated once it is no longer pending.
class NET_EXPORT ReportingCache {
public:
// Information about the number of deliveries that we've attempted for each
// origin and endpoint.
struct ClientStatistics {
// The number of attempts uploads that we've made for this client.
int attempted_uploads = 0;
// The number of uploads that have succeeded for this client.
int successful_uploads = 0;
// The number of individual reports that we've attempted to upload for this
// client. (Failed uploads will cause a report to be counted multiple
// times, once for each attempt.)
int attempted_reports = 0;
// The number of individual reports that we've successfully uploaded for
// this client.
int successful_reports = 0;
};
static std::unique_ptr<ReportingCache> Create(ReportingContext* context);
virtual ~ReportingCache();
// Adds a report to the cache.
//
// All parameters correspond to the desired values for the relevant fields in
// ReportingReport.
virtual void AddReport(const GURL& url,
const std::string& user_agent,
const std::string& group,
const std::string& type,
std::unique_ptr<const base::Value> body,
int depth,
base::TimeTicks queued,
int attempts) = 0;
// Gets all reports in the cache. The returned pointers are valid as long as
// either no calls to |RemoveReports| have happened or the reports' |pending|
// flag has been set to true using |SetReportsPending|. Does not return
// doomed reports (pending reports for which removal has been requested).
//
// (Clears any existing data in |*reports_out|.)
virtual void GetReports(
std::vector<const ReportingReport*>* reports_out) const = 0;
// Gets all reports in the cache, including pending and doomed reports, as a
// base::Value.
virtual base::Value GetReportsAsValue() const = 0;
// Gets all reports in the cache that aren't pending. The returned pointers
// are valid as long as either no calls to |RemoveReports| have happened or
// the reports' |pending| flag has been set to true using |SetReportsPending|.
//
// (Clears any existing data in |*reports_out|.)
virtual void GetNonpendingReports(
std::vector<const ReportingReport*>* reports_out) const = 0;
// Marks a set of reports as pending. |reports| must not already be marked as
// pending.
virtual void SetReportsPending(
const std::vector<const ReportingReport*>& reports) = 0;
// Unmarks a set of reports as pending. |reports| must be previously marked as
// pending.
virtual void ClearReportsPending(
const std::vector<const ReportingReport*>& reports) = 0;
// Increments |attempts| on a set of reports.
virtual void IncrementReportsAttempts(
const std::vector<const ReportingReport*>& reports) = 0;
// Records that we attempted (and possibly succeeded at) delivering |reports|
// to |endpoint|.
virtual void IncrementEndpointDeliveries(const url::Origin& origin,
const GURL& endpoint,
int reports_delivered,
bool successful) = 0;
// Removes a set of reports. Any reports that are pending will not be removed
// immediately, but rather marked doomed and removed once they are no longer
// pending.
virtual void RemoveReports(const std::vector<const ReportingReport*>& reports,
ReportingReport::Outcome outcome) = 0;
// Removes all reports. Like |RemoveReports()|, pending reports are doomed
// until no longer pending.
virtual void RemoveAllReports(ReportingReport::Outcome outcome) = 0;
// Creates or updates a client for a particular origin and a particular
// endpoint.
//
// All parameters correspond to the desired values for the fields in
// ReportingClient.
//
// |endpoint| must use a cryptographic scheme.
virtual void SetClient(const url::Origin& origin,
const GURL& endpoint,
ReportingClient::Subdomains subdomains,
const std::string& group,
base::TimeTicks expires,
int priority,
int client) = 0;
virtual void MarkClientUsed(const ReportingClient* client) = 0;
// Gets all of the clients in the cache, regardless of origin or group.
//
// (Clears any existing data in |*clients_out|.)
virtual void GetClients(
std::vector<const ReportingClient*>* clients_out) const = 0;
// Gets information about all of the clients in the cache, encoded as a
// base::Value.
virtual base::Value GetClientsAsValue() const = 0;
// Gets all of the clients configured for a particular origin in a particular
// group. The returned pointers are only guaranteed to be valid if no calls
// have been made to |SetClient| or |RemoveEndpoint| in between.
//
// If no origin match is found, the cache will return clients from the most
// specific superdomain which contains any clients with include_subdomains
// set. For example, given the origin https://foo.bar.baz.com/, the cache
// would prioritize returning each potential match below over the ones below
// it:
//
// 1. https://foo.bar.baz.com/ (exact origin match)
// 2. https://foo.bar.baz.com:444/ (technically, a superdomain)
// 3. https://bar.baz.com/, https://bar.baz.com:444/, etc. (superdomain)
// 4. https://baz.com/, https://baz.com:444/, etc. (superdomain)
// etc.
//
// (Clears any existing data in |*clients_out|.)
virtual void GetClientsForOriginAndGroup(
const url::Origin& origin,
const std::string& group,
std::vector<const ReportingClient*>* clients_out) const = 0;
// Gets all of the endpoints in the cache configured for a particular origin.
// Does not pay attention to wildcard hosts; only returns endpoints configured
// by |origin| itself.
virtual void GetEndpointsForOrigin(
const url::Origin& origin,
std::vector<GURL>* endpoints_out) const = 0;
// Removes a set of clients.
//
// May invalidate ReportingClient pointers returned by |GetClients| or
// |GetClientsForOriginAndGroup|.
virtual void RemoveClients(
const std::vector<const ReportingClient*>& clients) = 0;
// Removes a client for a particular origin and a particular endpoint.
virtual void RemoveClientForOriginAndEndpoint(const url::Origin& origin,
const GURL& endpoint) = 0;
// Removes all clients whose endpoint is |endpoint|.
//
// May invalidate ReportingClient pointers returned by |GetClients| or
// |GetClientsForOriginAndGroup|.
virtual void RemoveClientsForEndpoint(const GURL& endpoint) = 0;
// Removes all clients.
virtual void RemoveAllClients() = 0;
// Returns information about the number of attempted and successful uploads
// for a particular origin and endpoint.
virtual ClientStatistics GetStatisticsForOriginAndEndpoint(
const url::Origin& origin,
const GURL& endpoint) const = 0;
// Gets the count of reports in the cache, *including* doomed reports.
//
// Needed to ensure that doomed reports are eventually deleted, since no
// method provides a view of *every* report in the cache, just non-doomed
// ones.
virtual size_t GetFullReportCountForTesting() const = 0;
virtual bool IsReportPendingForTesting(
const ReportingReport* report) const = 0;
virtual bool IsReportDoomedForTesting(
const ReportingReport* report) const = 0;
};
} // namespace net
#endif // NET_REPORTING_REPORTING_CACHE_H_