diff options
author | Liang Qi <liang.qi@qt.io> | 2017-11-21 14:34:31 +0100 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2017-11-23 09:36:03 +0100 |
commit | 153e8b49adfe210cb00490284a14c94c08e03c3f (patch) | |
tree | 59d9522d6dc96215cc2cb1d19b3e8a0e580bcb41 /src/network | |
parent | ef7c0594bf9e41813c9c841e00c3a52269d363f5 (diff) | |
parent | a4113d0c644edba1c39d9d268a259e95ae51c61e (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.cpp | 2 | ||||
-rw-r--r-- | src/network/access/qhttp2protocolhandler_p.h | 10 | ||||
-rw-r--r-- | src/network/access/qnetworkreplyhttpimpl.cpp | 82 | ||||
-rw-r--r-- | src/network/kernel/kernel.pri | 2 | ||||
-rw-r--r-- | src/network/kernel/qdnslookup.cpp | 11 | ||||
-rw-r--r-- | src/network/socket/qnativesocketengine_win.cpp | 20 | ||||
-rw-r--r-- | src/network/ssl/qsslkey_qt.cpp | 2 | ||||
-rw-r--r-- | src/network/ssl/qsslsocket.cpp | 14 |
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()); |