| // Copyright 2012 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "net/proxy_resolution/proxy_config_service_ios.h" |
| |
| #include <CFNetwork/CFProxySupport.h> |
| #include <CoreFoundation/CoreFoundation.h> |
| |
| #include "base/apple/foundation_util.h" |
| #include "base/apple/scoped_cftyperef.h" |
| #include "base/strings/sys_string_conversions.h" |
| #include "net/base/proxy_chain.h" |
| #include "net/proxy_resolution/proxy_chain_util_apple.h" |
| #include "net/proxy_resolution/proxy_config_with_annotation.h" |
| |
| namespace net { |
| |
| namespace { |
| |
| const int kPollIntervalSec = 10; |
| |
| // Utility function to pull out a boolean value from a dictionary and return it, |
| // returning a default value if the key is not present. |
| bool GetBoolFromDictionary(CFDictionaryRef dict, |
| CFStringRef key, |
| bool default_value) { |
| CFNumberRef number = |
| base::apple::GetValueFromDictionary<CFNumberRef>(dict, key); |
| if (!number) |
| return default_value; |
| |
| int int_value; |
| if (CFNumberGetValue(number, kCFNumberIntType, &int_value)) |
| return int_value; |
| else |
| return default_value; |
| } |
| |
| void GetCurrentProxyConfig(const NetworkTrafficAnnotationTag traffic_annotation, |
| ProxyConfigWithAnnotation* config) { |
| base::apple::ScopedCFTypeRef<CFDictionaryRef> config_dict( |
| CFNetworkCopySystemProxySettings()); |
| DCHECK(config_dict); |
| ProxyConfig proxy_config; |
| // Auto-detect is not supported. |
| // The kCFNetworkProxiesProxyAutoDiscoveryEnable key is not available on iOS. |
| |
| // PAC file |
| |
| if (GetBoolFromDictionary(config_dict.get(), |
| kCFNetworkProxiesProxyAutoConfigEnable, |
| false)) { |
| CFStringRef pac_url_ref = base::apple::GetValueFromDictionary<CFStringRef>( |
| config_dict.get(), kCFNetworkProxiesProxyAutoConfigURLString); |
| if (pac_url_ref) |
| proxy_config.set_pac_url(GURL(base::SysCFStringRefToUTF8(pac_url_ref))); |
| } |
| |
| // Proxies (for now http). |
| |
| // The following keys are not available on iOS: |
| // kCFNetworkProxiesFTPEnable |
| // kCFNetworkProxiesFTPProxy |
| // kCFNetworkProxiesFTPPort |
| // kCFNetworkProxiesHTTPSEnable |
| // kCFNetworkProxiesHTTPSProxy |
| // kCFNetworkProxiesHTTPSPort |
| // kCFNetworkProxiesSOCKSEnable |
| // kCFNetworkProxiesSOCKSProxy |
| // kCFNetworkProxiesSOCKSPort |
| if (GetBoolFromDictionary(config_dict.get(), kCFNetworkProxiesHTTPEnable, |
| false)) { |
| ProxyChain proxy_chain = ProxyDictionaryToProxyChain( |
| kCFProxyTypeHTTP, config_dict.get(), kCFNetworkProxiesHTTPProxy, |
| kCFNetworkProxiesHTTPPort); |
| if (proxy_chain.IsValid()) { |
| proxy_config.proxy_rules().type = |
| ProxyConfig::ProxyRules::Type::PROXY_LIST_PER_SCHEME; |
| proxy_config.proxy_rules().proxies_for_http.SetSingleProxyChain( |
| proxy_chain); |
| // Desktop Safari applies the HTTP proxy to http:// URLs only, but |
| // Mobile Safari applies the HTTP proxy to https:// URLs as well. |
| proxy_config.proxy_rules().proxies_for_https.SetSingleProxyChain( |
| proxy_chain); |
| } |
| } |
| |
| // Proxy bypass list is not supported. |
| // The kCFNetworkProxiesExceptionsList key is not available on iOS. |
| |
| // Proxy bypass boolean is not supported. |
| // The kCFNetworkProxiesExcludeSimpleHostnames key is not available on iOS. |
| |
| // Source |
| proxy_config.set_from_system(true); |
| *config = ProxyConfigWithAnnotation(proxy_config, traffic_annotation); |
| } |
| |
| } // namespace |
| |
| ProxyConfigServiceIOS::ProxyConfigServiceIOS( |
| const NetworkTrafficAnnotationTag& traffic_annotation) |
| : PollingProxyConfigService(base::Seconds(kPollIntervalSec), |
| GetCurrentProxyConfig, |
| traffic_annotation) {} |
| |
| ProxyConfigServiceIOS::~ProxyConfigServiceIOS() = default; |
| |
| } // namespace net |