123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331 |
- // 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_NETWORK_ERROR_LOGGING_NETWORK_ERROR_LOGGING_SERVICE_H_
- #define NET_NETWORK_ERROR_LOGGING_NETWORK_ERROR_LOGGING_SERVICE_H_
- #include <map>
- #include <memory>
- #include <set>
- #include <string>
- #include <vector>
- #include "base/feature_list.h"
- #include "base/memory/raw_ptr.h"
- #include "base/time/clock.h"
- #include "base/time/time.h"
- #include "net/base/ip_address.h"
- #include "net/base/net_errors.h"
- #include "net/base/net_export.h"
- #include "net/base/network_isolation_key.h"
- #include "url/gurl.h"
- #include "url/origin.h"
- namespace base {
- class Value;
- } // namespace base
- namespace net {
- class ReportingService;
- } // namespace net
- namespace url {
- class Origin;
- } // namespace url
- namespace features {
- extern const base::Feature NET_EXPORT kNetworkErrorLogging;
- } // namespace features
- namespace net {
- class NET_EXPORT NetworkErrorLoggingService {
- public:
- class PersistentNelStore;
- // Every (NIK, origin) pair can have at most one policy.
- struct NET_EXPORT NelPolicyKey {
- NelPolicyKey();
- NelPolicyKey(const NetworkIsolationKey& network_isolation_key,
- const url::Origin& origin);
- NelPolicyKey(const NelPolicyKey& other);
- ~NelPolicyKey();
- bool operator<(const NelPolicyKey& other) const;
- bool operator==(const NelPolicyKey& other) const;
- bool operator!=(const NelPolicyKey& other) const;
- // The NIK of the request this policy was received from. This will be used
- // for any requests uploading reports according to this policy. (Not
- // included in the report itself.)
- NetworkIsolationKey network_isolation_key;
- url::Origin origin;
- };
- // Used for wildcard policies that are applicable to |domain| and its
- // subdomains.
- struct WildcardNelPolicyKey {
- WildcardNelPolicyKey();
- WildcardNelPolicyKey(const NetworkIsolationKey& network_isolation_key,
- const std::string& domain);
- explicit WildcardNelPolicyKey(const NelPolicyKey& origin_key);
- WildcardNelPolicyKey(const WildcardNelPolicyKey& other);
- ~WildcardNelPolicyKey();
- bool operator<(const WildcardNelPolicyKey& other) const;
- // The NIK of the request this policy was received from. This will be used
- // for any requests uploading reports according to this policy. (Not
- // included in the report itself.)
- NetworkIsolationKey network_isolation_key;
- std::string domain;
- };
- // NEL policy set by an origin.
- struct NET_EXPORT NelPolicy {
- NelPolicy();
- NelPolicy(const NelPolicy& other);
- ~NelPolicy();
- NelPolicyKey key;
- IPAddress received_ip_address = IPAddress();
- // Reporting API endpoint group to which reports should be sent.
- std::string report_to;
- base::Time expires;
- double success_fraction = 0.0;
- double failure_fraction = 1.0;
- bool include_subdomains = false;
- // Last time the policy was accessed to create a report, even if no report
- // ends up being queued. Also updated when the policy is first set.
- mutable base::Time last_used;
- };
- // The details of a network error that are included in an NEL report.
- //
- // See http://wicg.github.io/network-error-logging/#dfn-network-error-object
- // for details on the semantics of each field.
- struct NET_EXPORT RequestDetails {
- RequestDetails();
- RequestDetails(const RequestDetails& other);
- ~RequestDetails();
- // NetworkIsolationKey of the request triggering the error. Not included
- // in the uploaded report.
- NetworkIsolationKey network_isolation_key;
- GURL uri;
- GURL referrer;
- std::string user_agent;
- IPAddress server_ip;
- std::string protocol;
- std::string method;
- int status_code;
- base::TimeDelta elapsed_time;
- Error type;
- // Upload nesting depth of this request.
- //
- // If the request is not a Reporting upload, the depth is 0.
- //
- // If the request is a Reporting upload, the depth is the max of the depth
- // of the requests reported within it plus 1. (Non-NEL reports are
- // considered to have depth 0.)
- int reporting_upload_depth;
- };
- // The details of a signed exchange report.
- struct NET_EXPORT SignedExchangeReportDetails {
- SignedExchangeReportDetails();
- SignedExchangeReportDetails(const SignedExchangeReportDetails& other);
- ~SignedExchangeReportDetails();
- // NetworkIsolationKey of the request triggering the error. Not included
- // in the uploaded report.
- NetworkIsolationKey network_isolation_key;
- bool success;
- std::string type;
- GURL outer_url;
- GURL inner_url;
- GURL cert_url;
- std::string referrer;
- IPAddress server_ip_address;
- std::string protocol;
- std::string method;
- int32_t status_code;
- base::TimeDelta elapsed_time;
- std::string user_agent;
- };
- static const char kHeaderName[];
- static const char kReportType[];
- static const int kMaxNestedReportDepth;
- // Keys for data included in report bodies. Exposed for tests.
- static const char kReferrerKey[];
- static const char kSamplingFractionKey[];
- static const char kServerIpKey[];
- static const char kProtocolKey[];
- static const char kMethodKey[];
- static const char kStatusCodeKey[];
- static const char kElapsedTimeKey[];
- static const char kPhaseKey[];
- static const char kTypeKey[];
- static const char kSignedExchangePhaseValue[];
- static const char kSignedExchangeBodyKey[];
- static const char kOuterUrlKey[];
- static const char kInnerUrlKey[];
- static const char kCertUrlKey[];
- // Maximum number of NEL policies to store before evicting.
- static const size_t kMaxPolicies;
- static const char kSignedExchangeRequestOutcomeHistogram[];
- // Used for histogramming Signed Exchange request outcomes only. Previously,
- // the outcome of all requests would be histogrammed, but this was removed in
- // crbug.com/1007122 because the histogram was very large and not very useful.
- enum class RequestOutcome {
- kDiscardedNoNetworkErrorLoggingService = 0,
- kDiscardedNoReportingService = 1,
- kDiscardedInsecureOrigin = 2,
- kDiscardedNoOriginPolicy = 3,
- kDiscardedUnmappedError = 4,
- kDiscardedReportingUpload = 5,
- kDiscardedUnsampledSuccess = 6,
- kDiscardedUnsampledFailure = 7,
- kQueued = 8,
- kDiscardedNonDNSSubdomainReport = 9,
- kDiscardedIPAddressMismatch = 10,
- kMaxValue = kDiscardedIPAddressMismatch
- };
- // NEL policies are persisted to disk if |store| is not null.
- // The store, if given, should outlive |*this|.
- static std::unique_ptr<NetworkErrorLoggingService> Create(
- PersistentNelStore* store);
- NetworkErrorLoggingService(const NetworkErrorLoggingService&) = delete;
- NetworkErrorLoggingService& operator=(const NetworkErrorLoggingService&) =
- delete;
- virtual ~NetworkErrorLoggingService();
- // Ingests a "NEL:" header received for |network_isolation_key| and |origin|
- // from |received_ip_address| with normalized value |value|. May or may not
- // actually set a policy for that origin.
- virtual void OnHeader(const NetworkIsolationKey& network_isolation_key,
- const url::Origin& origin,
- const IPAddress& received_ip_address,
- const std::string& value) = 0;
- // Considers queueing a network error report for the request described in
- // |details|. The contents of |details| might be changed, depending on the
- // NEL policy associated with the request's origin. Note that |details| is
- // passed by value, so that it doesn't need to be copied in this function if
- // it needs to be changed. Consider using std::move to pass this parameter if
- // the caller doesn't need to access it after this method call.
- //
- // Note that Network Error Logging can report a fraction of successful
- // requests as well (to calculate error rates), so this should be called on
- // *all* secure requests. NEL is only available to secure origins, so this is
- // not called on any insecure requests.
- virtual void OnRequest(RequestDetails details) = 0;
- // Queues a Signed Exchange report.
- virtual void QueueSignedExchangeReport(
- SignedExchangeReportDetails details) = 0;
- // Removes browsing data (origin policies) associated with any origin for
- // which |origin_filter| returns true.
- virtual void RemoveBrowsingData(
- const base::RepeatingCallback<bool(const url::Origin&)>&
- origin_filter) = 0;
- // Removes browsing data (origin policies) for all origins. Allows slight
- // optimization over passing an always-true filter to RemoveBrowsingData.
- virtual void RemoveAllBrowsingData() = 0;
- // Sets the ReportingService that will be used to queue network error reports.
- // If |nullptr| is passed, reports will be queued locally or discarded.
- // |reporting_service| must outlive the NetworkErrorLoggingService.
- // Should not be called again if previously called with a non-null pointer.
- void SetReportingService(ReportingService* reporting_service);
- // Shuts down the NEL service, so that no more requests or headers can be
- // processed, no more reports are queued, and browsing data can no longer be
- // cleared.
- void OnShutdown();
- // Sets a base::Clock (used to track policy expiration) for tests.
- // |clock| must outlive the NetworkErrorLoggingService, and cannot be
- // nullptr.
- void SetClockForTesting(const base::Clock* clock);
- // Dumps info about all the currently stored policies, including expired ones.
- // Used to display information about NEL policies on the NetLog Reporting tab.
- virtual base::Value StatusAsValue() const;
- // Gets the (NIK, origin) keys of all currently stored policies, including
- // expired ones.
- virtual std::set<NelPolicyKey> GetPolicyKeysForTesting();
- virtual PersistentNelStore* GetPersistentNelStoreForTesting();
- virtual ReportingService* GetReportingServiceForTesting();
- protected:
- NetworkErrorLoggingService();
- // Unowned:
- raw_ptr<const base::Clock> clock_;
- raw_ptr<ReportingService> reporting_service_ = nullptr;
- bool shut_down_ = false;
- };
- // Persistent storage for NEL policies.
- class NET_EXPORT NetworkErrorLoggingService::PersistentNelStore {
- public:
- using NelPoliciesLoadedCallback =
- base::OnceCallback<void(std::vector<NelPolicy>)>;
- PersistentNelStore() = default;
- PersistentNelStore(const PersistentNelStore&) = delete;
- PersistentNelStore& operator=(const PersistentNelStore&) = delete;
- virtual ~PersistentNelStore() = default;
- // Initializes the store and retrieves stored NEL policies. This will be
- // called only once at startup.
- virtual void LoadNelPolicies(NelPoliciesLoadedCallback loaded_callback) = 0;
- // Adds a NEL policy to the store.
- virtual void AddNelPolicy(const NelPolicy& policy) = 0;
- // Updates the access time of the NEL policy in the store.
- virtual void UpdateNelPolicyAccessTime(const NelPolicy& policy) = 0;
- // Deletes a NEL policy from the store.
- virtual void DeleteNelPolicy(const NelPolicy& policy) = 0;
- // Flushes the store.
- virtual void Flush() = 0;
- };
- } // namespace net
- #endif // NET_NETWORK_ERROR_LOGGING_NETWORK_ERROR_LOGGING_SERVICE_H_
|