diff options
author | Lars Knoll <lars.knoll@nokia.com> | 2012-04-16 12:04:34 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@nokia.com> | 2012-04-16 12:04:34 +0200 |
commit | 9bd032355163d92cda5e7e59ecd21214b131f187 (patch) | |
tree | 002fa12558505683143c7eb08949a3d225bf0712 /src/network/kernel/qnetworkproxy_mac.cpp | |
parent | d037d25c3d5236623371cf051aaf6a9e59792ba7 (diff) | |
parent | 41673c45dde2eb95ee21dd918235218399f2be2c (diff) |
Merge remote-tracking branch 'origin/master' into api_changes
Conflicts:
configure
src/corelib/io/qurl.cpp
src/gui/kernel/qwindow.cpp
src/tools/moc/generator.cpp
src/widgets/kernel/qwidget_qpa.cpp
src/widgets/styles/qstyle.h
src/widgets/widgets/qtabbar.cpp
tests/auto/corelib/codecs/utf8/tst_utf8.cpp
Change-Id: Ia457228d6f684ec8184e13e8fcc9d25857b1751e
Diffstat (limited to 'src/network/kernel/qnetworkproxy_mac.cpp')
-rw-r--r-- | src/network/kernel/qnetworkproxy_mac.cpp | 116 |
1 files changed, 112 insertions, 4 deletions
diff --git a/src/network/kernel/qnetworkproxy_mac.cpp b/src/network/kernel/qnetworkproxy_mac.cpp index d25917ee47..3e62c0f867 100644 --- a/src/network/kernel/qnetworkproxy_mac.cpp +++ b/src/network/kernel/qnetworkproxy_mac.cpp @@ -48,6 +48,7 @@ #include <QtCore/QRegExp> #include <QtCore/QStringList> +#include <QtCore/QUrl> #include <QtCore/qendian.h> #include <QtCore/qstringlist.h> #include "private/qcore_mac_p.h" @@ -146,6 +147,66 @@ static QNetworkProxy proxyFromDictionary(CFDictionaryRef dict, QNetworkProxy::Pr return QNetworkProxy(); } + +static QNetworkProxy proxyFromDictionary(CFDictionaryRef dict) +{ + QNetworkProxy::ProxyType proxyType = QNetworkProxy::DefaultProxy; + QString hostName; + quint16 port = 0; + QString user; + QString password; + + CFStringRef cfProxyType = (CFStringRef)CFDictionaryGetValue(dict, kCFProxyTypeKey); + if (CFStringCompare(cfProxyType, kCFProxyTypeNone, 0) == kCFCompareEqualTo) { + proxyType = QNetworkProxy::NoProxy; + } else if (CFStringCompare(cfProxyType, kCFProxyTypeFTP, 0) == kCFCompareEqualTo) { + proxyType = QNetworkProxy::FtpCachingProxy; + } else if (CFStringCompare(cfProxyType, kCFProxyTypeHTTP, 0) == kCFCompareEqualTo) { + proxyType = QNetworkProxy::HttpProxy; + } else if (CFStringCompare(cfProxyType, kCFProxyTypeHTTPS, 0) == kCFCompareEqualTo) { + proxyType = QNetworkProxy::HttpProxy; + } else if (CFStringCompare(cfProxyType, kCFProxyTypeSOCKS, 0) == kCFCompareEqualTo) { + proxyType = QNetworkProxy::Socks5Proxy; + } + + hostName = QCFString::toQString((CFStringRef)CFDictionaryGetValue(dict, kCFProxyHostNameKey)); + user = QCFString::toQString((CFStringRef)CFDictionaryGetValue(dict, kCFProxyUsernameKey)); + password = QCFString::toQString((CFStringRef)CFDictionaryGetValue(dict, kCFProxyPasswordKey)); + + CFNumberRef portNumber = (CFNumberRef)CFDictionaryGetValue(dict, kCFProxyPortNumberKey); + if (portNumber) { + CFNumberGetValue(portNumber, kCFNumberSInt16Type, &port); + } + + return QNetworkProxy(proxyType, hostName, port, user, password); +} + +const char * cfurlErrorDescription(SInt32 errorCode) +{ + 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"; + } +} + QList<QNetworkProxy> macQueryInternal(const QNetworkProxyQuery &query) { QList<QNetworkProxy> result; @@ -168,11 +229,58 @@ QList<QNetworkProxy> macQueryInternal(const QNetworkProxyQuery &query) int enabled; if (CFNumberGetValue(pacEnabled, kCFNumberIntType, &enabled) && enabled) { // PAC is enabled - CFStringRef pacUrl = - (CFStringRef)CFDictionaryGetValue(dict, kSCPropNetProxiesProxyAutoConfigURLString); - QString url = QCFString::toQString(pacUrl); + CFStringRef cfPacLocation = (CFStringRef)CFDictionaryGetValue(dict, kSCPropNetProxiesProxyAutoConfigURLString); + +#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) + if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) { + QCFType<CFDataRef> pacData; + QCFType<CFURLRef> pacUrl = CFURLCreateWithString(kCFAllocatorDefault, cfPacLocation, NULL); + 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; + } - // ### TODO: Use PAC somehow + 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); + } + return result; + } else +#endif + { + QString pacLocation = QCFString::toQString(cfPacLocation); + qWarning("Mac system proxy: PAC script at \"%s\" not handled", qPrintable(pacLocation)); + } } } |