15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/proxy/proxy_config.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
85e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_util.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_tokenizer.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/proxy/proxy_info.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// If |proxies| is non-empty, sets it in |dict| under the key |name|.
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AddProxyListToValue(const char* name,
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         const ProxyList& proxies,
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         base::DictionaryValue* dict) {
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!proxies.IsEmpty())
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    dict->Set(name, proxies.ToValue());
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Split the |uri_list| on commas and add each entry to |proxy_list| in turn.
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AddProxyURIListToProxyList(std::string uri_list,
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                ProxyList* proxy_list,
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                ProxyServer::Scheme default_scheme) {
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::StringTokenizer proxy_uri_list(uri_list, ",");
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  while (proxy_uri_list.GetNext()) {
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    proxy_list->AddProxyServer(
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ProxyServer::FromURI(proxy_uri_list.token(), default_scheme));
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProxyConfig::ProxyRules::ProxyRules()
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : reverse_bypass(false),
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      type(TYPE_NO_RULES) {
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProxyConfig::ProxyRules::~ProxyRules() {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProxyConfig::ProxyRules::Apply(const GURL& url, ProxyInfo* result) const {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (empty()) {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result->UseDirect();
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool bypass_proxy = bypass_rules.Matches(url);
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (reverse_bypass)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bypass_proxy = !bypass_proxy;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (bypass_proxy) {
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result->UseDirectWithBypassedProxy();
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (type) {
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ProxyRules::TYPE_SINGLE_PROXY: {
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      result->UseProxyList(single_proxies);
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ProxyRules::TYPE_PROXY_PER_SCHEME: {
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const ProxyList* entry = MapUrlSchemeToProxyList(url.scheme());
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (entry) {
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        result->UseProxyList(*entry);
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // We failed to find a matching proxy server for the current URL
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // scheme. Default to direct.
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        result->UseDirect();
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default: {
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      result->UseDirect();
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProxyConfig::ProxyRules::ParseFromString(const std::string& proxy_rules) {
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reset.
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  type = TYPE_NO_RULES;
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  single_proxies = ProxyList();
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  proxies_for_http = ProxyList();
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  proxies_for_https = ProxyList();
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  proxies_for_ftp = ProxyList();
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  fallback_proxies = ProxyList();
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::StringTokenizer proxy_server_list(proxy_rules, ";");
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (proxy_server_list.GetNext()) {
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::StringTokenizer proxy_server_for_scheme(
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        proxy_server_list.token_begin(), proxy_server_list.token_end(), "=");
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (proxy_server_for_scheme.GetNext()) {
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::string url_scheme = proxy_server_for_scheme.token();
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // If we fail to get the proxy server here, it means that
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // this is a regular proxy server configuration, i.e. proxies
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // are not configured per protocol.
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!proxy_server_for_scheme.GetNext()) {
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (type == TYPE_PROXY_PER_SCHEME)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          continue;  // Unexpected.
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        AddProxyURIListToProxyList(url_scheme,
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   &single_proxies,
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   ProxyServer::SCHEME_HTTP);
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        type = TYPE_SINGLE_PROXY;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Trim whitespace off the url scheme.
115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::TrimWhitespaceASCII(url_scheme, base::TRIM_ALL, &url_scheme);
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Add it to the per-scheme mappings (if supported scheme).
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      type = TYPE_PROXY_PER_SCHEME;
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyList* entry = MapUrlSchemeToProxyListNoFallback(url_scheme);
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ProxyServer::Scheme default_scheme = ProxyServer::SCHEME_HTTP;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // socks=XXX is inconsistent with the other formats, since "socks"
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // is not a URL scheme. Rather this means "for everything else, send
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // it to the SOCKS proxy server XXX".
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (url_scheme == "socks") {
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        DCHECK(!entry);
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        entry = &fallback_proxies;
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        // Note that here 'socks' is understood to be SOCKS4, even though
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        // 'socks' maps to SOCKS5 in ProxyServer::GetSchemeFromURIInternal.
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        default_scheme = ProxyServer::SCHEME_SOCKS4;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (entry) {
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        AddProxyURIListToProxyList(proxy_server_for_scheme.token(),
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   entry,
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   default_scheme);
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const ProxyList* ProxyConfig::ProxyRules::MapUrlSchemeToProxyList(
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& url_scheme) const {
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const ProxyList* proxy_server_list = const_cast<ProxyRules*>(this)->
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      MapUrlSchemeToProxyListNoFallback(url_scheme);
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (proxy_server_list && !proxy_server_list->IsEmpty())
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return proxy_server_list;
14829b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch  if (url_scheme == "ws" || url_scheme == "wss")
14929b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch    return GetProxyListForWebSocketScheme();
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!fallback_proxies.IsEmpty())
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return &fallback_proxies;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;  // No mapping for this scheme. Use direct.
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProxyConfig::ProxyRules::Equals(const ProxyRules& other) const {
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return type == other.type &&
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         single_proxies.Equals(other.single_proxies) &&
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         proxies_for_http.Equals(other.proxies_for_http) &&
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         proxies_for_https.Equals(other.proxies_for_https) &&
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         proxies_for_ftp.Equals(other.proxies_for_ftp) &&
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         fallback_proxies.Equals(other.fallback_proxies) &&
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         bypass_rules.Equals(other.bypass_rules) &&
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         reverse_bypass == other.reverse_bypass;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ProxyList* ProxyConfig::ProxyRules::MapUrlSchemeToProxyListNoFallback(
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& scheme) {
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(TYPE_PROXY_PER_SCHEME, type);
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (scheme == "http")
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return &proxies_for_http;
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (scheme == "https")
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return &proxies_for_https;
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (scheme == "ftp")
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return &proxies_for_ftp;
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;  // No mapping for this scheme.
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17829b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdochconst ProxyList* ProxyConfig::ProxyRules::GetProxyListForWebSocketScheme()
17929b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch    const {
18029b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch  if (!fallback_proxies.IsEmpty())
18129b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch    return &fallback_proxies;
18229b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch  if (!proxies_for_https.IsEmpty())
18329b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch    return &proxies_for_https;
18429b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch  if (!proxies_for_http.IsEmpty())
18529b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch    return &proxies_for_http;
18629b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch  return NULL;
18729b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch}
18829b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProxyConfig::ProxyConfig()
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : auto_detect_(false), pac_mandatory_(false),
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      source_(PROXY_CONFIG_SOURCE_UNKNOWN), id_(kInvalidConfigID)  {
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProxyConfig::ProxyConfig(const ProxyConfig& config)
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : auto_detect_(config.auto_detect_),
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pac_url_(config.pac_url_),
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pac_mandatory_(config.pac_mandatory_),
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      proxy_rules_(config.proxy_rules_),
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      source_(config.source_),
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      id_(config.id_) {
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProxyConfig::~ProxyConfig() {
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProxyConfig& ProxyConfig::operator=(const ProxyConfig& config) {
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  auto_detect_ = config.auto_detect_;
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pac_url_ = config.pac_url_;
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pac_mandatory_ = config.pac_mandatory_;
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  proxy_rules_ = config.proxy_rules_;
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  source_ = config.source_;
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  id_ = config.id_;
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return *this;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProxyConfig::Equals(const ProxyConfig& other) const {
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The two configs can have different IDs and sources.  We are just interested
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in if they have the same settings.
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return auto_detect_ == other.auto_detect_ &&
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         pac_url_ == other.pac_url_ &&
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         pac_mandatory_ == other.pac_mandatory_ &&
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         proxy_rules_.Equals(other.proxy_rules());
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProxyConfig::HasAutomaticSettings() const {
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return auto_detect_ || has_pac_url();
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProxyConfig::ClearAutomaticSettings() {
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  auto_detect_ = false;
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pac_url_ = GURL();
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
234868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)base::DictionaryValue* ProxyConfig::ToValue() const {
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::DictionaryValue* dict = new base::DictionaryValue();
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Output the automatic settings.
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (auto_detect_)
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dict->SetBoolean("auto_detect", auto_detect_);
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (has_pac_url()) {
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dict->SetString("pac_url", pac_url_.possibly_invalid_spec());
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (pac_mandatory_)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dict->SetBoolean("pac_mandatory", pac_mandatory_);
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Output the manual settings.
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (proxy_rules_.type != ProxyRules::TYPE_NO_RULES) {
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (proxy_rules_.type) {
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case ProxyRules::TYPE_SINGLE_PROXY:
250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        AddProxyListToValue("single_proxy",
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            proxy_rules_.single_proxies, dict);
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case ProxyRules::TYPE_PROXY_PER_SCHEME: {
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::DictionaryValue* dict2 = new base::DictionaryValue();
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        AddProxyListToValue("http", proxy_rules_.proxies_for_http, dict2);
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        AddProxyListToValue("https", proxy_rules_.proxies_for_https, dict2);
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        AddProxyListToValue("ftp", proxy_rules_.proxies_for_ftp, dict2);
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        AddProxyListToValue("fallback", proxy_rules_.fallback_proxies, dict2);
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dict->Set("proxy_per_scheme", dict2);
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      default:
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NOTREACHED();
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Output the bypass rules.
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ProxyBypassRules& bypass = proxy_rules_.bypass_rules;
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!bypass.rules().empty()) {
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (proxy_rules_.reverse_bypass)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dict->SetBoolean("reverse_bypass", true);
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::ListValue* list = new base::ListValue();
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for (ProxyBypassRules::RuleList::const_iterator it =
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              bypass.rules().begin();
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           it != bypass.rules().end(); ++it) {
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        list->Append(new base::StringValue((*it)->ToString()));
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dict->Set("bypass_list", list);
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Output the source.
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dict->SetString("source", ProxyConfigSourceToString(source_));
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return dict;
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
291