0f9be54060bca7ee1a6cc8d711bea1798e73a149
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / proxy_cros_settings_parser.cc
1 // Copyright (c) 2012 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 "chrome/browser/chromeos/proxy_cros_settings_parser.h"
6
7 #include "base/strings/string_util.h"
8 #include "base/values.h"
9 #include "chrome/browser/chromeos/ui_proxy_config.h"
10 #include "chrome/browser/chromeos/ui_proxy_config_service.h"
11
12 namespace chromeos {
13
14 // Common prefix of all proxy prefs.
15 const char kProxyPrefsPrefix[] = "cros.session.proxy";
16
17 // Names of proxy preferences.
18 const char kProxyPacUrl[]         = "cros.session.proxy.pacurl";
19 const char kProxySingleHttp[]     = "cros.session.proxy.singlehttp";
20 const char kProxySingleHttpPort[] = "cros.session.proxy.singlehttpport";
21 const char kProxyHttpUrl[]        = "cros.session.proxy.httpurl";
22 const char kProxyHttpPort[]       = "cros.session.proxy.httpport";
23 const char kProxyHttpsUrl[]       = "cros.session.proxy.httpsurl";
24 const char kProxyHttpsPort[]      = "cros.session.proxy.httpsport";
25 const char kProxyType[]           = "cros.session.proxy.type";
26 const char kProxySingle[]         = "cros.session.proxy.single";
27 const char kProxyFtpUrl[]         = "cros.session.proxy.ftpurl";
28 const char kProxyFtpPort[]        = "cros.session.proxy.ftpport";
29 const char kProxySocks[]          = "cros.session.proxy.socks";
30 const char kProxySocksPort[]      = "cros.session.proxy.socksport";
31 const char kProxyIgnoreList[]     = "cros.session.proxy.ignorelist";
32 const char kProxyUsePacUrl[]      = "cros.session.proxy.usepacurl";
33
34 const char* const kProxySettings[] = {
35   kProxyPacUrl,
36   kProxySingleHttp,
37   kProxySingleHttpPort,
38   kProxyHttpUrl,
39   kProxyHttpPort,
40   kProxyHttpsUrl,
41   kProxyHttpsPort,
42   kProxyType,
43   kProxySingle,
44   kProxyFtpUrl,
45   kProxyFtpPort,
46   kProxySocks,
47   kProxySocksPort,
48   kProxyIgnoreList,
49   kProxyUsePacUrl,
50 };
51
52 // We have to explicitly export this because the arraysize macro doesn't like
53 // extern arrays as their size is not known on compile time.
54 const size_t kProxySettingsCount = arraysize(kProxySettings);
55
56 namespace {
57
58 base::Value* CreateServerHostValue(const UIProxyConfig::ManualProxy& proxy) {
59   return proxy.server.is_valid() ?
60          new base::StringValue(proxy.server.host_port_pair().host()) :
61          NULL;
62 }
63
64 base::Value* CreateServerPortValue(const UIProxyConfig::ManualProxy& proxy) {
65   return proxy.server.is_valid()
66              ? new base::FundamentalValue(proxy.server.host_port_pair().port())
67              : NULL;
68 }
69
70 net::ProxyServer CreateProxyServer(std::string host,
71                                    uint16 port,
72                                    net::ProxyServer::Scheme scheme) {
73   if (host.empty() && port == 0)
74     return net::ProxyServer();
75   uint16 default_port = net::ProxyServer::GetDefaultPortForScheme(scheme);
76   net::HostPortPair host_port_pair;
77   // Check if host is a valid URL or a string of valid format <server>::<port>.
78   GURL url(host);
79   if (url.is_valid())  // See if host is URL.
80     host_port_pair = net::HostPortPair::FromURL(url);
81   if (host_port_pair.host().empty())  // See if host is <server>::<port>.
82     host_port_pair = net::HostPortPair::FromString(host);
83   if (host_port_pair.host().empty())  // Host is not URL or <server>::<port>.
84     host_port_pair = net::HostPortPair(host, port);
85   if (host_port_pair.port() == 0)  // No port in host, use default.
86     host_port_pair.set_port(default_port);
87   return net::ProxyServer(scheme, host_port_pair);
88 }
89
90 net::ProxyServer CreateProxyServerFromHost(
91     const std::string& host,
92     const UIProxyConfig::ManualProxy& proxy,
93     net::ProxyServer::Scheme scheme) {
94   uint16 port = 0;
95   if (proxy.server.is_valid())
96     port = proxy.server.host_port_pair().port();
97   return CreateProxyServer(host, port, scheme);
98 }
99
100 net::ProxyServer CreateProxyServerFromPort(
101     uint16 port,
102     const UIProxyConfig::ManualProxy& proxy,
103     net::ProxyServer::Scheme scheme) {
104   std::string host;
105   if (proxy.server.is_valid())
106     host = proxy.server.host_port_pair().host();
107   return CreateProxyServer(host, port, scheme);
108 }
109
110 }  // namespace
111
112 namespace proxy_cros_settings_parser {
113
114 bool IsProxyPref(const std::string& path) {
115   return StartsWithASCII(path, kProxyPrefsPrefix, true);
116 }
117
118 void SetProxyPrefValue(const std::string& path,
119                        const base::Value* in_value,
120                        UIProxyConfigService* config_service) {
121   if (!in_value) {
122     NOTREACHED();
123     return;
124   }
125
126   // Retrieve proxy config.
127   UIProxyConfig config;
128   config_service->GetProxyConfig(&config);
129
130   if (path == kProxyPacUrl) {
131     std::string val;
132     if (in_value->GetAsString(&val)) {
133       GURL url(val);
134       if (url.is_valid())
135         config.SetPacUrl(url);
136       else
137         config.mode = UIProxyConfig::MODE_AUTO_DETECT;
138     }
139   } else if (path == kProxySingleHttp) {
140     std::string val;
141     if (in_value->GetAsString(&val)) {
142       config.SetSingleProxy(CreateProxyServerFromHost(
143           val, config.single_proxy, net::ProxyServer::SCHEME_HTTP));
144     }
145   } else if (path == kProxySingleHttpPort) {
146     int val;
147     if (in_value->GetAsInteger(&val)) {
148       config.SetSingleProxy(CreateProxyServerFromPort(
149           val, config.single_proxy, net::ProxyServer::SCHEME_HTTP));
150     }
151   } else if (path == kProxyHttpUrl) {
152     std::string val;
153     if (in_value->GetAsString(&val)) {
154       config.SetProxyForScheme(
155           "http", CreateProxyServerFromHost(
156               val, config.http_proxy, net::ProxyServer::SCHEME_HTTP));
157     }
158   } else if (path == kProxyHttpPort) {
159     int val;
160     if (in_value->GetAsInteger(&val)) {
161       config.SetProxyForScheme(
162           "http", CreateProxyServerFromPort(
163               val, config.http_proxy, net::ProxyServer::SCHEME_HTTP));
164     }
165   } else if (path == kProxyHttpsUrl) {
166     std::string val;
167     if (in_value->GetAsString(&val)) {
168       config.SetProxyForScheme(
169           "https", CreateProxyServerFromHost(
170               val, config.https_proxy, net::ProxyServer::SCHEME_HTTP));
171     }
172   } else if (path == kProxyHttpsPort) {
173     int val;
174     if (in_value->GetAsInteger(&val)) {
175       config.SetProxyForScheme(
176           "https", CreateProxyServerFromPort(
177               val, config.https_proxy, net::ProxyServer::SCHEME_HTTP));
178     }
179   } else if (path == kProxyType) {
180     int val;
181     if (in_value->GetAsInteger(&val)) {
182       if (val == 3) {
183         if (config.automatic_proxy.pac_url.is_valid())
184           config.SetPacUrl(config.automatic_proxy.pac_url);
185         else
186           config.mode = UIProxyConfig::MODE_AUTO_DETECT;
187       } else if (val == 2) {
188         if (config.single_proxy.server.is_valid()) {
189           config.SetSingleProxy(config.single_proxy.server);
190         } else {
191           bool set_config = false;
192           if (config.http_proxy.server.is_valid()) {
193             config.SetProxyForScheme("http", config.http_proxy.server);
194             set_config = true;
195           }
196           if (config.https_proxy.server.is_valid()) {
197             config.SetProxyForScheme("https", config.https_proxy.server);
198             set_config = true;
199           }
200           if (config.ftp_proxy.server.is_valid()) {
201             config.SetProxyForScheme("ftp", config.ftp_proxy.server);
202             set_config = true;
203           }
204           if (config.socks_proxy.server.is_valid()) {
205             config.SetProxyForScheme("socks", config.socks_proxy.server);
206             set_config = true;
207           }
208           if (!set_config)
209             config.SetProxyForScheme("http", net::ProxyServer());
210         }
211       } else {
212         config.mode = UIProxyConfig::MODE_DIRECT;
213       }
214     }
215   } else if (path == kProxySingle) {
216     bool val;
217     if (in_value->GetAsBoolean(&val)) {
218       if (val)
219         config.SetSingleProxy(config.single_proxy.server);
220       else
221         config.SetProxyForScheme("http", config.http_proxy.server);
222     }
223   } else if (path == kProxyUsePacUrl) {
224     bool use_pac_url;
225     if (in_value->GetAsBoolean(&use_pac_url)) {
226       if (use_pac_url && config.automatic_proxy.pac_url.is_valid())
227         config.SetPacUrl(config.automatic_proxy.pac_url);
228       else
229         config.mode = UIProxyConfig::MODE_AUTO_DETECT;
230     }
231   } else if (path == kProxyFtpUrl) {
232     std::string val;
233     if (in_value->GetAsString(&val)) {
234       config.SetProxyForScheme(
235           "ftp", CreateProxyServerFromHost(
236               val, config.ftp_proxy, net::ProxyServer::SCHEME_HTTP));
237     }
238   } else if (path == kProxyFtpPort) {
239     int val;
240     if (in_value->GetAsInteger(&val)) {
241       config.SetProxyForScheme(
242           "ftp", CreateProxyServerFromPort(
243               val, config.ftp_proxy, net::ProxyServer::SCHEME_HTTP));
244     }
245   } else if (path == kProxySocks) {
246     std::string val;
247     if (in_value->GetAsString(&val)) {
248       config.SetProxyForScheme(
249           "socks", CreateProxyServerFromHost(
250               val,
251               config.socks_proxy,
252               StartsWithASCII(val, "socks5://", false) ?
253               net::ProxyServer::SCHEME_SOCKS5 :
254               net::ProxyServer::SCHEME_SOCKS4));
255     }
256   } else if (path == kProxySocksPort) {
257     int val;
258     if (in_value->GetAsInteger(&val)) {
259       std::string host = config.socks_proxy.server.host_port_pair().host();
260       config.SetProxyForScheme(
261           "socks", CreateProxyServerFromPort(
262               val,
263               config.socks_proxy,
264               StartsWithASCII(host, "socks5://", false) ?
265               net::ProxyServer::SCHEME_SOCKS5 :
266               net::ProxyServer::SCHEME_SOCKS4));
267     }
268   } else if (path == kProxyIgnoreList) {
269     net::ProxyBypassRules bypass_rules;
270     if (in_value->GetType() == base::Value::TYPE_LIST) {
271       const base::ListValue* list_value =
272           static_cast<const base::ListValue*>(in_value);
273       for (size_t x = 0; x < list_value->GetSize(); x++) {
274         std::string val;
275         if (list_value->GetString(x, &val))
276           bypass_rules.AddRuleFromString(val);
277       }
278       config.SetBypassRules(bypass_rules);
279     }
280   } else {
281     LOG(WARNING) << "Unknown proxy settings path " << path;
282     return;
283   }
284
285   config_service->SetProxyConfig(config);
286 }
287
288 bool GetProxyPrefValue(const UIProxyConfigService& config_service,
289                        const std::string& path,
290                        base::Value** out_value) {
291   std::string controlled_by;
292   base::Value* data = NULL;
293   UIProxyConfig config;
294   config_service.GetProxyConfig(&config);
295
296   if (path == kProxyPacUrl) {
297     // Only show pacurl for pac-script mode.
298     if (config.mode == UIProxyConfig::MODE_PAC_SCRIPT &&
299         config.automatic_proxy.pac_url.is_valid()) {
300       data = new base::StringValue(config.automatic_proxy.pac_url.spec());
301     }
302   } else if (path == kProxySingleHttp) {
303     data = CreateServerHostValue(config.single_proxy);
304   } else if (path == kProxySingleHttpPort) {
305     data = CreateServerPortValue(config.single_proxy);
306   } else if (path == kProxyHttpUrl) {
307     data = CreateServerHostValue(config.http_proxy);
308   } else if (path == kProxyHttpsUrl) {
309     data = CreateServerHostValue(config.https_proxy);
310   } else if (path == kProxyType) {
311     if (config.mode == UIProxyConfig::MODE_AUTO_DETECT ||
312         config.mode == UIProxyConfig::MODE_PAC_SCRIPT) {
313       data = new base::FundamentalValue(3);
314     } else if (config.mode == UIProxyConfig::MODE_SINGLE_PROXY ||
315                config.mode == UIProxyConfig::MODE_PROXY_PER_SCHEME) {
316       data = new base::FundamentalValue(2);
317     } else {
318       data = new base::FundamentalValue(1);
319     }
320     switch (config.state) {
321       case ProxyPrefs::CONFIG_POLICY:
322         controlled_by = "policy";
323         break;
324       case ProxyPrefs::CONFIG_EXTENSION:
325         controlled_by = "extension";
326         break;
327       case ProxyPrefs::CONFIG_OTHER_PRECEDE:
328         controlled_by = "other";
329         break;
330       default:
331         if (!config.user_modifiable)
332           controlled_by = "shared";
333         break;
334     }
335   } else if (path == kProxySingle) {
336     data = new base::FundamentalValue(config.mode ==
337                                       UIProxyConfig::MODE_SINGLE_PROXY);
338   } else if (path == kProxyUsePacUrl) {
339     data = new base::FundamentalValue(config.mode ==
340                                       UIProxyConfig::MODE_PAC_SCRIPT);
341   } else if (path == kProxyFtpUrl) {
342     data = CreateServerHostValue(config.ftp_proxy);
343   } else if (path == kProxySocks) {
344     data = CreateServerHostValue(config.socks_proxy);
345   } else if (path == kProxyHttpPort) {
346     data = CreateServerPortValue(config.http_proxy);
347   } else if (path == kProxyHttpsPort) {
348     data = CreateServerPortValue(config.https_proxy);
349   } else if (path == kProxyFtpPort) {
350     data = CreateServerPortValue(config.ftp_proxy);
351   } else if (path == kProxySocksPort) {
352     data = CreateServerPortValue(config.socks_proxy);
353   } else if (path == kProxyIgnoreList) {
354     base::ListValue* list =  new base::ListValue();
355     net::ProxyBypassRules::RuleList bypass_rules = config.bypass_rules.rules();
356     for (size_t x = 0; x < bypass_rules.size(); x++)
357       list->Append(new base::StringValue(bypass_rules[x]->ToString()));
358     data = list;
359   } else {
360     *out_value = NULL;
361     return false;
362   }
363
364   // Decorate pref value as CoreOptionsHandler::CreateValueForPref() does.
365   base::DictionaryValue* dict = new base::DictionaryValue;
366   if (!data)
367     data = new base::StringValue("");
368   dict->Set("value", data);
369   if (path == kProxyType) {
370     if (!controlled_by.empty())
371       dict->SetString("controlledBy", controlled_by);
372     dict->SetBoolean("disabled", !config.user_modifiable);
373   } else {
374     dict->SetBoolean("disabled", false);
375   }
376   *out_value = dict;
377   return true;
378 }
379
380 }  // namespace proxy_cros_settings_parser
381
382 }  // namespace chromeos