1 // Copyright 2013 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/ui_proxy_config.h" 6 7 #include "base/logging.h" 8 #include "base/values.h" 9 #include "chrome/browser/policy/proto/chromeos/chrome_device_policy.pb.h" 10 #include "chrome/browser/prefs/proxy_config_dictionary.h" 11 #include "net/proxy/proxy_config.h" 12 13 namespace chromeos { 14 15 UIProxyConfig::UIProxyConfig() 16 : mode(MODE_DIRECT), 17 state(ProxyPrefs::CONFIG_UNSET), 18 user_modifiable(true) { 19 } 20 21 UIProxyConfig::~UIProxyConfig() { 22 } 23 24 void UIProxyConfig::SetPacUrl(const GURL& pac_url) { 25 mode = UIProxyConfig::MODE_PAC_SCRIPT; 26 automatic_proxy.pac_url = pac_url; 27 } 28 29 void UIProxyConfig::SetSingleProxy(const net::ProxyServer& server) { 30 mode = UIProxyConfig::MODE_SINGLE_PROXY; 31 single_proxy.server = server; 32 } 33 34 void UIProxyConfig::SetProxyForScheme(const std::string& scheme, 35 const net::ProxyServer& server) { 36 ManualProxy* proxy = MapSchemeToProxy(scheme); 37 if (!proxy) { 38 NOTREACHED() << "Cannot set proxy: invalid scheme [" << scheme << "]"; 39 return; 40 } 41 mode = UIProxyConfig::MODE_PROXY_PER_SCHEME; 42 proxy->server = server; 43 } 44 45 void UIProxyConfig::SetBypassRules(const net::ProxyBypassRules& rules) { 46 if (mode != UIProxyConfig::MODE_SINGLE_PROXY && 47 mode != UIProxyConfig::MODE_PROXY_PER_SCHEME) { 48 NOTREACHED() << "Cannot set bypass rules for proxy mode [" << mode << "]"; 49 return; 50 } 51 bypass_rules = rules; 52 } 53 54 bool UIProxyConfig::FromNetProxyConfig(const net::ProxyConfig& net_config) { 55 *this = UIProxyConfig(); // Reset to default. 56 const net::ProxyConfig::ProxyRules& rules = net_config.proxy_rules(); 57 switch (rules.type) { 58 case net::ProxyConfig::ProxyRules::TYPE_NO_RULES: 59 if (!net_config.HasAutomaticSettings()) { 60 mode = UIProxyConfig::MODE_DIRECT; 61 } else if (net_config.auto_detect()) { 62 mode = UIProxyConfig::MODE_AUTO_DETECT; 63 } else if (net_config.has_pac_url()) { 64 mode = UIProxyConfig::MODE_PAC_SCRIPT; 65 automatic_proxy.pac_url = net_config.pac_url(); 66 } else { 67 return false; 68 } 69 return true; 70 case net::ProxyConfig::ProxyRules::TYPE_SINGLE_PROXY: 71 if (rules.single_proxies.IsEmpty()) 72 return false; 73 mode = MODE_SINGLE_PROXY; 74 single_proxy.server = rules.single_proxies.Get(); 75 bypass_rules = rules.bypass_rules; 76 return true; 77 case net::ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME: 78 // Make sure we have valid server for at least one of the protocols. 79 if (rules.proxies_for_http.IsEmpty() && 80 rules.proxies_for_https.IsEmpty() && 81 rules.proxies_for_ftp.IsEmpty() && 82 rules.fallback_proxies.IsEmpty()) { 83 return false; 84 } 85 mode = MODE_PROXY_PER_SCHEME; 86 if (!rules.proxies_for_http.IsEmpty()) 87 http_proxy.server = rules.proxies_for_http.Get(); 88 if (!rules.proxies_for_https.IsEmpty()) 89 https_proxy.server = rules.proxies_for_https.Get(); 90 if (!rules.proxies_for_ftp.IsEmpty()) 91 ftp_proxy.server = rules.proxies_for_ftp.Get(); 92 if (!rules.fallback_proxies.IsEmpty()) 93 socks_proxy.server = rules.fallback_proxies.Get(); 94 bypass_rules = rules.bypass_rules; 95 return true; 96 default: 97 NOTREACHED() << "Unrecognized proxy config mode"; 98 break; 99 } 100 return false; 101 } 102 103 base::DictionaryValue* UIProxyConfig::ToPrefProxyConfig() const { 104 switch (mode) { 105 case MODE_DIRECT: { 106 return ProxyConfigDictionary::CreateDirect(); 107 } 108 case MODE_AUTO_DETECT: { 109 return ProxyConfigDictionary::CreateAutoDetect(); 110 } 111 case MODE_PAC_SCRIPT: { 112 return ProxyConfigDictionary::CreatePacScript( 113 automatic_proxy.pac_url.spec(), false); 114 } 115 case MODE_SINGLE_PROXY: { 116 std::string spec; 117 if (single_proxy.server.is_valid()) 118 spec = single_proxy.server.ToURI(); 119 return ProxyConfigDictionary::CreateFixedServers( 120 spec, bypass_rules.ToString()); 121 } 122 case MODE_PROXY_PER_SCHEME: { 123 std::string spec; 124 EncodeAndAppendProxyServer("http", http_proxy.server, &spec); 125 EncodeAndAppendProxyServer("https", https_proxy.server, &spec); 126 EncodeAndAppendProxyServer("ftp", ftp_proxy.server, &spec); 127 EncodeAndAppendProxyServer("socks", socks_proxy.server, &spec); 128 return ProxyConfigDictionary::CreateFixedServers( 129 spec, bypass_rules.ToString()); 130 } 131 default: 132 break; 133 } 134 NOTREACHED() << "Unrecognized proxy config mode for preference"; 135 return NULL; 136 } 137 138 UIProxyConfig::ManualProxy* UIProxyConfig::MapSchemeToProxy( 139 const std::string& scheme) { 140 if (scheme == "http") 141 return &http_proxy; 142 if (scheme == "https") 143 return &https_proxy; 144 if (scheme == "ftp") 145 return &ftp_proxy; 146 if (scheme == "socks") 147 return &socks_proxy; 148 NOTREACHED() << "Invalid scheme: " << scheme; 149 return NULL; 150 } 151 152 // static 153 void UIProxyConfig::EncodeAndAppendProxyServer(const std::string& url_scheme, 154 const net::ProxyServer& server, 155 std::string* spec) { 156 if (!server.is_valid()) 157 return; 158 159 if (!spec->empty()) 160 *spec += ';'; 161 162 if (!url_scheme.empty()) { 163 *spec += url_scheme; 164 *spec += "="; 165 } 166 *spec += server.ToURI(); 167 } 168 169 } // namespace chromeos 170