xref: /aosp_15_r20/external/cronet/net/proxy_resolution/proxy_config_service_ios.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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