summaryrefslogtreecommitdiffstats
path: root/src/network/access
diff options
context:
space:
mode:
Diffstat (limited to 'src/network/access')
-rw-r--r--src/network/access/access.pri2
-rw-r--r--src/network/access/qnetworkaccessmanager.cpp70
-rw-r--r--src/network/access/qnetworkreplyhttpimpl.cpp118
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;