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

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

Issue 2779983002: Reporting: Properly support endpoints with includeSubdomains. (Closed)
Patch Set: rebase 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
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 std::string GetSuperdomain(const std::string& domain) {
shivanisha 2017/04/10 20:08:41 A brief comment on this function with an example o
Julia Tuttle 2017/04/12 16:11:37 Done.
26 size_t dot_pos = domain.find('.');
27 if (dot_pos == std::string::npos)
28 return "";
29
30 return domain.substr(dot_pos + 1);
31 }
32
33 } // namespace
34
23 ReportingCache::ReportingCache(ReportingContext* context) : context_(context) { 35 ReportingCache::ReportingCache(ReportingContext* context) : context_(context) {
24 DCHECK(context_); 36 DCHECK(context_);
25 } 37 }
26 38
27 ReportingCache::~ReportingCache() {} 39 ReportingCache::~ReportingCache() {}
28 40
29 void ReportingCache::AddReport(const GURL& url, 41 void ReportingCache::AddReport(const GURL& url,
30 const std::string& group, 42 const std::string& group,
31 const std::string& type, 43 const std::string& type,
32 std::unique_ptr<const base::Value> body, 44 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)); 93 DCHECK(base::ContainsKey(reports_, report));
82 reports_[report]->attempts++; 94 reports_[report]->attempts++;
83 } 95 }
84 96
85 context_->NotifyCacheUpdated(); 97 context_->NotifyCacheUpdated();
86 } 98 }
87 99
88 void ReportingCache::RemoveReports( 100 void ReportingCache::RemoveReports(
89 const std::vector<const ReportingReport*>& reports) { 101 const std::vector<const ReportingReport*>& reports) {
90 for (const ReportingReport* report : reports) { 102 for (const ReportingReport* report : reports) {
91 DCHECK(base::ContainsKey(reports_, report));
92 if (base::ContainsKey(pending_reports_, report)) 103 if (base::ContainsKey(pending_reports_, report))
93 doomed_reports_.insert(report); 104 doomed_reports_.insert(report);
94 else { 105 else {
shivanisha 2017/04/10 20:08:41 For readability, if else has {} then include in th
Julia Tuttle 2017/04/12 16:11:37 Done.
95 DCHECK(!base::ContainsKey(doomed_reports_, report)); 106 DCHECK(!base::ContainsKey(doomed_reports_, report));
96 reports_.erase(report); 107 size_t erased = reports_.erase(report);
108 DCHECK_EQ(1u, erased);
shivanisha 2017/04/10 20:08:41 Why removing the dcheck above? It is still applica
Julia Tuttle 2017/04/12 16:11:37 If a caller passes in a random Report pointer that
97 } 109 }
98 } 110 }
99 111
100 context_->NotifyCacheUpdated(); 112 context_->NotifyCacheUpdated();
101 } 113 }
102 114
103 void ReportingCache::RemoveAllReports() { 115 void ReportingCache::RemoveAllReports() {
104 std::vector<std::unordered_map<const ReportingReport*, 116 std::vector<std::unordered_map<const ReportingReport*,
105 std::unique_ptr<ReportingReport>>::iterator> 117 std::unique_ptr<ReportingReport>>::iterator>
106 reports_to_remove; 118 reports_to_remove;
(...skipping 19 matching lines...) Expand all
126 clients_out->push_back(endpoint_and_client.second.get()); 138 clients_out->push_back(endpoint_and_client.second.get());
127 } 139 }
128 140
129 void ReportingCache::GetClientsForOriginAndGroup( 141 void ReportingCache::GetClientsForOriginAndGroup(
130 const url::Origin& origin, 142 const url::Origin& origin,
131 const std::string& group, 143 const std::string& group,
132 std::vector<const ReportingClient*>* clients_out) const { 144 std::vector<const ReportingClient*>* clients_out) const {
133 clients_out->clear(); 145 clients_out->clear();
134 146
135 const auto it = clients_.find(origin); 147 const auto it = clients_.find(origin);
136 if (it == clients_.end()) 148 if (it != clients_.end()) {
137 return; 149 for (const auto& endpoint_and_client : it->second) {
150 if (endpoint_and_client.second->group == group)
151 clients_out->push_back(endpoint_and_client.second.get());
152 }
153 }
shivanisha 2017/04/10 20:08:41 Should there be a return in the case when clients_
Julia Tuttle 2017/04/12 16:11:37 Nope, it'll get to the while loop and clients_out-
138 154
139 for (const auto& endpoint_and_client : it->second) { 155 // If no clients were found, try successive superdomain suffixes until a
140 if (endpoint_and_client.second->group == group) 156 // client with includeSubdomains is found or there are no more domain
141 clients_out->push_back(endpoint_and_client.second.get()); 157 // components left.
158 std::string domain = origin.host();
shivanisha 2017/04/10 20:08:41 I am not sure what origin.host returns. Does it re
Julia Tuttle 2017/04/12 16:11:37 Yes, it's just the hostname, no port number.
159 while (clients_out->empty() && !domain.empty()) {
160 GetWildcardClientsForDomainAndGroup(domain, group, clients_out);
161 domain = GetSuperdomain(domain);
142 } 162 }
143 } 163 }
144 164
145 void ReportingCache::SetClient(const url::Origin& origin, 165 void ReportingCache::SetClient(const url::Origin& origin,
146 const GURL& endpoint, 166 const GURL& endpoint,
147 ReportingClient::Subdomains subdomains, 167 ReportingClient::Subdomains subdomains,
148 const std::string& group, 168 const std::string& group,
149 base::TimeTicks expires) { 169 base::TimeTicks expires) {
150 DCHECK(endpoint.SchemeIsCryptographic()); 170 DCHECK(endpoint.SchemeIsCryptographic());
151 171
172 if (base::ContainsKey(clients_, origin) &&
shivanisha 2017/04/10 20:08:41 Comment explaining why we are using the Wildcard r
Julia Tuttle 2017/04/12 16:11:37 Done.
173 base::ContainsKey(clients_[origin], endpoint)) {
174 MaybeRemoveWildcardClient(clients_[origin][endpoint].get());
175 }
176
152 clients_[origin][endpoint] = base::MakeUnique<ReportingClient>( 177 clients_[origin][endpoint] = base::MakeUnique<ReportingClient>(
153 origin, endpoint, subdomains, group, expires); 178 origin, endpoint, subdomains, group, expires);
154 179
180 MaybeAddWildcardClient(clients_[origin][endpoint].get());
181
155 context_->NotifyCacheUpdated(); 182 context_->NotifyCacheUpdated();
156 } 183 }
157 184
158 void ReportingCache::RemoveClients( 185 void ReportingCache::RemoveClients(
159 const std::vector<const ReportingClient*>& clients_to_remove) { 186 const std::vector<const ReportingClient*>& clients_to_remove) {
160 for (const ReportingClient* client : clients_to_remove) { 187 for (const ReportingClient* client : clients_to_remove) {
161 DCHECK(base::ContainsKey(clients_[client->origin], client->endpoint)); 188 MaybeRemoveWildcardClient(client);
162 DCHECK(clients_[client->origin][client->endpoint].get() == client); 189 size_t erased = clients_[client->origin].erase(client->endpoint);
163 clients_[client->origin].erase(client->endpoint); 190 DCHECK_EQ(1u, erased);
164 } 191 }
165 192
166 context_->NotifyCacheUpdated(); 193 context_->NotifyCacheUpdated();
167 } 194 }
168 195
169 void ReportingCache::RemoveClientForOriginAndEndpoint(const url::Origin& origin, 196 void ReportingCache::RemoveClientForOriginAndEndpoint(const url::Origin& origin,
170 const GURL& endpoint) { 197 const GURL& endpoint) {
171 DCHECK(base::ContainsKey(clients_, origin)); 198 MaybeRemoveWildcardClient(clients_[origin][endpoint].get());
172 DCHECK(base::ContainsKey(clients_[origin], endpoint)); 199 size_t erased = clients_[origin].erase(endpoint);
173 clients_[origin].erase(endpoint); 200 DCHECK_EQ(1u, erased);
174 201
175 context_->NotifyCacheUpdated(); 202 context_->NotifyCacheUpdated();
176 } 203 }
177 204
178 void ReportingCache::RemoveClientsForEndpoint(const GURL& endpoint) { 205 void ReportingCache::RemoveClientsForEndpoint(const GURL& endpoint) {
179 for (auto& it : clients_) 206 for (auto& origin_and_endpoints : clients_) {
180 it.second.erase(endpoint); 207 if (base::ContainsKey(origin_and_endpoints.second, endpoint)) {
208 MaybeRemoveWildcardClient(origin_and_endpoints.second[endpoint].get());
209 origin_and_endpoints.second.erase(endpoint);
210 }
211 }
181 212
182 context_->NotifyCacheUpdated(); 213 context_->NotifyCacheUpdated();
183 } 214 }
184 215
185 void ReportingCache::RemoveAllClients() { 216 void ReportingCache::RemoveAllClients() {
186 clients_.clear(); 217 clients_.clear();
218 wildcard_clients_.clear();
187 219
188 context_->NotifyCacheUpdated(); 220 context_->NotifyCacheUpdated();
189 } 221 }
190 222
223 void ReportingCache::MaybeAddWildcardClient(const ReportingClient* client) {
224 if (client->subdomains != ReportingClient::Subdomains::INCLUDE)
225 return;
226
227 const std::string& domain = client->origin.host();
228 auto inserted = wildcard_clients_[domain].insert(client);
229 DCHECK(inserted.second);
230 }
231
232 void ReportingCache::MaybeRemoveWildcardClient(const ReportingClient* client) {
233 if (client->subdomains != ReportingClient::Subdomains::INCLUDE)
234 return;
235
236 const std::string& domain = client->origin.host();
237 size_t erased = wildcard_clients_[domain].erase(client);
238 DCHECK_EQ(1u, erased);
239 }
240
241 void ReportingCache::GetWildcardClientsForDomainAndGroup(
242 const std::string& domain,
243 const std::string& group,
244 std::vector<const ReportingClient*>* clients_out) const {
245 clients_out->clear();
246
247 auto it = wildcard_clients_.find(domain);
248 if (it == wildcard_clients_.end())
249 return;
250
251 for (const ReportingClient* client : it->second) {
252 if (client->group == group &&
253 client->subdomains == ReportingClient::Subdomains::INCLUDE) {
shivanisha 2017/04/10 20:08:41 Should this be a dcheck instead of a condition sin
Julia Tuttle 2017/04/12 16:11:37 Done.
254 clients_out->push_back(client);
255 }
256 }
257 }
258
191 } // namespace net 259 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698