summaryrefslogtreecommitdiffstats
path: root/src/network/kernel/qnetworkproxy_mac.cpp
diff options
context:
space:
mode:
authorGabriel de Dietrich <gabriel.dedietrich@qt.io>2016-06-29 16:23:40 -0700
committerGabriel de Dietrich <gabriel.dedietrich@qt.io>2016-08-31 14:33:16 +0000
commitb09e0636f8c781f5643d7582706bfcfc47106e7c (patch)
tree8a512dc500e8853a9eadb0ff538b787d748733c5 /src/network/kernel/qnetworkproxy_mac.cpp
parent982f17e961500128c9bc849cf5d3ff404b4b4d7c (diff)
QNetworkProxy: Remove calls to deprecated API on macOS
CFURLCreateDataAndPropertiesFromResource has been deprecated since 10.9. Instead of loading the PAC file contents, we call CFNetworkExecuteProxyAutoConfigurationURL. This function being asynchronous, we make sure we block until the CFProxyAutoConfigurationResultCallback has been invoked. Change-Id: I97e32d7f9b349e8e15fe1fdcb35b10e7aab39b3a Reviewed-by: Jake Petroules <jake.petroules@qt.io>
Diffstat (limited to 'src/network/kernel/qnetworkproxy_mac.cpp')
-rw-r--r--src/network/kernel/qnetworkproxy_mac.cpp80
1 files changed, 34 insertions, 46 deletions
diff --git a/src/network/kernel/qnetworkproxy_mac.cpp b/src/network/kernel/qnetworkproxy_mac.cpp
index 37126298c6..76a2d2df9f 100644
--- a/src/network/kernel/qnetworkproxy_mac.cpp
+++ b/src/network/kernel/qnetworkproxy_mac.cpp
@@ -180,31 +180,23 @@ static QNetworkProxy proxyFromDictionary(CFDictionaryRef dict)
return QNetworkProxy(proxyType, hostName, port, user, password);
}
-const char * cfurlErrorDescription(SInt32 errorCode)
+namespace {
+struct PACInfo {
+ QCFType<CFArrayRef> proxies;
+ QCFType<CFErrorRef> error;
+ bool done = false;
+};
+
+void proxyAutoConfigCallback(void *client, CFArrayRef proxylist, CFErrorRef error)
{
- switch (errorCode) {
- case kCFURLUnknownError:
- return "Unknown Error";
- case kCFURLUnknownSchemeError:
- return "Unknown Scheme";
- case kCFURLResourceNotFoundError:
- return "Resource Not Found";
- case kCFURLResourceAccessViolationError:
- return "Resource Access Violation";
- case kCFURLRemoteHostUnavailableError:
- return "Remote Host Unavailable";
- case kCFURLImproperArgumentsError:
- return "Improper Arguments";
- case kCFURLUnknownPropertyKeyError:
- return "Unknown Property Key";
- case kCFURLPropertyKeyUnavailableError:
- return "Property Key Unavailable";
- case kCFURLTimeoutError:
- return "Timeout";
- default:
- return "Really Unknown Error";
- }
+ PACInfo *info = reinterpret_cast<PACInfo *>(reinterpret_cast<CFStreamClientContext *>(client)->info);
+ info->done = true;
+ if (proxylist)
+ CFRetain(proxylist);
+ info->proxies = proxylist;
+ info->error = error;
}
+} // anon namespace
QList<QNetworkProxy> macQueryInternal(const QNetworkProxyQuery &query)
{
@@ -240,23 +232,6 @@ QList<QNetworkProxy> macQueryInternal(const QNetworkProxyQuery &query)
qWarning("Invalid PAC URL \"%s\"", qPrintable(QCFString::toQString(cfPacLocation)));
return result;
}
- SInt32 errorCode;
- if (!CFURLCreateDataAndPropertiesFromResource(kCFAllocatorDefault, pacUrl, &pacData, NULL, NULL, &errorCode)) {
- QString pacLocation = QCFString::toQString(cfPacLocation);
- qWarning("Unable to get the PAC script at \"%s\" (%s)", qPrintable(pacLocation), cfurlErrorDescription(errorCode));
- return result;
- }
- if (!pacData) {
- qWarning("\"%s\" returned an empty PAC script", qPrintable(QCFString::toQString(cfPacLocation)));
- return result;
- }
- QCFType<CFStringRef> pacScript = CFStringCreateFromExternalRepresentation(kCFAllocatorDefault, pacData, kCFStringEncodingISOLatin1);
- if (!pacScript) {
- // This should never happen, but the documentation says it may return NULL if there was a problem creating the object.
- QString pacLocation = QCFString::toQString(cfPacLocation);
- qWarning("Unable to read the PAC script at \"%s\"", qPrintable(pacLocation));
- return result;
- }
QByteArray encodedURL = query.url().toEncoded(); // converted to UTF-8
if (encodedURL.isEmpty()) {
@@ -268,18 +243,31 @@ QList<QNetworkProxy> macQueryInternal(const QNetworkProxyQuery &query)
return result; // URL creation problem, abort
}
- QCFType<CFErrorRef> pacError;
- QCFType<CFArrayRef> proxies = CFNetworkCopyProxiesForAutoConfigurationScript(pacScript, targetURL, &pacError);
- if (!proxies) {
+ CFStreamClientContext pacCtx;
+ pacCtx.version = 0;
+ PACInfo pacInfo;
+ pacCtx.info = &pacInfo;
+ pacCtx.retain = NULL;
+ pacCtx.release = NULL;
+ pacCtx.copyDescription = NULL;
+
+ static CFStringRef pacRunLoopMode = CFSTR("qtPACRunLoopMode");
+
+ QCFType<CFRunLoopSourceRef> pacRunLoopSource = CFNetworkExecuteProxyAutoConfigurationURL(pacUrl, targetURL, &proxyAutoConfigCallback, &pacCtx);
+ CFRunLoopAddSource(CFRunLoopGetCurrent(), pacRunLoopSource, pacRunLoopMode);
+ while (!pacInfo.done)
+ CFRunLoopRunInMode(pacRunLoopMode, 1000, /*returnAfterSourceHandled*/ true);
+
+ if (!pacInfo.proxies) {
QString pacLocation = QCFString::toQString(cfPacLocation);
- QCFType<CFStringRef> pacErrorDescription = CFErrorCopyDescription(pacError);
+ QCFType<CFStringRef> pacErrorDescription = CFErrorCopyDescription(pacInfo.error);
qWarning("Execution of PAC script at \"%s\" failed: %s", qPrintable(pacLocation), qPrintable(QCFString::toQString(pacErrorDescription)));
return result;
}
- CFIndex size = CFArrayGetCount(proxies);
+ CFIndex size = CFArrayGetCount(pacInfo.proxies);
for (CFIndex i = 0; i < size; ++i) {
- CFDictionaryRef proxy = (CFDictionaryRef)CFArrayGetValueAtIndex(proxies, i);
+ CFDictionaryRef proxy = (CFDictionaryRef)CFArrayGetValueAtIndex(pacInfo.proxies, i);
result << proxyFromDictionary(proxy);
}
return result;