context_manager.cc 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. // Copyright 2015 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "components/domain_reliability/context_manager.h"
  5. #include <utility>
  6. #include "base/callback_helpers.h"
  7. #include "components/domain_reliability/google_configs.h"
  8. #include "net/base/url_util.h"
  9. namespace domain_reliability {
  10. DomainReliabilityContextManager::DomainReliabilityContextManager(
  11. const MockableTime* time,
  12. const std::string& upload_reporter_string,
  13. DomainReliabilityContext::UploadAllowedCallback upload_allowed_callback,
  14. DomainReliabilityDispatcher* dispatcher)
  15. : time_(time),
  16. upload_reporter_string_(upload_reporter_string),
  17. upload_allowed_callback_(upload_allowed_callback),
  18. dispatcher_(dispatcher) {
  19. DCHECK(time_);
  20. DCHECK(dispatcher_);
  21. }
  22. DomainReliabilityContextManager::~DomainReliabilityContextManager() = default;
  23. void DomainReliabilityContextManager::RouteBeacon(
  24. std::unique_ptr<DomainReliabilityBeacon> beacon) {
  25. const std::string& beacon_host = beacon->url.host();
  26. // An exact match for the host always takes priority.
  27. DomainReliabilityContext* context_to_use = GetContext(beacon_host);
  28. if (context_to_use) {
  29. context_to_use->OnBeacon(std::move(beacon));
  30. return;
  31. }
  32. DomainReliabilityContext* superdomain_context =
  33. GetSuperdomainContext(beacon_host);
  34. // Try to get a Google config which may match the host itself, or the host's
  35. // parent domain.
  36. std::unique_ptr<const DomainReliabilityConfig> google_config =
  37. MaybeGetGoogleConfig(beacon_host);
  38. if (!google_config) {
  39. if (superdomain_context)
  40. superdomain_context->OnBeacon(std::move(beacon));
  41. return;
  42. }
  43. context_to_use = superdomain_context;
  44. bool google_config_is_exact = (google_config->origin.host() == beacon_host);
  45. // An exact match takes priority over an existing superdomain context, if any
  46. // exists.
  47. if (google_config_is_exact || !context_to_use)
  48. context_to_use = AddContextForConfig(std::move(google_config));
  49. context_to_use->OnBeacon(std::move(beacon));
  50. }
  51. void DomainReliabilityContextManager::ClearBeacons(
  52. const base::RepeatingCallback<bool(const url::Origin&)>& origin_filter) {
  53. for (auto& context_entry : contexts_) {
  54. if (origin_filter.is_null() ||
  55. origin_filter.Run(context_entry.second->config().origin)) {
  56. context_entry.second->ClearBeacons();
  57. }
  58. }
  59. }
  60. DomainReliabilityContext* DomainReliabilityContextManager::AddContextForConfig(
  61. std::unique_ptr<const DomainReliabilityConfig> config) {
  62. const std::string& key = config->origin.host();
  63. auto pair = contexts_.insert(
  64. std::make_pair(key, CreateContextForConfig(std::move(config))));
  65. // Insertion should have succeeded (the key should not have already existed).
  66. DCHECK(pair.second);
  67. return pair.first->second.get();
  68. }
  69. void DomainReliabilityContextManager::RemoveContexts(
  70. const base::RepeatingCallback<bool(const url::Origin&)>& origin_filter) {
  71. if (origin_filter.is_null()) {
  72. contexts_.clear();
  73. return;
  74. }
  75. for (auto it = contexts_.begin(); it != contexts_.end();) {
  76. if (origin_filter.Run(it->second->config().origin)) {
  77. it = contexts_.erase(it);
  78. continue;
  79. }
  80. ++it;
  81. }
  82. }
  83. DomainReliabilityContext* DomainReliabilityContextManager::GetContext(
  84. const std::string& host) const {
  85. ContextMap::const_iterator context_it = contexts_.find(host);
  86. if (context_it == contexts_.end())
  87. return nullptr;
  88. return context_it->second.get();
  89. }
  90. DomainReliabilityContext*
  91. DomainReliabilityContextManager::GetSuperdomainContext(
  92. const std::string& host) const {
  93. // TODO(juliatuttle): Make sure parent is not in PSL before using.
  94. std::string parent_host = net::GetSuperdomain(host);
  95. if (parent_host.empty())
  96. return nullptr;
  97. DomainReliabilityContext* context = GetContext(parent_host);
  98. if (context && context->config().include_subdomains)
  99. return context;
  100. return nullptr;
  101. }
  102. void DomainReliabilityContextManager::OnNetworkChanged(base::TimeTicks now) {
  103. last_network_change_time_ = now;
  104. }
  105. void DomainReliabilityContextManager::SetUploader(
  106. DomainReliabilityUploader* uploader) {
  107. DCHECK(!uploader_);
  108. DCHECK(uploader);
  109. uploader_ = uploader;
  110. }
  111. std::unique_ptr<DomainReliabilityContext>
  112. DomainReliabilityContextManager::CreateContextForConfig(
  113. std::unique_ptr<const DomainReliabilityConfig> config) const {
  114. DCHECK(config);
  115. DCHECK(config->IsValid());
  116. DCHECK(uploader_);
  117. return std::make_unique<DomainReliabilityContext>(
  118. time_, DomainReliabilityScheduler::Params::GetFromFieldTrialsOrDefaults(),
  119. upload_reporter_string_, &last_network_change_time_,
  120. upload_allowed_callback_, dispatcher_, uploader_, std::move(config));
  121. }
  122. } // namespace domain_reliability