// Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "chrome/browser/chromeos/ui_proxy_config.h" #include "base/logging.h" #include "base/values.h" #include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h" #include "chrome/browser/prefs/proxy_config_dictionary.h" #include "net/proxy/proxy_config.h" namespace chromeos { UIProxyConfig::UIProxyConfig() : mode(MODE_DIRECT), state(ProxyPrefs::CONFIG_UNSET), user_modifiable(true) { } UIProxyConfig::~UIProxyConfig() { } void UIProxyConfig::SetPacUrl(const GURL& pac_url) { mode = UIProxyConfig::MODE_PAC_SCRIPT; automatic_proxy.pac_url = pac_url; } void UIProxyConfig::SetSingleProxy(const net::ProxyServer& server) { mode = UIProxyConfig::MODE_SINGLE_PROXY; single_proxy.server = server; } void UIProxyConfig::SetProxyForScheme(const std::string& scheme, const net::ProxyServer& server) { ManualProxy* proxy = MapSchemeToProxy(scheme); if (!proxy) { NOTREACHED() << "Cannot set proxy: invalid scheme [" << scheme << "]"; return; } mode = UIProxyConfig::MODE_PROXY_PER_SCHEME; proxy->server = server; } void UIProxyConfig::SetBypassRules(const net::ProxyBypassRules& rules) { if (mode != UIProxyConfig::MODE_SINGLE_PROXY && mode != UIProxyConfig::MODE_PROXY_PER_SCHEME) { NOTREACHED() << "Cannot set bypass rules for proxy mode [" << mode << "]"; return; } bypass_rules = rules; } bool UIProxyConfig::FromNetProxyConfig(const net::ProxyConfig& net_config) { *this = UIProxyConfig(); // Reset to default. const net::ProxyConfig::ProxyRules& rules = net_config.proxy_rules(); switch (rules.type) { case net::ProxyConfig::ProxyRules::TYPE_NO_RULES: if (!net_config.HasAutomaticSettings()) { mode = UIProxyConfig::MODE_DIRECT; } else if (net_config.auto_detect()) { mode = UIProxyConfig::MODE_AUTO_DETECT; } else if (net_config.has_pac_url()) { mode = UIProxyConfig::MODE_PAC_SCRIPT; automatic_proxy.pac_url = net_config.pac_url(); } else { return false; } return true; case net::ProxyConfig::ProxyRules::TYPE_SINGLE_PROXY: if (rules.single_proxies.IsEmpty()) return false; mode = MODE_SINGLE_PROXY; single_proxy.server = rules.single_proxies.Get(); bypass_rules = rules.bypass_rules; return true; case net::ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME: // Make sure we have valid server for at least one of the protocols. if (rules.proxies_for_http.IsEmpty() && rules.proxies_for_https.IsEmpty() && rules.proxies_for_ftp.IsEmpty() && rules.fallback_proxies.IsEmpty()) { return false; } mode = MODE_PROXY_PER_SCHEME; if (!rules.proxies_for_http.IsEmpty()) http_proxy.server = rules.proxies_for_http.Get(); if (!rules.proxies_for_https.IsEmpty()) https_proxy.server = rules.proxies_for_https.Get(); if (!rules.proxies_for_ftp.IsEmpty()) ftp_proxy.server = rules.proxies_for_ftp.Get(); if (!rules.fallback_proxies.IsEmpty()) socks_proxy.server = rules.fallback_proxies.Get(); bypass_rules = rules.bypass_rules; return true; default: NOTREACHED() << "Unrecognized proxy config mode"; break; } return false; } base::DictionaryValue* UIProxyConfig::ToPrefProxyConfig() const { switch (mode) { case MODE_DIRECT: { return ProxyConfigDictionary::CreateDirect(); } case MODE_AUTO_DETECT: { return ProxyConfigDictionary::CreateAutoDetect(); } case MODE_PAC_SCRIPT: { return ProxyConfigDictionary::CreatePacScript( automatic_proxy.pac_url.spec(), false); } case MODE_SINGLE_PROXY: { std::string spec; if (single_proxy.server.is_valid()) spec = single_proxy.server.ToURI(); return ProxyConfigDictionary::CreateFixedServers( spec, bypass_rules.ToString()); } case MODE_PROXY_PER_SCHEME: { std::string spec; EncodeAndAppendProxyServer("http", http_proxy.server, &spec); EncodeAndAppendProxyServer("https", https_proxy.server, &spec); EncodeAndAppendProxyServer("ftp", ftp_proxy.server, &spec); EncodeAndAppendProxyServer("socks", socks_proxy.server, &spec); return ProxyConfigDictionary::CreateFixedServers( spec, bypass_rules.ToString()); } default: break; } NOTREACHED() << "Unrecognized proxy config mode for preference"; return NULL; } UIProxyConfig::ManualProxy* UIProxyConfig::MapSchemeToProxy( const std::string& scheme) { if (scheme == "http") return &http_proxy; if (scheme == "https") return &https_proxy; if (scheme == "ftp") return &ftp_proxy; if (scheme == "socks") return &socks_proxy; NOTREACHED() << "Invalid scheme: " << scheme; return NULL; } // static void UIProxyConfig::EncodeAndAppendProxyServer(const std::string& url_scheme, const net::ProxyServer& server, std::string* spec) { if (!server.is_valid()) return; if (!spec->empty()) *spec += ';'; if (!url_scheme.empty()) { *spec += url_scheme; *spec += "="; } *spec += server.ToURI(); } } // namespace chromeos