Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / components / data_reduction_proxy / browser / data_reduction_proxy_config_service.cc
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.
4
5 #include "components/data_reduction_proxy/browser/data_reduction_proxy_config_service.h"
6
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"
11
12 namespace data_reduction_proxy {
13
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();
21 }
22
23 DataReductionProxyConfigService::~DataReductionProxyConfigService() {
24   if (registered_observer_ && base_service_.get())
25     base_service_->RemoveObserver(this);
26 }
27
28 void DataReductionProxyConfigService::AddObserver(
29     net::ProxyConfigService::Observer* observer) {
30   RegisterObserver();
31   observers_.AddObserver(observer);
32 }
33
34 void DataReductionProxyConfigService::RemoveObserver(
35     net::ProxyConfigService::Observer* observer) {
36   observers_.RemoveObserver(observer);
37 }
38
39 net::ProxyConfigService::ConfigAvailability
40 DataReductionProxyConfigService::GetLatestProxyConfig(
41     net::ProxyConfig* config) {
42   RegisterObserver();
43
44   if (enabled_) {
45     *config = config_;
46     return net::ProxyConfigService::CONFIG_VALID;
47   }
48
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;
56   }
57   if (system_availability == net::ProxyConfigService::CONFIG_UNSET) {
58     *config = net::ProxyConfig::CreateDirect();
59   }
60
61   return net::ProxyConfigService::CONFIG_VALID;
62 }
63
64 void DataReductionProxyConfigService::OnLazyPoll() {
65   if (base_service_.get())
66     base_service_->OnLazyPoll();
67 }
68
69 void DataReductionProxyConfigService::UpdateProxyConfig(
70     bool enabled,
71     const net::ProxyConfig& config) {
72
73   config_read_pending_ = false;
74   enabled_ = enabled;
75   config_ = config;
76
77   if (!observers_.might_have_observers())
78     return;
79
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));
93   }
94 }
95
96 void DataReductionProxyConfigService::OnProxyConfigChanged(
97     const net::ProxyConfig& config,
98     ConfigAvailability availability) {
99
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));
108   }
109 }
110
111 void DataReductionProxyConfigService::RegisterObserver() {
112   if (!registered_observer_ && base_service_.get()) {
113     base_service_->AddObserver(this);
114     registered_observer_ = true;
115   }
116 }
117
118 DataReductionProxyConfigTracker::DataReductionProxyConfigTracker(
119     base::Callback<void(bool, const net::ProxyConfig&)> update_proxy_config,
120     base::TaskRunner* task_runner)
121     : update_proxy_config_(update_proxy_config),
122       task_runner_(task_runner) {
123 }
124
125 DataReductionProxyConfigTracker::~DataReductionProxyConfigTracker() {
126 }
127
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) {
134
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);
141   }
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);
147   }
148   if (proxies.empty()) {
149     std::string mode;
150     Disable();
151     return;
152   }
153
154   std::string trimmed_ssl;
155   base::TrimString(ssl_origin, "/", &trimmed_ssl);
156
157   std::string server = "http=" + JoinString(proxies, ",") + ",direct://;"
158       + (ssl_origin.empty() ? "" : ("https=" + ssl_origin + ",direct://;"));
159
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);
165 }
166
167
168 void DataReductionProxyConfigTracker::Disable() {
169   net::ProxyConfig config = net::ProxyConfig::CreateDirect();
170   UpdateProxyConfigOnIOThread(false, config);
171 }
172
173 void DataReductionProxyConfigTracker::AddHostPatternToBypass(
174     const std::string& pattern) {
175   bypass_rules_.push_back(pattern);
176 }
177
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);
183
184   std::string host_pattern;
185   if (pos != std::string::npos)
186     host_pattern = pattern.substr(0, pos);
187   else
188     host_pattern = pattern;
189
190   AddHostPatternToBypass(host_pattern);
191 }
192
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));
198 }
199
200 }  // namespace data_reduction_proxy