OLD | NEW |
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 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/mac_util.h" | 10 #include "base/mac_util.h" |
11 #include "base/scoped_cftyperef.h" | 11 #include "base/mac/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_info.h" | 15 #include "net/proxy/proxy_info.h" |
16 #include "net/proxy/proxy_server.h" | 16 #include "net/proxy/proxy_server.h" |
17 | 17 |
18 namespace { | 18 namespace { |
19 | 19 |
20 // Utility function to map a CFProxyType to a ProxyServer::Scheme. | 20 // Utility function to map a CFProxyType to a ProxyServer::Scheme. |
21 // If the type is unknown, returns ProxyServer::SCHEME_INVALID. | 21 // If the type is unknown, returns ProxyServer::SCHEME_INVALID. |
(...skipping 31 matching lines...) Loading... |
53 | 53 |
54 namespace net { | 54 namespace net { |
55 | 55 |
56 // 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 |
57 // inspired by http://developer.apple.com/samplecode/CFProxySupportTool/ | 57 // inspired by http://developer.apple.com/samplecode/CFProxySupportTool/ |
58 int ProxyResolverMac::GetProxyForURL(const GURL& query_url, | 58 int ProxyResolverMac::GetProxyForURL(const GURL& query_url, |
59 ProxyInfo* results, | 59 ProxyInfo* results, |
60 CompletionCallback* /*callback*/, | 60 CompletionCallback* /*callback*/, |
61 RequestHandle* /*request*/, | 61 RequestHandle* /*request*/, |
62 const BoundNetLog& net_log) { | 62 const BoundNetLog& net_log) { |
63 scoped_cftyperef<CFStringRef> query_ref( | 63 base::mac::ScopedCFTypeRef<CFStringRef> query_ref( |
64 base::SysUTF8ToCFStringRef(query_url.spec())); | 64 base::SysUTF8ToCFStringRef(query_url.spec())); |
65 scoped_cftyperef<CFURLRef> query_url_ref( | 65 base::mac::ScopedCFTypeRef<CFURLRef> query_url_ref( |
66 CFURLCreateWithString(kCFAllocatorDefault, | 66 CFURLCreateWithString(kCFAllocatorDefault, |
67 query_ref.get(), | 67 query_ref.get(), |
68 NULL)); | 68 NULL)); |
69 if (!query_url_ref.get()) | 69 if (!query_url_ref.get()) |
70 return ERR_FAILED; | 70 return ERR_FAILED; |
71 scoped_cftyperef<CFStringRef> pac_ref( | 71 base::mac::ScopedCFTypeRef<CFStringRef> pac_ref( |
72 base::SysUTF8ToCFStringRef( | 72 base::SysUTF8ToCFStringRef( |
73 script_data_->type() == ProxyResolverScriptData::TYPE_AUTO_DETECT ? | 73 script_data_->type() == ProxyResolverScriptData::TYPE_AUTO_DETECT ? |
74 std::string() : script_data_->url().spec())); | 74 std::string() : script_data_->url().spec())); |
75 scoped_cftyperef<CFURLRef> pac_url_ref( | 75 base::mac::ScopedCFTypeRef<CFURLRef> pac_url_ref( |
76 CFURLCreateWithString(kCFAllocatorDefault, | 76 CFURLCreateWithString(kCFAllocatorDefault, |
77 pac_ref.get(), | 77 pac_ref.get(), |
78 NULL)); | 78 NULL)); |
79 if (!pac_url_ref.get()) | 79 if (!pac_url_ref.get()) |
80 return ERR_FAILED; | 80 return ERR_FAILED; |
81 | 81 |
82 // Work around <rdar://problem/5530166>. This dummy call to | 82 // Work around <rdar://problem/5530166>. This dummy call to |
83 // CFNetworkCopyProxiesForURL initializes some state within CFNetwork that is | 83 // CFNetworkCopyProxiesForURL initializes some state within CFNetwork that is |
84 // required by CFNetworkExecuteProxyAutoConfigurationURL. | 84 // required by CFNetworkExecuteProxyAutoConfigurationURL. |
85 | 85 |
86 CFArrayRef dummy_result = CFNetworkCopyProxiesForURL(query_url_ref.get(), | 86 CFArrayRef dummy_result = CFNetworkCopyProxiesForURL(query_url_ref.get(), |
87 NULL); | 87 NULL); |
88 if (dummy_result) | 88 if (dummy_result) |
89 CFRelease(dummy_result); | 89 CFRelease(dummy_result); |
90 | 90 |
91 // We cheat here. We need to act as if we were synchronous, so we pump the | 91 // We cheat here. We need to act as if we were synchronous, so we pump the |
92 // runloop ourselves. Our caller moved us to a new thread anyway, so this is | 92 // runloop ourselves. Our caller moved us to a new thread anyway, so this is |
93 // OK to do. (BTW, CFNetworkExecuteProxyAutoConfigurationURL returns a | 93 // OK to do. (BTW, CFNetworkExecuteProxyAutoConfigurationURL returns a |
94 // runloop source we need to release despite its name.) | 94 // runloop source we need to release despite its name.) |
95 | 95 |
96 CFTypeRef result = NULL; | 96 CFTypeRef result = NULL; |
97 CFStreamClientContext context = { 0, &result, NULL, NULL, NULL }; | 97 CFStreamClientContext context = { 0, &result, NULL, NULL, NULL }; |
98 scoped_cftyperef<CFRunLoopSourceRef> runloop_source( | 98 base::mac::ScopedCFTypeRef<CFRunLoopSourceRef> runloop_source( |
99 CFNetworkExecuteProxyAutoConfigurationURL(pac_url_ref.get(), | 99 CFNetworkExecuteProxyAutoConfigurationURL(pac_url_ref.get(), |
100 query_url_ref.get(), | 100 query_url_ref.get(), |
101 ResultCallback, | 101 ResultCallback, |
102 &context)); | 102 &context)); |
103 if (!runloop_source) | 103 if (!runloop_source) |
104 return ERR_FAILED; | 104 return ERR_FAILED; |
105 | 105 |
106 const CFStringRef private_runloop_mode = | 106 const CFStringRef private_runloop_mode = |
107 CFSTR("org.chromium.ProxyResolverMac"); | 107 CFSTR("org.chromium.ProxyResolverMac"); |
108 | 108 |
109 CFRunLoopAddSource(CFRunLoopGetCurrent(), runloop_source.get(), | 109 CFRunLoopAddSource(CFRunLoopGetCurrent(), runloop_source.get(), |
110 private_runloop_mode); | 110 private_runloop_mode); |
111 CFRunLoopRunInMode(private_runloop_mode, DBL_MAX, false); | 111 CFRunLoopRunInMode(private_runloop_mode, DBL_MAX, false); |
112 CFRunLoopRemoveSource(CFRunLoopGetCurrent(), runloop_source.get(), | 112 CFRunLoopRemoveSource(CFRunLoopGetCurrent(), runloop_source.get(), |
113 private_runloop_mode); | 113 private_runloop_mode); |
114 DCHECK(result != NULL); | 114 DCHECK(result != NULL); |
115 | 115 |
116 if (CFGetTypeID(result) == CFErrorGetTypeID()) { | 116 if (CFGetTypeID(result) == CFErrorGetTypeID()) { |
117 // TODO(avi): do something better than this | 117 // TODO(avi): do something better than this |
118 CFRelease(result); | 118 CFRelease(result); |
119 return ERR_FAILED; | 119 return ERR_FAILED; |
120 } | 120 } |
121 DCHECK(CFGetTypeID(result) == CFArrayGetTypeID()); | 121 DCHECK(CFGetTypeID(result) == CFArrayGetTypeID()); |
122 scoped_cftyperef<CFArrayRef> proxy_array_ref((CFArrayRef)result); | 122 base::mac::ScopedCFTypeRef<CFArrayRef> proxy_array_ref((CFArrayRef)result); |
123 | 123 |
124 // This string will be an ordered list of <proxy-uri> entries, separated by | 124 // This string will be an ordered list of <proxy-uri> entries, separated by |
125 // semi-colons. It is the format that ProxyInfo::UseNamedProxy() expects. | 125 // semi-colons. It is the format that ProxyInfo::UseNamedProxy() expects. |
126 // proxy-uri = [<proxy-scheme>"://"]<proxy-host>":"<proxy-port> | 126 // proxy-uri = [<proxy-scheme>"://"]<proxy-host>":"<proxy-port> |
127 // (This also includes entries for direct connection, as "direct://"). | 127 // (This also includes entries for direct connection, as "direct://"). |
128 std::string proxy_uri_list; | 128 std::string proxy_uri_list; |
129 | 129 |
130 CFIndex proxy_array_count = CFArrayGetCount(proxy_array_ref.get()); | 130 CFIndex proxy_array_count = CFArrayGetCount(proxy_array_ref.get()); |
131 for (CFIndex i = 0; i < proxy_array_count; ++i) { | 131 for (CFIndex i = 0; i < proxy_array_count; ++i) { |
132 CFDictionaryRef proxy_dictionary = | 132 CFDictionaryRef proxy_dictionary = |
(...skipping 32 matching lines...) Loading... |
165 } | 165 } |
166 | 166 |
167 if (!proxy_uri_list.empty()) | 167 if (!proxy_uri_list.empty()) |
168 results->UseNamedProxy(proxy_uri_list); | 168 results->UseNamedProxy(proxy_uri_list); |
169 // Else do nothing (results is already guaranteed to be in the default state). | 169 // Else do nothing (results is already guaranteed to be in the default state). |
170 | 170 |
171 return OK; | 171 return OK; |
172 } | 172 } |
173 | 173 |
174 } // namespace net | 174 } // namespace net |
OLD | NEW |