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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: net/reporting/reporting_cache.cc
diff --git a/net/reporting/reporting_cache.cc b/net/reporting/reporting_cache.cc
index 9e43153b4f96556ec8017a29a9d3d2365ef90943..f1da1cf59d3137f411f613cf1b9ecbfb69296162 100644
--- a/net/reporting/reporting_cache.cc
+++ b/net/reporting/reporting_cache.cc
@@ -20,6 +20,18 @@
namespace net {
+namespace {
+
+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.
+ size_t dot_pos = domain.find('.');
+ if (dot_pos == std::string::npos)
+ return "";
+
+ return domain.substr(dot_pos + 1);
+}
+
+} // namespace
+
ReportingCache::ReportingCache(ReportingContext* context) : context_(context) {
DCHECK(context_);
}
@@ -88,12 +100,12 @@ void ReportingCache::IncrementReportsAttempts(
void ReportingCache::RemoveReports(
const std::vector<const ReportingReport*>& reports) {
for (const ReportingReport* report : reports) {
- DCHECK(base::ContainsKey(reports_, report));
if (base::ContainsKey(pending_reports_, report))
doomed_reports_.insert(report);
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.
DCHECK(!base::ContainsKey(doomed_reports_, report));
- reports_.erase(report);
+ size_t erased = reports_.erase(report);
+ 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
}
}
@@ -133,12 +145,20 @@ void ReportingCache::GetClientsForOriginAndGroup(
clients_out->clear();
const auto it = clients_.find(origin);
- if (it == clients_.end())
- return;
+ if (it != clients_.end()) {
+ for (const auto& endpoint_and_client : it->second) {
+ if (endpoint_and_client.second->group == group)
+ clients_out->push_back(endpoint_and_client.second.get());
+ }
+ }
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-
- for (const auto& endpoint_and_client : it->second) {
- if (endpoint_and_client.second->group == group)
- clients_out->push_back(endpoint_and_client.second.get());
+ // If no clients were found, try successive superdomain suffixes until a
+ // client with includeSubdomains is found or there are no more domain
+ // components left.
+ 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.
+ while (clients_out->empty() && !domain.empty()) {
+ GetWildcardClientsForDomainAndGroup(domain, group, clients_out);
+ domain = GetSuperdomain(domain);
}
}
@@ -149,18 +169,25 @@ void ReportingCache::SetClient(const url::Origin& origin,
base::TimeTicks expires) {
DCHECK(endpoint.SchemeIsCryptographic());
+ 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.
+ base::ContainsKey(clients_[origin], endpoint)) {
+ MaybeRemoveWildcardClient(clients_[origin][endpoint].get());
+ }
+
clients_[origin][endpoint] = base::MakeUnique<ReportingClient>(
origin, endpoint, subdomains, group, expires);
+ MaybeAddWildcardClient(clients_[origin][endpoint].get());
+
context_->NotifyCacheUpdated();
}
void ReportingCache::RemoveClients(
const std::vector<const ReportingClient*>& clients_to_remove) {
for (const ReportingClient* client : clients_to_remove) {
- DCHECK(base::ContainsKey(clients_[client->origin], client->endpoint));
- DCHECK(clients_[client->origin][client->endpoint].get() == client);
- clients_[client->origin].erase(client->endpoint);
+ MaybeRemoveWildcardClient(client);
+ size_t erased = clients_[client->origin].erase(client->endpoint);
+ DCHECK_EQ(1u, erased);
}
context_->NotifyCacheUpdated();
@@ -168,24 +195,65 @@ void ReportingCache::RemoveClients(
void ReportingCache::RemoveClientForOriginAndEndpoint(const url::Origin& origin,
const GURL& endpoint) {
- DCHECK(base::ContainsKey(clients_, origin));
- DCHECK(base::ContainsKey(clients_[origin], endpoint));
- clients_[origin].erase(endpoint);
+ MaybeRemoveWildcardClient(clients_[origin][endpoint].get());
+ size_t erased = clients_[origin].erase(endpoint);
+ DCHECK_EQ(1u, erased);
context_->NotifyCacheUpdated();
}
void ReportingCache::RemoveClientsForEndpoint(const GURL& endpoint) {
- for (auto& it : clients_)
- it.second.erase(endpoint);
+ for (auto& origin_and_endpoints : clients_) {
+ if (base::ContainsKey(origin_and_endpoints.second, endpoint)) {
+ MaybeRemoveWildcardClient(origin_and_endpoints.second[endpoint].get());
+ origin_and_endpoints.second.erase(endpoint);
+ }
+ }
context_->NotifyCacheUpdated();
}
void ReportingCache::RemoveAllClients() {
clients_.clear();
+ wildcard_clients_.clear();
context_->NotifyCacheUpdated();
}
+void ReportingCache::MaybeAddWildcardClient(const ReportingClient* client) {
+ if (client->subdomains != ReportingClient::Subdomains::INCLUDE)
+ return;
+
+ const std::string& domain = client->origin.host();
+ auto inserted = wildcard_clients_[domain].insert(client);
+ DCHECK(inserted.second);
+}
+
+void ReportingCache::MaybeRemoveWildcardClient(const ReportingClient* client) {
+ if (client->subdomains != ReportingClient::Subdomains::INCLUDE)
+ return;
+
+ const std::string& domain = client->origin.host();
+ size_t erased = wildcard_clients_[domain].erase(client);
+ DCHECK_EQ(1u, erased);
+}
+
+void ReportingCache::GetWildcardClientsForDomainAndGroup(
+ const std::string& domain,
+ const std::string& group,
+ std::vector<const ReportingClient*>* clients_out) const {
+ clients_out->clear();
+
+ auto it = wildcard_clients_.find(domain);
+ if (it == wildcard_clients_.end())
+ return;
+
+ for (const ReportingClient* client : it->second) {
+ if (client->group == group &&
+ 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.
+ clients_out->push_back(client);
+ }
+ }
+}
+
} // namespace net

Powered by Google App Engine
This is Rietveld 408576698