summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Shaw <andy.shaw@qt.io>2019-01-30 12:05:31 +0100
committerLiang Qi <liang.qi@qt.io>2019-02-06 22:11:17 +0000
commit5133e22ae200eb3c5169340a16b419c9fce747cb (patch)
tree66665588d98b010d0d9f47d1ec28c712d25683c4
parent8a7c373f8e745427d5fe7afc08d698837b7b8f2b (diff)
Add support for setting the peer verify name via the QNetwork* classes
This adds functions to QNetworkRequest to be able to set the peerVerifyName. An overload of connectToHostEncrypted is also added to have an extra argument to allow setting it directly in this manner too. Fixes: QTBUG-73125 Change-Id: I371e90035b53a74c9eb3cef64f367e307dce073e Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
-rw-r--r--src/network/access/qhttpnetworkconnection.cpp12
-rw-r--r--src/network/access/qhttpnetworkconnection_p.h4
-rw-r--r--src/network/access/qhttpnetworkconnectionchannel.cpp1
-rw-r--r--src/network/access/qhttpnetworkrequest.cpp15
-rw-r--r--src/network/access/qhttpnetworkrequest_p.h3
-rw-r--r--src/network/access/qhttpthreaddelegate.cpp13
-rw-r--r--src/network/access/qnetworkaccessmanager.cpp29
-rw-r--r--src/network/access/qnetworkaccessmanager.h3
-rw-r--r--src/network/access/qnetworkreplyhttpimpl.cpp1
-rw-r--r--src/network/access/qnetworkrequest.cpp31
-rw-r--r--src/network/access/qnetworkrequest.h2
11 files changed, 105 insertions, 9 deletions
diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp
index 9fd6acb26c..681d84fee8 100644
--- a/src/network/access/qhttpnetworkconnection.cpp
+++ b/src/network/access/qhttpnetworkconnection.cpp
@@ -1518,6 +1518,18 @@ void QHttpNetworkConnection::preConnectFinished()
d_func()->preConnectRequests--;
}
+QString QHttpNetworkConnection::peerVerifyName() const
+{
+ Q_D(const QHttpNetworkConnection);
+ return d->peerVerifyName;
+}
+
+void QHttpNetworkConnection::setPeerVerifyName(const QString &peerName)
+{
+ Q_D(QHttpNetworkConnection);
+ d->peerVerifyName = peerName;
+}
+
#ifndef QT_NO_NETWORKPROXY
// only called from QHttpNetworkConnectionChannel::_q_proxyAuthenticationRequired, not
// from QHttpNetworkConnectionChannel::handleAuthenticationChallenge
diff --git a/src/network/access/qhttpnetworkconnection_p.h b/src/network/access/qhttpnetworkconnection_p.h
index da54fbac2c..2bd727e0af 100644
--- a/src/network/access/qhttpnetworkconnection_p.h
+++ b/src/network/access/qhttpnetworkconnection_p.h
@@ -154,6 +154,8 @@ public:
void preConnectFinished();
+ QString peerVerifyName() const;
+ void setPeerVerifyName(const QString &peerName);
private:
Q_DECLARE_PRIVATE(QHttpNetworkConnection)
Q_DISABLE_COPY_MOVE(QHttpNetworkConnection)
@@ -289,6 +291,8 @@ public:
Http2::ProtocolParameters http2Parameters;
+ QString peerVerifyName;
+
friend class QHttpNetworkConnectionChannel;
};
diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp
index 5726925cb0..9df3d73dd7 100644
--- a/src/network/access/qhttpnetworkconnectionchannel.cpp
+++ b/src/network/access/qhttpnetworkconnectionchannel.cpp
@@ -392,6 +392,7 @@ bool QHttpNetworkConnectionChannel::ensureConnection()
if (!connection->sslContext().isNull())
QSslSocketPrivate::checkSettingSslContext(sslSocket, connection->sslContext());
+ sslSocket->setPeerVerifyName(connection->d_func()->peerVerifyName);
sslSocket->connectToHostEncrypted(connectHost, connectPort, QIODevice::ReadWrite, networkLayerPreference);
if (ignoreAllSslErrors)
sslSocket->ignoreSslErrors();
diff --git a/src/network/access/qhttpnetworkrequest.cpp b/src/network/access/qhttpnetworkrequest.cpp
index 8de9760710..a3f71b8d2f 100644
--- a/src/network/access/qhttpnetworkrequest.cpp
+++ b/src/network/access/qhttpnetworkrequest.cpp
@@ -66,7 +66,8 @@ QHttpNetworkRequestPrivate::QHttpNetworkRequestPrivate(const QHttpNetworkRequest
ssl(other.ssl),
preConnect(other.preConnect),
redirectCount(other.redirectCount),
- redirectPolicy(other.redirectPolicy)
+ redirectPolicy(other.redirectPolicy),
+ peerVerifyName(other.peerVerifyName)
{
}
@@ -90,7 +91,8 @@ bool QHttpNetworkRequestPrivate::operator==(const QHttpNetworkRequestPrivate &ot
&& (withCredentials == other.withCredentials)
&& (ssl == other.ssl)
&& (preConnect == other.preConnect)
- && (redirectPolicy == other.redirectPolicy);
+ && (redirectPolicy == other.redirectPolicy)
+ && (peerVerifyName == other.peerVerifyName);
}
QByteArray QHttpNetworkRequest::methodName() const
@@ -397,6 +399,15 @@ int QHttpNetworkRequest::minorVersion() const
return 1;
}
+QString QHttpNetworkRequest::peerVerifyName() const
+{
+ return d->peerVerifyName;
+}
+
+void QHttpNetworkRequest::setPeerVerifyName(const QString &peerName)
+{
+ d->peerVerifyName = peerName;
+}
QT_END_NAMESPACE
diff --git a/src/network/access/qhttpnetworkrequest_p.h b/src/network/access/qhttpnetworkrequest_p.h
index bc797537ae..fb4896195b 100644
--- a/src/network/access/qhttpnetworkrequest_p.h
+++ b/src/network/access/qhttpnetworkrequest_p.h
@@ -147,6 +147,8 @@ public:
QByteArray methodName() const;
QByteArray uri(bool throughProxy) const;
+ QString peerVerifyName() const;
+ void setPeerVerifyName(const QString &peerName);
private:
QSharedDataPointer<QHttpNetworkRequestPrivate> d;
friend class QHttpNetworkRequestPrivate;
@@ -182,6 +184,7 @@ public:
bool preConnect;
int redirectCount;
QNetworkRequest::RedirectPolicy redirectPolicy;
+ QString peerVerifyName;
};
diff --git a/src/network/access/qhttpthreaddelegate.cpp b/src/network/access/qhttpthreaddelegate.cpp
index 0e97acdd9d..1fdf28df9d 100644
--- a/src/network/access/qhttpthreaddelegate.cpp
+++ b/src/network/access/qhttpthreaddelegate.cpp
@@ -123,7 +123,7 @@ static QNetworkReply::NetworkError statusCodeFromHttp(int httpStatusCode, const
}
-static QByteArray makeCacheKey(QUrl &url, QNetworkProxy *proxy)
+static QByteArray makeCacheKey(QUrl &url, QNetworkProxy *proxy, const QString &peerVerifyName)
{
QString result;
QUrl copy = url;
@@ -170,7 +170,8 @@ static QByteArray makeCacheKey(QUrl &url, QNetworkProxy *proxy)
#else
Q_UNUSED(proxy)
#endif
-
+ if (!peerVerifyName.isEmpty())
+ result += QLatin1Char(':') + peerVerifyName;
return "http-connection:" + std::move(result).toLatin1();
}
@@ -317,12 +318,12 @@ void QHttpThreadDelegate::startRequest()
#ifndef QT_NO_NETWORKPROXY
if (transparentProxy.type() != QNetworkProxy::NoProxy)
- cacheKey = makeCacheKey(urlCopy, &transparentProxy);
+ cacheKey = makeCacheKey(urlCopy, &transparentProxy, httpRequest.peerVerifyName());
else if (cacheProxy.type() != QNetworkProxy::NoProxy)
- cacheKey = makeCacheKey(urlCopy, &cacheProxy);
+ cacheKey = makeCacheKey(urlCopy, &cacheProxy, httpRequest.peerVerifyName());
else
#endif
- cacheKey = makeCacheKey(urlCopy, 0);
+ cacheKey = makeCacheKey(urlCopy, 0, httpRequest.peerVerifyName());
// the http object is actually a QHttpNetworkConnection
@@ -352,7 +353,7 @@ void QHttpThreadDelegate::startRequest()
httpConnection->setTransparentProxy(transparentProxy);
httpConnection->setCacheProxy(cacheProxy);
#endif
-
+ httpConnection->setPeerVerifyName(httpRequest.peerVerifyName());
// cache the QHttpNetworkConnection corresponding to this cache key
connections.localData()->addEntry(cacheKey, httpConnection);
} else {
diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp
index 1f0d2f92e2..8e78857259 100644
--- a/src/network/access/qnetworkaccessmanager.cpp
+++ b/src/network/access/qnetworkaccessmanager.cpp
@@ -1181,9 +1181,37 @@ QSharedPointer<QNetworkSession> QNetworkAccessManagerPrivate::getNetworkSession(
\sa connectToHost(), get(), post(), put(), deleteResource()
*/
+
void QNetworkAccessManager::connectToHostEncrypted(const QString &hostName, quint16 port,
const QSslConfiguration &sslConfiguration)
{
+ connectToHostEncrypted(hostName, port, sslConfiguration, QString());
+}
+
+/*!
+ \since 5.13
+ \overload
+
+ Initiates a connection to the host given by \a hostName at port \a port, using
+ \a sslConfiguration with \a peerName set to be the hostName used for certificate
+ validation. This function is useful to complete the TCP and SSL handshake
+ to a host before the HTTPS request is made, resulting in a lower network latency.
+
+ \note Preconnecting a SPDY connection can be done by calling setAllowedNextProtocols()
+ on \a sslConfiguration with QSslConfiguration::NextProtocolSpdy3_0 contained in
+ the list of allowed protocols. When using SPDY, one single connection per host is
+ enough, i.e. calling this method multiple times per host will not result in faster
+ network transactions.
+
+ \note This function has no possibility to report errors.
+
+ \sa connectToHost(), get(), post(), put(), deleteResource()
+*/
+
+void QNetworkAccessManager::connectToHostEncrypted(const QString &hostName, quint16 port,
+ const QSslConfiguration &sslConfiguration,
+ const QString &peerName)
+{
QUrl url;
url.setHost(hostName);
url.setPort(port);
@@ -1198,6 +1226,7 @@ void QNetworkAccessManager::connectToHostEncrypted(const QString &hostName, quin
QSslConfiguration::NextProtocolSpdy3_0))
request.setAttribute(QNetworkRequest::SpdyAllowedAttribute, true);
+ request.setPeerVerifyName(peerName);
get(request);
}
#endif
diff --git a/src/network/access/qnetworkaccessmanager.h b/src/network/access/qnetworkaccessmanager.h
index 67b3a8b71b..7e2f7683d0 100644
--- a/src/network/access/qnetworkaccessmanager.h
+++ b/src/network/access/qnetworkaccessmanager.h
@@ -158,6 +158,9 @@ public:
#ifndef QT_NO_SSL
void connectToHostEncrypted(const QString &hostName, quint16 port = 443,
const QSslConfiguration &sslConfiguration = QSslConfiguration::defaultConfiguration());
+ void connectToHostEncrypted(const QString &hostName, quint16 port,
+ const QSslConfiguration &sslConfiguration,
+ const QString &peerName);
#endif
void connectToHost(const QString &hostName, quint16 port = 80);
diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp
index ef54c198ba..9378e058b1 100644
--- a/src/network/access/qnetworkreplyhttpimpl.cpp
+++ b/src/network/access/qnetworkreplyhttpimpl.cpp
@@ -785,6 +785,7 @@ void QNetworkReplyHttpImplPrivate::postRequest(const QNetworkRequest &newHttpReq
if (request.attribute(QNetworkRequest::EmitAllUploadProgressSignalsAttribute).toBool())
emitAllUploadProgressSignals = true;
+ httpRequest.setPeerVerifyName(newHttpRequest.peerVerifyName());
// Create the HTTP thread delegate
QHttpThreadDelegate *delegate = new QHttpThreadDelegate;
diff --git a/src/network/access/qnetworkrequest.cpp b/src/network/access/qnetworkrequest.cpp
index e4c46c3183..f15c43cdd8 100644
--- a/src/network/access/qnetworkrequest.cpp
+++ b/src/network/access/qnetworkrequest.cpp
@@ -438,6 +438,7 @@ public:
if (other.sslConfiguration)
sslConfiguration = new QSslConfiguration(*other.sslConfiguration);
#endif
+ peerVerifyName = other.peerVerifyName;
}
inline bool operator==(const QNetworkRequestPrivate &other) const
@@ -446,7 +447,8 @@ public:
priority == other.priority &&
rawHeaders == other.rawHeaders &&
attributes == other.attributes &&
- maxRedirectsAllowed == other.maxRedirectsAllowed;
+ maxRedirectsAllowed == other.maxRedirectsAllowed &&
+ peerVerifyName == other.peerVerifyName;
// don't compare cookedHeaders
}
@@ -456,6 +458,7 @@ public:
mutable QSslConfiguration *sslConfiguration;
#endif
int maxRedirectsAllowed;
+ QString peerVerifyName;
};
/*!
@@ -789,6 +792,32 @@ void QNetworkRequest::setMaximumRedirectsAllowed(int maxRedirectsAllowed)
d->maxRedirectsAllowed = maxRedirectsAllowed;
}
+/*!
+ \since 5.13
+
+ Returns the host name set for the certificate validation, as set by
+ setPeerVerifyName. By default this returns a null string.
+
+ \sa setPeerVerifyName
+*/
+QString QNetworkRequest::peerVerifyName() const
+{
+ return d->peerVerifyName;
+}
+
+/*!
+ \since 5.13
+
+ Sets \a peerName as host name for the certificate validation, instead of the one used for the
+ TCP connection.
+
+ \sa peerVerifyName
+*/
+void QNetworkRequest::setPeerVerifyName(const QString &peerName)
+{
+ d->peerVerifyName = peerName;
+}
+
static QByteArray headerName(QNetworkRequest::KnownHeaders header)
{
switch (header) {
diff --git a/src/network/access/qnetworkrequest.h b/src/network/access/qnetworkrequest.h
index 8462eae8c8..efb9cbecba 100644
--- a/src/network/access/qnetworkrequest.h
+++ b/src/network/access/qnetworkrequest.h
@@ -173,6 +173,8 @@ public:
int maximumRedirectsAllowed() const;
void setMaximumRedirectsAllowed(int maximumRedirectsAllowed);
+ QString peerVerifyName() const;
+ void setPeerVerifyName(const QString &peerName);
private:
QSharedDataPointer<QNetworkRequestPrivate> d;
friend class QNetworkRequestPrivate;