Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(177)

Side by Side Diff: net/proxy/proxy_resolver_mac.cc

Issue 463028: Separate ProxyResolverMac and ProxyConfigServiceMac into their own files (Closed)
Patch Set: '' Created 11 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/proxy/proxy_resolver_mac.h ('k') | net/proxy/proxy_server.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/proxy/proxy_resolver_mac.h" 5 #include "net/proxy/proxy_resolver_mac.h"
6 6
7 #include <CoreFoundation/CoreFoundation.h> 7 #include <CoreFoundation/CoreFoundation.h>
8 #include <CoreServices/CoreServices.h>
9 #include <SystemConfiguration/SystemConfiguration.h>
10 8
9 #include "base/logging.h"
10 #include "base/mac_util.h"
11 #include "base/scoped_cftyperef.h" 11 #include "base/scoped_cftyperef.h"
12 #include "base/string_util.h" 12 #include "base/string_util.h"
13 #include "base/sys_string_conversions.h" 13 #include "base/sys_string_conversions.h"
14 #include "net/base/net_errors.h" 14 #include "net/base/net_errors.h"
15 #include "net/proxy/proxy_config.h"
16 #include "net/proxy/proxy_info.h" 15 #include "net/proxy/proxy_info.h"
17 #include "net/proxy/proxy_server.h" 16 #include "net/proxy/proxy_server.h"
18 17
19 namespace { 18 namespace {
20 19
21 // Utility function to pull out a value from a dictionary, check its type, and
22 // return it. Returns NULL if the key is not present or of the wrong type.
23 CFTypeRef GetValueFromDictionary(CFDictionaryRef dict,
24 CFStringRef key,
25 CFTypeID expected_type) {
26 CFTypeRef value = CFDictionaryGetValue(dict, key);
27 if (!value)
28 return value;
29
30 if (CFGetTypeID(value) != expected_type) {
31 scoped_cftyperef<CFStringRef> expected_type_ref(
32 CFCopyTypeIDDescription(expected_type));
33 scoped_cftyperef<CFStringRef> actual_type_ref(
34 CFCopyTypeIDDescription(CFGetTypeID(value)));
35 LOG(WARNING) << "Expected value for key "
36 << base::SysCFStringRefToUTF8(key)
37 << " to be "
38 << base::SysCFStringRefToUTF8(expected_type_ref)
39 << " but it was "
40 << base::SysCFStringRefToUTF8(actual_type_ref)
41 << " instead";
42 return NULL;
43 }
44
45 return value;
46 }
47
48 // Utility function to pull out a boolean value from a dictionary and return it,
49 // returning a default value if the key is not present.
50 bool GetBoolFromDictionary(CFDictionaryRef dict,
51 CFStringRef key,
52 bool default_value) {
53 CFNumberRef number = (CFNumberRef)GetValueFromDictionary(dict, key,
54 CFNumberGetTypeID());
55 if (!number)
56 return default_value;
57
58 int int_value;
59 if (CFNumberGetValue(number, kCFNumberIntType, &int_value))
60 return int_value;
61 else
62 return default_value;
63 }
64
65 // Utility function to pull out a host/port pair from a dictionary and return it
66 // as a ProxyServer object. Pass in a dictionary that has a value for the host
67 // key and optionally a value for the port key. In the error condition where
68 // the host value is especially malformed, returns an invalid ProxyServer.
69 net::ProxyServer GetProxyServerFromDictionary(net::ProxyServer::Scheme scheme,
70 CFDictionaryRef dict,
71 CFStringRef host_key,
72 CFStringRef port_key) {
73 if (scheme == net::ProxyServer::SCHEME_INVALID ||
74 scheme == net::ProxyServer::SCHEME_DIRECT) {
75 // No hostname port to extract; we are done.
76 return net::ProxyServer(scheme, std::string(), -1);
77 }
78
79 CFStringRef host_ref =
80 (CFStringRef)GetValueFromDictionary(dict, host_key,
81 CFStringGetTypeID());
82 if (!host_ref) {
83 LOG(WARNING) << "Could not find expected key "
84 << base::SysCFStringRefToUTF8(host_key)
85 << " in the proxy dictionary";
86 return net::ProxyServer(); // Invalid.
87 }
88 std::string host = base::SysCFStringRefToUTF8(host_ref);
89
90 CFNumberRef port_ref =
91 (CFNumberRef)GetValueFromDictionary(dict, port_key,
92 CFNumberGetTypeID());
93 int port;
94 if (port_ref) {
95 CFNumberGetValue(port_ref, kCFNumberIntType, &port);
96 } else {
97 port = net::ProxyServer::GetDefaultPortForScheme(scheme);
98 }
99
100 return net::ProxyServer(scheme, host, port);
101 }
102
103 // Utility function to map a CFProxyType to a ProxyServer::Scheme. 20 // Utility function to map a CFProxyType to a ProxyServer::Scheme.
104 // If the type is unknown, returns ProxyServer::SCHEME_INVALID. 21 // If the type is unknown, returns ProxyServer::SCHEME_INVALID.
105 net::ProxyServer::Scheme GetProxyServerScheme(CFStringRef proxy_type) { 22 net::ProxyServer::Scheme GetProxyServerScheme(CFStringRef proxy_type) {
106 if (CFEqual(proxy_type, kCFProxyTypeNone)) 23 if (CFEqual(proxy_type, kCFProxyTypeNone))
107 return net::ProxyServer::SCHEME_DIRECT; 24 return net::ProxyServer::SCHEME_DIRECT;
108 if (CFEqual(proxy_type, kCFProxyTypeHTTP)) 25 if (CFEqual(proxy_type, kCFProxyTypeHTTP))
109 return net::ProxyServer::SCHEME_HTTP; 26 return net::ProxyServer::SCHEME_HTTP;
110 if (CFEqual(proxy_type, kCFProxyTypeSOCKS)) { 27 if (CFEqual(proxy_type, kCFProxyTypeSOCKS)) {
111 // We can't tell whether this was v4 or v5. We will assume it is 28 // We can't tell whether this was v4 or v5. We will assume it is
112 // v5 since that is the only version OS X supports. 29 // v5 since that is the only version OS X supports.
113 return net::ProxyServer::SCHEME_SOCKS5; 30 return net::ProxyServer::SCHEME_SOCKS5;
114 } 31 }
115 return net::ProxyServer::SCHEME_INVALID; 32 return net::ProxyServer::SCHEME_INVALID;
116 } 33 }
117 34
118 // Callback for CFNetworkExecuteProxyAutoConfigurationURL. |client| is a pointer 35 // Callback for CFNetworkExecuteProxyAutoConfigurationURL. |client| is a pointer
119 // to a CFTypeRef. This stashes either |error| or |proxies| in that location. 36 // to a CFTypeRef. This stashes either |error| or |proxies| in that location.
120 void ResultCallback(void* client, CFArrayRef proxies, CFErrorRef error) { 37 void ResultCallback(void* client, CFArrayRef proxies, CFErrorRef error) {
121 DCHECK((proxies != NULL) == (error == NULL)); 38 DCHECK((proxies != NULL) == (error == NULL));
122 39
123 CFTypeRef* result_ptr = (CFTypeRef*)client; 40 CFTypeRef* result_ptr = reinterpret_cast<CFTypeRef*>(client);
124 DCHECK(result_ptr != NULL); 41 DCHECK(result_ptr != NULL);
125 DCHECK(*result_ptr == NULL); 42 DCHECK(*result_ptr == NULL);
126 43
127 if (error != NULL) { 44 if (error != NULL) {
128 *result_ptr = CFRetain(error); 45 *result_ptr = CFRetain(error);
129 } else { 46 } else {
130 *result_ptr = CFRetain(proxies); 47 *result_ptr = CFRetain(proxies);
131 } 48 }
132 CFRunLoopStop(CFRunLoopGetCurrent()); 49 CFRunLoopStop(CFRunLoopGetCurrent());
133 } 50 }
134 51
135 } // namespace 52 } // namespace
136 53
137 namespace net { 54 namespace net {
138 55
139 int ProxyConfigServiceMac::GetProxyConfig(ProxyConfig* config) {
140 scoped_cftyperef<CFDictionaryRef> config_dict(
141 SCDynamicStoreCopyProxies(NULL));
142 DCHECK(config_dict);
143
144 // auto-detect
145
146 // There appears to be no UI for this configuration option, and we're not sure
147 // if Apple's proxy code even takes it into account. But the constant is in
148 // the header file so we'll use it.
149 config->auto_detect =
150 GetBoolFromDictionary(config_dict.get(),
151 kSCPropNetProxiesProxyAutoDiscoveryEnable,
152 false);
153
154 // PAC file
155
156 if (GetBoolFromDictionary(config_dict.get(),
157 kSCPropNetProxiesProxyAutoConfigEnable,
158 false)) {
159 CFStringRef pac_url_ref =
160 (CFStringRef)GetValueFromDictionary(
161 config_dict.get(),
162 kSCPropNetProxiesProxyAutoConfigURLString,
163 CFStringGetTypeID());
164 if (pac_url_ref)
165 config->pac_url = GURL(base::SysCFStringRefToUTF8(pac_url_ref));
166 }
167
168 // proxies (for now ftp, http, https, and SOCKS)
169
170 if (GetBoolFromDictionary(config_dict.get(),
171 kSCPropNetProxiesFTPEnable,
172 false)) {
173 ProxyServer proxy_server =
174 GetProxyServerFromDictionary(ProxyServer::SCHEME_HTTP,
175 config_dict.get(),
176 kSCPropNetProxiesFTPProxy,
177 kSCPropNetProxiesFTPPort);
178 if (proxy_server.is_valid()) {
179 config->proxy_rules.type = ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME;
180 config->proxy_rules.proxy_for_ftp = proxy_server;
181 }
182 }
183 if (GetBoolFromDictionary(config_dict.get(),
184 kSCPropNetProxiesHTTPEnable,
185 false)) {
186 ProxyServer proxy_server =
187 GetProxyServerFromDictionary(ProxyServer::SCHEME_HTTP,
188 config_dict.get(),
189 kSCPropNetProxiesHTTPProxy,
190 kSCPropNetProxiesHTTPPort);
191 if (proxy_server.is_valid()) {
192 config->proxy_rules.type = ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME;
193 config->proxy_rules.proxy_for_http = proxy_server;
194 }
195 }
196 if (GetBoolFromDictionary(config_dict.get(),
197 kSCPropNetProxiesHTTPSEnable,
198 false)) {
199 ProxyServer proxy_server =
200 GetProxyServerFromDictionary(ProxyServer::SCHEME_HTTP,
201 config_dict.get(),
202 kSCPropNetProxiesHTTPSProxy,
203 kSCPropNetProxiesHTTPSPort);
204 if (proxy_server.is_valid()) {
205 config->proxy_rules.type = ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME;
206 config->proxy_rules.proxy_for_https = proxy_server;
207 }
208 }
209 if (GetBoolFromDictionary(config_dict.get(),
210 kSCPropNetProxiesSOCKSEnable,
211 false)) {
212 ProxyServer proxy_server =
213 GetProxyServerFromDictionary(ProxyServer::SCHEME_SOCKS5,
214 config_dict.get(),
215 kSCPropNetProxiesSOCKSProxy,
216 kSCPropNetProxiesSOCKSPort);
217 if (proxy_server.is_valid()) {
218 config->proxy_rules.type = ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME;
219 config->proxy_rules.socks_proxy = proxy_server;
220 }
221 }
222
223 // proxy bypass list
224
225 CFArrayRef bypass_array_ref =
226 (CFArrayRef)GetValueFromDictionary(config_dict.get(),
227 kSCPropNetProxiesExceptionsList,
228 CFArrayGetTypeID());
229 if (bypass_array_ref) {
230 CFIndex bypass_array_count = CFArrayGetCount(bypass_array_ref);
231 for (CFIndex i = 0; i < bypass_array_count; ++i) {
232 CFStringRef bypass_item_ref =
233 (CFStringRef)CFArrayGetValueAtIndex(bypass_array_ref, i);
234 if (CFGetTypeID(bypass_item_ref) != CFStringGetTypeID()) {
235 LOG(WARNING) << "Expected value for item " << i
236 << " in the kSCPropNetProxiesExceptionsList"
237 " to be a CFStringRef but it was not";
238
239 } else {
240 config->proxy_bypass.push_back(
241 base::SysCFStringRefToUTF8(bypass_item_ref));
242 }
243 }
244 }
245
246 // proxy bypass boolean
247
248 config->proxy_bypass_local_names =
249 GetBoolFromDictionary(config_dict.get(),
250 kSCPropNetProxiesExcludeSimpleHostnames,
251 false);
252
253 return OK;
254 }
255
256 // Gets the proxy information for a query URL from a PAC. Implementation 56 // Gets the proxy information for a query URL from a PAC. Implementation
257 // inspired by http://developer.apple.com/samplecode/CFProxySupportTool/ 57 // inspired by http://developer.apple.com/samplecode/CFProxySupportTool/
258 int ProxyResolverMac::GetProxyForURL(const GURL& query_url, 58 int ProxyResolverMac::GetProxyForURL(const GURL& query_url,
259 ProxyInfo* results, 59 ProxyInfo* results,
260 CompletionCallback* /*callback*/, 60 CompletionCallback* /*callback*/,
261 RequestHandle* /*request*/, 61 RequestHandle* /*request*/,
262 LoadLog* load_log) { 62 LoadLog* load_log) {
263 scoped_cftyperef<CFStringRef> query_ref( 63 scoped_cftyperef<CFStringRef> query_ref(
264 base::SysUTF8ToCFStringRef(query_url.spec())); 64 base::SysUTF8ToCFStringRef(query_url.spec()));
265 scoped_cftyperef<CFURLRef> query_url_ref( 65 scoped_cftyperef<CFURLRef> query_url_ref(
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
339 // - kCFProxyPasswordKey : Despite the existence of these keys in the 139 // - kCFProxyPasswordKey : Despite the existence of these keys in the
340 // documentation, they're never populated. Even if a 140 // documentation, they're never populated. Even if a
341 // username/password were to be set in the network 141 // username/password were to be set in the network
342 // proxy system preferences, we'd need to fetch it 142 // proxy system preferences, we'd need to fetch it
343 // from the Keychain ourselves. CFProxy is such a 143 // from the Keychain ourselves. CFProxy is such a
344 // tease. 144 // tease.
345 // - kCFProxyAutoConfigurationURLKey : If the PAC file specifies another 145 // - kCFProxyAutoConfigurationURLKey : If the PAC file specifies another
346 // PAC file, I'm going home. 146 // PAC file, I'm going home.
347 147
348 CFStringRef proxy_type = 148 CFStringRef proxy_type =
349 (CFStringRef)GetValueFromDictionary(proxy_dictionary, 149 (CFStringRef)mac_util::GetValueFromDictionary(proxy_dictionary,
350 kCFProxyTypeKey, 150 kCFProxyTypeKey,
351 CFStringGetTypeID()); 151 CFStringGetTypeID());
352 ProxyServer proxy_server = 152 ProxyServer proxy_server = ProxyServer::FromDictionary(
353 GetProxyServerFromDictionary(GetProxyServerScheme(proxy_type), 153 GetProxyServerScheme(proxy_type),
354 proxy_dictionary, 154 proxy_dictionary,
355 kCFProxyHostNameKey, 155 kCFProxyHostNameKey,
356 kCFProxyPortNumberKey); 156 kCFProxyPortNumberKey);
357 if (!proxy_server.is_valid()) 157 if (!proxy_server.is_valid())
358 continue; 158 continue;
359 159
360 if (!proxy_uri_list.empty()) 160 if (!proxy_uri_list.empty())
361 proxy_uri_list += ";"; 161 proxy_uri_list += ";";
362 proxy_uri_list += proxy_server.ToURI(); 162 proxy_uri_list += proxy_server.ToURI();
363 } 163 }
364 164
365 if (!proxy_uri_list.empty()) 165 if (!proxy_uri_list.empty())
366 results->UseNamedProxy(proxy_uri_list); 166 results->UseNamedProxy(proxy_uri_list);
367 // Else do nothing (results is already guaranteed to be in the default state). 167 // Else do nothing (results is already guaranteed to be in the default state).
368 168
369 return OK; 169 return OK;
370 } 170 }
371 171
372 } // namespace net 172 } // namespace net
OLDNEW
« no previous file with comments | « net/proxy/proxy_resolver_mac.h ('k') | net/proxy/proxy_server.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698