1 // Copyright 2017 The Chromium Authors 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_ENDPOINT_H_ 6 #define NET_REPORTING_REPORTING_ENDPOINT_H_ 7 8 #include <optional> 9 #include <string> 10 #include <vector> 11 12 #include "base/time/time.h" 13 #include "base/unguessable_token.h" 14 #include "net/base/net_export.h" 15 #include "net/base/network_anonymization_key.h" 16 #include "net/reporting/reporting_target_type.h" 17 #include "url/gurl.h" 18 #include "url/origin.h" 19 20 namespace net { 21 22 // Identifies an endpoint group. 23 struct NET_EXPORT ReportingEndpointGroupKey { 24 // Constructs a default ReportingEndpointGroupKey. 25 ReportingEndpointGroupKey(); 26 27 // Constructs a ReportingEndpointGroupKey with a null `reporting_source`. 28 ReportingEndpointGroupKey( 29 const NetworkAnonymizationKey& network_anonymization_key, 30 const std::optional<url::Origin>& origin, 31 const std::string& group_name, 32 ReportingTargetType target_type); 33 34 // Constructs a ReportingEndpointGroupKey with the given parameters. 35 ReportingEndpointGroupKey( 36 const NetworkAnonymizationKey& network_anonymization_key, 37 std::optional<base::UnguessableToken> reporting_source, 38 const std::optional<url::Origin>& origin, 39 const std::string& group_name, 40 ReportingTargetType target_type); 41 42 // Constructs a ReportingEndpointGroupKey with the given `reporting_source` 43 // and all other members from `other`. 44 ReportingEndpointGroupKey( 45 const ReportingEndpointGroupKey& other, 46 const std::optional<base::UnguessableToken>& reporting_source); 47 48 ReportingEndpointGroupKey(const ReportingEndpointGroupKey& other); 49 ReportingEndpointGroupKey(ReportingEndpointGroupKey&& other); 50 51 ReportingEndpointGroupKey& operator=(const ReportingEndpointGroupKey&); 52 ReportingEndpointGroupKey& operator=(ReportingEndpointGroupKey&&); 53 54 ~ReportingEndpointGroupKey(); 55 56 std::string ToString() const; 57 58 // True if this endpoint "group" is actually being used to represent a single 59 // V1 document endpoint. IsDocumentEndpointReportingEndpointGroupKey60 bool IsDocumentEndpoint() const { return reporting_source.has_value(); } 61 62 // True if this endpoint "group" is set by the enterprise policy. IsEnterpriseEndpointReportingEndpointGroupKey63 bool IsEnterpriseEndpoint() const { 64 return target_type == ReportingTargetType::kEnterprise; 65 } 66 67 // The NetworkAnonymizationKey the group is scoped to. Needed to prevent 68 // leaking third party contexts across sites. This is empty for 69 // enterprise groups. 70 NetworkAnonymizationKey network_anonymization_key; 71 72 // Source token for the document or worker which configured this endpoint, if 73 // this was configured with the Reporting-Endpoints header. For endpoint 74 // groups configured with the Report-To header and enterprise endpoint groups, 75 // this will be nullopt. 76 std::optional<base::UnguessableToken> reporting_source; 77 78 // Origin that configured this endpoint group. For enterprise endpoint groups, 79 // this will be nullopt. 80 std::optional<url::Origin> origin; 81 82 // Name of the endpoint group (defaults to "default" during header parsing). 83 std::string group_name; 84 85 // Used to distinguish web developer and enterprise entities so that 86 // enterprise reports aren’t sent to web developer endpoints and web developer 87 // reports aren’t sent to enterprise endpoints. 88 ReportingTargetType target_type = ReportingTargetType::kDeveloper; 89 90 friend bool operator==(const ReportingEndpointGroupKey& lhs, 91 const ReportingEndpointGroupKey& rhs) = default; 92 }; 93 94 NET_EXPORT bool operator!=(const ReportingEndpointGroupKey& lhs, 95 const ReportingEndpointGroupKey& rhs); 96 NET_EXPORT bool operator<(const ReportingEndpointGroupKey& lhs, 97 const ReportingEndpointGroupKey& rhs); 98 NET_EXPORT bool operator>(const ReportingEndpointGroupKey& lhs, 99 const ReportingEndpointGroupKey& rhs); 100 101 // The configuration by an origin to use an endpoint for report delivery. 102 // TODO(crbug.com/41430426): Track endpoint failures for garbage collection. 103 struct NET_EXPORT ReportingEndpoint { 104 struct NET_EXPORT EndpointInfo { 105 static const int kDefaultPriority; 106 static const int kDefaultWeight; 107 108 // The endpoint to which reports may be delivered. (Origins may configure 109 // many.) 110 GURL url; 111 112 // Priority when multiple endpoints are configured for an origin; endpoints 113 // with numerically lower priorities are used first. 114 int priority = kDefaultPriority; 115 116 // Weight when multiple endpoints are configured for an origin with the same 117 // priority; among those with the same priority, each endpoint has a chance 118 // of being chosen that is proportional to its weight. 119 int weight = kDefaultWeight; 120 121 friend bool operator==(const EndpointInfo& lhs, 122 const EndpointInfo& rhs) = default; 123 }; 124 125 struct Statistics { 126 // The number of attempted uploads that we've made for this endpoint. 127 int attempted_uploads = 0; 128 // The number of uploads that have succeeded for this endpoint. 129 int successful_uploads = 0; 130 // The number of individual reports that we've attempted to upload for this 131 // endpoint. (Failed uploads will cause a report to be counted multiple 132 // times, once for each attempt.) 133 int attempted_reports = 0; 134 // The number of individual reports that we've successfully uploaded for 135 // this endpoint. 136 int successful_reports = 0; 137 138 friend bool operator==(const Statistics& lhs, 139 const Statistics& rhs) = default; 140 }; 141 142 // Constructs an invalid ReportingEndpoint. 143 ReportingEndpoint(); 144 145 ReportingEndpoint(const ReportingEndpointGroupKey& group, 146 const EndpointInfo& info); 147 148 ReportingEndpoint(const ReportingEndpoint& other); 149 ReportingEndpoint(ReportingEndpoint&& other); 150 151 ReportingEndpoint& operator=(const ReportingEndpoint&); 152 ReportingEndpoint& operator=(ReportingEndpoint&&); 153 154 friend bool operator==(const ReportingEndpoint& lhs, 155 const ReportingEndpoint& rhs) = default; 156 157 ~ReportingEndpoint(); 158 159 bool is_valid() const; 160 explicit operator bool() const { return is_valid(); } 161 162 // Identifies the endpoint group to which this endpoint belongs. 163 ReportingEndpointGroupKey group_key; 164 165 // URL, priority, and weight of the endpoint. 166 EndpointInfo info; 167 168 // Information about the number of deliveries that we've attempted for this 169 // endpoint. Not persisted across restarts. 170 Statistics stats; 171 }; 172 173 // Marks whether a given endpoint group is configured to include its origin's 174 // subdomains. 175 enum class OriginSubdomains { EXCLUDE, INCLUDE, DEFAULT = EXCLUDE }; 176 177 // Represents an endpoint group set by an origin via Report-To header. 178 struct NET_EXPORT ReportingEndpointGroup { 179 ReportingEndpointGroup(); 180 181 ReportingEndpointGroup(const ReportingEndpointGroup& other); 182 183 ~ReportingEndpointGroup(); 184 185 ReportingEndpointGroupKey group_key; 186 187 // Whether this group applies to subdomains of its origin. 188 OriginSubdomains include_subdomains = OriginSubdomains::DEFAULT; 189 190 // Time for which the endpoint group remains valid after it is set. 191 base::TimeDelta ttl; 192 193 // Endpoints in this group. 194 std::vector<ReportingEndpoint::EndpointInfo> endpoints; 195 }; 196 197 // Representation of an endpoint group used for in-memory and persistent 198 // storage. 199 struct NET_EXPORT CachedReportingEndpointGroup { 200 CachedReportingEndpointGroup(const ReportingEndpointGroupKey& group_key, 201 OriginSubdomains include_subdomains, 202 base::Time expires, 203 base::Time last_used); 204 205 // |now| is the time at which the header was processed. 206 CachedReportingEndpointGroup(const ReportingEndpointGroup& endpoint_group, 207 base::Time now); 208 209 // Origin and group name. 210 ReportingEndpointGroupKey group_key; 211 212 // Whether this group applies to subdomains of |group_key.origin|. 213 OriginSubdomains include_subdomains = OriginSubdomains::DEFAULT; 214 215 // When this group's max_age expires. 216 // (base::Time is used here instead of base::TimeTicks for ease of 217 // serialization for persistent storage, and because it is more appropriate 218 // for expiration times, as per //base/time/time.h.) 219 base::Time expires; 220 221 // Last time that this group was accessed for a delivery or updated via a 222 // new header. 223 base::Time last_used; 224 }; 225 226 } // namespace net 227 228 #endif // NET_REPORTING_REPORTING_ENDPOINT_H_ 229