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.
5 #include "chrome/browser/chromeos/proxy_cros_settings_parser.h"
7 #include "base/string_util.h"
8 #include "base/values.h"
9 #include "chrome/browser/chromeos/proxy_config_service_impl.h"
10 #include "chrome/browser/profiles/profile.h"
14 // Common prefix of all proxy prefs.
15 const char kProxyPrefsPrefix
[] = "cros.session.proxy";
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";
33 const char* const kProxySettings
[] = {
50 // We have to explicitly export this because the arraysize macro doesn't like
51 // extern arrays as their size is not known on compile time.
52 const size_t kProxySettingsCount
= arraysize(kProxySettings
);
56 base::Value
* CreateServerHostValue(
57 const ProxyConfigServiceImpl::ProxyConfig::ManualProxy
& proxy
) {
58 return proxy
.server
.is_valid() ?
59 base::Value::CreateStringValue(proxy
.server
.host_port_pair().host()) :
63 base::Value
* CreateServerPortValue(
64 const ProxyConfigServiceImpl::ProxyConfig::ManualProxy
& proxy
) {
65 return proxy
.server
.is_valid() ?
66 base::Value::CreateIntegerValue(proxy
.server
.host_port_pair().port()) :
70 net::ProxyServer
CreateProxyServer(std::string host
,
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>.
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 // Formal parameter port overrides what may have been specified in host.
86 if (port
!= 0 && port
!= default_port
)
87 host_port_pair
.set_port(port
);
88 else if (host_port_pair
.port() == 0) // No port in host, use default.
89 host_port_pair
.set_port(default_port
);
90 return net::ProxyServer(scheme
, host_port_pair
);
93 net::ProxyServer
CreateProxyServerFromHost(
94 const std::string
& host
,
95 const ProxyConfigServiceImpl::ProxyConfig::ManualProxy
& proxy
,
96 net::ProxyServer::Scheme scheme
) {
98 if (proxy
.server
.is_valid())
99 port
= proxy
.server
.host_port_pair().port();
100 return CreateProxyServer(host
, port
, scheme
);
103 net::ProxyServer
CreateProxyServerFromPort(
105 const ProxyConfigServiceImpl::ProxyConfig::ManualProxy
& proxy
,
106 net::ProxyServer::Scheme scheme
) {
108 if (proxy
.server
.is_valid())
109 host
= proxy
.server
.host_port_pair().host();
110 return CreateProxyServer(host
, port
, scheme
);
115 namespace proxy_cros_settings_parser
{
117 bool IsProxyPref(const std::string
& path
) {
118 return StartsWithASCII(path
, kProxyPrefsPrefix
, true);
121 void SetProxyPrefValue(Profile
* profile
,
122 const std::string
& path
,
123 const base::Value
* in_value
) {
129 chromeos::ProxyConfigServiceImpl
* config_service
=
130 profile
->GetProxyConfigTracker();
131 // Retrieve proxy config.
132 chromeos::ProxyConfigServiceImpl::ProxyConfig config
;
133 config_service
->UIGetProxyConfig(&config
);
135 if (path
== kProxyPacUrl
) {
137 if (in_value
->GetAsString(&val
)) {
140 config_service
->UISetProxyConfigToPACScript(url
);
142 config_service
->UISetProxyConfigToAutoDetect();
144 } else if (path
== kProxySingleHttp
) {
146 if (in_value
->GetAsString(&val
)) {
147 config_service
->UISetProxyConfigToSingleProxy(CreateProxyServerFromHost(
148 val
, config
.single_proxy
, net::ProxyServer::SCHEME_HTTP
));
150 } else if (path
== kProxySingleHttpPort
) {
152 if (in_value
->GetAsInteger(&val
)) {
153 config_service
->UISetProxyConfigToSingleProxy(CreateProxyServerFromPort(
154 val
, config
.single_proxy
, net::ProxyServer::SCHEME_HTTP
));
156 } else if (path
== kProxyHttpUrl
) {
158 if (in_value
->GetAsString(&val
)) {
159 config_service
->UISetProxyConfigToProxyPerScheme("http",
160 CreateProxyServerFromHost(
161 val
, config
.http_proxy
, net::ProxyServer::SCHEME_HTTP
));
163 } else if (path
== kProxyHttpPort
) {
165 if (in_value
->GetAsInteger(&val
)) {
166 config_service
->UISetProxyConfigToProxyPerScheme("http",
167 CreateProxyServerFromPort(
168 val
, config
.http_proxy
, net::ProxyServer::SCHEME_HTTP
));
170 } else if (path
== kProxyHttpsUrl
) {
172 if (in_value
->GetAsString(&val
)) {
173 config_service
->UISetProxyConfigToProxyPerScheme("https",
174 CreateProxyServerFromHost(
175 val
, config
.https_proxy
, net::ProxyServer::SCHEME_HTTP
));
177 } else if (path
== kProxyHttpsPort
) {
179 if (in_value
->GetAsInteger(&val
)) {
180 config_service
->UISetProxyConfigToProxyPerScheme("https",
181 CreateProxyServerFromPort(
182 val
, config
.https_proxy
, net::ProxyServer::SCHEME_HTTP
));
184 } else if (path
== kProxyType
) {
186 if (in_value
->GetAsInteger(&val
)) {
188 if (config
.automatic_proxy
.pac_url
.is_valid())
189 config_service
->UISetProxyConfigToPACScript(
190 config
.automatic_proxy
.pac_url
);
192 config_service
->UISetProxyConfigToAutoDetect();
193 } else if (val
== 2) {
194 if (config
.single_proxy
.server
.is_valid()) {
195 config_service
->UISetProxyConfigToSingleProxy(
196 config
.single_proxy
.server
);
198 bool set_config
= false;
199 if (config
.http_proxy
.server
.is_valid()) {
200 config_service
->UISetProxyConfigToProxyPerScheme("http",
201 config
.http_proxy
.server
);
204 if (config
.https_proxy
.server
.is_valid()) {
205 config_service
->UISetProxyConfigToProxyPerScheme("https",
206 config
.https_proxy
.server
);
209 if (config
.ftp_proxy
.server
.is_valid()) {
210 config_service
->UISetProxyConfigToProxyPerScheme("ftp",
211 config
.ftp_proxy
.server
);
214 if (config
.socks_proxy
.server
.is_valid()) {
215 config_service
->UISetProxyConfigToProxyPerScheme("socks",
216 config
.socks_proxy
.server
);
220 config_service
->UISetProxyConfigToProxyPerScheme("http",
225 config_service
->UISetProxyConfigToDirect();
228 } else if (path
== kProxySingle
) {
230 if (in_value
->GetAsBoolean(&val
)) {
232 config_service
->UISetProxyConfigToSingleProxy(
233 config
.single_proxy
.server
);
235 config_service
->UISetProxyConfigToProxyPerScheme("http",
236 config
.http_proxy
.server
);
238 } else if (path
== kProxyFtpUrl
) {
240 if (in_value
->GetAsString(&val
)) {
241 config_service
->UISetProxyConfigToProxyPerScheme("ftp",
242 CreateProxyServerFromHost(
243 val
, config
.ftp_proxy
, net::ProxyServer::SCHEME_HTTP
));
245 } else if (path
== kProxyFtpPort
) {
247 if (in_value
->GetAsInteger(&val
)) {
248 config_service
->UISetProxyConfigToProxyPerScheme("ftp",
249 CreateProxyServerFromPort(
250 val
, config
.ftp_proxy
, net::ProxyServer::SCHEME_HTTP
));
252 } else if (path
== kProxySocks
) {
254 if (in_value
->GetAsString(&val
)) {
255 config_service
->UISetProxyConfigToProxyPerScheme("socks",
256 CreateProxyServerFromHost(val
, config
.socks_proxy
,
257 StartsWithASCII(val
, "socks5://", false) ?
258 net::ProxyServer::SCHEME_SOCKS5
:
259 net::ProxyServer::SCHEME_SOCKS4
));
261 } else if (path
== kProxySocksPort
) {
263 if (in_value
->GetAsInteger(&val
)) {
264 std::string host
= config
.socks_proxy
.server
.host_port_pair().host();
265 config_service
->UISetProxyConfigToProxyPerScheme("socks",
266 CreateProxyServerFromPort(val
, config
.socks_proxy
,
267 StartsWithASCII(host
, "socks5://", false) ?
268 net::ProxyServer::SCHEME_SOCKS5
:
269 net::ProxyServer::SCHEME_SOCKS4
));
271 } else if (path
== kProxyIgnoreList
) {
272 net::ProxyBypassRules bypass_rules
;
273 if (in_value
->GetType() == base::Value::TYPE_LIST
) {
274 const ListValue
* list_value
= static_cast<const ListValue
*>(in_value
);
275 for (size_t x
= 0; x
< list_value
->GetSize(); x
++) {
277 if (list_value
->GetString(x
, &val
)) {
278 bypass_rules
.AddRuleFromString(val
);
281 config_service
->UISetProxyConfigBypassRules(bypass_rules
);
286 bool GetProxyPrefValue(Profile
* profile
,
287 const std::string
& path
,
288 base::Value
** out_value
) {
289 std::string controlled_by
;
290 base::Value
* data
= NULL
;
291 chromeos::ProxyConfigServiceImpl
* config_service
=
292 profile
->GetProxyConfigTracker();
293 chromeos::ProxyConfigServiceImpl::ProxyConfig config
;
294 config_service
->UIGetProxyConfig(&config
);
296 if (path
== kProxyPacUrl
) {
297 // Only show pacurl for pac-script mode.
299 chromeos::ProxyConfigServiceImpl::ProxyConfig::MODE_PAC_SCRIPT
&&
300 config
.automatic_proxy
.pac_url
.is_valid()) {
302 base::Value::CreateStringValue(config
.automatic_proxy
.pac_url
.spec());
304 } else if (path
== kProxySingleHttp
) {
305 data
= CreateServerHostValue(config
.single_proxy
);
306 } else if (path
== kProxySingleHttpPort
) {
307 data
= CreateServerPortValue(config
.single_proxy
);
308 } else if (path
== kProxyHttpUrl
) {
309 data
= CreateServerHostValue(config
.http_proxy
);
310 } else if (path
== kProxyHttpsUrl
) {
311 data
= CreateServerHostValue(config
.https_proxy
);
312 } else if (path
== kProxyType
) {
314 chromeos::ProxyConfigServiceImpl::ProxyConfig::MODE_AUTO_DETECT
||
316 chromeos::ProxyConfigServiceImpl::ProxyConfig::MODE_PAC_SCRIPT
) {
317 data
= base::Value::CreateIntegerValue(3);
318 } else if (config
.mode
==
319 chromeos::ProxyConfigServiceImpl::ProxyConfig::MODE_SINGLE_PROXY
||
321 chromeos::ProxyConfigServiceImpl::ProxyConfig::MODE_PROXY_PER_SCHEME
) {
322 data
= base::Value::CreateIntegerValue(2);
324 data
= base::Value::CreateIntegerValue(1);
326 switch (config
.state
) {
327 case ProxyPrefs::CONFIG_POLICY
:
328 controlled_by
= "policy";
330 case ProxyPrefs::CONFIG_EXTENSION
:
331 controlled_by
= "extension";
333 case ProxyPrefs::CONFIG_OTHER_PRECEDE
:
334 controlled_by
= "other";
337 if (!config
.user_modifiable
)
338 controlled_by
= "shared";
341 } else if (path
== kProxySingle
) {
342 data
= base::Value::CreateBooleanValue(config
.mode
==
343 chromeos::ProxyConfigServiceImpl::ProxyConfig::MODE_SINGLE_PROXY
);
344 } else if (path
== kProxyFtpUrl
) {
345 data
= CreateServerHostValue(config
.ftp_proxy
);
346 } else if (path
== kProxySocks
) {
347 data
= CreateServerHostValue(config
.socks_proxy
);
348 } else if (path
== kProxyHttpPort
) {
349 data
= CreateServerPortValue(config
.http_proxy
);
350 } else if (path
== kProxyHttpsPort
) {
351 data
= CreateServerPortValue(config
.https_proxy
);
352 } else if (path
== kProxyFtpPort
) {
353 data
= CreateServerPortValue(config
.ftp_proxy
);
354 } else if (path
== kProxySocksPort
) {
355 data
= CreateServerPortValue(config
.socks_proxy
);
356 } else if (path
== kProxyIgnoreList
) {
357 ListValue
* list
= new ListValue();
358 net::ProxyBypassRules::RuleList bypass_rules
= config
.bypass_rules
.rules();
359 for (size_t x
= 0; x
< bypass_rules
.size(); x
++) {
360 list
->Append(base::Value::CreateStringValue(bypass_rules
[x
]->ToString()));
368 // Decorate pref value as CoreOptionsHandler::CreateValueForPref() does.
369 DictionaryValue
* dict
= new DictionaryValue
;
371 data
= base::Value::CreateStringValue("");
372 dict
->Set("value", data
);
373 if (path
== kProxyType
) {
374 dict
->SetString("controlledBy", controlled_by
);
375 dict
->SetBoolean("disabled", !config
.user_modifiable
);
377 dict
->SetBoolean("disabled", false);
383 } // namespace proxy_cros_settings_parser
385 } // namespace chromeos