summaryrefslogtreecommitdiffstats
path: root/src/network/access
diff options
context:
space:
mode:
authorPeter Hartmann <peter.hartmann@trolltech.com>2009-07-02 09:32:49 (GMT)
committerPeter Hartmann <peter.hartmann@trolltech.com>2009-07-22 16:07:13 (GMT)
commit8e05fd54935be488165abe6762e69aabb9adf232 (patch)
treecbb6e29ccb10950233077f0d6e9cb8879bcf3727 /src/network/access
parentd63f3c4c3940b4293c8763d5bfc01ed430075efb (diff)
downloadQt-8e05fd54935be488165abe6762e69aabb9adf232.zip
Qt-8e05fd54935be488165abe6762e69aabb9adf232.tar.gz
Qt-8e05fd54935be488165abe6762e69aabb9adf232.tar.bz2
QNetworkReply: add possibility to ignore specific SSL errors
the same method was also added to QSslSocket. previously, it was only possible to ignore all SSL errors; now, it is also possible to only ignore specific SSL errors, given by a QList of QSslErrors. Moreover, it is possible to call this newly added method right after connecting, not just when we get the SSL error. Reviewed-by: Thiago Task-number: 257322
Diffstat (limited to 'src/network/access')
-rw-r--r--src/network/access/qhttpnetworkconnection.cpp24
-rw-r--r--src/network/access/qhttpnetworkconnection_p.h6
-rw-r--r--src/network/access/qhttpnetworkreply.cpp7
-rw-r--r--src/network/access/qhttpnetworkreply_p.h1
-rw-r--r--src/network/access/qnetworkaccessbackend.cpp6
-rw-r--r--src/network/access/qnetworkaccessbackend_p.h1
-rw-r--r--src/network/access/qnetworkaccessdebugpipebackend.cpp1
-rw-r--r--src/network/access/qnetworkaccesshttpbackend.cpp18
-rw-r--r--src/network/access/qnetworkaccesshttpbackend_p.h4
-rw-r--r--src/network/access/qnetworkreply.cpp34
-rw-r--r--src/network/access/qnetworkreply.h1
-rw-r--r--src/network/access/qnetworkreplyimpl.cpp6
-rw-r--r--src/network/access/qnetworkreplyimpl_p.h1
13 files changed, 100 insertions, 10 deletions
diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp
index c661596..c824fac 100644
--- a/src/network/access/qhttpnetworkconnection.cpp
+++ b/src/network/access/qhttpnetworkconnection.cpp
@@ -340,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
@@ -1448,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/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, &copy };
+ 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 1d4f70e..de7f8b4 100644
--- a/src/network/access/qnetworkreplyimpl.cpp
+++ b/src/network/access/qnetworkreplyimpl.cpp
@@ -659,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)