921a2e4b47e5bc4549ef6bae411c1dffc017341e
[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     const std::string& ssl_origin) {
135
136   std::vector<std::string> proxies;
137   if (!primary_restricted) {
138     std::string trimmed_primary;
139     base::TrimString(primary_origin, "/", &trimmed_primary);
140     if (!trimmed_primary.empty())
141       proxies.push_back(trimmed_primary);
142   }
143   if (!fallback_restricted) {
144     std::string trimmed_fallback;
145     base::TrimString(fallback_origin, "/", &trimmed_fallback);
146     if (!trimmed_fallback.empty())
147       proxies.push_back(trimmed_fallback);
148   }
149   if (proxies.empty()) {
150     std::string mode;
151     Disable();
152     return;
153   }
154
155   std::string trimmed_ssl;
156   base::TrimString(ssl_origin, "/", &trimmed_ssl);
157
158   std::string server = "http=" + JoinString(proxies, ",") + ",direct://;"
159       + (ssl_origin.empty() ? "" : ("https=" + ssl_origin + ",direct://;"));
160
161   net::ProxyConfig config;
162   config.proxy_rules().ParseFromString(server);
163   config.proxy_rules().bypass_rules.ParseFromString(
164       JoinString(bypass_rules_, ", "));
165   UpdateProxyConfigOnIOThread(true, config);
166 }
167
168
169 void DataReductionProxyConfigTracker::Disable() {
170   net::ProxyConfig config = net::ProxyConfig::CreateDirect();
171   UpdateProxyConfigOnIOThread(false, config);
172 }
173
174 void DataReductionProxyConfigTracker::AddHostPatternToBypass(
175     const std::string& pattern) {
176   bypass_rules_.push_back(pattern);
177 }
178
179 void DataReductionProxyConfigTracker::AddURLPatternToBypass(
180     const std::string& pattern) {
181   size_t pos = pattern.find("/");
182   if (pattern.find("/", pos + 1) == pos + 1)
183     pos = pattern.find("/", pos + 2);
184
185   std::string host_pattern;
186   if (pos != std::string::npos)
187     host_pattern = pattern.substr(0, pos);
188   else
189     host_pattern = pattern;
190
191   AddHostPatternToBypass(host_pattern);
192 }
193
194 void DataReductionProxyConfigTracker::UpdateProxyConfigOnIOThread(
195     bool enabled,
196     const net::ProxyConfig& config) {
197   task_runner_->PostTask(FROM_HERE,
198       base::Bind(
199           &DataReductionProxyConfigService::UpdateProxyConfig,
200           base::Unretained(config_service_),
201           enabled, config));
202 }
203
204 }  // namespace data_reduction_proxy