Home | History | Annotate | Download | only in chromeos
      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/chromeos/policy/proto/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