summaryrefslogtreecommitdiffstats
path: root/src/network/kernel/qnetworkproxy_mac.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/network/kernel/qnetworkproxy_mac.cpp')
-rw-r--r--src/network/kernel/qnetworkproxy_mac.cpp143
1 files changed, 63 insertions, 80 deletions
diff --git a/src/network/kernel/qnetworkproxy_mac.cpp b/src/network/kernel/qnetworkproxy_mac.cpp
index 06a6fbac45..c13a472b90 100644
--- a/src/network/kernel/qnetworkproxy_mac.cpp
+++ b/src/network/kernel/qnetworkproxy_mac.cpp
@@ -104,7 +104,7 @@ static bool isHostExcluded(CFDictionaryRef dict, const QString &host)
CFIndex size = CFArrayGetCount(exclusionList);
for (CFIndex i = 0; i < size; ++i) {
CFStringRef cfentry = (CFStringRef)CFArrayGetValueAtIndex(exclusionList, i);
- QString entry = QCFString::toQString(cfentry);
+ QString entry = QString::fromCFString(cfentry);
if (isIpAddress && ipAddress.isInSubnet(QHostAddress::parseSubnet(entry))) {
return true; // excluded
@@ -133,7 +133,7 @@ static QNetworkProxy proxyFromDictionary(CFDictionaryRef dict, QNetworkProxy::Pr
&& (protoPort = (CFNumberRef)CFDictionaryGetValue(dict, portKey))) {
int enabled;
if (CFNumberGetValue(protoEnabled, kCFNumberIntType, &enabled) && enabled) {
- QString host = QCFString::toQString(protoHost);
+ QString host = QString::fromCFString(protoHost);
int port;
CFNumberGetValue(protoPort, kCFNumberIntType, &port);
@@ -168,9 +168,9 @@ static QNetworkProxy proxyFromDictionary(CFDictionaryRef dict)
proxyType = QNetworkProxy::Socks5Proxy;
}
- hostName = QCFString::toQString((CFStringRef)CFDictionaryGetValue(dict, kCFProxyHostNameKey));
- user = QCFString::toQString((CFStringRef)CFDictionaryGetValue(dict, kCFProxyUsernameKey));
- password = QCFString::toQString((CFStringRef)CFDictionaryGetValue(dict, kCFProxyPasswordKey));
+ hostName = QString::fromCFString((CFStringRef)CFDictionaryGetValue(dict, kCFProxyHostNameKey));
+ user = QString::fromCFString((CFStringRef)CFDictionaryGetValue(dict, kCFProxyUsernameKey));
+ password = QString::fromCFString((CFStringRef)CFDictionaryGetValue(dict, kCFProxyPasswordKey));
CFNumberRef portNumber = (CFNumberRef)CFDictionaryGetValue(dict, kCFProxyPortNumberKey);
if (portNumber) {
@@ -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)
{
@@ -234,60 +226,51 @@ QList<QNetworkProxy> macQueryInternal(const QNetworkProxyQuery &query)
QCFType<CFStringRef> cfPacLocation = CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, pacLocationSetting, NULL, NULL,
kCFStringEncodingUTF8);
- if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) {
- QCFType<CFDataRef> pacData;
- QCFType<CFURLRef> pacUrl = CFURLCreateWithString(kCFAllocatorDefault, cfPacLocation, NULL);
- if (!pacUrl) {
- 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()) {
- return result; // Invalid URL, abort
- }
-
- QCFType<CFURLRef> targetURL = CFURLCreateWithBytes(kCFAllocatorDefault, (UInt8*)encodedURL.data(), encodedURL.size(), kCFStringEncodingUTF8, NULL);
- if (!targetURL) {
- return result; // URL creation problem, abort
- }
-
- QCFType<CFErrorRef> pacError;
- QCFType<CFArrayRef> proxies = CFNetworkCopyProxiesForAutoConfigurationScript(pacScript, targetURL, &pacError);
- if (!proxies) {
- QString pacLocation = QCFString::toQString(cfPacLocation);
- QCFType<CFStringRef> pacErrorDescription = CFErrorCopyDescription(pacError);
- qWarning("Execution of PAC script at \"%s\" failed: %s", qPrintable(pacLocation), qPrintable(QCFString::toQString(pacErrorDescription)));
- return result;
- }
-
- CFIndex size = CFArrayGetCount(proxies);
- for (CFIndex i = 0; i < size; ++i) {
- CFDictionaryRef proxy = (CFDictionaryRef)CFArrayGetValueAtIndex(proxies, i);
- result << proxyFromDictionary(proxy);
- }
+ QCFType<CFDataRef> pacData;
+ QCFType<CFURLRef> pacUrl = CFURLCreateWithString(kCFAllocatorDefault, cfPacLocation, NULL);
+ if (!pacUrl) {
+ qWarning("Invalid PAC URL \"%s\"", qPrintable(QString::fromCFString(cfPacLocation)));
return result;
- } else {
- QString pacLocation = QCFString::toQString(cfPacLocation);
- qWarning("Mac system proxy: PAC script at \"%s\" not handled", qPrintable(pacLocation));
}
+
+ QByteArray encodedURL = query.url().toEncoded(); // converted to UTF-8
+ if (encodedURL.isEmpty()) {
+ return result; // Invalid URL, abort
+ }
+
+ QCFType<CFURLRef> targetURL = CFURLCreateWithBytes(kCFAllocatorDefault, (UInt8*)encodedURL.data(), encodedURL.size(), kCFStringEncodingUTF8, NULL);
+ if (!targetURL) {
+ return result; // URL creation problem, abort
+ }
+
+ 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 = QString::fromCFString(cfPacLocation);
+ QCFType<CFStringRef> pacErrorDescription = CFErrorCopyDescription(pacInfo.error);
+ qWarning("Execution of PAC script at \"%s\" failed: %s", qPrintable(pacLocation), qPrintable(QString::fromCFString(pacErrorDescription)));
+ return result;
+ }
+
+ CFIndex size = CFArrayGetCount(pacInfo.proxies);
+ for (CFIndex i = 0; i < size; ++i) {
+ CFDictionaryRef proxy = (CFDictionaryRef)CFArrayGetValueAtIndex(pacInfo.proxies, i);
+ result << proxyFromDictionary(proxy);
+ }
+ return result;
}
}