blob: c85f82b5a15e58fb6f27227632e0b4aaa3ae60cb [file] [log] [blame]
ttuttleca1ac312015-03-12 17:07:001// 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
dcheng51606352015-12-26 21:16:237#include <utility>
8
ttuttleca1ac312015-03-12 17:07:009namespace domain_reliability {
10
11DomainReliabilityContextManager::DomainReliabilityContextManager(
12 DomainReliabilityContext::Factory* context_factory)
13 : context_factory_(context_factory) {
14}
15
16DomainReliabilityContextManager::~DomainReliabilityContextManager() {
17 RemoveAllContexts();
18}
19
20void DomainReliabilityContextManager::RouteBeacon(
ttuttleccdd6cc52015-11-22 06:09:4021 scoped_ptr<DomainReliabilityBeacon> beacon) {
22 DomainReliabilityContext* context = GetContextForHost(beacon->url.host());
ttuttleca1ac312015-03-12 17:07:0023 if (!context)
24 return;
25
dcheng51606352015-12-26 21:16:2326 context->OnBeacon(std::move(beacon));
ttuttleca1ac312015-03-12 17:07:0027}
28
ttuttle2935096c2016-02-09 22:31:4429void DomainReliabilityContextManager::SetConfig(
30 const GURL& origin,
31 scoped_ptr<DomainReliabilityConfig> config,
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 }
ttuttle960fcbf2016-04-19 13:26:3252 // TODO(juliatuttle): Make Context accept Config changes.
ttuttle2935096c2016-02-09 22:31:4453 }
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
62void 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
ttuttleca1ac312015-03-12 17:07:0072void DomainReliabilityContextManager::ClearBeaconsInAllContexts() {
73 for (auto& context_entry : contexts_)
74 context_entry.second->ClearBeacons();
75}
76
77DomainReliabilityContext* DomainReliabilityContextManager::AddContextForConfig(
78 scoped_ptr<const DomainReliabilityConfig> config) {
ttuttle2935096c2016-02-09 22:31:4479 std::string key = config->origin.host();
ttuttle960fcbf2016-04-19 13:26:3280 // TODO(juliatuttle): Convert this to actual origin.
ttuttleccdd6cc52015-11-22 06:09:4081
ttuttleca1ac312015-03-12 17:07:0082 scoped_ptr<DomainReliabilityContext> context =
dcheng51606352015-12-26 21:16:2383 context_factory_->CreateContextForConfig(std::move(config));
ttuttle2935096c2016-02-09 22:31:4484 DomainReliabilityContext** entry = &contexts_[key];
ttuttleca1ac312015-03-12 17:07:0085 if (*entry)
86 delete *entry;
ttuttle2935096c2016-02-09 22:31:4487
ttuttleca1ac312015-03-12 17:07:0088 *entry = context.release();
89 return *entry;
90}
91
92void DomainReliabilityContextManager::RemoveAllContexts() {
93 STLDeleteContainerPairSecondPointers(
94 contexts_.begin(), contexts_.end());
95 contexts_.clear();
96}
97
ttuttlec72f27d2015-03-17 23:55:5998scoped_ptr<base::Value> DomainReliabilityContextManager::GetWebUIData() const {
99 scoped_ptr<base::ListValue> contexts_value(new base::ListValue());
ttuttleca1ac312015-03-12 17:07:00100 for (const auto& context_entry : contexts_)
101 contexts_value->Append(context_entry.second->GetWebUIData().release());
dcheng51606352015-12-26 21:16:23102 return std::move(contexts_value);
ttuttleca1ac312015-03-12 17:07:00103}
104
105DomainReliabilityContext* DomainReliabilityContextManager::GetContextForHost(
106 const std::string& host) {
107 ContextMap::const_iterator context_it;
108
109 context_it = contexts_.find(host);
110 if (context_it != contexts_.end())
111 return context_it->second;
112
ttuttleca1ac312015-03-12 17:07:00113 size_t dot_pos = host.find('.');
114 if (dot_pos == std::string::npos)
ttuttlec72f27d2015-03-17 23:55:59115 return nullptr;
ttuttleca1ac312015-03-12 17:07:00116
ttuttle960fcbf2016-04-19 13:26:32117 // TODO(juliatuttle): Make sure parent is not in PSL before using.
ttuttleca1ac312015-03-12 17:07:00118
ttuttle2935096c2016-02-09 22:31:44119 std::string parent_host = host.substr(dot_pos + 1);
120 context_it = contexts_.find(parent_host);
121 if (context_it != contexts_.end()
122 && context_it->second->config().include_subdomains) {
ttuttleca1ac312015-03-12 17:07:00123 return context_it->second;
ttuttle2935096c2016-02-09 22:31:44124 }
ttuttleca1ac312015-03-12 17:07:00125
ttuttlec72f27d2015-03-17 23:55:59126 return nullptr;
ttuttleca1ac312015-03-12 17:07:00127}
128
129} // namespace domain_reliability