summaryrefslogtreecommitdiffstats
path: root/src/network
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2017-11-21 14:34:31 +0100
committerLiang Qi <liang.qi@qt.io>2017-11-23 09:36:03 +0100
commit153e8b49adfe210cb00490284a14c94c08e03c3f (patch)
tree59d9522d6dc96215cc2cb1d19b3e8a0e580bcb41 /src/network
parentef7c0594bf9e41813c9c841e00c3a52269d363f5 (diff)
parenta4113d0c644edba1c39d9d268a259e95ae51c61e (diff)
Merge remote-tracking branch 'origin/5.10' into dev
Conflicts: src/network/access/qhttp2protocolhandler_p.h src/network/kernel/kernel.pri src/network/ssl/qsslkey_qt.cpp src/plugins/platforms/cocoa/qcocoascreen.mm src/plugins/platforms/windows/accessible/iaccessible2.cpp src/plugins/platforms/windows/accessible/iaccessible2.h src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.h src/widgets/widgets/qmenu_p.h tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp tests/auto/other/qaccessibility/tst_qaccessibility.cpp tests/auto/testlib/selftests/expected_cmptest.lightxml tests/auto/testlib/selftests/expected_cmptest.teamcity tests/auto/testlib/selftests/expected_cmptest.txt tests/auto/testlib/selftests/expected_cmptest.xml Done-with: Edward Welbourne <edward.welbourne@qt.io> Change-Id: I4217cc7d840cbae3e3dd28574741544469c4c6b9
Diffstat (limited to 'src/network')
-rw-r--r--src/network/access/qhttp2protocolhandler.cpp2
-rw-r--r--src/network/access/qhttp2protocolhandler_p.h10
-rw-r--r--src/network/access/qnetworkreplyhttpimpl.cpp82
-rw-r--r--src/network/kernel/kernel.pri2
-rw-r--r--src/network/kernel/qdnslookup.cpp11
-rw-r--r--src/network/socket/qnativesocketengine_win.cpp20
-rw-r--r--src/network/ssl/qsslkey_qt.cpp2
-rw-r--r--src/network/ssl/qsslsocket.cpp14
8 files changed, 75 insertions, 68 deletions
diff --git a/src/network/access/qhttp2protocolhandler.cpp b/src/network/access/qhttp2protocolhandler.cpp
index dbcbcff8d1..0cdcee6b59 100644
--- a/src/network/access/qhttp2protocolhandler.cpp
+++ b/src/network/access/qhttp2protocolhandler.cpp
@@ -1102,7 +1102,7 @@ void QHttp2ProtocolHandler::updateStream(Stream &stream, const HPack::HttpHeader
QByteArray binder(", ");
if (name == "set-cookie")
binder = "\n";
- httpReply->setHeaderField(name, value.replace('\0', binder));
+ httpReplyPrivate->fields.append(qMakePair(name, value.replace('\0', binder)));
}
}
diff --git a/src/network/access/qhttp2protocolhandler_p.h b/src/network/access/qhttp2protocolhandler_p.h
index b338934691..9165808302 100644
--- a/src/network/access/qhttp2protocolhandler_p.h
+++ b/src/network/access/qhttp2protocolhandler_p.h
@@ -55,11 +55,11 @@
#include <private/qabstractprotocolhandler_p.h>
#include <private/qhttpnetworkrequest_p.h>
-#include "http2/http2protocol_p.h"
-#include "http2/http2streams_p.h"
-#include "http2/http2frames_p.h"
-#include "http2/hpacktable_p.h"
-#include "http2/hpack_p.h"
+#include <private/http2protocol_p.h>
+#include <private/http2streams_p.h>
+#include <private/http2frames_p.h>
+#include <private/hpacktable_p.h>
+#include <private/hpack_p.h>
#include <QtCore/qnamespace.h>
#include <QtCore/qbytearray.h>
diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp
index 18d85a27a1..96016453c2 100644
--- a/src/network/access/qnetworkreplyhttpimpl.cpp
+++ b/src/network/access/qnetworkreplyhttpimpl.cpp
@@ -180,6 +180,7 @@ QNetworkReplyHttpImpl::QNetworkReplyHttpImpl(QNetworkAccessManager* const manage
: QNetworkReply(*new QNetworkReplyHttpImplPrivate, manager)
{
Q_D(QNetworkReplyHttpImpl);
+ Q_ASSERT(manager);
d->manager = manager;
d->managerPrivate = manager->d_func();
d->request = request;
@@ -393,9 +394,9 @@ bool QNetworkReplyHttpImpl::canReadLine () const
void QNetworkReplyHttpImpl::ignoreSslErrors()
{
Q_D(QNetworkReplyHttpImpl);
+ Q_ASSERT(d->managerPrivate);
- if (d->managerPrivate && d->managerPrivate->stsEnabled
- && d->managerPrivate->stsCache.isKnownHost(url())) {
+ if (d->managerPrivate->stsEnabled && d->managerPrivate->stsCache.isKnownHost(url())) {
// We cannot ignore any Security Transport-related errors for this host.
return;
}
@@ -406,9 +407,9 @@ void QNetworkReplyHttpImpl::ignoreSslErrors()
void QNetworkReplyHttpImpl::ignoreSslErrorsImplementation(const QList<QSslError> &errors)
{
Q_D(QNetworkReplyHttpImpl);
+ Q_ASSERT(d->managerPrivate);
- if (d->managerPrivate && d->managerPrivate->stsEnabled
- && d->managerPrivate->stsCache.isKnownHost(url())) {
+ if (d->managerPrivate->stsEnabled && d->managerPrivate->stsCache.isKnownHost(url())) {
// We cannot ignore any Security Transport-related errors for this host.
return;
}
@@ -1122,16 +1123,14 @@ QNetworkAccessManager::Operation QNetworkReplyHttpImplPrivate::getRedirectOperat
// HTTP status code can be used to decide if we can redirect with a GET
// operation or not. See http://www.ietf.org/rfc/rfc2616.txt [Sec 10.3] for
// more details
- Q_UNUSED(httpStatus);
+
+ // We MUST keep using the verb that was used originally when being redirected with 307 or 308.
+ if (httpStatus == 307 || httpStatus == 308)
+ return currentOp;
switch (currentOp) {
case QNetworkAccessManager::HeadOperation:
return QNetworkAccessManager::HeadOperation;
- case QNetworkAccessManager::PostOperation:
- // We MUST keep using POST when being redirected with 307 or 308.
- if (statusCode == 307 || statusCode == 308)
- return QNetworkAccessManager::PostOperation;
- break;
default:
break;
}
@@ -1158,6 +1157,8 @@ QNetworkRequest QNetworkReplyHttpImplPrivate::createRedirectRequest(const QNetwo
void QNetworkReplyHttpImplPrivate::onRedirected(const QUrl &redirectUrl, int httpStatus, int maxRedirectsRemaining)
{
Q_Q(QNetworkReplyHttpImpl);
+ Q_ASSERT(manager);
+ Q_ASSERT(managerPrivate);
if (isFinished)
return;
@@ -1192,7 +1193,7 @@ void QNetworkReplyHttpImplPrivate::onRedirected(const QUrl &redirectUrl, int htt
redirectRequest = createRedirectRequest(originalRequest, url, maxRedirectsRemaining);
operation = getRedirectOperation(operation, httpStatus);
- if (const QNetworkCookieJar *const cookieJar = (manager ? manager->cookieJar() : nullptr)) {
+ if (const QNetworkCookieJar *const cookieJar = manager->cookieJar()) {
auto cookies = cookieJar->cookiesForUrl(url);
if (!cookies.empty()) {
redirectRequest.setHeader(QNetworkRequest::KnownHeaders::CookieHeader,
@@ -1209,6 +1210,7 @@ void QNetworkReplyHttpImplPrivate::onRedirected(const QUrl &redirectUrl, int htt
void QNetworkReplyHttpImplPrivate::followRedirect()
{
Q_Q(QNetworkReplyHttpImpl);
+ Q_ASSERT(managerPrivate);
rawHeaders.clear();
cookedHeaders.clear();
@@ -1220,7 +1222,7 @@ void QNetworkReplyHttpImplPrivate::followRedirect()
// If the original request didn't need a session (i.e. it was to localhost)
// then we might not have a session open, to which to redirect, if the
// new URL is remote. When this happens, we need to open the session now:
- if (managerPrivate && isSessionNeeded(url)) {
+ if (isSessionNeeded(url)) {
if (auto session = managerPrivate->getNetworkSession()) {
if (session->state() != QNetworkSession::State::Connected || !session->isOpen()) {
startWaitForSession(session);
@@ -2058,9 +2060,7 @@ void QNetworkReplyHttpImplPrivate::_q_bufferOutgoingData()
void QNetworkReplyHttpImplPrivate::_q_networkSessionConnected()
{
Q_Q(QNetworkReplyHttpImpl);
-
- if (!manager)
- return;
+ Q_ASSERT(managerPrivate);
QSharedPointer<QNetworkSession> session = managerPrivate->getNetworkSession();
if (!session)
@@ -2190,28 +2190,27 @@ void QNetworkReplyHttpImplPrivate::finished()
if (preMigrationDownloaded != Q_INT64_C(-1))
totalSize = totalSize.toLongLong() + preMigrationDownloaded;
- if (manager) {
#ifndef QT_NO_BEARERMANAGEMENT
- QSharedPointer<QNetworkSession> session = managerPrivate->getNetworkSession();
- if (session && session->state() == QNetworkSession::Roaming &&
- state == Working && errorCode != QNetworkReply::OperationCanceledError) {
- // only content with a known size will fail with a temporary network failure error
- if (!totalSize.isNull()) {
- if (bytesDownloaded != totalSize) {
- if (migrateBackend()) {
- // either we are migrating or the request is finished/aborted
- if (state == Reconnecting || state == WaitingForSession) {
- return; // exit early if we are migrating.
- }
- } else {
- error(QNetworkReply::TemporaryNetworkFailureError,
- QNetworkReply::tr("Temporary network failure."));
+ Q_ASSERT(managerPrivate);
+ QSharedPointer<QNetworkSession> session = managerPrivate->getNetworkSession();
+ if (session && session->state() == QNetworkSession::Roaming &&
+ state == Working && errorCode != QNetworkReply::OperationCanceledError) {
+ // only content with a known size will fail with a temporary network failure error
+ if (!totalSize.isNull()) {
+ if (bytesDownloaded != totalSize) {
+ if (migrateBackend()) {
+ // either we are migrating or the request is finished/aborted
+ if (state == Reconnecting || state == WaitingForSession) {
+ return; // exit early if we are migrating.
}
+ } else {
+ error(QNetworkReply::TemporaryNetworkFailureError,
+ QNetworkReply::tr("Temporary network failure."));
}
}
}
-#endif
}
+#endif
// if we don't know the total size of or we received everything save the cache
if (totalSize.isNull() || totalSize == -1 || bytesDownloaded == totalSize)
@@ -2269,17 +2268,16 @@ void QNetworkReplyHttpImplPrivate::_q_metaDataChanged()
Q_Q(QNetworkReplyHttpImpl);
// 1. do we have cookies?
// 2. are we allowed to set them?
- if (manager) {
- const auto it = cookedHeaders.constFind(QNetworkRequest::SetCookieHeader);
- if (it != cookedHeaders.cend()
- && request.attribute(QNetworkRequest::CookieSaveControlAttribute,
- QNetworkRequest::Automatic).toInt() == QNetworkRequest::Automatic) {
- QNetworkCookieJar *jar = manager->cookieJar();
- if (jar) {
- QList<QNetworkCookie> cookies =
- qvariant_cast<QList<QNetworkCookie> >(it.value());
- jar->setCookiesFromUrl(cookies, url);
- }
+ Q_ASSERT(manager);
+ const auto it = cookedHeaders.constFind(QNetworkRequest::SetCookieHeader);
+ if (it != cookedHeaders.cend()
+ && request.attribute(QNetworkRequest::CookieSaveControlAttribute,
+ QNetworkRequest::Automatic).toInt() == QNetworkRequest::Automatic) {
+ QNetworkCookieJar *jar = manager->cookieJar();
+ if (jar) {
+ QList<QNetworkCookie> cookies =
+ qvariant_cast<QList<QNetworkCookie> >(it.value());
+ jar->setCookiesFromUrl(cookies, url);
}
}
emit q->metaDataChanged();
diff --git a/src/network/kernel/kernel.pri b/src/network/kernel/kernel.pri
index f2fe3fe134..11b80d59d5 100644
--- a/src/network/kernel/kernel.pri
+++ b/src/network/kernel/kernel.pri
@@ -6,7 +6,7 @@ INCLUDEPATH += $$PWD
HEADERS += kernel/qtnetworkglobal.h \
kernel/qtnetworkglobal_p.h \
kernel/qauthenticator.h \
- kernel/qauthenticator_p.h \
+ kernel/qauthenticator_p.h \
kernel/qhostaddress.h \
kernel/qhostaddress_p.h \
kernel/qhostinfo.h \
diff --git a/src/network/kernel/qdnslookup.cpp b/src/network/kernel/qdnslookup.cpp
index 6203ba37b3..10ff35b72c 100644
--- a/src/network/kernel/qdnslookup.cpp
+++ b/src/network/kernel/qdnslookup.cpp
@@ -42,7 +42,7 @@
#include <qcoreapplication.h>
#include <qdatetime.h>
-#include <qthreadstorage.h>
+#include <qrandom.h>
#include <qurl.h>
#include <algorithm>
@@ -50,7 +50,6 @@
QT_BEGIN_NAMESPACE
Q_GLOBAL_STATIC(QDnsLookupThreadPool, theDnsLookupThreadPool);
-Q_GLOBAL_STATIC(QThreadStorage<bool *>, theDnsLookupSeedStorage);
static bool qt_qdnsmailexchangerecord_less_than(const QDnsMailExchangeRecord &r1, const QDnsMailExchangeRecord &r2)
{
@@ -85,7 +84,7 @@ static void qt_qdnsmailexchangerecord_sort(QList<QDnsMailExchangeRecord> &record
// Randomize the slice of records.
while (!slice.isEmpty()) {
- const unsigned int pos = qrand() % slice.size();
+ const unsigned int pos = QRandomGenerator::global()->bounded(slice.size());
records[i++] = slice.takeAt(pos);
}
}
@@ -134,7 +133,7 @@ static void qt_qdnsservicerecord_sort(QList<QDnsServiceRecord> &records)
// Order the slice of records.
while (!slice.isEmpty()) {
- const unsigned int weightThreshold = qrand() % (sliceWeight + 1);
+ const unsigned int weightThreshold = QRandomGenerator::global()->bounded(sliceWeight + 1);
unsigned int summedWeight = 0;
for (int j = 0; j < slice.size(); ++j) {
summedWeight += slice.at(j).weight();
@@ -1011,10 +1010,6 @@ void QDnsLookupRunnable::run()
query(requestType, requestName, nameserver, &reply);
// Sort results.
- if (!theDnsLookupSeedStorage()->hasLocalData()) {
- qsrand(QTime(0,0,0).msecsTo(QTime::currentTime()) ^ reinterpret_cast<quintptr>(this));
- theDnsLookupSeedStorage()->setLocalData(new bool(true));
- }
qt_qdnsmailexchangerecord_sort(reply.mailExchangeRecords);
qt_qdnsservicerecord_sort(reply.serviceRecords);
diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp
index fb31607e2c..afdc4cf319 100644
--- a/src/network/socket/qnativesocketengine_win.cpp
+++ b/src/network/socket/qnativesocketengine_win.cpp
@@ -411,13 +411,13 @@ bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType soc
// get the pointer to sendmsg and recvmsg
DWORD bytesReturned;
GUID recvmsgguid = WSAID_WSARECVMSG;
- if (WSAIoctl(socketDescriptor, SIO_GET_EXTENSION_FUNCTION_POINTER,
+ if (WSAIoctl(socket, SIO_GET_EXTENSION_FUNCTION_POINTER,
&recvmsgguid, sizeof(recvmsgguid),
&recvmsg, sizeof(recvmsg), &bytesReturned, NULL, NULL) == SOCKET_ERROR)
recvmsg = 0;
GUID sendmsgguid = WSAID_WSASENDMSG;
- if (WSAIoctl(socketDescriptor, SIO_GET_EXTENSION_FUNCTION_POINTER,
+ if (WSAIoctl(socket, SIO_GET_EXTENSION_FUNCTION_POINTER,
&sendmsgguid, sizeof(sendmsgguid),
&sendmsg, sizeof(sendmsg), &bytesReturned, NULL, NULL) == SOCKET_ERROR)
sendmsg = 0;
@@ -1257,26 +1257,28 @@ qint64 QNativeSocketEnginePrivate::nativeReceiveDatagram(char *data, qint64 maxL
qt_socket_getPortAndAddress(socketDescriptor, &aa, &header->senderPort, &header->senderAddress);
}
- if (ret != -1 && recvmsg) {
+ if (ret != -1 && recvmsg && options != QAbstractSocketEngine::WantNone) {
// get the ancillary data
+ header->destinationPort = localPort;
WSACMSGHDR *cmsgptr;
for (cmsgptr = WSA_CMSG_FIRSTHDR(&msg); cmsgptr != NULL;
cmsgptr = WSA_CMSG_NXTHDR(&msg, cmsgptr)) {
if (cmsgptr->cmsg_level == IPPROTO_IPV6 && cmsgptr->cmsg_type == IPV6_PKTINFO
&& cmsgptr->cmsg_len >= WSA_CMSG_LEN(sizeof(in6_pktinfo))) {
in6_pktinfo *info = reinterpret_cast<in6_pktinfo *>(WSA_CMSG_DATA(cmsgptr));
- QHostAddress target(reinterpret_cast<quint8 *>(&info->ipi6_addr));
- if (info->ipi6_ifindex)
- target.setScopeId(QString::number(info->ipi6_ifindex));
+
+ header->destinationAddress.setAddress(reinterpret_cast<quint8 *>(&info->ipi6_addr));
+ header->ifindex = info->ipi6_ifindex;
+ if (header->ifindex)
+ header->destinationAddress.setScopeId(QString::number(info->ipi6_ifindex));
}
if (cmsgptr->cmsg_level == IPPROTO_IP && cmsgptr->cmsg_type == IP_PKTINFO
&& cmsgptr->cmsg_len >= WSA_CMSG_LEN(sizeof(in_pktinfo))) {
in_pktinfo *info = reinterpret_cast<in_pktinfo *>(WSA_CMSG_DATA(cmsgptr));
u_long addr;
WSANtohl(socketDescriptor, info->ipi_addr.s_addr, &addr);
- QHostAddress target(addr);
- if (info->ipi_ifindex)
- target.setScopeId(QString::number(info->ipi_ifindex));
+ header->destinationAddress.setAddress(addr);
+ header->ifindex = info->ipi_ifindex;
}
if (cmsgptr->cmsg_len == WSA_CMSG_LEN(sizeof(int))
diff --git a/src/network/ssl/qsslkey_qt.cpp b/src/network/ssl/qsslkey_qt.cpp
index 6716c0158b..817317f303 100644
--- a/src/network/ssl/qsslkey_qt.cpp
+++ b/src/network/ssl/qsslkey_qt.cpp
@@ -287,7 +287,7 @@ QByteArray QSslKeyPrivate::toPem(const QByteArray &passPhrase) const
if (type == QSsl::PrivateKey && !passPhrase.isEmpty()) {
// ### use a cryptographically secure random number generator
- quint64 random = QRandomGenerator::generate64();
+ quint64 random = QRandomGenerator::system()->generate64();
QByteArray iv = QByteArray::fromRawData(reinterpret_cast<const char *>(&random), sizeof(random));
Cipher cipher = DesEde3Cbc;
diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp
index 84c814cca4..145ae1a3c8 100644
--- a/src/network/ssl/qsslsocket.cpp
+++ b/src/network/ssl/qsslsocket.cpp
@@ -1686,7 +1686,8 @@ bool QSslSocket::waitForDisconnected(int msecs)
if (!d->plainSocket)
return false;
- if (d->mode == UnencryptedMode)
+ // Forward to the plain socket unless the connection is secure.
+ if (d->mode == UnencryptedMode && !d->autoStartHandshake)
return d->plainSocket->waitForDisconnected(msecs);
QElapsedTimer stopWatch;
@@ -1697,6 +1698,17 @@ bool QSslSocket::waitForDisconnected(int msecs)
if (!waitForEncrypted(msecs))
return false;
}
+ // We are delaying the disconnect, if the write buffer is not empty.
+ // So, start the transmission.
+ if (!d->writeBuffer.isEmpty())
+ d->transmit();
+
+ // At this point, the socket might be disconnected, if disconnectFromHost()
+ // was called just after the connectToHostEncrypted() call. Also, we can
+ // lose the connection as a result of the transmit() call.
+ if (state() == UnconnectedState)
+ return true;
+
bool retVal = d->plainSocket->waitForDisconnected(qt_subtract_from_timeout(msecs, stopWatch.elapsed()));
if (!retVal) {
setSocketState(d->plainSocket->state());