Modified: trunk/Source/WebCore/ChangeLog (107965 => 107966)
--- trunk/Source/WebCore/ChangeLog 2012-02-16 20:16:46 UTC (rev 107965)
+++ trunk/Source/WebCore/ChangeLog 2012-02-16 20:19:57 UTC (rev 107966)
@@ -1,3 +1,21 @@
+2012-02-15 Mark Rowe <[email protected]>
+
+ NPN_GetValueForURL / NPNURLVProxy returns DIRECT when proxy configured via PAC
+ <http://webkit.org/b/78766> / <rdar://problem/10729283>
+
+ Reviewed by Anders Carlsson.
+
+ * platform/network/cf/ProxyServerCFNet.cpp:
+ (WebCore::proxyAutoConfigurationResultCallback): Stop the runloop, and then process
+ the results that we received.
+ (WebCore::processProxyServers): Processing of array of proxy configuration information
+ moved from addProxyServersForURL. Handling of proxy auto-configuration URLs is now handled
+ by calling CFNetworkExecuteProxyAutoConfigurationURL and waiting synchronously on the result
+ callback. Doing this synchronously is not great, but it's the best we can do without a lot
+ of restructuring of the code that calls this. We arbitrarily time out the execution after five
+ seconds to avoid permanently hanging.
+ (WebCore::addProxyServersForURL): Call in to our helper function.
+
2012-02-16 Abhishek Arya <[email protected]>
Fix clone() function to handle descendant classes of RenderBlock.
Modified: trunk/Source/WebCore/platform/network/cf/ProxyServerCFNet.cpp (107965 => 107966)
--- trunk/Source/WebCore/platform/network/cf/ProxyServerCFNet.cpp 2012-02-16 20:16:46 UTC (rev 107965)
+++ trunk/Source/WebCore/platform/network/cf/ProxyServerCFNet.cpp 2012-02-16 20:19:57 UTC (rev 107966)
@@ -27,7 +27,9 @@
#include "ProxyServer.h"
#include "KURL.h"
+#include "Logging.h"
#include <wtf/RetainPtr.h>
+#include <wtf/text/CString.h>
#if PLATFORM(WIN)
#include <CFNetwork/CFNetwork.h>
@@ -36,33 +38,69 @@
namespace WebCore {
#ifndef BUILDING_ON_LEOPARD
-static void addProxyServersForURL(Vector<ProxyServer>& proxyServers, const KURL& url)
+
+static void processProxyServers(Vector<ProxyServer>& proxyServers, CFArrayRef proxies, CFURLRef url);
+
+static void proxyAutoConfigurationResultCallback(void *context, CFArrayRef proxies, CFErrorRef error)
{
- RetainPtr<CFDictionaryRef> proxySettings(AdoptCF, CFNetworkCopySystemProxySettings());
- if (!proxySettings)
- return;
+ // We only expect a single result callback per invocation. Stop our runloop to unblock our caller.
+ CFRunLoopStop(CFRunLoopGetCurrent());
- RetainPtr<CFURLRef> cfURL(AdoptCF, url.createCFURL());
- RetainPtr<CFArrayRef> proxiesForURL(AdoptCF, CFNetworkCopyProxiesForURL(cfURL.get(), proxySettings.get()));
- if (!proxiesForURL)
+ Vector<ProxyServer>* proxyServers = (Vector<ProxyServer>*)context;
+ if (!proxies) {
+ ASSERT(error);
+ RetainPtr<CFStringRef> errorDescriptionCF(AdoptCF, CFErrorCopyDescription(error));
+ String errorDescription(errorDescriptionCF.get());
+ LOG(Network, "Failed to process proxy auto-configuration file with error: %s", errorDescription.utf8().data());
return;
+ }
- CFIndex numProxies = CFArrayGetCount(proxiesForURL.get());
+ processProxyServers(*proxyServers, proxies, 0);
+}
+
+static void processProxyServers(Vector<ProxyServer>& proxyServers, CFArrayRef proxies, CFURLRef url)
+{
+ CFIndex numProxies = CFArrayGetCount(proxies);
for (CFIndex i = 0; i < numProxies; ++i) {
- CFDictionaryRef proxyDictionary = static_cast<CFDictionaryRef>(CFArrayGetValueAtIndex(proxiesForURL.get(), i));
+ CFDictionaryRef proxyDictionary = static_cast<CFDictionaryRef>(CFArrayGetValueAtIndex(proxies, i));
ProxyServer::Type type = ProxyServer::Direct;
CFStringRef typeString = static_cast<CFStringRef>(CFDictionaryGetValue(proxyDictionary, kCFProxyTypeKey));
+
+ if (!url) {
+ // If we have no URL then we're processing an auto-configuration response.
+ // It isn't sensible to receive another auto-configured proxy in such a response.
+ ASSERT(!CFEqual(typeString, kCFProxyTypeAutoConfigurationURL));
+ }
+
if (CFEqual(typeString, kCFProxyTypeAutoConfigurationURL)) {
- // FIXME: Handle PAC URLs.
+ if (!url)
+ continue;
+
+ // FIXME: We should restructure to allow this to happen asynchronously.
+ CFURLRef scriptURL = static_cast<CFURLRef>(CFDictionaryGetValue(proxyDictionary, kCFProxyAutoConfigurationURLKey));
+ if (!scriptURL || CFGetTypeID(scriptURL) != CFURLGetTypeID())
+ continue;
+
+ CFStreamClientContext context = { 0, (void*)&proxyServers, 0, 0, 0 };
+ RetainPtr<CFRunLoopSourceRef> runLoopSource(AdoptCF, CFNetworkExecuteProxyAutoConfigurationURL(scriptURL, url, proxyAutoConfigurationResultCallback, &context));
+
+ CFStringRef privateRunLoopMode = CFSTR("com.apple.WebKit.ProxyAutoConfiguration");
+ CFTimeInterval timeout = 5;
+ CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource.get(), privateRunLoopMode);
+ CFRunLoopRunInMode(privateRunLoopMode, timeout, 0);
+ CFRunLoopRemoveSource(CFRunLoopGetCurrent(), runLoopSource.get(), privateRunLoopMode);
+ CFRunLoopSourceInvalidate(runLoopSource.get());
+
+ // The proxyAutoConfigurationResultCallback has added any relevant ProxyServers to proxyServers.
continue;
- }
-
+ }
+
if (CFEqual(typeString, kCFProxyTypeNone)) {
proxyServers.append(ProxyServer(ProxyServer::Direct, String(), -1));
continue;
}
-
+
if (CFEqual(typeString, kCFProxyTypeHTTP))
type = ProxyServer::HTTP;
else if (CFEqual(typeString, kCFProxyTypeHTTPS))
@@ -83,6 +121,20 @@
}
}
+static void addProxyServersForURL(Vector<ProxyServer>& proxyServers, const KURL& url)
+{
+ RetainPtr<CFDictionaryRef> proxySettings(AdoptCF, CFNetworkCopySystemProxySettings());
+ if (!proxySettings)
+ return;
+
+ RetainPtr<CFURLRef> cfURL(AdoptCF, url.createCFURL());
+ RetainPtr<CFArrayRef> proxiesForURL(AdoptCF, CFNetworkCopyProxiesForURL(cfURL.get(), proxySettings.get()));
+ if (!proxiesForURL)
+ return;
+
+ processProxyServers(proxyServers, proxiesForURL.get(), cfURL.get());
+}
+
Vector<ProxyServer> proxyServersForURL(const KURL& url, const NetworkingContext*)
{
Vector<ProxyServer> proxyServers;