ttuttle | ca1ac31 | 2015-03-12 17:07:00 | [diff] [blame] | 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 | |
| 5 | #include "components/domain_reliability/context_manager.h" |
| 6 | |
dcheng | 5160635 | 2015-12-26 21:16:23 | [diff] [blame] | 7 | #include <utility> |
| 8 | |
ttuttle | ca1ac31 | 2015-03-12 17:07:00 | [diff] [blame] | 9 | namespace domain_reliability { |
| 10 | |
| 11 | DomainReliabilityContextManager::DomainReliabilityContextManager( |
| 12 | DomainReliabilityContext::Factory* context_factory) |
| 13 | : context_factory_(context_factory) { |
| 14 | } |
| 15 | |
| 16 | DomainReliabilityContextManager::~DomainReliabilityContextManager() { |
| 17 | RemoveAllContexts(); |
| 18 | } |
| 19 | |
| 20 | void DomainReliabilityContextManager::RouteBeacon( |
dcheng | 04a35cd | 2016-04-22 15:07:24 | [diff] [blame^] | 21 | std::unique_ptr<DomainReliabilityBeacon> beacon) { |
ttuttle | ccdd6cc5 | 2015-11-22 06:09:40 | [diff] [blame] | 22 | DomainReliabilityContext* context = GetContextForHost(beacon->url.host()); |
ttuttle | ca1ac31 | 2015-03-12 17:07:00 | [diff] [blame] | 23 | if (!context) |
| 24 | return; |
| 25 | |
dcheng | 5160635 | 2015-12-26 21:16:23 | [diff] [blame] | 26 | context->OnBeacon(std::move(beacon)); |
ttuttle | ca1ac31 | 2015-03-12 17:07:00 | [diff] [blame] | 27 | } |
| 28 | |
ttuttle | 2935096c | 2016-02-09 22:31:44 | [diff] [blame] | 29 | void DomainReliabilityContextManager::SetConfig( |
| 30 | const GURL& origin, |
dcheng | 04a35cd | 2016-04-22 15:07:24 | [diff] [blame^] | 31 | std::unique_ptr<DomainReliabilityConfig> config, |
ttuttle | 2935096c | 2016-02-09 22:31:44 | [diff] [blame] | 32 | base::TimeDelta max_age) { |
| 33 | std::string key = origin.host(); |
| 34 | |
| 35 | if (!contexts_.count(key) && !removed_contexts_.count(key)) { |
| 36 | LOG(WARNING) << "Ignoring NEL header for unknown origin " << origin.spec() |
| 37 | << "."; |
| 38 | return; |
| 39 | } |
| 40 | |
| 41 | if (contexts_.count(key)) { |
| 42 | // Currently, there is no easy way to change the config of a context, so |
| 43 | // updating the config requires recreating the context, which loses |
| 44 | // pending beacons and collector backoff state. Therefore, don't do so |
| 45 | // needlessly; make sure the config has actually changed before recreating |
| 46 | // the context. |
| 47 | if (contexts_[key]->config().Equals(*config)) { |
| 48 | DVLOG(1) << "Ignoring unchanged NEL header for existing origin " |
| 49 | << origin.spec() << "."; |
| 50 | return; |
| 51 | } |
ttuttle | 960fcbf | 2016-04-19 13:26:32 | [diff] [blame] | 52 | // TODO(juliatuttle): Make Context accept Config changes. |
ttuttle | 2935096c | 2016-02-09 22:31:44 | [diff] [blame] | 53 | } |
| 54 | |
| 55 | DVLOG(1) << "Adding/replacing context for existing origin " << origin.spec() |
| 56 | << "."; |
| 57 | removed_contexts_.erase(key); |
| 58 | config->origin = origin; |
| 59 | AddContextForConfig(std::move(config)); |
| 60 | } |
| 61 | |
| 62 | void DomainReliabilityContextManager::ClearConfig(const GURL& origin) { |
| 63 | std::string key = origin.host(); |
| 64 | |
| 65 | if (contexts_.count(key)) { |
| 66 | DVLOG(1) << "Removing context for existing origin " << origin.spec() << "."; |
| 67 | contexts_.erase(key); |
| 68 | removed_contexts_.insert(key); |
| 69 | } |
| 70 | } |
| 71 | |
ttuttle | ca1ac31 | 2015-03-12 17:07:00 | [diff] [blame] | 72 | void DomainReliabilityContextManager::ClearBeaconsInAllContexts() { |
| 73 | for (auto& context_entry : contexts_) |
| 74 | context_entry.second->ClearBeacons(); |
| 75 | } |
| 76 | |
| 77 | DomainReliabilityContext* DomainReliabilityContextManager::AddContextForConfig( |
dcheng | 04a35cd | 2016-04-22 15:07:24 | [diff] [blame^] | 78 | std::unique_ptr<const DomainReliabilityConfig> config) { |
ttuttle | 2935096c | 2016-02-09 22:31:44 | [diff] [blame] | 79 | std::string key = config->origin.host(); |
ttuttle | 960fcbf | 2016-04-19 13:26:32 | [diff] [blame] | 80 | // TODO(juliatuttle): Convert this to actual origin. |
ttuttle | ccdd6cc5 | 2015-11-22 06:09:40 | [diff] [blame] | 81 | |
dcheng | 04a35cd | 2016-04-22 15:07:24 | [diff] [blame^] | 82 | std::unique_ptr<DomainReliabilityContext> context = |
dcheng | 5160635 | 2015-12-26 21:16:23 | [diff] [blame] | 83 | context_factory_->CreateContextForConfig(std::move(config)); |
ttuttle | 2935096c | 2016-02-09 22:31:44 | [diff] [blame] | 84 | DomainReliabilityContext** entry = &contexts_[key]; |
ttuttle | ca1ac31 | 2015-03-12 17:07:00 | [diff] [blame] | 85 | if (*entry) |
| 86 | delete *entry; |
ttuttle | 2935096c | 2016-02-09 22:31:44 | [diff] [blame] | 87 | |
ttuttle | ca1ac31 | 2015-03-12 17:07:00 | [diff] [blame] | 88 | *entry = context.release(); |
| 89 | return *entry; |
| 90 | } |
| 91 | |
| 92 | void DomainReliabilityContextManager::RemoveAllContexts() { |
| 93 | STLDeleteContainerPairSecondPointers( |
| 94 | contexts_.begin(), contexts_.end()); |
| 95 | contexts_.clear(); |
| 96 | } |
| 97 | |
dcheng | 04a35cd | 2016-04-22 15:07:24 | [diff] [blame^] | 98 | std::unique_ptr<base::Value> DomainReliabilityContextManager::GetWebUIData() |
| 99 | const { |
| 100 | std::unique_ptr<base::ListValue> contexts_value(new base::ListValue()); |
ttuttle | ca1ac31 | 2015-03-12 17:07:00 | [diff] [blame] | 101 | for (const auto& context_entry : contexts_) |
| 102 | contexts_value->Append(context_entry.second->GetWebUIData().release()); |
dcheng | 5160635 | 2015-12-26 21:16:23 | [diff] [blame] | 103 | return std::move(contexts_value); |
ttuttle | ca1ac31 | 2015-03-12 17:07:00 | [diff] [blame] | 104 | } |
| 105 | |
| 106 | DomainReliabilityContext* DomainReliabilityContextManager::GetContextForHost( |
| 107 | const std::string& host) { |
| 108 | ContextMap::const_iterator context_it; |
| 109 | |
| 110 | context_it = contexts_.find(host); |
| 111 | if (context_it != contexts_.end()) |
| 112 | return context_it->second; |
| 113 | |
ttuttle | ca1ac31 | 2015-03-12 17:07:00 | [diff] [blame] | 114 | size_t dot_pos = host.find('.'); |
| 115 | if (dot_pos == std::string::npos) |
ttuttle | c72f27d | 2015-03-17 23:55:59 | [diff] [blame] | 116 | return nullptr; |
ttuttle | ca1ac31 | 2015-03-12 17:07:00 | [diff] [blame] | 117 | |
ttuttle | 960fcbf | 2016-04-19 13:26:32 | [diff] [blame] | 118 | // TODO(juliatuttle): Make sure parent is not in PSL before using. |
ttuttle | ca1ac31 | 2015-03-12 17:07:00 | [diff] [blame] | 119 | |
ttuttle | 2935096c | 2016-02-09 22:31:44 | [diff] [blame] | 120 | std::string parent_host = host.substr(dot_pos + 1); |
| 121 | context_it = contexts_.find(parent_host); |
| 122 | if (context_it != contexts_.end() |
| 123 | && context_it->second->config().include_subdomains) { |
ttuttle | ca1ac31 | 2015-03-12 17:07:00 | [diff] [blame] | 124 | return context_it->second; |
ttuttle | 2935096c | 2016-02-09 22:31:44 | [diff] [blame] | 125 | } |
ttuttle | ca1ac31 | 2015-03-12 17:07:00 | [diff] [blame] | 126 | |
ttuttle | c72f27d | 2015-03-17 23:55:59 | [diff] [blame] | 127 | return nullptr; |
ttuttle | ca1ac31 | 2015-03-12 17:07:00 | [diff] [blame] | 128 | } |
| 129 | |
| 130 | } // namespace domain_reliability |