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