// Copyright 2015 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. #include "components/domain_reliability/context_manager.h" #include #include "base/callback_helpers.h" #include "components/domain_reliability/google_configs.h" #include "net/base/url_util.h" namespace domain_reliability { DomainReliabilityContextManager::DomainReliabilityContextManager( const MockableTime* time, const std::string& upload_reporter_string, DomainReliabilityContext::UploadAllowedCallback upload_allowed_callback, DomainReliabilityDispatcher* dispatcher) : time_(time), upload_reporter_string_(upload_reporter_string), upload_allowed_callback_(upload_allowed_callback), dispatcher_(dispatcher) { DCHECK(time_); DCHECK(dispatcher_); } DomainReliabilityContextManager::~DomainReliabilityContextManager() = default; void DomainReliabilityContextManager::RouteBeacon( std::unique_ptr beacon) { const std::string& beacon_host = beacon->url.host(); // An exact match for the host always takes priority. DomainReliabilityContext* context_to_use = GetContext(beacon_host); if (context_to_use) { context_to_use->OnBeacon(std::move(beacon)); return; } DomainReliabilityContext* superdomain_context = GetSuperdomainContext(beacon_host); // Try to get a Google config which may match the host itself, or the host's // parent domain. std::unique_ptr google_config = MaybeGetGoogleConfig(beacon_host); if (!google_config) { if (superdomain_context) superdomain_context->OnBeacon(std::move(beacon)); return; } context_to_use = superdomain_context; bool google_config_is_exact = (google_config->origin.host() == beacon_host); // An exact match takes priority over an existing superdomain context, if any // exists. if (google_config_is_exact || !context_to_use) context_to_use = AddContextForConfig(std::move(google_config)); context_to_use->OnBeacon(std::move(beacon)); } void DomainReliabilityContextManager::ClearBeacons( const base::RepeatingCallback& origin_filter) { for (auto& context_entry : contexts_) { if (origin_filter.is_null() || origin_filter.Run(context_entry.second->config().origin)) { context_entry.second->ClearBeacons(); } } } DomainReliabilityContext* DomainReliabilityContextManager::AddContextForConfig( std::unique_ptr config) { const std::string& key = config->origin.host(); auto pair = contexts_.insert( std::make_pair(key, CreateContextForConfig(std::move(config)))); // Insertion should have succeeded (the key should not have already existed). DCHECK(pair.second); return pair.first->second.get(); } void DomainReliabilityContextManager::RemoveContexts( const base::RepeatingCallback& origin_filter) { if (origin_filter.is_null()) { contexts_.clear(); return; } for (auto it = contexts_.begin(); it != contexts_.end();) { if (origin_filter.Run(it->second->config().origin)) { it = contexts_.erase(it); continue; } ++it; } } DomainReliabilityContext* DomainReliabilityContextManager::GetContext( const std::string& host) const { ContextMap::const_iterator context_it = contexts_.find(host); if (context_it == contexts_.end()) return nullptr; return context_it->second.get(); } DomainReliabilityContext* DomainReliabilityContextManager::GetSuperdomainContext( const std::string& host) const { // TODO(juliatuttle): Make sure parent is not in PSL before using. std::string parent_host = net::GetSuperdomain(host); if (parent_host.empty()) return nullptr; DomainReliabilityContext* context = GetContext(parent_host); if (context && context->config().include_subdomains) return context; return nullptr; } void DomainReliabilityContextManager::OnNetworkChanged(base::TimeTicks now) { last_network_change_time_ = now; } void DomainReliabilityContextManager::SetUploader( DomainReliabilityUploader* uploader) { DCHECK(!uploader_); DCHECK(uploader); uploader_ = uploader; } std::unique_ptr DomainReliabilityContextManager::CreateContextForConfig( std::unique_ptr config) const { DCHECK(config); DCHECK(config->IsValid()); DCHECK(uploader_); return std::make_unique( time_, DomainReliabilityScheduler::Params::GetFromFieldTrialsOrDefaults(), upload_reporter_string_, &last_network_change_time_, upload_allowed_callback_, dispatcher_, uploader_, std::move(config)); } } // namespace domain_reliability