diff options
Diffstat (limited to 'src/network/access')
-rw-r--r-- | src/network/access/qhttp.cpp | 3 | ||||
-rw-r--r-- | src/network/access/qhttpnetworkconnection.cpp | 31 | ||||
-rw-r--r-- | src/network/access/qhttpnetworkconnection_p.h | 6 | ||||
-rw-r--r-- | src/network/access/qhttpnetworkreply.cpp | 7 | ||||
-rw-r--r-- | src/network/access/qhttpnetworkreply_p.h | 1 | ||||
-rw-r--r-- | src/network/access/qnetworkaccessbackend.cpp | 6 | ||||
-rw-r--r-- | src/network/access/qnetworkaccessbackend_p.h | 1 | ||||
-rw-r--r-- | src/network/access/qnetworkaccesscachebackend.cpp | 14 | ||||
-rw-r--r-- | src/network/access/qnetworkaccessdebugpipebackend.cpp | 1 | ||||
-rw-r--r-- | src/network/access/qnetworkaccesshttpbackend.cpp | 18 | ||||
-rw-r--r-- | src/network/access/qnetworkaccesshttpbackend_p.h | 4 | ||||
-rw-r--r-- | src/network/access/qnetworkreply.cpp | 34 | ||||
-rw-r--r-- | src/network/access/qnetworkreply.h | 1 | ||||
-rw-r--r-- | src/network/access/qnetworkreplyimpl.cpp | 16 | ||||
-rw-r--r-- | src/network/access/qnetworkreplyimpl_p.h | 1 |
15 files changed, 133 insertions, 11 deletions
diff --git a/src/network/access/qhttp.cpp b/src/network/access/qhttp.cpp index 790b48a..faa2398 100644 --- a/src/network/access/qhttp.cpp +++ b/src/network/access/qhttp.cpp @@ -513,6 +513,7 @@ public: /*! \class QHttpHeader + \obsolete \brief The QHttpHeader class contains header information for HTTP. \ingroup io @@ -1007,6 +1008,7 @@ public: /*! \class QHttpResponseHeader + \obsolete \brief The QHttpResponseHeader class contains response header information for HTTP. \ingroup io @@ -1211,6 +1213,7 @@ public: /*! \class QHttpRequestHeader + \obsolete \brief The QHttpRequestHeader class contains request header information for HTTP. \ingroup io diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index afcdf17..c824fac 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -261,7 +261,12 @@ void QHttpNetworkConnectionPrivate::prepareRequest(HttpMessagePair &messagePair) #ifndef QT_NO_NETWORKPROXY } #endif - // set the gzip header + + // If the request had a accept-encoding set, we better not mess + // with it. If it was not set, we announce that we understand gzip + // and remember this fact in request.d->autoDecompress so that + // we can later decompress the HTTP reply if it has such an + // encoding. value = request.headerField("accept-encoding"); if (value.isEmpty()) { #ifndef QT_NO_COMPRESS @@ -335,8 +340,9 @@ bool QHttpNetworkConnectionPrivate::ensureConnection(QAbstractSocket *socket) #ifndef QT_NO_OPENSSL QSslSocket *sslSocket = qobject_cast<QSslSocket*>(socket); sslSocket->connectToHostEncrypted(connectHost, connectPort); - if (channels[index].ignoreSSLErrors) + if (channels[index].ignoreAllSslErrors) sslSocket->ignoreSslErrors(); + sslSocket->ignoreSslErrors(channels[index].ignoreSslErrorsList); #else emitReplyError(socket, channels[index].reply, QNetworkReply::ProtocolUnknownError); #endif @@ -1443,15 +1449,32 @@ void QHttpNetworkConnection::ignoreSslErrors(int channel) if (channel == -1) { // ignore for all channels for (int i = 0; i < d->channelCount; ++i) { static_cast<QSslSocket *>(d->channels[i].socket)->ignoreSslErrors(); - d->channels[i].ignoreSSLErrors = true; + d->channels[i].ignoreAllSslErrors = true; } } else { static_cast<QSslSocket *>(d->channels[channel].socket)->ignoreSslErrors(); - d->channels[channel].ignoreSSLErrors = true; + d->channels[channel].ignoreAllSslErrors = true; } } +void QHttpNetworkConnection::ignoreSslErrors(const QList<QSslError> &errors, int channel) +{ + Q_D(QHttpNetworkConnection); + if (!d->encrypt) + return; + + if (channel == -1) { // ignore for all channels + for (int i = 0; i < d->channelCount; ++i) { + static_cast<QSslSocket *>(d->channels[i].socket)->ignoreSslErrors(errors); + d->channels[i].ignoreSslErrorsList = errors; + } + + } else { + static_cast<QSslSocket *>(d->channels[channel].socket)->ignoreSslErrors(errors); + d->channels[channel].ignoreSslErrorsList = errors; + } +} #endif //QT_NO_OPENSSL diff --git a/src/network/access/qhttpnetworkconnection_p.h b/src/network/access/qhttpnetworkconnection_p.h index 842a2f4..52a73a7 100644 --- a/src/network/access/qhttpnetworkconnection_p.h +++ b/src/network/access/qhttpnetworkconnection_p.h @@ -117,6 +117,7 @@ public: #ifndef QT_NO_OPENSSL void setSslConfiguration(const QSslConfiguration &config); void ignoreSslErrors(int channel = -1); + void ignoreSslErrors(const QList<QSslError> &errors, int channel = -1); Q_SIGNALS: void sslErrors(const QList<QSslError> &errors); @@ -241,13 +242,14 @@ public: QAuthenticator authenticator; QAuthenticator proxyAuthenticator; #ifndef QT_NO_OPENSSL - bool ignoreSSLErrors; + bool ignoreAllSslErrors; + QList<QSslError> ignoreSslErrorsList; #endif Channel() : socket(0), state(IdleState), reply(0), written(0), bytesTotal(0), resendCurrent(false), lastStatus(0), pendingEncrypt(false), reconnectAttempts(2), authMehtod(QAuthenticatorPrivate::None), proxyAuthMehtod(QAuthenticatorPrivate::None) #ifndef QT_NO_OPENSSL - , ignoreSSLErrors(false) + , ignoreAllSslErrors(false) #endif {} }; diff --git a/src/network/access/qhttpnetworkreply.cpp b/src/network/access/qhttpnetworkreply.cpp index 2fe0d78..a623999 100644 --- a/src/network/access/qhttpnetworkreply.cpp +++ b/src/network/access/qhttpnetworkreply.cpp @@ -712,6 +712,13 @@ void QHttpNetworkReply::ignoreSslErrors() d->connection->ignoreSslErrors(); } +void QHttpNetworkReply::ignoreSslErrors(const QList<QSslError> &errors) +{ + Q_D(QHttpNetworkReply); + if (d->connection) + d->connection->ignoreSslErrors(errors); +} + #endif //QT_NO_OPENSSL diff --git a/src/network/access/qhttpnetworkreply_p.h b/src/network/access/qhttpnetworkreply_p.h index fbbee12..575e824 100644 --- a/src/network/access/qhttpnetworkreply_p.h +++ b/src/network/access/qhttpnetworkreply_p.h @@ -131,6 +131,7 @@ public: QSslConfiguration sslConfiguration() const; void setSslConfiguration(const QSslConfiguration &config); void ignoreSslErrors(); + void ignoreSslErrors(const QList<QSslError> &errors); Q_SIGNALS: void sslErrors(const QList<QSslError> &errors); diff --git a/src/network/access/qnetworkaccessbackend.cpp b/src/network/access/qnetworkaccessbackend.cpp index 9e17b54..caaa38e 100644 --- a/src/network/access/qnetworkaccessbackend.cpp +++ b/src/network/access/qnetworkaccessbackend.cpp @@ -165,6 +165,12 @@ void QNetworkAccessBackend::ignoreSslErrors() // do nothing } +void QNetworkAccessBackend::ignoreSslErrors(const QList<QSslError> &errors) +{ + Q_UNUSED(errors); + // do nothing +} + void QNetworkAccessBackend::fetchSslConfiguration(QSslConfiguration &) const { // do nothing diff --git a/src/network/access/qnetworkaccessbackend_p.h b/src/network/access/qnetworkaccessbackend_p.h index 553b795..27da5bc 100644 --- a/src/network/access/qnetworkaccessbackend_p.h +++ b/src/network/access/qnetworkaccessbackend_p.h @@ -118,6 +118,7 @@ public: virtual void downstreamReadyWrite(); virtual void copyFinished(QIODevice *); virtual void ignoreSslErrors(); + virtual void ignoreSslErrors(const QList<QSslError> &errors); virtual void fetchSslConfiguration(QSslConfiguration &configuration) const; virtual void setSslConfiguration(const QSslConfiguration &configuration); diff --git a/src/network/access/qnetworkaccesscachebackend.cpp b/src/network/access/qnetworkaccesscachebackend.cpp index f46a50a..8571ba3 100644 --- a/src/network/access/qnetworkaccesscachebackend.cpp +++ b/src/network/access/qnetworkaccesscachebackend.cpp @@ -86,6 +86,20 @@ bool QNetworkAccessCacheBackend::sendCacheContents() setAttribute(QNetworkRequest::HttpReasonPhraseAttribute, attributes.value(QNetworkRequest::HttpReasonPhraseAttribute)); setAttribute(QNetworkRequest::SourceIsFromCacheAttribute, true); + // set the raw headers + QNetworkCacheMetaData::RawHeaderList rawHeaders = item.rawHeaders(); + QNetworkCacheMetaData::RawHeaderList::ConstIterator it = rawHeaders.constBegin(), + end = rawHeaders.constEnd(); + for ( ; it != end; ++it) + setRawHeader(it->first, it->second); + + // handle a possible redirect + QVariant redirectionTarget = attributes.value(QNetworkRequest::RedirectionTargetAttribute); + if (redirectionTarget.isValid()) { + setAttribute(QNetworkRequest::RedirectionTargetAttribute, redirectionTarget); + redirectionRequested(redirectionTarget.toUrl()); + } + // signal we're open metaDataChanged(); diff --git a/src/network/access/qnetworkaccessdebugpipebackend.cpp b/src/network/access/qnetworkaccessdebugpipebackend.cpp index 2b3c128..394e196 100644 --- a/src/network/access/qnetworkaccessdebugpipebackend.cpp +++ b/src/network/access/qnetworkaccessdebugpipebackend.cpp @@ -280,6 +280,7 @@ void QNetworkAccessDebugPipeBackend::socketConnected() bool QNetworkAccessDebugPipeBackend::waitForDownstreamReadyRead(int ms) { + Q_UNUSED(ms); qCritical("QNetworkAccess: Debug pipe backend does not support waitForReadyRead()"); return false; } diff --git a/src/network/access/qnetworkaccesshttpbackend.cpp b/src/network/access/qnetworkaccesshttpbackend.cpp index 9c36026..5c85735 100644 --- a/src/network/access/qnetworkaccesshttpbackend.cpp +++ b/src/network/access/qnetworkaccesshttpbackend.cpp @@ -294,7 +294,7 @@ public: QNetworkAccessHttpBackend::QNetworkAccessHttpBackend() : QNetworkAccessBackend(), httpReply(0), http(0), uploadDevice(0) #ifndef QT_NO_OPENSSL - , pendingSslConfiguration(0), pendingIgnoreSslErrors(false) + , pendingSslConfiguration(0), pendingIgnoreAllSslErrors(false) #endif { } @@ -521,8 +521,9 @@ void QNetworkAccessHttpBackend::postRequest() #ifndef QT_NO_OPENSSL if (pendingSslConfiguration) httpReply->setSslConfiguration(*pendingSslConfiguration); - if (pendingIgnoreSslErrors) + if (pendingIgnoreAllSslErrors) httpReply->ignoreSslErrors(); + httpReply->ignoreSslErrors(pendingIgnoreSslErrorsList); #endif connect(httpReply, SIGNAL(readyRead()), SLOT(replyReadyRead())); @@ -883,7 +884,18 @@ void QNetworkAccessHttpBackend::ignoreSslErrors() if (httpReply) httpReply->ignoreSslErrors(); else - pendingIgnoreSslErrors = true; + pendingIgnoreAllSslErrors = true; +} + +void QNetworkAccessHttpBackend::ignoreSslErrors(const QList<QSslError> &errors) +{ + if (httpReply) { + httpReply->ignoreSslErrors(errors); + } else { + // the pending list is set if QNetworkReply::ignoreSslErrors(const QList<QSslError> &errors) + // is called before QNetworkAccessManager::get() (or post(), etc.) + pendingIgnoreSslErrorsList = errors; + } } void QNetworkAccessHttpBackend::fetchSslConfiguration(QSslConfiguration &config) const diff --git a/src/network/access/qnetworkaccesshttpbackend_p.h b/src/network/access/qnetworkaccesshttpbackend_p.h index dec69d0..968f4a5 100644 --- a/src/network/access/qnetworkaccesshttpbackend_p.h +++ b/src/network/access/qnetworkaccesshttpbackend_p.h @@ -85,6 +85,7 @@ public: virtual void copyFinished(QIODevice *); #ifndef QT_NO_OPENSSL virtual void ignoreSslErrors(); + virtual void ignoreSslErrors(const QList<QSslError> &errors); virtual void fetchSslConfiguration(QSslConfiguration &configuration) const; virtual void setSslConfiguration(const QSslConfiguration &configuration); @@ -112,7 +113,8 @@ private: #ifndef QT_NO_OPENSSL QSslConfiguration *pendingSslConfiguration; - bool pendingIgnoreSslErrors; + bool pendingIgnoreAllSslErrors; + QList<QSslError> pendingIgnoreSslErrorsList; #endif void disconnectFromHttp(); diff --git a/src/network/access/qnetworkreply.cpp b/src/network/access/qnetworkreply.cpp index e807d29..3abf927 100644 --- a/src/network/access/qnetworkreply.cpp +++ b/src/network/access/qnetworkreply.cpp @@ -584,6 +584,38 @@ void QNetworkReply::setSslConfiguration(const QSslConfiguration &config) qt_metacall(QMetaObject::InvokeMetaMethod, id, arr); } } + +/*! + \overload + \since 4.6 + + If this function is called, the SSL errors given in \a errors + will be ignored. + + Note that you can set the expected certificate in the SSL error: + If, for instance, you want to issue a request to a server that uses + a self-signed certificate, consider the following snippet: + + \snippet doc/src/snippets/code/src_network_access_qnetworkreply.cpp 0 + + Multiple calls to this function will replace the list of errors that + were passed in previous calls. + You can clear the list of errors you want to ignore by calling this + function with an empty list. + + \sa sslConfiguration(), sslErrors(), QSslSocket::ignoreSslErrors() +*/ +void QNetworkReply::ignoreSslErrors(const QList<QSslError> &errors) +{ + // do this cryptic trick, because we could not add a virtual method to this class later on + // since that breaks binary compatibility + int id = metaObject()->indexOfMethod("ignoreSslErrorsImplementation(QList<QSslError>)"); + if (id != -1) { + QList<QSslError> copy(errors); + void *arr[] = { 0, © }; + qt_metacall(QMetaObject::InvokeMetaMethod, id, arr); + } +} #endif /*! @@ -598,7 +630,7 @@ void QNetworkReply::setSslConfiguration(const QSslConfiguration &config) sslErrors() signal, which indicates which errors were found. - \sa sslConfiguration(), sslErrors() + \sa sslConfiguration(), sslErrors(), QSslSocket::ignoreSslErrors() */ void QNetworkReply::ignoreSslErrors() { diff --git a/src/network/access/qnetworkreply.h b/src/network/access/qnetworkreply.h index 30e89f1..679ab71 100644 --- a/src/network/access/qnetworkreply.h +++ b/src/network/access/qnetworkreply.h @@ -134,6 +134,7 @@ public: #ifndef QT_NO_OPENSSL QSslConfiguration sslConfiguration() const; void setSslConfiguration(const QSslConfiguration &configuration); + void ignoreSslErrors(const QList<QSslError> &errors); #endif public Q_SLOTS: diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp index 44ae328..de7f8b4 100644 --- a/src/network/access/qnetworkreplyimpl.cpp +++ b/src/network/access/qnetworkreplyimpl.cpp @@ -401,7 +401,17 @@ void QNetworkReplyImplPrivate::appendDownstreamData(QByteDataBuffer &data) QNetworkCacheMetaData metaData; metaData.setUrl(url); metaData = backend->fetchCacheMetaData(metaData); + + // save the redirect request also in the cache + QVariant redirectionTarget = q->attribute(QNetworkRequest::RedirectionTargetAttribute); + if (redirectionTarget.isValid()) { + QNetworkCacheMetaData::AttributesMap attributes = metaData.attributes(); + attributes.insert(QNetworkRequest::RedirectionTargetAttribute, redirectionTarget); + metaData.setAttributes(attributes); + } + cacheSaveDevice = networkCache->prepare(metaData); + if (!cacheSaveDevice || (cacheSaveDevice && !cacheSaveDevice->isOpen())) { if (cacheSaveDevice && !cacheSaveDevice->isOpen()) qCritical("QNetworkReplyImpl: network cache returned a device that is not open -- " @@ -649,6 +659,12 @@ void QNetworkReplyImpl::ignoreSslErrors() d->backend->ignoreSslErrors(); } +void QNetworkReplyImpl::ignoreSslErrorsImplementation(const QList<QSslError> &errors) +{ + Q_D(QNetworkReplyImpl); + if (d->backend) + d->backend->ignoreSslErrors(errors); +} #endif // QT_NO_OPENSSL /*! diff --git a/src/network/access/qnetworkreplyimpl_p.h b/src/network/access/qnetworkreplyimpl_p.h index 83a8aca..fba8d34 100644 --- a/src/network/access/qnetworkreplyimpl_p.h +++ b/src/network/access/qnetworkreplyimpl_p.h @@ -89,6 +89,7 @@ public: Q_INVOKABLE QSslConfiguration sslConfigurationImplementation() const; Q_INVOKABLE void setSslConfigurationImplementation(const QSslConfiguration &configuration); virtual void ignoreSslErrors(); + Q_INVOKABLE virtual void ignoreSslErrorsImplementation(const QList<QSslError> &errors); #endif Q_DECLARE_PRIVATE(QNetworkReplyImpl) |