Upstream version 7.36.149.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     DataReductionProxyConfigService* config_service,
120     base::TaskRunner* task_runner)
121     : config_service_(config_service),
122       task_runner_(task_runner) {
123   DCHECK(config_service);
124 }
125
126 DataReductionProxyConfigTracker::~DataReductionProxyConfigTracker() {
127 }
128
129 void DataReductionProxyConfigTracker::Enable(
130     bool primary_restricted,
131     bool fallback_restricted,
132     const std::string& primary_origin,
133     const std::string& fallback_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   net::ProxyConfig config;
155   config.proxy_rules().ParseFromString(
156       "http=" + JoinString(proxies, ",") + ",direct://;");
157   config.proxy_rules().bypass_rules.ParseFromString(
158       JoinString(bypass_rules_, ", "));
159   UpdateProxyConfigOnIOThread(true, config);
160 }
161
162
163 void DataReductionProxyConfigTracker::Disable() {
164   net::ProxyConfig config = net::ProxyConfig::CreateDirect();
165   UpdateProxyConfigOnIOThread(false, config);
166 }
167
168 void DataReductionProxyConfigTracker::AddHostPatternToBypass(
169     const std::string& pattern) {
170   bypass_rules_.push_back(pattern);
171 }
172
173 void DataReductionProxyConfigTracker::AddURLPatternToBypass(
174     const std::string& pattern) {
175   size_t pos = pattern.find("/");
176   if (pattern.find("/", pos + 1) == pos + 1)
177     pos = pattern.find("/", pos + 2);
178
179   std::string host_pattern;
180   if (pos != std::string::npos)
181     host_pattern = pattern.substr(0, pos);
182   else
183     host_pattern = pattern;
184
185   AddHostPatternToBypass(host_pattern);
186 }
187
188 void DataReductionProxyConfigTracker::UpdateProxyConfigOnIOThread(
189     bool enabled,
190     const net::ProxyConfig& config) {
191   task_runner_->PostTask(FROM_HERE,
192       base::Bind(
193           &DataReductionProxyConfigService::UpdateProxyConfig,
194           base::Unretained(config_service_),
195           enabled, config));
196 }
197
198 }  // namespace data_reduction_proxy