Home | History | Annotate | Download | only in chromeos
      1 // Copyright (c) 2011 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/proxy_cros_settings_provider.h"
      6 
      7 #include "base/command_line.h"
      8 #include "base/string_util.h"
      9 #include "chrome/browser/browser_process.h"
     10 #include "chrome/browser/ui/browser_list.h"
     11 #include "chrome/common/chrome_switches.h"
     12 
     13 namespace chromeos {
     14 
     15 static const char kProxyPacUrl[]         = "cros.session.proxy.pacurl";
     16 static const char kProxySingleHttp[]     = "cros.session.proxy.singlehttp";
     17 static const char kProxySingleHttpPort[] = "cros.session.proxy.singlehttpport";
     18 static const char kProxyHttpUrl[]        = "cros.session.proxy.httpurl";
     19 static const char kProxyHttpPort[]       = "cros.session.proxy.httpport";
     20 static const char kProxyHttpsUrl[]       = "cros.session.proxy.httpsurl";
     21 static const char kProxyHttpsPort[]      = "cros.session.proxy.httpsport";
     22 static const char kProxyType[]           = "cros.session.proxy.type";
     23 static const char kProxySingle[]         = "cros.session.proxy.single";
     24 static const char kProxyFtpUrl[]         = "cros.session.proxy.ftpurl";
     25 static const char kProxyFtpPort[]        = "cros.session.proxy.ftpport";
     26 static const char kProxySocks[]          = "cros.session.proxy.socks";
     27 static const char kProxySocksPort[]      = "cros.session.proxy.socksport";
     28 static const char kProxyIgnoreList[]     = "cros.session.proxy.ignorelist";
     29 
     30 //------------------ ProxyCrosSettingsProvider: public methods -----------------
     31 
     32 ProxyCrosSettingsProvider::ProxyCrosSettingsProvider() { }
     33 
     34 void ProxyCrosSettingsProvider::DoSet(const std::string& path,
     35                                       Value* in_value) {
     36   if (!in_value) {
     37     return;
     38   }
     39 
     40   chromeos::ProxyConfigServiceImpl* config_service = GetConfigService();
     41   // Don't persist settings to device for guest session.
     42   config_service->UISetPersistToDevice(
     43       !CommandLine::ForCurrentProcess()->HasSwitch(switches::kGuestSession));
     44   // Retrieve proxy config.
     45   chromeos::ProxyConfigServiceImpl::ProxyConfig config;
     46   config_service->UIGetProxyConfig(&config);
     47 
     48   if (path == kProxyPacUrl) {
     49     std::string val;
     50     if (in_value->GetAsString(&val)) {
     51       GURL url(val);
     52       config_service->UISetProxyConfigToPACScript(url);
     53     }
     54   } else if (path == kProxySingleHttp) {
     55     std::string val;
     56     if (in_value->GetAsString(&val)) {
     57       config_service->UISetProxyConfigToSingleProxy(CreateProxyServerFromHost(
     58           val, config.single_proxy, net::ProxyServer::SCHEME_HTTP));
     59     }
     60   } else if (path == kProxySingleHttpPort) {
     61     int val;
     62     if (in_value->GetAsInteger(&val)) {
     63       config_service->UISetProxyConfigToSingleProxy(CreateProxyServerFromPort(
     64           val, config.single_proxy, net::ProxyServer::SCHEME_HTTP));
     65     }
     66   } else if (path == kProxyHttpUrl) {
     67     std::string val;
     68     if (in_value->GetAsString(&val)) {
     69       config_service->UISetProxyConfigToProxyPerScheme("http",
     70           CreateProxyServerFromHost(
     71               val, config.http_proxy, net::ProxyServer::SCHEME_HTTP));
     72     }
     73   } else if (path == kProxyHttpPort) {
     74     int val;
     75     if (in_value->GetAsInteger(&val)) {
     76       config_service->UISetProxyConfigToProxyPerScheme("http",
     77           CreateProxyServerFromPort(
     78               val, config.http_proxy, net::ProxyServer::SCHEME_HTTP));
     79     }
     80   } else if (path == kProxyHttpsUrl) {
     81     std::string val;
     82     if (in_value->GetAsString(&val)) {
     83       config_service->UISetProxyConfigToProxyPerScheme("https",
     84           CreateProxyServerFromHost(
     85               val, config.https_proxy, net::ProxyServer::SCHEME_HTTP));
     86     }
     87   } else if (path == kProxyHttpsPort) {
     88     int val;
     89     if (in_value->GetAsInteger(&val)) {
     90       config_service->UISetProxyConfigToProxyPerScheme("https",
     91           CreateProxyServerFromPort(
     92               val, config.https_proxy, net::ProxyServer::SCHEME_HTTP));
     93     }
     94   } else if (path == kProxyType) {
     95     int val;
     96     if (in_value->GetAsInteger(&val)) {
     97       if (val == 3) {
     98         if (config.automatic_proxy.pac_url.is_valid())
     99           config_service->UISetProxyConfigToPACScript(
    100               config.automatic_proxy.pac_url);
    101         else
    102           config_service->UISetProxyConfigToAutoDetect();
    103       } else if (val == 2) {
    104         if (config.single_proxy.server.is_valid()) {
    105           config_service->UISetProxyConfigToSingleProxy(
    106               config.single_proxy.server);
    107         } else {
    108           bool set_config = false;
    109           if (config.http_proxy.server.is_valid()) {
    110             config_service->UISetProxyConfigToProxyPerScheme("http",
    111                 config.http_proxy.server);
    112             set_config = true;
    113           }
    114           if (config.https_proxy.server.is_valid()) {
    115             config_service->UISetProxyConfigToProxyPerScheme("https",
    116                 config.https_proxy.server);
    117             set_config = true;
    118           }
    119           if (config.ftp_proxy.server.is_valid()) {
    120             config_service->UISetProxyConfigToProxyPerScheme("ftp",
    121                 config.ftp_proxy.server);
    122             set_config = true;
    123           }
    124           if (config.socks_proxy.server.is_valid()) {
    125             config_service->UISetProxyConfigToProxyPerScheme("socks",
    126                 config.socks_proxy.server);
    127             set_config = true;
    128           }
    129           if (!set_config) {
    130             config_service->UISetProxyConfigToProxyPerScheme("http",
    131                 net::ProxyServer());
    132           }
    133         }
    134       } else {
    135         config_service->UISetProxyConfigToDirect();
    136       }
    137     }
    138   } else if (path == kProxySingle) {
    139     bool val;
    140     if (in_value->GetAsBoolean(&val)) {
    141       if (val)
    142         config_service->UISetProxyConfigToSingleProxy(
    143             config.single_proxy.server);
    144       else
    145         config_service->UISetProxyConfigToProxyPerScheme("http",
    146             config.http_proxy.server);
    147     }
    148   } else if (path == kProxyFtpUrl) {
    149     std::string val;
    150     if (in_value->GetAsString(&val)) {
    151       config_service->UISetProxyConfigToProxyPerScheme("ftp",
    152           CreateProxyServerFromHost(
    153               val, config.ftp_proxy, net::ProxyServer::SCHEME_HTTP));
    154     }
    155   } else if (path == kProxyFtpPort) {
    156     int val;
    157     if (in_value->GetAsInteger(&val)) {
    158       config_service->UISetProxyConfigToProxyPerScheme("ftp",
    159           CreateProxyServerFromPort(
    160               val, config.ftp_proxy, net::ProxyServer::SCHEME_HTTP));
    161     }
    162   } else if (path == kProxySocks) {
    163     std::string val;
    164     if (in_value->GetAsString(&val)) {
    165       config_service->UISetProxyConfigToProxyPerScheme("socks",
    166           CreateProxyServerFromHost(val, config.socks_proxy,
    167                                     StartsWithASCII(val, "socks5://", false) ?
    168                                         net::ProxyServer::SCHEME_SOCKS5 :
    169                                         net::ProxyServer::SCHEME_SOCKS4));
    170     }
    171   } else if (path == kProxySocksPort) {
    172     int val;
    173     if (in_value->GetAsInteger(&val)) {
    174       std::string host = config.socks_proxy.server.host_port_pair().host();
    175       config_service->UISetProxyConfigToProxyPerScheme("socks",
    176           CreateProxyServerFromPort(val, config.socks_proxy,
    177                                     StartsWithASCII(host, "socks5://", false) ?
    178                                         net::ProxyServer::SCHEME_SOCKS5 :
    179                                         net::ProxyServer::SCHEME_SOCKS4));
    180     }
    181   } else if (path == kProxyIgnoreList) {
    182     net::ProxyBypassRules bypass_rules;
    183     if (in_value->GetType() == Value::TYPE_LIST) {
    184       const ListValue* list_value = static_cast<const ListValue*>(in_value);
    185       for (size_t x = 0; x < list_value->GetSize(); x++) {
    186         std::string val;
    187         if (list_value->GetString(x, &val)) {
    188           bypass_rules.AddRuleFromString(val);
    189         }
    190       }
    191       config_service->UISetProxyConfigBypassRules(bypass_rules);
    192     }
    193   }
    194 }
    195 
    196 bool ProxyCrosSettingsProvider::Get(const std::string& path,
    197                                     Value** out_value) const {
    198   bool found = false;
    199   bool managed = false;
    200   Value* data;
    201   chromeos::ProxyConfigServiceImpl* config_service = GetConfigService();
    202   chromeos::ProxyConfigServiceImpl::ProxyConfig config;
    203   config_service->UIGetProxyConfig(&config);
    204 
    205   if (path == kProxyPacUrl) {
    206     if (config.automatic_proxy.pac_url.is_valid()) {
    207       data = Value::CreateStringValue(config.automatic_proxy.pac_url.spec());
    208       found = true;
    209     }
    210   } else if (path == kProxySingleHttp) {
    211     found = (data = CreateServerHostValue(config.single_proxy));
    212   } else if (path == kProxySingleHttpPort) {
    213     found = (data = CreateServerPortValue(config.single_proxy));
    214   } else if (path == kProxyHttpUrl) {
    215     found = (data = CreateServerHostValue(config.http_proxy));
    216   } else if (path == kProxyHttpsUrl) {
    217     found = (data = CreateServerHostValue(config.https_proxy));
    218   } else if (path == kProxyType) {
    219     if (config.mode ==
    220         chromeos::ProxyConfigServiceImpl::ProxyConfig::MODE_AUTO_DETECT ||
    221         config.mode ==
    222         chromeos::ProxyConfigServiceImpl::ProxyConfig::MODE_PAC_SCRIPT) {
    223       data = Value::CreateIntegerValue(3);
    224     } else if (config.mode ==
    225         chromeos::ProxyConfigServiceImpl::ProxyConfig::MODE_SINGLE_PROXY ||
    226         config.mode ==
    227         chromeos::ProxyConfigServiceImpl::ProxyConfig::MODE_PROXY_PER_SCHEME) {
    228       data = Value::CreateIntegerValue(2);
    229     } else {
    230       data = Value::CreateIntegerValue(1);
    231     }
    232     found = true;
    233   } else if (path == kProxySingle) {
    234     data = Value::CreateBooleanValue(config.mode ==
    235         chromeos::ProxyConfigServiceImpl::ProxyConfig::MODE_SINGLE_PROXY);
    236     found = true;
    237   } else if (path == kProxyFtpUrl) {
    238     found = (data = CreateServerHostValue(config.ftp_proxy));
    239   } else if (path == kProxySocks) {
    240     found = (data = CreateServerHostValue(config.socks_proxy));
    241   } else if (path == kProxyHttpPort) {
    242     found = (data = CreateServerPortValue(config.http_proxy));
    243   } else if (path == kProxyHttpsPort) {
    244     found = (data = CreateServerPortValue(config.https_proxy));
    245   } else if (path == kProxyFtpPort) {
    246     found = (data = CreateServerPortValue(config.ftp_proxy));
    247   } else if (path == kProxySocksPort) {
    248     found = (data = CreateServerPortValue(config.socks_proxy));
    249   } else if (path == kProxyIgnoreList) {
    250     ListValue* list =  new ListValue();
    251     net::ProxyBypassRules::RuleList bypass_rules = config.bypass_rules.rules();
    252     for (size_t x = 0; x < bypass_rules.size(); x++) {
    253       list->Append(Value::CreateStringValue(bypass_rules[x]->ToString()));
    254     }
    255     *out_value = list;
    256     return true;
    257   }
    258   if (found) {
    259     DictionaryValue* dict = new DictionaryValue;
    260     dict->Set("value", data);
    261     dict->SetBoolean("managed", managed);
    262     *out_value = dict;
    263     return true;
    264   } else {
    265     *out_value = NULL;
    266     return false;
    267   }
    268 }
    269 
    270 bool ProxyCrosSettingsProvider::HandlesSetting(const std::string& path) {
    271   return ::StartsWithASCII(path, "cros.session.proxy", true);
    272 }
    273 
    274 //----------------- ProxyCrosSettingsProvider: private methods -----------------
    275 
    276 chromeos::ProxyConfigServiceImpl*
    277     ProxyCrosSettingsProvider::GetConfigService() const {
    278   return g_browser_process->chromeos_proxy_config_service_impl();
    279 }
    280 
    281 net::ProxyServer ProxyCrosSettingsProvider::CreateProxyServerFromHost(
    282     const std::string& host,
    283     const ProxyConfigServiceImpl::ProxyConfig::ManualProxy& proxy,
    284     net::ProxyServer::Scheme scheme) const {
    285   uint16 port = 0;
    286   if (proxy.server.is_valid())
    287     port = proxy.server.host_port_pair().port();
    288   if (host.length() == 0 && port == 0)
    289     return net::ProxyServer();
    290   if (port == 0)
    291     port = net::ProxyServer::GetDefaultPortForScheme(scheme);
    292   net::HostPortPair host_port_pair(host, port);
    293   return net::ProxyServer(scheme, host_port_pair);
    294 }
    295 
    296 net::ProxyServer ProxyCrosSettingsProvider::CreateProxyServerFromPort(
    297     uint16 port,
    298     const ProxyConfigServiceImpl::ProxyConfig::ManualProxy& proxy,
    299     net::ProxyServer::Scheme scheme) const {
    300   std::string host;
    301   if (proxy.server.is_valid())
    302     host = proxy.server.host_port_pair().host();
    303   if (host.length() == 0 && port == 0)
    304     return net::ProxyServer();
    305   net::HostPortPair host_port_pair(host, port);
    306   return net::ProxyServer(scheme, host_port_pair);
    307 }
    308 
    309 Value* ProxyCrosSettingsProvider::CreateServerHostValue(
    310     const ProxyConfigServiceImpl::ProxyConfig::ManualProxy& proxy) const {
    311   return proxy.server.is_valid() ?
    312          Value::CreateStringValue(proxy.server.host_port_pair().host()) :
    313          NULL;
    314 }
    315 
    316 Value* ProxyCrosSettingsProvider::CreateServerPortValue(
    317     const ProxyConfigServiceImpl::ProxyConfig::ManualProxy& proxy) const {
    318   return proxy.server.is_valid() ?
    319          Value::CreateIntegerValue(proxy.server.host_port_pair().port()) :
    320          NULL;
    321 }
    322 
    323 }  // namespace chromeos
    324