blob: 4cb52420bed7bb32e70c04ba5f2cc28eb2cc993c [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(
dcheng04a35cd2016-04-22 15:07:2421 std::unique_ptr<DomainReliabilityBeacon> beacon) {
ttuttleccdd6cc52015-11-22 06:09:4022 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,
dcheng04a35cd2016-04-22 15:07:2431 std::unique_ptr<DomainReliabilityConfig> config,
ttuttle2935096c2016-02-09 22:31:4432 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(
dcheng04a35cd2016-04-22 15:07:2478 std::unique_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
dcheng04a35cd2016-04-22 15:07:2482 std::unique_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
dcheng04a35cd2016-04-22 15:07:2498std::unique_ptr<base::Value> DomainReliabilityContextManager::GetWebUIData()
99 const {
100 std::unique_ptr<base::ListValue> contexts_value(new base::ListValue());
ttuttleca1ac312015-03-12 17:07:00101 for (const auto& context_entry : contexts_)
102 contexts_value->Append(context_entry.second->GetWebUIData().release());
dcheng51606352015-12-26 21:16:23103 return std::move(contexts_value);
ttuttleca1ac312015-03-12 17:07:00104}
105
106DomainReliabilityContext* 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
ttuttleca1ac312015-03-12 17:07:00114 size_t dot_pos = host.find('.');
115 if (dot_pos == std::string::npos)
ttuttlec72f27d2015-03-17 23:55:59116 return nullptr;
ttuttleca1ac312015-03-12 17:07:00117
ttuttle960fcbf2016-04-19 13:26:32118 // TODO(juliatuttle): Make sure parent is not in PSL before using.
ttuttleca1ac312015-03-12 17:07:00119
ttuttle2935096c2016-02-09 22:31:44120 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) {
ttuttleca1ac312015-03-12 17:07:00124 return context_it->second;
ttuttle2935096c2016-02-09 22:31:44125 }
ttuttleca1ac312015-03-12 17:07:00126
ttuttlec72f27d2015-03-17 23:55:59127 return nullptr;
ttuttleca1ac312015-03-12 17:07:00128}
129
130} // namespace domain_reliability