1 // Copyright 2012 The Chromium Authors
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 "net/proxy_resolution/proxy_config_service_ios.h"
6
7 #include <CFNetwork/CFProxySupport.h>
8 #include <CoreFoundation/CoreFoundation.h>
9
10 #include "base/apple/foundation_util.h"
11 #include "base/apple/scoped_cftyperef.h"
12 #include "base/strings/sys_string_conversions.h"
13 #include "net/base/proxy_chain.h"
14 #include "net/proxy_resolution/proxy_chain_util_apple.h"
15 #include "net/proxy_resolution/proxy_config_with_annotation.h"
16
17 namespace net {
18
19 namespace {
20
21 const int kPollIntervalSec = 10;
22
23 // Utility function to pull out a boolean value from a dictionary and return it,
24 // returning a default value if the key is not present.
GetBoolFromDictionary(CFDictionaryRef dict,CFStringRef key,bool default_value)25 bool GetBoolFromDictionary(CFDictionaryRef dict,
26 CFStringRef key,
27 bool default_value) {
28 CFNumberRef number =
29 base::apple::GetValueFromDictionary<CFNumberRef>(dict, key);
30 if (!number)
31 return default_value;
32
33 int int_value;
34 if (CFNumberGetValue(number, kCFNumberIntType, &int_value))
35 return int_value;
36 else
37 return default_value;
38 }
39
GetCurrentProxyConfig(const NetworkTrafficAnnotationTag traffic_annotation,ProxyConfigWithAnnotation * config)40 void GetCurrentProxyConfig(const NetworkTrafficAnnotationTag traffic_annotation,
41 ProxyConfigWithAnnotation* config) {
42 base::apple::ScopedCFTypeRef<CFDictionaryRef> config_dict(
43 CFNetworkCopySystemProxySettings());
44 DCHECK(config_dict);
45 ProxyConfig proxy_config;
46 // Auto-detect is not supported.
47 // The kCFNetworkProxiesProxyAutoDiscoveryEnable key is not available on iOS.
48
49 // PAC file
50
51 if (GetBoolFromDictionary(config_dict.get(),
52 kCFNetworkProxiesProxyAutoConfigEnable,
53 false)) {
54 CFStringRef pac_url_ref = base::apple::GetValueFromDictionary<CFStringRef>(
55 config_dict.get(), kCFNetworkProxiesProxyAutoConfigURLString);
56 if (pac_url_ref)
57 proxy_config.set_pac_url(GURL(base::SysCFStringRefToUTF8(pac_url_ref)));
58 }
59
60 // Proxies (for now http).
61
62 // The following keys are not available on iOS:
63 // kCFNetworkProxiesFTPEnable
64 // kCFNetworkProxiesFTPProxy
65 // kCFNetworkProxiesFTPPort
66 // kCFNetworkProxiesHTTPSEnable
67 // kCFNetworkProxiesHTTPSProxy
68 // kCFNetworkProxiesHTTPSPort
69 // kCFNetworkProxiesSOCKSEnable
70 // kCFNetworkProxiesSOCKSProxy
71 // kCFNetworkProxiesSOCKSPort
72 if (GetBoolFromDictionary(config_dict.get(), kCFNetworkProxiesHTTPEnable,
73 false)) {
74 ProxyChain proxy_chain = ProxyDictionaryToProxyChain(
75 kCFProxyTypeHTTP, config_dict.get(), kCFNetworkProxiesHTTPProxy,
76 kCFNetworkProxiesHTTPPort);
77 if (proxy_chain.IsValid()) {
78 proxy_config.proxy_rules().type =
79 ProxyConfig::ProxyRules::Type::PROXY_LIST_PER_SCHEME;
80 proxy_config.proxy_rules().proxies_for_http.SetSingleProxyChain(
81 proxy_chain);
82 // Desktop Safari applies the HTTP proxy to http:// URLs only, but
83 // Mobile Safari applies the HTTP proxy to https:// URLs as well.
84 proxy_config.proxy_rules().proxies_for_https.SetSingleProxyChain(
85 proxy_chain);
86 }
87 }
88
89 // Proxy bypass list is not supported.
90 // The kCFNetworkProxiesExceptionsList key is not available on iOS.
91
92 // Proxy bypass boolean is not supported.
93 // The kCFNetworkProxiesExcludeSimpleHostnames key is not available on iOS.
94
95 // Source
96 proxy_config.set_from_system(true);
97 *config = ProxyConfigWithAnnotation(proxy_config, traffic_annotation);
98 }
99
100 } // namespace
101
ProxyConfigServiceIOS(const NetworkTrafficAnnotationTag & traffic_annotation)102 ProxyConfigServiceIOS::ProxyConfigServiceIOS(
103 const NetworkTrafficAnnotationTag& traffic_annotation)
104 : PollingProxyConfigService(base::Seconds(kPollIntervalSec),
105 GetCurrentProxyConfig,
106 traffic_annotation) {}
107
108 ProxyConfigServiceIOS::~ProxyConfigServiceIOS() = default;
109
110 } // namespace net
111