root/chrome/browser/chromeos/proxy_cros_settings_parser.cc

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. CreateServerHostValue
  2. CreateServerPortValue
  3. CreateProxyServer
  4. CreateProxyServerFromHost
  5. CreateProxyServerFromPort
  6. IsProxyPref
  7. SetProxyPrefValue
  8. GetProxyPrefValue

// Copyright (c) 2012 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/proxy_cros_settings_parser.h"

#include "base/strings/string_util.h"
#include "base/values.h"
#include "chrome/browser/chromeos/ui_proxy_config.h"
#include "chrome/browser/chromeos/ui_proxy_config_service.h"

namespace chromeos {

// Common prefix of all proxy prefs.
const char kProxyPrefsPrefix[] = "cros.session.proxy";

// Names of proxy preferences.
const char kProxyPacUrl[]         = "cros.session.proxy.pacurl";
const char kProxySingleHttp[]     = "cros.session.proxy.singlehttp";
const char kProxySingleHttpPort[] = "cros.session.proxy.singlehttpport";
const char kProxyHttpUrl[]        = "cros.session.proxy.httpurl";
const char kProxyHttpPort[]       = "cros.session.proxy.httpport";
const char kProxyHttpsUrl[]       = "cros.session.proxy.httpsurl";
const char kProxyHttpsPort[]      = "cros.session.proxy.httpsport";
const char kProxyType[]           = "cros.session.proxy.type";
const char kProxySingle[]         = "cros.session.proxy.single";
const char kProxyFtpUrl[]         = "cros.session.proxy.ftpurl";
const char kProxyFtpPort[]        = "cros.session.proxy.ftpport";
const char kProxySocks[]          = "cros.session.proxy.socks";
const char kProxySocksPort[]      = "cros.session.proxy.socksport";
const char kProxyIgnoreList[]     = "cros.session.proxy.ignorelist";
const char kProxyUsePacUrl[]      = "cros.session.proxy.usepacurl";

const char* const kProxySettings[] = {
  kProxyPacUrl,
  kProxySingleHttp,
  kProxySingleHttpPort,
  kProxyHttpUrl,
  kProxyHttpPort,
  kProxyHttpsUrl,
  kProxyHttpsPort,
  kProxyType,
  kProxySingle,
  kProxyFtpUrl,
  kProxyFtpPort,
  kProxySocks,
  kProxySocksPort,
  kProxyIgnoreList,
  kProxyUsePacUrl,
};

// We have to explicitly export this because the arraysize macro doesn't like
// extern arrays as their size is not known on compile time.
const size_t kProxySettingsCount = arraysize(kProxySettings);

namespace {

base::Value* CreateServerHostValue(const UIProxyConfig::ManualProxy& proxy) {
  return proxy.server.is_valid() ?
         new base::StringValue(proxy.server.host_port_pair().host()) :
         NULL;
}

base::Value* CreateServerPortValue(const UIProxyConfig::ManualProxy& proxy) {
  return proxy.server.is_valid() ?
         base::Value::CreateIntegerValue(proxy.server.host_port_pair().port()) :
         NULL;
}

net::ProxyServer CreateProxyServer(std::string host,
                                   uint16 port,
                                   net::ProxyServer::Scheme scheme) {
  if (host.empty() && port == 0)
    return net::ProxyServer();
  uint16 default_port = net::ProxyServer::GetDefaultPortForScheme(scheme);
  net::HostPortPair host_port_pair;
  // Check if host is a valid URL or a string of valid format <server>::<port>.
  GURL url(host);
  if (url.is_valid())  // See if host is URL.
    host_port_pair = net::HostPortPair::FromURL(url);
  if (host_port_pair.host().empty())  // See if host is <server>::<port>.
    host_port_pair = net::HostPortPair::FromString(host);
  if (host_port_pair.host().empty())  // Host is not URL or <server>::<port>.
    host_port_pair = net::HostPortPair(host, port);
  if (host_port_pair.port() == 0)  // No port in host, use default.
    host_port_pair.set_port(default_port);
  return net::ProxyServer(scheme, host_port_pair);
}

net::ProxyServer CreateProxyServerFromHost(
    const std::string& host,
    const UIProxyConfig::ManualProxy& proxy,
    net::ProxyServer::Scheme scheme) {
  uint16 port = 0;
  if (proxy.server.is_valid())
    port = proxy.server.host_port_pair().port();
  return CreateProxyServer(host, port, scheme);
}

net::ProxyServer CreateProxyServerFromPort(
    uint16 port,
    const UIProxyConfig::ManualProxy& proxy,
    net::ProxyServer::Scheme scheme) {
  std::string host;
  if (proxy.server.is_valid())
    host = proxy.server.host_port_pair().host();
  return CreateProxyServer(host, port, scheme);
}

}  // namespace

namespace proxy_cros_settings_parser {

bool IsProxyPref(const std::string& path) {
  return StartsWithASCII(path, kProxyPrefsPrefix, true);
}

void SetProxyPrefValue(const std::string& path,
                       const base::Value* in_value,
                       UIProxyConfigService* config_service) {
  if (!in_value) {
    NOTREACHED();
    return;
  }

  // Retrieve proxy config.
  UIProxyConfig config;
  config_service->GetProxyConfig(&config);

  if (path == kProxyPacUrl) {
    std::string val;
    if (in_value->GetAsString(&val)) {
      GURL url(val);
      if (url.is_valid())
        config.SetPacUrl(url);
      else
        config.mode = UIProxyConfig::MODE_AUTO_DETECT;
    }
  } else if (path == kProxySingleHttp) {
    std::string val;
    if (in_value->GetAsString(&val)) {
      config.SetSingleProxy(CreateProxyServerFromHost(
          val, config.single_proxy, net::ProxyServer::SCHEME_HTTP));
    }
  } else if (path == kProxySingleHttpPort) {
    int val;
    if (in_value->GetAsInteger(&val)) {
      config.SetSingleProxy(CreateProxyServerFromPort(
          val, config.single_proxy, net::ProxyServer::SCHEME_HTTP));
    }
  } else if (path == kProxyHttpUrl) {
    std::string val;
    if (in_value->GetAsString(&val)) {
      config.SetProxyForScheme(
          "http", CreateProxyServerFromHost(
              val, config.http_proxy, net::ProxyServer::SCHEME_HTTP));
    }
  } else if (path == kProxyHttpPort) {
    int val;
    if (in_value->GetAsInteger(&val)) {
      config.SetProxyForScheme(
          "http", CreateProxyServerFromPort(
              val, config.http_proxy, net::ProxyServer::SCHEME_HTTP));
    }
  } else if (path == kProxyHttpsUrl) {
    std::string val;
    if (in_value->GetAsString(&val)) {
      config.SetProxyForScheme(
          "https", CreateProxyServerFromHost(
              val, config.https_proxy, net::ProxyServer::SCHEME_HTTP));
    }
  } else if (path == kProxyHttpsPort) {
    int val;
    if (in_value->GetAsInteger(&val)) {
      config.SetProxyForScheme(
          "https", CreateProxyServerFromPort(
              val, config.https_proxy, net::ProxyServer::SCHEME_HTTP));
    }
  } else if (path == kProxyType) {
    int val;
    if (in_value->GetAsInteger(&val)) {
      if (val == 3) {
        if (config.automatic_proxy.pac_url.is_valid())
          config.SetPacUrl(config.automatic_proxy.pac_url);
        else
          config.mode = UIProxyConfig::MODE_AUTO_DETECT;
      } else if (val == 2) {
        if (config.single_proxy.server.is_valid()) {
          config.SetSingleProxy(config.single_proxy.server);
        } else {
          bool set_config = false;
          if (config.http_proxy.server.is_valid()) {
            config.SetProxyForScheme("http", config.http_proxy.server);
            set_config = true;
          }
          if (config.https_proxy.server.is_valid()) {
            config.SetProxyForScheme("https", config.https_proxy.server);
            set_config = true;
          }
          if (config.ftp_proxy.server.is_valid()) {
            config.SetProxyForScheme("ftp", config.ftp_proxy.server);
            set_config = true;
          }
          if (config.socks_proxy.server.is_valid()) {
            config.SetProxyForScheme("socks", config.socks_proxy.server);
            set_config = true;
          }
          if (!set_config)
            config.SetProxyForScheme("http", net::ProxyServer());
        }
      } else {
        config.mode = UIProxyConfig::MODE_DIRECT;
      }
    }
  } else if (path == kProxySingle) {
    bool val;
    if (in_value->GetAsBoolean(&val)) {
      if (val)
        config.SetSingleProxy(config.single_proxy.server);
      else
        config.SetProxyForScheme("http", config.http_proxy.server);
    }
  } else if (path == kProxyUsePacUrl) {
    bool use_pac_url;
    if (in_value->GetAsBoolean(&use_pac_url)) {
      if (use_pac_url && config.automatic_proxy.pac_url.is_valid())
        config.SetPacUrl(config.automatic_proxy.pac_url);
      else
        config.mode = UIProxyConfig::MODE_AUTO_DETECT;
    }
  } else if (path == kProxyFtpUrl) {
    std::string val;
    if (in_value->GetAsString(&val)) {
      config.SetProxyForScheme(
          "ftp", CreateProxyServerFromHost(
              val, config.ftp_proxy, net::ProxyServer::SCHEME_HTTP));
    }
  } else if (path == kProxyFtpPort) {
    int val;
    if (in_value->GetAsInteger(&val)) {
      config.SetProxyForScheme(
          "ftp", CreateProxyServerFromPort(
              val, config.ftp_proxy, net::ProxyServer::SCHEME_HTTP));
    }
  } else if (path == kProxySocks) {
    std::string val;
    if (in_value->GetAsString(&val)) {
      config.SetProxyForScheme(
          "socks", CreateProxyServerFromHost(
              val,
              config.socks_proxy,
              StartsWithASCII(val, "socks5://", false) ?
              net::ProxyServer::SCHEME_SOCKS5 :
              net::ProxyServer::SCHEME_SOCKS4));
    }
  } else if (path == kProxySocksPort) {
    int val;
    if (in_value->GetAsInteger(&val)) {
      std::string host = config.socks_proxy.server.host_port_pair().host();
      config.SetProxyForScheme(
          "socks", CreateProxyServerFromPort(
              val,
              config.socks_proxy,
              StartsWithASCII(host, "socks5://", false) ?
              net::ProxyServer::SCHEME_SOCKS5 :
              net::ProxyServer::SCHEME_SOCKS4));
    }
  } else if (path == kProxyIgnoreList) {
    net::ProxyBypassRules bypass_rules;
    if (in_value->GetType() == base::Value::TYPE_LIST) {
      const base::ListValue* list_value =
          static_cast<const base::ListValue*>(in_value);
      for (size_t x = 0; x < list_value->GetSize(); x++) {
        std::string val;
        if (list_value->GetString(x, &val))
          bypass_rules.AddRuleFromString(val);
      }
      config.SetBypassRules(bypass_rules);
    }
  } else {
    LOG(WARNING) << "Unknown proxy settings path " << path;
    return;
  }

  config_service->SetProxyConfig(config);
}

bool GetProxyPrefValue(const UIProxyConfigService& config_service,
                       const std::string& path,
                       base::Value** out_value) {
  std::string controlled_by;
  base::Value* data = NULL;
  UIProxyConfig config;
  config_service.GetProxyConfig(&config);

  if (path == kProxyPacUrl) {
    // Only show pacurl for pac-script mode.
    if (config.mode == UIProxyConfig::MODE_PAC_SCRIPT &&
        config.automatic_proxy.pac_url.is_valid()) {
      data = new base::StringValue(config.automatic_proxy.pac_url.spec());
    }
  } else if (path == kProxySingleHttp) {
    data = CreateServerHostValue(config.single_proxy);
  } else if (path == kProxySingleHttpPort) {
    data = CreateServerPortValue(config.single_proxy);
  } else if (path == kProxyHttpUrl) {
    data = CreateServerHostValue(config.http_proxy);
  } else if (path == kProxyHttpsUrl) {
    data = CreateServerHostValue(config.https_proxy);
  } else if (path == kProxyType) {
    if (config.mode == UIProxyConfig::MODE_AUTO_DETECT ||
        config.mode == UIProxyConfig::MODE_PAC_SCRIPT) {
      data = base::Value::CreateIntegerValue(3);
    } else if (config.mode == UIProxyConfig::MODE_SINGLE_PROXY ||
               config.mode == UIProxyConfig::MODE_PROXY_PER_SCHEME) {
      data = base::Value::CreateIntegerValue(2);
    } else {
      data = base::Value::CreateIntegerValue(1);
    }
    switch (config.state) {
      case ProxyPrefs::CONFIG_POLICY:
        controlled_by = "policy";
        break;
      case ProxyPrefs::CONFIG_EXTENSION:
        controlled_by = "extension";
        break;
      case ProxyPrefs::CONFIG_OTHER_PRECEDE:
        controlled_by = "other";
        break;
      default:
        if (!config.user_modifiable)
          controlled_by = "shared";
        break;
    }
  } else if (path == kProxySingle) {
    data = base::Value::CreateBooleanValue(
        config.mode == UIProxyConfig::MODE_SINGLE_PROXY);
  } else if (path == kProxyUsePacUrl) {
    data = base::Value::CreateBooleanValue(
        config.mode == UIProxyConfig::MODE_PAC_SCRIPT);
  } else if (path == kProxyFtpUrl) {
    data = CreateServerHostValue(config.ftp_proxy);
  } else if (path == kProxySocks) {
    data = CreateServerHostValue(config.socks_proxy);
  } else if (path == kProxyHttpPort) {
    data = CreateServerPortValue(config.http_proxy);
  } else if (path == kProxyHttpsPort) {
    data = CreateServerPortValue(config.https_proxy);
  } else if (path == kProxyFtpPort) {
    data = CreateServerPortValue(config.ftp_proxy);
  } else if (path == kProxySocksPort) {
    data = CreateServerPortValue(config.socks_proxy);
  } else if (path == kProxyIgnoreList) {
    base::ListValue* list =  new base::ListValue();
    net::ProxyBypassRules::RuleList bypass_rules = config.bypass_rules.rules();
    for (size_t x = 0; x < bypass_rules.size(); x++)
      list->Append(new base::StringValue(bypass_rules[x]->ToString()));
    data = list;
  } else {
    *out_value = NULL;
    return false;
  }

  // Decorate pref value as CoreOptionsHandler::CreateValueForPref() does.
  base::DictionaryValue* dict = new base::DictionaryValue;
  if (!data)
    data = new base::StringValue("");
  dict->Set("value", data);
  if (path == kProxyType) {
    if (!controlled_by.empty())
      dict->SetString("controlledBy", controlled_by);
    dict->SetBoolean("disabled", !config.user_modifiable);
  } else {
    dict->SetBoolean("disabled", false);
  }
  *out_value = dict;
  return true;
}

}  // namespace proxy_cros_settings_parser

}  // namespace chromeos

/* [<][>][^][v][top][bottom][index][help] */