Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(65)

Side by Side Diff: net/reporting/reporting_cache.cc

Issue 2779983002: Reporting: Properly support endpoints with includeSubdomains. (Closed)
Patch Set: Make requested changes. Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/reporting/reporting_cache.h ('k') | net/reporting/reporting_cache_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/reporting/reporting_cache.h" 5 #include "net/reporting/reporting_cache.h"
6 6
7 #include <map> 7 #include <map>
8 #include <memory> 8 #include <memory>
9 #include <set> 9 #include <set>
10 #include <string> 10 #include <string>
11 #include <vector> 11 #include <vector>
12 12
13 #include "base/memory/ptr_util.h" 13 #include "base/memory/ptr_util.h"
14 #include "base/stl_util.h" 14 #include "base/stl_util.h"
15 #include "base/time/time.h" 15 #include "base/time/time.h"
16 #include "net/reporting/reporting_client.h" 16 #include "net/reporting/reporting_client.h"
17 #include "net/reporting/reporting_context.h" 17 #include "net/reporting/reporting_context.h"
18 #include "net/reporting/reporting_report.h" 18 #include "net/reporting/reporting_report.h"
19 #include "url/gurl.h" 19 #include "url/gurl.h"
20 20
21 namespace net { 21 namespace net {
22 22
23 namespace {
24
25 // Returns the superdomain of a given domain, or the empty string if the given
26 // domain is just a single label. Note that this does not take into account
27 // anything like the Public Suffix List, so the superdomain may end up being a
28 // bare TLD.
29 //
30 // Examples:
31 //
32 // GetSuperdomain("assets.example.com") -> "example.com"
33 // GetSuperdomain("example.net") -> "net"
34 // GetSuperdomain("littlebox") -> ""
35 std::string GetSuperdomain(const std::string& domain) {
36 size_t dot_pos = domain.find('.');
37 if (dot_pos == std::string::npos)
38 return "";
39
40 return domain.substr(dot_pos + 1);
41 }
42
43 } // namespace
44
23 ReportingCache::ReportingCache(ReportingContext* context) : context_(context) { 45 ReportingCache::ReportingCache(ReportingContext* context) : context_(context) {
24 DCHECK(context_); 46 DCHECK(context_);
25 } 47 }
26 48
27 ReportingCache::~ReportingCache() {} 49 ReportingCache::~ReportingCache() {}
28 50
29 void ReportingCache::AddReport(const GURL& url, 51 void ReportingCache::AddReport(const GURL& url,
30 const std::string& group, 52 const std::string& group,
31 const std::string& type, 53 const std::string& type,
32 std::unique_ptr<const base::Value> body, 54 std::unique_ptr<const base::Value> body,
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
81 DCHECK(base::ContainsKey(reports_, report)); 103 DCHECK(base::ContainsKey(reports_, report));
82 reports_[report]->attempts++; 104 reports_[report]->attempts++;
83 } 105 }
84 106
85 context_->NotifyCacheUpdated(); 107 context_->NotifyCacheUpdated();
86 } 108 }
87 109
88 void ReportingCache::RemoveReports( 110 void ReportingCache::RemoveReports(
89 const std::vector<const ReportingReport*>& reports) { 111 const std::vector<const ReportingReport*>& reports) {
90 for (const ReportingReport* report : reports) { 112 for (const ReportingReport* report : reports) {
91 DCHECK(base::ContainsKey(reports_, report)); 113 if (base::ContainsKey(pending_reports_, report)) {
92 if (base::ContainsKey(pending_reports_, report))
93 doomed_reports_.insert(report); 114 doomed_reports_.insert(report);
94 else { 115 } else {
95 DCHECK(!base::ContainsKey(doomed_reports_, report)); 116 DCHECK(!base::ContainsKey(doomed_reports_, report));
96 reports_.erase(report); 117 size_t erased = reports_.erase(report);
118 DCHECK_EQ(1u, erased);
97 } 119 }
98 } 120 }
99 121
100 context_->NotifyCacheUpdated(); 122 context_->NotifyCacheUpdated();
101 } 123 }
102 124
103 void ReportingCache::RemoveAllReports() { 125 void ReportingCache::RemoveAllReports() {
104 std::vector<std::unordered_map<const ReportingReport*, 126 std::vector<std::unordered_map<const ReportingReport*,
105 std::unique_ptr<ReportingReport>>::iterator> 127 std::unique_ptr<ReportingReport>>::iterator>
106 reports_to_remove; 128 reports_to_remove;
(...skipping 19 matching lines...) Expand all
126 clients_out->push_back(endpoint_and_client.second.get()); 148 clients_out->push_back(endpoint_and_client.second.get());
127 } 149 }
128 150
129 void ReportingCache::GetClientsForOriginAndGroup( 151 void ReportingCache::GetClientsForOriginAndGroup(
130 const url::Origin& origin, 152 const url::Origin& origin,
131 const std::string& group, 153 const std::string& group,
132 std::vector<const ReportingClient*>* clients_out) const { 154 std::vector<const ReportingClient*>* clients_out) const {
133 clients_out->clear(); 155 clients_out->clear();
134 156
135 const auto it = clients_.find(origin); 157 const auto it = clients_.find(origin);
136 if (it == clients_.end()) 158 if (it != clients_.end()) {
137 return; 159 for (const auto& endpoint_and_client : it->second) {
160 if (endpoint_and_client.second->group == group)
161 clients_out->push_back(endpoint_and_client.second.get());
162 }
163 }
138 164
139 for (const auto& endpoint_and_client : it->second) { 165 // If no clients were found, try successive superdomain suffixes until a
140 if (endpoint_and_client.second->group == group) 166 // client with includeSubdomains is found or there are no more domain
141 clients_out->push_back(endpoint_and_client.second.get()); 167 // components left.
168 std::string domain = origin.host();
169 while (clients_out->empty() && !domain.empty()) {
170 GetWildcardClientsForDomainAndGroup(domain, group, clients_out);
171 domain = GetSuperdomain(domain);
142 } 172 }
143 } 173 }
144 174
145 void ReportingCache::SetClient(const url::Origin& origin, 175 void ReportingCache::SetClient(const url::Origin& origin,
146 const GURL& endpoint, 176 const GURL& endpoint,
147 ReportingClient::Subdomains subdomains, 177 ReportingClient::Subdomains subdomains,
148 const std::string& group, 178 const std::string& group,
149 base::TimeTicks expires) { 179 base::TimeTicks expires) {
150 DCHECK(endpoint.SchemeIsCryptographic()); 180 DCHECK(endpoint.SchemeIsCryptographic());
151 181
182 // Since |subdomains| may differ from a previous call to SetClient for this
183 // origin and endpoint, the cache needs to remove and re-add the client to the
184 // index of wildcard clients, if applicable.
185 if (base::ContainsKey(clients_, origin) &&
186 base::ContainsKey(clients_[origin], endpoint)) {
187 MaybeRemoveWildcardClient(clients_[origin][endpoint].get());
188 }
189
152 clients_[origin][endpoint] = base::MakeUnique<ReportingClient>( 190 clients_[origin][endpoint] = base::MakeUnique<ReportingClient>(
153 origin, endpoint, subdomains, group, expires); 191 origin, endpoint, subdomains, group, expires);
154 192
193 MaybeAddWildcardClient(clients_[origin][endpoint].get());
194
155 context_->NotifyCacheUpdated(); 195 context_->NotifyCacheUpdated();
156 } 196 }
157 197
158 void ReportingCache::RemoveClients( 198 void ReportingCache::RemoveClients(
159 const std::vector<const ReportingClient*>& clients_to_remove) { 199 const std::vector<const ReportingClient*>& clients_to_remove) {
160 for (const ReportingClient* client : clients_to_remove) { 200 for (const ReportingClient* client : clients_to_remove) {
161 DCHECK(base::ContainsKey(clients_[client->origin], client->endpoint)); 201 MaybeRemoveWildcardClient(client);
162 DCHECK(clients_[client->origin][client->endpoint].get() == client); 202 size_t erased = clients_[client->origin].erase(client->endpoint);
163 clients_[client->origin].erase(client->endpoint); 203 DCHECK_EQ(1u, erased);
164 } 204 }
165 205
166 context_->NotifyCacheUpdated(); 206 context_->NotifyCacheUpdated();
167 } 207 }
168 208
169 void ReportingCache::RemoveClientForOriginAndEndpoint(const url::Origin& origin, 209 void ReportingCache::RemoveClientForOriginAndEndpoint(const url::Origin& origin,
170 const GURL& endpoint) { 210 const GURL& endpoint) {
171 DCHECK(base::ContainsKey(clients_, origin)); 211 MaybeRemoveWildcardClient(clients_[origin][endpoint].get());
172 DCHECK(base::ContainsKey(clients_[origin], endpoint)); 212 size_t erased = clients_[origin].erase(endpoint);
173 clients_[origin].erase(endpoint); 213 DCHECK_EQ(1u, erased);
174 214
175 context_->NotifyCacheUpdated(); 215 context_->NotifyCacheUpdated();
176 } 216 }
177 217
178 void ReportingCache::RemoveClientsForEndpoint(const GURL& endpoint) { 218 void ReportingCache::RemoveClientsForEndpoint(const GURL& endpoint) {
179 for (auto& it : clients_) 219 for (auto& origin_and_endpoints : clients_) {
180 it.second.erase(endpoint); 220 if (base::ContainsKey(origin_and_endpoints.second, endpoint)) {
221 MaybeRemoveWildcardClient(origin_and_endpoints.second[endpoint].get());
222 origin_and_endpoints.second.erase(endpoint);
223 }
224 }
181 225
182 context_->NotifyCacheUpdated(); 226 context_->NotifyCacheUpdated();
183 } 227 }
184 228
185 void ReportingCache::RemoveAllClients() { 229 void ReportingCache::RemoveAllClients() {
186 clients_.clear(); 230 clients_.clear();
231 wildcard_clients_.clear();
187 232
188 context_->NotifyCacheUpdated(); 233 context_->NotifyCacheUpdated();
189 } 234 }
190 235
236 void ReportingCache::MaybeAddWildcardClient(const ReportingClient* client) {
237 if (client->subdomains != ReportingClient::Subdomains::INCLUDE)
238 return;
239
240 const std::string& domain = client->origin.host();
241 auto inserted = wildcard_clients_[domain].insert(client);
242 DCHECK(inserted.second);
243 }
244
245 void ReportingCache::MaybeRemoveWildcardClient(const ReportingClient* client) {
246 if (client->subdomains != ReportingClient::Subdomains::INCLUDE)
247 return;
248
249 const std::string& domain = client->origin.host();
250 size_t erased = wildcard_clients_[domain].erase(client);
251 DCHECK_EQ(1u, erased);
252 }
253
254 void ReportingCache::GetWildcardClientsForDomainAndGroup(
255 const std::string& domain,
256 const std::string& group,
257 std::vector<const ReportingClient*>* clients_out) const {
258 clients_out->clear();
259
260 auto it = wildcard_clients_.find(domain);
261 if (it == wildcard_clients_.end())
262 return;
263
264 for (const ReportingClient* client : it->second) {
265 DCHECK_EQ(ReportingClient::Subdomains::INCLUDE, client->subdomains);
266 if (client->group == group)
267 clients_out->push_back(client);
268 }
269 }
270
191 } // namespace net 271 } // namespace net
OLDNEW
« no previous file with comments | « net/reporting/reporting_cache.h ('k') | net/reporting/reporting_cache_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698