diff options
Diffstat (limited to 'src/network/access')
-rw-r--r-- | src/network/access/access.pri | 2 | ||||
-rw-r--r-- | src/network/access/qnetworkaccessmanager.cpp | 70 | ||||
-rw-r--r-- | src/network/access/qnetworkreplyhttpimpl.cpp | 118 |
3 files changed, 132 insertions, 58 deletions
diff --git a/src/network/access/access.pri b/src/network/access/access.pri index e0a0253b6c..590a37bf15 100644 --- a/src/network/access/access.pri +++ b/src/network/access/access.pri @@ -65,3 +65,5 @@ SOURCES += \ access/qhttpmultipart.cpp include($$PWD/../../3rdparty/zlib_dependency.pri) + +mac:LIBS_PRIVATE += -framework Security diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp index 7f1f819436..8d68f439f1 100644 --- a/src/network/access/qnetworkaccessmanager.cpp +++ b/src/network/access/qnetworkaccessmanager.cpp @@ -82,6 +82,64 @@ Q_GLOBAL_STATIC(QNetworkAccessFtpBackendFactory, ftpBackend) Q_GLOBAL_STATIC(QNetworkAccessDebugPipeBackendFactory, debugpipeBackend) #endif +#ifdef Q_OS_MAC + +#include <CoreServices/CoreServices.h> +#include <SystemConfiguration/SystemConfiguration.h> +#include <Security/SecKeychain.h> + +bool getProxyAuth(const QString& proxyHostname, const QString &scheme, QString& username, QString& password) +{ + OSStatus err; + SecKeychainItemRef itemRef; + bool retValue = false; + SecProtocolType protocolType = kSecProtocolTypeAny; + if (scheme.compare(QLatin1String("ftp"),Qt::CaseInsensitive)==0) { + protocolType = kSecProtocolTypeFTP; + } else if (scheme.compare(QLatin1String("http"),Qt::CaseInsensitive)==0) { + protocolType = kSecProtocolTypeHTTP; + } else if (scheme.compare(QLatin1String("https"),Qt::CaseInsensitive)==0) { + protocolType = kSecProtocolTypeHTTPS; + } + QByteArray proxyHostnameUtf8(proxyHostname.toUtf8()); + err = SecKeychainFindInternetPassword(NULL, + proxyHostnameUtf8.length(), proxyHostnameUtf8.constData(), + 0,NULL, + 0, NULL, + 0, NULL, + 0, + protocolType, + kSecAuthenticationTypeAny, + 0, NULL, + &itemRef); + if (err == noErr) { + + SecKeychainAttribute attr; + SecKeychainAttributeList attrList; + UInt32 length; + void *outData; + + attr.tag = kSecAccountItemAttr; + attr.length = 0; + attr.data = NULL; + + attrList.count = 1; + attrList.attr = &attr; + + if (SecKeychainItemCopyContent(itemRef, NULL, &attrList, &length, &outData) == noErr) { + username = QString::fromUtf8((const char*)attr.data, attr.length); + password = QString::fromUtf8((const char*)outData, length); + SecKeychainItemFreeContent(&attrList,outData); + retValue = true; + } + CFRelease(itemRef); + } + return retValue; +} +#endif + + + static void ensureInitialized() { #ifndef QT_NO_FTP @@ -1128,6 +1186,18 @@ void QNetworkAccessManagerPrivate::authenticationRequired(QAuthenticator *authen return; } } +#ifdef Q_OS_MAC + //now we try to get the username and password from keychain + //if not successful signal will be emitted + QString username; + QString password; + if (getProxyAuth(proxy.hostName(),reply->request().url().scheme(),username,password)) { + authenticator->setUser(username); + authenticator->setPassword(password); + authenticationManager->cacheProxyCredentials(proxy, authenticator); + return; + } +#endif // if we emit a signal here in synchronous mode, the user might spin // an event loop, which might recurse and lead to problems diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp index fbddd98998..0ac3e26ada 100644 --- a/src/network/access/qnetworkreplyhttpimpl.cpp +++ b/src/network/access/qnetworkreplyhttpimpl.cpp @@ -513,69 +513,71 @@ bool QNetworkReplyHttpImplPrivate::loadFromCacheIfAllowed(QHttpNetworkRequest &h QDateTime currentDateTime = QDateTime::currentDateTime(); QDateTime expirationDate = metaData.expirationDate(); -#if 0 - /* - * age_value - * is the value of Age: header received by the cache with - * this response. - * date_value - * is the value of the origin server's Date: header - * request_time - * is the (local) time when the cache made the request - * that resulted in this cached response - * response_time - * is the (local) time when the cache received the - * response - * now - * is the current (local) time - */ - int age_value = 0; - it = cacheHeaders.findRawHeader("age"); - if (it != cacheHeaders.rawHeaders.constEnd()) - age_value = it->second.toInt(); - - QDateTime dateHeader; - int date_value = 0; - it = cacheHeaders.findRawHeader("date"); - if (it != cacheHeaders.rawHeaders.constEnd()) { - dateHeader = QNetworkHeadersPrivate::fromHttpDate(it->second); - date_value = dateHeader.toTime_t(); - } - - int now = currentDateTime.toUTC().toTime_t(); - int request_time = now; - int response_time = now; + bool response_is_fresh; + if (!expirationDate.isValid()) { + /* + * age_value + * is the value of Age: header received by the cache with + * this response. + * date_value + * is the value of the origin server's Date: header + * request_time + * is the (local) time when the cache made the request + * that resulted in this cached response + * response_time + * is the (local) time when the cache received the + * response + * now + * is the current (local) time + */ + int age_value = 0; + it = cacheHeaders.findRawHeader("age"); + if (it != cacheHeaders.rawHeaders.constEnd()) + age_value = it->second.toInt(); - // Algorithm from RFC 2616 section 13.2.3 - int apparent_age = qMax(0, response_time - date_value); - int corrected_received_age = qMax(apparent_age, age_value); - int response_delay = response_time - request_time; - int corrected_initial_age = corrected_received_age + response_delay; - int resident_time = now - response_time; - int current_age = corrected_initial_age + resident_time; + QDateTime dateHeader; + int date_value = 0; + it = cacheHeaders.findRawHeader("date"); + if (it != cacheHeaders.rawHeaders.constEnd()) { + dateHeader = QNetworkHeadersPrivate::fromHttpDate(it->second); + date_value = dateHeader.toTime_t(); + } - // RFC 2616 13.2.4 Expiration Calculations - if (!expirationDate.isValid()) { - if (lastModified.isValid()) { - int diff = currentDateTime.secsTo(lastModified); - expirationDate = lastModified; - expirationDate.addSecs(diff / 10); - if (httpRequest.headerField("Warning").isEmpty()) { - QDateTime dt; - dt.setTime_t(current_age); - if (dt.daysTo(currentDateTime) > 1) - httpRequest.setHeaderField("Warning", "113"); + int now = currentDateTime.toUTC().toTime_t(); + int request_time = now; + int response_time = now; + + // Algorithm from RFC 2616 section 13.2.3 + int apparent_age = qMax(0, response_time - date_value); + int corrected_received_age = qMax(apparent_age, age_value); + int response_delay = response_time - request_time; + int corrected_initial_age = corrected_received_age + response_delay; + int resident_time = now - response_time; + int current_age = corrected_initial_age + resident_time; + + // RFC 2616 13.2.4 Expiration Calculations + if (!expirationDate.isValid()) { + if (lastModified.isValid()) { + int diff = currentDateTime.secsTo(lastModified); + expirationDate = lastModified; + expirationDate.addSecs(diff / 10); + if (httpRequest.headerField("Warning").isEmpty()) { + QDateTime dt; + dt.setTime_t(current_age); + if (dt.daysTo(currentDateTime) > 1) + httpRequest.setHeaderField("Warning", "113"); + } } } - } - // the cache-saving code below sets the expirationDate with date+max_age - // if "max-age" is present, or to Expires otherwise - int freshness_lifetime = dateHeader.secsTo(expirationDate); - bool response_is_fresh = (freshness_lifetime > current_age); -#else - bool response_is_fresh = currentDateTime.secsTo(expirationDate) >= 0; -#endif + // the cache-saving code below sets the expirationDate with date+max_age + // if "max-age" is present, or to Expires otherwise + int freshness_lifetime = dateHeader.secsTo(expirationDate); + response_is_fresh = (freshness_lifetime > current_age); + } else { + // expiration date was calculated earlier (e.g. when storing object to the cache) + response_is_fresh = currentDateTime.secsTo(expirationDate) >= 0; + } if (!response_is_fresh) return false; |