onc_utils.cc revision c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d
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/net/onc_utils.h"
6
7#include "base/values.h"
8#include "chrome/browser/chromeos/proxy_config_service_impl.h"
9#include "chrome/browser/prefs/proxy_config_dictionary.h"
10#include "chromeos/network/onc/onc_utils.h"
11#include "googleurl/src/gurl.h"
12#include "net/proxy/proxy_server.h"
13
14namespace chromeos {
15namespace onc {
16
17namespace {
18
19net::ProxyServer ConvertOncProxyLocationToHostPort(
20    net::ProxyServer::Scheme default_proxy_scheme,
21    const base::DictionaryValue& onc_proxy_location) {
22  std::string host;
23  onc_proxy_location.GetStringWithoutPathExpansion(onc::proxy::kHost, &host);
24  // Parse |host| according to the format [<scheme>"://"]<server>[":"<port>].
25  net::ProxyServer proxy_server =
26      net::ProxyServer::FromURI(host, default_proxy_scheme);
27  int port = 0;
28  onc_proxy_location.GetIntegerWithoutPathExpansion(onc::proxy::kPort, &port);
29
30  // Replace the port parsed from |host| by the provided |port|.
31  return net::ProxyServer(
32      proxy_server.scheme(),
33      net::HostPortPair(proxy_server.host_port_pair().host(),
34                        static_cast<uint16>(port)));
35}
36
37void AppendProxyServerForScheme(
38    const base::DictionaryValue& onc_manual,
39    const std::string& onc_scheme,
40    std::string* spec) {
41  const base::DictionaryValue* onc_proxy_location = NULL;
42  if (!onc_manual.GetDictionaryWithoutPathExpansion(onc_scheme,
43                                                    &onc_proxy_location)) {
44    return;
45  }
46
47  net::ProxyServer::Scheme default_proxy_scheme = net::ProxyServer::SCHEME_HTTP;
48  std::string url_scheme;
49  if (onc_scheme == proxy::kFtp) {
50    url_scheme = "ftp";
51  } else if (onc_scheme == proxy::kHttp) {
52    url_scheme = "http";
53  } else if (onc_scheme == proxy::kHttps) {
54    url_scheme = "https";
55  } else if (onc_scheme == proxy::kSocks) {
56    default_proxy_scheme = net::ProxyServer::SCHEME_SOCKS4;
57    url_scheme = "socks";
58  } else {
59    NOTREACHED();
60  }
61
62  net::ProxyServer proxy_server = ConvertOncProxyLocationToHostPort(
63      default_proxy_scheme, *onc_proxy_location);
64
65  ProxyConfigServiceImpl::ProxyConfig::EncodeAndAppendProxyServer(
66      url_scheme, proxy_server, spec);
67}
68
69net::ProxyBypassRules ConvertOncExcludeDomainsToBypassRules(
70    const base::ListValue& onc_exclude_domains) {
71  net::ProxyBypassRules rules;
72  for (base::ListValue::const_iterator it = onc_exclude_domains.begin();
73       it != onc_exclude_domains.end(); ++it) {
74    std::string rule;
75    (*it)->GetAsString(&rule);
76    rules.AddRuleFromString(rule);
77  }
78  return rules;
79}
80
81}  // namespace
82
83scoped_ptr<base::DictionaryValue> ConvertOncProxySettingsToProxyConfig(
84    const base::DictionaryValue& onc_proxy_settings) {
85  std::string type;
86  onc_proxy_settings.GetStringWithoutPathExpansion(proxy::kType, &type);
87  scoped_ptr<DictionaryValue> proxy_dict;
88
89  if (type == proxy::kDirect) {
90    proxy_dict.reset(ProxyConfigDictionary::CreateDirect());
91  } else if (type == proxy::kWPAD) {
92    proxy_dict.reset(ProxyConfigDictionary::CreateAutoDetect());
93  } else if (type == proxy::kPAC) {
94    std::string pac_url;
95    onc_proxy_settings.GetStringWithoutPathExpansion(proxy::kPAC, &pac_url);
96    GURL url(pac_url);
97    DCHECK(url.is_valid())
98        << "PAC field is invalid for this ProxySettings.Type";
99    proxy_dict.reset(ProxyConfigDictionary::CreatePacScript(url.spec(),
100                                                            false));
101  } else if (type == proxy::kManual) {
102    const base::DictionaryValue* manual_dict = NULL;
103    onc_proxy_settings.GetDictionaryWithoutPathExpansion(proxy::kManual,
104                                                         &manual_dict);
105    std::string manual_spec;
106    AppendProxyServerForScheme(*manual_dict, proxy::kFtp, &manual_spec);
107    AppendProxyServerForScheme(*manual_dict, proxy::kHttp, &manual_spec);
108    AppendProxyServerForScheme(*manual_dict, proxy::kSocks, &manual_spec);
109    AppendProxyServerForScheme(*manual_dict, proxy::kHttps, &manual_spec);
110
111    const base::ListValue* exclude_domains = NULL;
112    net::ProxyBypassRules bypass_rules;
113    if (onc_proxy_settings.GetListWithoutPathExpansion(proxy::kExcludeDomains,
114                                                       &exclude_domains)) {
115      bypass_rules.AssignFrom(
116          ConvertOncExcludeDomainsToBypassRules(*exclude_domains));
117    }
118    proxy_dict.reset(ProxyConfigDictionary::CreateFixedServers(
119        manual_spec, bypass_rules.ToString()));
120  } else {
121    NOTREACHED();
122  }
123  return proxy_dict.Pass();
124}
125
126}  // namespace onc
127}  // namespace chromeos
128