diff options
author | avi@google.com <avi@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-10-30 18:51:16 +0000 |
---|---|---|
committer | avi@google.com <avi@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-10-30 18:51:16 +0000 |
commit | 21a52557fc2373e7c3f525072384bb97f7978012 (patch) | |
tree | 84539a3aba112abf72b88c644b791c23cdfefe93 /net/proxy/proxy_resolver_mac.cc | |
parent | 074ff16d3029256a9585529cad5487c1ae6eb409 (diff) | |
download | chromium_src-21a52557fc2373e7c3f525072384bb97f7978012.zip chromium_src-21a52557fc2373e7c3f525072384bb97f7978012.tar.gz chromium_src-21a52557fc2373e7c3f525072384bb97f7978012.tar.bz2 |
oops; will reland once tree is open
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@4223 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/proxy/proxy_resolver_mac.cc')
-rw-r--r-- | net/proxy/proxy_resolver_mac.cc | 342 |
1 files changed, 0 insertions, 342 deletions
diff --git a/net/proxy/proxy_resolver_mac.cc b/net/proxy/proxy_resolver_mac.cc deleted file mode 100644 index 0bf52b91..0000000 --- a/net/proxy/proxy_resolver_mac.cc +++ /dev/null @@ -1,342 +0,0 @@ -// Copyright (c) 2008 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/proxy/proxy_resolver_mac.h" - -#include <CoreFoundation/CoreFoundation.h> -#include <CoreServices/CoreServices.h> -#include <SystemConfiguration/SystemConfiguration.h> - -#include "base/scoped_cftyperef.h" -#include "base/string_util.h" -#include "base/sys_string_conversions.h" -#include "net/base/net_errors.h" - -namespace { - -// Utility function to pull out a value from a dictionary, check its type, and -// return it. Returns NULL if the key is not present or of the wrong type. -CFTypeRef GetValueFromDictionary(CFDictionaryRef dict, - CFStringRef key, - CFTypeID expected_type) { - CFTypeRef value = CFDictionaryGetValue(dict, key); - if (!value) - return value; - - if (CFGetTypeID(value) != expected_type) { - scoped_cftyperef<CFStringRef> expected_type_ref( - CFCopyTypeIDDescription(expected_type)); - scoped_cftyperef<CFStringRef> actual_type_ref( - CFCopyTypeIDDescription(CFGetTypeID(value))); - LOG(WARNING) << "Expected value for key " - << base::SysCFStringRefToUTF8(key) - << " to be " - << base::SysCFStringRefToUTF8(expected_type_ref) - << " but it was " - << base::SysCFStringRefToUTF8(actual_type_ref) - << " instead"; - return NULL; - } - - return value; -} - -// 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 = (CFNumberRef)GetValueFromDictionary(dict, key, - CFNumberGetTypeID()); - if (!number) - return default_value; - - int int_value; - if (CFNumberGetValue(number, kCFNumberIntType, &int_value)) - return int_value; - else - return default_value; -} - -// Utility function to pull out a host/port pair from a dictionary and format -// them into a "<host>[:<port>]" style string. Pass in a dictionary that has a -// value for the host key and optionally a value for the port key. Returns a -// formatted string. In the error condition where the host value is especially -// malformed, returns an empty string. (You may still want to check for that -// result anyway.) -std::string GetHostPortFromDictionary(CFDictionaryRef dict, - CFStringRef host_key, - CFStringRef port_key) { - std::string result; - - CFStringRef host_ref = - (CFStringRef)GetValueFromDictionary(dict, host_key, - CFStringGetTypeID()); - if (!host_ref) { - LOG(WARNING) << "Could not find expected key " - << base::SysCFStringRefToUTF8(host_key) - << " in the proxy dictionary"; - return result; - } - result = base::SysCFStringRefToUTF8(host_ref); - - CFNumberRef port_ref = - (CFNumberRef)GetValueFromDictionary(dict, port_key, - CFNumberGetTypeID()); - if (port_ref) { - int port; - CFNumberGetValue(port_ref, kCFNumberIntType, &port); - result += ":"; - result += IntToString(port); - } - - return result; -} - -// Callback for CFNetworkExecuteProxyAutoConfigurationURL. |client| is a pointer -// to a CFTypeRef. This stashes either |error| or |proxies| in that location. -void ResultCallback(void* client, CFArrayRef proxies, CFErrorRef error) { - DCHECK((proxies != NULL) == (error == NULL)); - - CFTypeRef* result_ptr = (CFTypeRef*)client; - DCHECK(result_ptr != NULL); - DCHECK(*result_ptr == NULL); - - if (error != NULL) { - *result_ptr = CFRetain(error); - } else { - *result_ptr = CFRetain(proxies); - } - CFRunLoopStop(CFRunLoopGetCurrent()); -} - -} // namespace - -namespace net { - -int ProxyResolverMac::GetProxyConfig(ProxyConfig* config) { - scoped_cftyperef<CFDictionaryRef> config_dict( - SCDynamicStoreCopyProxies(NULL)); - DCHECK(config_dict); - - // auto-detect - - // There appears to be no UI for this configuration option, and we're not sure - // if Apple's proxy code even takes it into account. But the constant is in - // the header file so we'll use it. - config->auto_detect = - GetBoolFromDictionary(config_dict.get(), - kSCPropNetProxiesProxyAutoDiscoveryEnable, - false); - - // PAC file - - if (GetBoolFromDictionary(config_dict.get(), - kSCPropNetProxiesProxyAutoConfigEnable, - false)) { - CFStringRef pac_url_ref = - (CFStringRef)GetValueFromDictionary( - config_dict.get(), - kSCPropNetProxiesProxyAutoConfigURLString, - CFStringGetTypeID()); - if (pac_url_ref) - config->pac_url = base::SysCFStringRefToUTF8(pac_url_ref); - } - - // proxies (for now only ftp, http and https) - - if (GetBoolFromDictionary(config_dict.get(), - kSCPropNetProxiesFTPEnable, - false)) { - std::string host_port = - GetHostPortFromDictionary(config_dict.get(), - kSCPropNetProxiesFTPProxy, - kSCPropNetProxiesFTPPort); - if (!host_port.empty()) { - config->proxy_server += "ftp="; - config->proxy_server += host_port; - } - } - if (GetBoolFromDictionary(config_dict.get(), - kSCPropNetProxiesHTTPEnable, - false)) { - std::string host_port = - GetHostPortFromDictionary(config_dict.get(), - kSCPropNetProxiesHTTPProxy, - kSCPropNetProxiesHTTPPort); - if (!host_port.empty()) { - if (!config->proxy_server.empty()) - config->proxy_server += ";"; - config->proxy_server += "http="; - config->proxy_server += host_port; - } - } - if (GetBoolFromDictionary(config_dict.get(), - kSCPropNetProxiesHTTPSEnable, - false)) { - std::string host_port = - GetHostPortFromDictionary(config_dict.get(), - kSCPropNetProxiesHTTPSProxy, - kSCPropNetProxiesHTTPSPort); - if (!host_port.empty()) { - if (!config->proxy_server.empty()) - config->proxy_server += ";"; - config->proxy_server += "https="; - config->proxy_server += host_port; - } - } - - // proxy bypass list - - CFArrayRef bypass_array_ref = - (CFArrayRef)GetValueFromDictionary(config_dict.get(), - kSCPropNetProxiesExceptionsList, - CFArrayGetTypeID()); - if (bypass_array_ref) { - CFIndex bypass_array_count = CFArrayGetCount(bypass_array_ref); - for (CFIndex i = 0; i < bypass_array_count; ++i) { - CFStringRef bypass_item_ref = - (CFStringRef)CFArrayGetValueAtIndex(bypass_array_ref, i); - if (CFGetTypeID(bypass_item_ref) != CFStringGetTypeID()) { - LOG(WARNING) << "Expected value for item " << i - << " in the kSCPropNetProxiesExceptionsList" - " to be a CFStringRef but it was not"; - - } else { - config->proxy_bypass.push_back( - base::SysCFStringRefToUTF8(bypass_item_ref)); - } - } - } - - // proxy bypass boolean - - config->proxy_bypass_local_names = - GetBoolFromDictionary(config_dict.get(), - kSCPropNetProxiesExcludeSimpleHostnames, - false); - - return OK; -} - -// Gets the proxy information for a query URL from a PAC. Implementation -// inspired by http://developer.apple.com/samplecode/CFProxySupportTool/ -int ProxyResolverMac::GetProxyForURL(const std::string& query_url, - const std::string& pac_url, - ProxyInfo* results) { - scoped_cftyperef<CFStringRef> query_ref( - base::SysUTF8ToCFStringRef(query_url)); - scoped_cftyperef<CFStringRef> pac_ref( - base::SysUTF8ToCFStringRef(pac_url)); - scoped_cftyperef<CFURLRef> query_url_ref( - CFURLCreateWithString(kCFAllocatorDefault, - query_ref.get(), - NULL)); - scoped_cftyperef<CFURLRef> pac_url_ref( - CFURLCreateWithString(kCFAllocatorDefault, - pac_ref.get(), - NULL)); - - // Work around <rdar://problem/5530166>. This dummy call to - // CFNetworkCopyProxiesForURL initializes some state within CFNetwork that is - // required by CFNetworkExecuteProxyAutoConfigurationURL. - - CFArrayRef dummy_result = CFNetworkCopyProxiesForURL(query_url_ref.get(), - NULL); - if (dummy_result) - CFRelease(dummy_result); - - // We cheat here. We need to act as if we were synchronous, so we pump the - // runloop ourselves. Our caller moved us to a new thread anyway, so this is - // OK to do. (BTW, CFNetworkExecuteProxyAutoConfigurationURL returns a - // runloop source we need to release despite its name.) - - CFTypeRef result; - CFStreamClientContext context = { 0, &result, NULL, NULL, NULL }; - scoped_cftyperef<CFRunLoopSourceRef> runloop_source( - CFNetworkExecuteProxyAutoConfigurationURL(pac_url_ref.get(), - query_url_ref.get(), - ResultCallback, - &context)); - if (!runloop_source) - return ERR_FAILED; - - const CFStringRef private_runloop_mode = - CFSTR("org.chromium.ProxyResolverMac"); - - CFRunLoopAddSource(CFRunLoopGetCurrent(), runloop_source.get(), - private_runloop_mode); - CFRunLoopRunInMode(private_runloop_mode, DBL_MAX, false); - CFRunLoopRemoveSource(CFRunLoopGetCurrent(), runloop_source.get(), - private_runloop_mode); - DCHECK(result != NULL); - - if (CFGetTypeID(result) == CFErrorGetTypeID()) { - // TODO(avi): do something better than this - CFRelease(result); - return ERR_FAILED; - } - DCHECK(CFGetTypeID(result) == CFArrayGetTypeID()); - scoped_cftyperef<CFArrayRef> proxy_array_ref((CFArrayRef)result); - - // Proxy information. If we're allowed to contact the site directly, we set - // allow_direct to true. If we've found proxies to use, apart from - // accumulating them in proxy_list, we set found_proxy to true. These - // bool results are orthogonal. - bool allow_direct = false; - std::string proxy_list; - bool found_proxy = false; - - CFIndex proxy_array_count = CFArrayGetCount(proxy_array_ref.get()); - for (CFIndex i = 0; i < proxy_array_count; ++i) { - CFDictionaryRef proxy_dictionary = - (CFDictionaryRef)CFArrayGetValueAtIndex(proxy_array_ref.get(), i); - DCHECK(CFGetTypeID(proxy_dictionary) == CFDictionaryGetTypeID()); - - // The dictionary may have the following keys: - // - kCFProxyTypeKey : The type of the proxy. We're assuming that it's of - // the type we asked for (e.g. kCFProxyTypeHTTP for - // http://... ) if it's not kCFProxyTypeNone. - // - kCFProxyHostNameKey - // - kCFProxyPortNumberKey : The meat we're after. - // - kCFProxyUsernameKey - // - kCFProxyPasswordKey : Despite the existence of these keys in the - // documentation, they're never populated. Even if a - // username/password were to be set in the network - // proxy system preferences, we'd need to fetch it - // from the Keychain ourselves. CFProxy is such a - // tease. - // - kCFProxyAutoConfigurationURLKey : If the PAC file specifies another - // PAC file, I'm going home. - - CFStringRef proxy_type = - (CFStringRef)GetValueFromDictionary(proxy_dictionary, - kCFProxyTypeKey, - CFStringGetTypeID()); - if (CFEqual(proxy_type, kCFProxyTypeNone)) - allow_direct = true; - if (CFEqual(proxy_type, kCFProxyTypeNone) || - CFEqual(proxy_type, kCFProxyTypeSOCKS) || - CFEqual(proxy_type, kCFProxyTypeAutoConfigurationURL)) - continue; - - if (found_proxy) - proxy_list += ";"; - else - found_proxy = true; - - proxy_list += GetHostPortFromDictionary(proxy_dictionary, - kCFProxyHostNameKey, - kCFProxyPortNumberKey); - } - - if (found_proxy) - results->UseNamedProxy(proxy_list); - if (allow_direct) - results->UseDirect(); - - return OK; -} - -} // namespace net |