ProjectingObserverChromeos: Drop DBusThreadManager dependency for better testing.
[chromium-blink-merge.git] / components / data_reduction_proxy / browser / data_reduction_proxy_config_service.cc
blobd85a15bdde3d83d2ed288e8f155d560199680cb9
1 // Copyright 2014 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.
5 #include "components/data_reduction_proxy/browser/data_reduction_proxy_config_service.h"
7 #include "base/bind.h"
8 #include "base/memory/ref_counted.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/strings/string_util.h"
12 namespace data_reduction_proxy {
14 DataReductionProxyConfigService::DataReductionProxyConfigService(
15 scoped_ptr<net::ProxyConfigService> base_service)
16 : config_read_pending_(true),
17 registered_observer_(false),
18 enabled_(false),
19 restricted_(false) {
20 base_service_ = base_service.Pass();
23 DataReductionProxyConfigService::~DataReductionProxyConfigService() {
24 if (registered_observer_ && base_service_.get())
25 base_service_->RemoveObserver(this);
28 void DataReductionProxyConfigService::AddObserver(
29 net::ProxyConfigService::Observer* observer) {
30 RegisterObserver();
31 observers_.AddObserver(observer);
34 void DataReductionProxyConfigService::RemoveObserver(
35 net::ProxyConfigService::Observer* observer) {
36 observers_.RemoveObserver(observer);
39 net::ProxyConfigService::ConfigAvailability
40 DataReductionProxyConfigService::GetLatestProxyConfig(
41 net::ProxyConfig* config) {
42 RegisterObserver();
44 if (enabled_) {
45 *config = config_;
46 return net::ProxyConfigService::CONFIG_VALID;
49 // Ask the base service if available.
50 net::ProxyConfig system_config;
51 ConfigAvailability system_availability =
52 net::ProxyConfigService::CONFIG_UNSET;
53 if (base_service_.get()) {
54 system_availability = base_service_->GetLatestProxyConfig(&system_config);
55 *config = system_config;
57 if (system_availability == net::ProxyConfigService::CONFIG_UNSET) {
58 *config = net::ProxyConfig::CreateDirect();
61 return net::ProxyConfigService::CONFIG_VALID;
64 void DataReductionProxyConfigService::OnLazyPoll() {
65 if (base_service_.get())
66 base_service_->OnLazyPoll();
69 void DataReductionProxyConfigService::UpdateProxyConfig(
70 bool enabled,
71 const net::ProxyConfig& config) {
73 config_read_pending_ = false;
74 enabled_ = enabled;
75 config_ = config;
77 if (!observers_.might_have_observers())
78 return;
80 // Evaluate the proxy configuration. If GetLatestProxyConfig returns
81 // CONFIG_PENDING, we are using the system proxy service, but it doesn't have
82 // a valid configuration yet. Once it is ready, OnProxyConfigChanged() will be
83 // called and broadcast the proxy configuration.
84 // Note: If a switch between a preference proxy configuration and the system
85 // proxy configuration occurs an unnecessary notification might get sent if
86 // the two configurations agree. This case should be rare however, so we don't
87 // handle that case specially.
88 net::ProxyConfig new_config;
89 ConfigAvailability availability = GetLatestProxyConfig(&new_config);
90 if (availability != CONFIG_PENDING) {
91 FOR_EACH_OBSERVER(net::ProxyConfigService::Observer, observers_,
92 OnProxyConfigChanged(new_config, availability));
96 void DataReductionProxyConfigService::OnProxyConfigChanged(
97 const net::ProxyConfig& config,
98 ConfigAvailability availability) {
100 // Check whether the data reduction proxy is enabled. In this case that proxy
101 // configuration takes precedence and the change event from the delegate proxy
102 // service can be disregarded.
103 if (!enabled_) {
104 net::ProxyConfig actual_config;
105 availability = GetLatestProxyConfig(&actual_config);
106 FOR_EACH_OBSERVER(net::ProxyConfigService::Observer, observers_,
107 OnProxyConfigChanged(actual_config, availability));
111 void DataReductionProxyConfigService::RegisterObserver() {
112 if (!registered_observer_ && base_service_.get()) {
113 base_service_->AddObserver(this);
114 registered_observer_ = true;
118 DataReductionProxyConfigTracker::DataReductionProxyConfigTracker(
119 base::Callback<void(bool, const net::ProxyConfig&)> update_proxy_config,
120 const scoped_refptr<base::TaskRunner>& task_runner)
121 : update_proxy_config_(update_proxy_config),
122 task_runner_(task_runner) {
125 DataReductionProxyConfigTracker::~DataReductionProxyConfigTracker() {
128 void DataReductionProxyConfigTracker::Enable(
129 bool primary_restricted,
130 bool fallback_restricted,
131 const std::string& primary_origin,
132 const std::string& fallback_origin,
133 const std::string& ssl_origin) {
135 std::vector<std::string> proxies;
136 if (!primary_restricted) {
137 std::string trimmed_primary;
138 base::TrimString(primary_origin, "/", &trimmed_primary);
139 if (!trimmed_primary.empty())
140 proxies.push_back(trimmed_primary);
142 if (!fallback_restricted) {
143 std::string trimmed_fallback;
144 base::TrimString(fallback_origin, "/", &trimmed_fallback);
145 if (!trimmed_fallback.empty())
146 proxies.push_back(trimmed_fallback);
148 if (proxies.empty()) {
149 std::string mode;
150 Disable();
151 return;
154 std::string trimmed_ssl;
155 base::TrimString(ssl_origin, "/", &trimmed_ssl);
157 std::string server = "http=" + JoinString(proxies, ",") + ",direct://;"
158 + (ssl_origin.empty() ? "" : ("https=" + ssl_origin + ",direct://;"));
160 net::ProxyConfig config;
161 config.proxy_rules().ParseFromString(server);
162 config.proxy_rules().bypass_rules.ParseFromString(
163 JoinString(bypass_rules_, ", "));
164 UpdateProxyConfigOnIOThread(true, config);
168 void DataReductionProxyConfigTracker::Disable() {
169 net::ProxyConfig config = net::ProxyConfig::CreateDirect();
170 UpdateProxyConfigOnIOThread(false, config);
173 void DataReductionProxyConfigTracker::AddHostPatternToBypass(
174 const std::string& pattern) {
175 bypass_rules_.push_back(pattern);
178 void DataReductionProxyConfigTracker::AddURLPatternToBypass(
179 const std::string& pattern) {
180 size_t pos = pattern.find("/");
181 if (pattern.find("/", pos + 1) == pos + 1)
182 pos = pattern.find("/", pos + 2);
184 std::string host_pattern;
185 if (pos != std::string::npos)
186 host_pattern = pattern.substr(0, pos);
187 else
188 host_pattern = pattern;
190 AddHostPatternToBypass(host_pattern);
193 void DataReductionProxyConfigTracker::UpdateProxyConfigOnIOThread(
194 bool enabled,
195 const net::ProxyConfig& config) {
196 task_runner_->PostTask(
197 FROM_HERE, base::Bind(update_proxy_config_, enabled, config));
200 } // namespace data_reduction_proxy