diff options
author | Liang Qi <liang.qi@theqtcompany.com> | 2016-03-22 07:24:57 +0100 |
---|---|---|
committer | Liang Qi <liang.qi@theqtcompany.com> | 2016-03-22 07:28:42 +0100 |
commit | a02863234d76abb6c9f289026ae4ea3145924f30 (patch) | |
tree | aef6381d0000a78ba69ac80eb03739b1c8ca5fc3 /src/network | |
parent | e77b13621f0057374d83a2b884f03dd2e5b7b88c (diff) | |
parent | e4d79e1fdeb6b26ba0b12b578daacf7cd672b960 (diff) |
Merge remote-tracking branch 'origin/5.7' into dev
Conflicts:
configure
mkspecs/common/wince/qplatformdefs.h
src/plugins/platforms/directfb/qdirectfbbackingstore.cpp
src/plugins/platforms/xcb/qxcbbackingstore.cpp
Change-Id: Ied4d31264a9afca9514b51a7eb1494c28712793c
Diffstat (limited to 'src/network')
43 files changed, 400 insertions, 287 deletions
diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index 15a886c21d..69687b5ab8 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -234,7 +234,7 @@ bool QHttpNetworkConnectionPrivate::shouldEmitChannelError(QAbstractSocket *sock emitError = false; } if (networkLayerState == QHttpNetworkConnectionPrivate::Unknown) - qWarning() << "We got a connection error when networkLayerState is Unknown"; + qWarning("We got a connection error when networkLayerState is Unknown"); } } return emitError; @@ -1180,10 +1180,9 @@ void QHttpNetworkConnectionPrivate::_q_hostLookupFinished(const QHostInfo &info) } #ifndef QT_NO_SSL else if (connectionType == QHttpNetworkConnection::ConnectionTypeSPDY) { - QList<HttpMessagePair> spdyPairs = channels[0].spdyRequestsToSend.values(); - for (int a = 0; a < spdyPairs.count(); ++a) { + for (const HttpMessagePair &spdyPair : qAsConst(channels[0].spdyRequestsToSend)) { // emit error for all replies - QHttpNetworkReply *currentReply = spdyPairs.at(a).second; + QHttpNetworkReply *currentReply = spdyPair.second; Q_ASSERT(currentReply); emitReplyError(channels[0].socket, currentReply, QNetworkReply::HostNotFoundError); } @@ -1191,7 +1190,7 @@ void QHttpNetworkConnectionPrivate::_q_hostLookupFinished(const QHostInfo &info) #endif // QT_NO_SSL else { // Should not happen - qWarning() << "QHttpNetworkConnectionPrivate::_q_hostLookupFinished could not dequeu request"; + qWarning("QHttpNetworkConnectionPrivate::_q_hostLookupFinished could not de-queue request"); networkLayerState = QHttpNetworkConnectionPrivate::Unknown; } } diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index dc1f12ff6b..56716cbe01 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -418,7 +418,7 @@ void QHttpNetworkConnectionChannel::allDone() Q_ASSERT(reply); if (!reply) { - qWarning() << "QHttpNetworkConnectionChannel::allDone() called without reply. Please report at http://bugreports.qt.io/"; + qWarning("QHttpNetworkConnectionChannel::allDone() called without reply. Please report at http://bugreports.qt.io/"); return; } diff --git a/src/network/access/qhttpnetworkreply.cpp b/src/network/access/qhttpnetworkreply.cpp index f4510c3498..3601c36bc2 100644 --- a/src/network/access/qhttpnetworkreply.cpp +++ b/src/network/access/qhttpnetworkreply.cpp @@ -558,9 +558,8 @@ qint64 QHttpNetworkReplyPrivate::readHeader(QAbstractSocket *socket) if (c == '\n') { // check for possible header endings. As per HTTP rfc, // the header endings will be marked by CRLFCRLF. But - // we will allow CRLFCRLF, CRLFLF, LFLF - if (fragment.endsWith("\r\n\r\n") - || fragment.endsWith("\r\n\n") + // we will allow CRLFCRLF, CRLFLF, LFCRLF, LFLF + if (fragment.endsWith("\n\r\n") || fragment.endsWith("\n\n")) allHeaders = true; diff --git a/src/network/access/qhttpnetworkreply_p.h b/src/network/access/qhttpnetworkreply_p.h index 653097fed3..da39633dd1 100644 --- a/src/network/access/qhttpnetworkreply_p.h +++ b/src/network/access/qhttpnetworkreply_p.h @@ -181,7 +181,7 @@ private: }; -class QHttpNetworkReplyPrivate : public QObjectPrivate, public QHttpNetworkHeaderPrivate +class Q_AUTOTEST_EXPORT QHttpNetworkReplyPrivate : public QObjectPrivate, public QHttpNetworkHeaderPrivate { public: QHttpNetworkReplyPrivate(const QUrl &newUrl = QUrl()); diff --git a/src/network/access/qhttpprotocolhandler.cpp b/src/network/access/qhttpprotocolhandler.cpp index 6adafae868..b486b75449 100644 --- a/src/network/access/qhttpprotocolhandler.cpp +++ b/src/network/access/qhttpprotocolhandler.cpp @@ -260,7 +260,7 @@ bool QHttpProtocolHandler::sendRequest() if (!m_reply) { // heh, how should that happen! - qWarning() << "QAbstractProtocolHandler::sendRequest() called without QHttpNetworkReply"; + qWarning("QAbstractProtocolHandler::sendRequest() called without QHttpNetworkReply"); return false; } diff --git a/src/network/access/qhttpthreaddelegate.cpp b/src/network/access/qhttpthreaddelegate.cpp index 43eb85f1af..3adf71ccfb 100644 --- a/src/network/access/qhttpthreaddelegate.cpp +++ b/src/network/access/qhttpthreaddelegate.cpp @@ -128,7 +128,7 @@ static QByteArray makeCacheKey(QUrl &url, QNetworkProxy *proxy) { QString result; QUrl copy = url; - QString scheme = copy.scheme().toLower(); + QString scheme = copy.scheme(); bool isEncrypted = scheme == QLatin1String("https"); copy.setPort(copy.port(isEncrypted ? 443 : 80)); if (scheme == QLatin1String("preconnect-http")) { diff --git a/src/network/access/qnetworkaccessbackend.cpp b/src/network/access/qnetworkaccessbackend.cpp index c2914117db..9c223dd32f 100644 --- a/src/network/access/qnetworkaccessbackend.cpp +++ b/src/network/access/qnetworkaccessbackend.cpp @@ -385,15 +385,11 @@ bool QNetworkAccessBackend::start() // Session not ready, but can skip for loopback connections // This is not ideal. - const QString host = reply->url.host(); - - if (host == QLatin1String("localhost") || - QHostAddress(host).isLoopback() || - reply->url.isLocalFile()) { - // Don't need an open session for localhost access. - } else { - // need to wait for session to be opened - return false; + // Don't need an open session for localhost access. + if (!reply->url.isLocalFile()) { + const QString host = reply->url.host(); + if (host != QLatin1String("localhost") && !QHostAddress(host).isLoopback()) + return false; // need to wait for session to be opened } } } diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp index c481eba9e6..ed586c1de5 100644 --- a/src/network/access/qnetworkaccessmanager.cpp +++ b/src/network/access/qnetworkaccessmanager.cpp @@ -1125,42 +1125,40 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera Q_D(QNetworkAccessManager); bool isLocalFile = req.url().isLocalFile(); - QString scheme = req.url().scheme().toLower(); + QString scheme = req.url().scheme(); // fast path for GET on file:// URLs // The QNetworkAccessFileBackend will right now only be used for PUT - if ((op == QNetworkAccessManager::GetOperation || op == QNetworkAccessManager::HeadOperation) - && (isLocalFile || scheme == QLatin1String("qrc") -#if defined(Q_OS_ANDROID) + if (op == QNetworkAccessManager::GetOperation + || op == QNetworkAccessManager::HeadOperation) { + if (isLocalFile +#ifdef Q_OS_ANDROID || scheme == QLatin1String("assets") #endif - )) { - return new QNetworkReplyFileImpl(this, req, op); - } + || scheme == QLatin1String("qrc")) { + return new QNetworkReplyFileImpl(this, req, op); + } - if ((op == QNetworkAccessManager::GetOperation || op == QNetworkAccessManager::HeadOperation) - && scheme == QLatin1String("data")) { - return new QNetworkReplyDataImpl(this, req, op); - } + if (scheme == QLatin1String("data")) + return new QNetworkReplyDataImpl(this, req, op); - // A request with QNetworkRequest::AlwaysCache does not need any bearer management - QNetworkRequest::CacheLoadControl mode = - static_cast<QNetworkRequest::CacheLoadControl>( - req.attribute(QNetworkRequest::CacheLoadControlAttribute, + // A request with QNetworkRequest::AlwaysCache does not need any bearer management + QNetworkRequest::CacheLoadControl mode = + static_cast<QNetworkRequest::CacheLoadControl>( + req.attribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferNetwork).toInt()); - if (mode == QNetworkRequest::AlwaysCache - && (op == QNetworkAccessManager::GetOperation - || op == QNetworkAccessManager::HeadOperation)) { - // FIXME Implement a QNetworkReplyCacheImpl instead, see QTBUG-15106 - QNetworkReplyImpl *reply = new QNetworkReplyImpl(this); - QNetworkReplyImplPrivate *priv = reply->d_func(); - priv->manager = this; - priv->backend = new QNetworkAccessCacheBackend(); - priv->backend->manager = this->d_func(); - priv->backend->setParent(reply); - priv->backend->reply = priv; - priv->setup(op, req, outgoingData); - return reply; + if (mode == QNetworkRequest::AlwaysCache) { + // FIXME Implement a QNetworkReplyCacheImpl instead, see QTBUG-15106 + QNetworkReplyImpl *reply = new QNetworkReplyImpl(this); + QNetworkReplyImplPrivate *priv = reply->d_func(); + priv->manager = this; + priv->backend = new QNetworkAccessCacheBackend(); + priv->backend->manager = this->d_func(); + priv->backend->setParent(reply); + priv->backend->reply = priv; + priv->setup(op, req, outgoingData); + return reply; + } } #ifndef QT_NO_BEARERMANAGEMENT diff --git a/src/network/access/qnetworkcookiejar.cpp b/src/network/access/qnetworkcookiejar.cpp index 1ae49aeee9..398895e92f 100644 --- a/src/network/access/qnetworkcookiejar.cpp +++ b/src/network/access/qnetworkcookiejar.cpp @@ -224,7 +224,7 @@ QList<QNetworkCookie> QNetworkCookieJar::cookiesForUrl(const QUrl &url) const Q_D(const QNetworkCookieJar); const QDateTime now = QDateTime::currentDateTimeUtc(); QList<QNetworkCookie> result; - bool isEncrypted = url.scheme().toLower() == QLatin1String("https"); + bool isEncrypted = url.scheme() == QLatin1String("https"); // scan our cookies for something that matches QList<QNetworkCookie>::ConstIterator it = d->allCookies.constBegin(), @@ -331,7 +331,8 @@ bool QNetworkCookieJar::deleteCookie(const QNetworkCookie &cookie) bool QNetworkCookieJar::validateCookie(const QNetworkCookie &cookie, const QUrl &url) const { QString domain = cookie.domain(); - if (!(isParentDomain(domain, url.host()) || isParentDomain(url.host(), domain))) + const QString host = url.host(); + if (!isParentDomain(domain, host) && !isParentDomain(host, domain)) return false; // not accepted // the check for effective TLDs makes the "embedded dot" rule from RFC 2109 section 4.3.2 diff --git a/src/network/access/qnetworkdiskcache.cpp b/src/network/access/qnetworkdiskcache.cpp index 5d38ebcd86..99e67cb463 100644 --- a/src/network/access/qnetworkdiskcache.cpp +++ b/src/network/access/qnetworkdiskcache.cpp @@ -160,7 +160,7 @@ void QNetworkDiskCache::setCacheDirectory(const QString &cacheDir) qint64 QNetworkDiskCache::cacheSize() const { #if defined(QNETWORKDISKCACHE_DEBUG) - qDebug() << "QNetworkDiskCache::cacheSize()"; + qDebug("QNetworkDiskCache::cacheSize()"); #endif Q_D(const QNetworkDiskCache); if (d->cacheDirectory.isEmpty()) @@ -185,7 +185,7 @@ QIODevice *QNetworkDiskCache::prepare(const QNetworkCacheMetaData &metaData) return 0; if (d->cacheDirectory.isEmpty()) { - qWarning() << "QNetworkDiskCache::prepare() The cache directory is not set"; + qWarning("QNetworkDiskCache::prepare() The cache directory is not set"); return 0; } @@ -212,7 +212,7 @@ QIODevice *QNetworkDiskCache::prepare(const QNetworkCacheMetaData &metaData) cacheItem->file = 0; } if (!cacheItem->file || !cacheItem->file->open()) { - qWarning() << "QNetworkDiskCache::prepare() unable to open temporary file"; + qWarning("QNetworkDiskCache::prepare() unable to open temporary file"); cacheItem.reset(); return 0; } @@ -448,7 +448,7 @@ void QNetworkDiskCache::updateMetaData(const QNetworkCacheMetaData &metaData) QIODevice *oldDevice = data(url); if (!oldDevice) { #if defined(QNETWORKDISKCACHE_DEBUG) - qDebug() << "QNetworkDiskCache::updateMetaData(), no device!"; + qDebug("QNetworkDiskCache::updateMetaData(), no device!"); #endif return; } @@ -521,7 +521,7 @@ qint64 QNetworkDiskCache::expire() return d->currentCacheSize; if (cacheDirectory().isEmpty()) { - qWarning() << "QNetworkDiskCache::expire() The cache directory is not set"; + qWarning("QNetworkDiskCache::expire() The cache directory is not set"); return 0; } @@ -584,7 +584,7 @@ qint64 QNetworkDiskCache::expire() void QNetworkDiskCache::clear() { #if defined(QNETWORKDISKCACHE_DEBUG) - qDebug() << "QNetworkDiskCache::clear()"; + qDebug("QNetworkDiskCache::clear()"); #endif Q_D(QNetworkDiskCache); qint64 size = d->maximumCacheSize; diff --git a/src/network/access/qnetworkreplyfileimpl.cpp b/src/network/access/qnetworkreplyfileimpl.cpp index 8d63fa3fd6..ef319ebf0d 100644 --- a/src/network/access/qnetworkreplyfileimpl.cpp +++ b/src/network/access/qnetworkreplyfileimpl.cpp @@ -101,11 +101,12 @@ QNetworkReplyFileImpl::QNetworkReplyFileImpl(QNetworkAccessManager *manager, con QString fileName = url.toLocalFile(); if (fileName.isEmpty()) { - if (url.scheme() == QLatin1String("qrc")) { + const QString scheme = url.scheme(); + if (scheme == QLatin1String("qrc")) { fileName = QLatin1Char(':') + url.path(); } else { #if defined(Q_OS_ANDROID) - if (url.scheme() == QLatin1String("assets")) + if (scheme == QLatin1String("assets")) fileName = QLatin1String("assets:") + url.path(); else #endif diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp index 9e39315268..6b77ab303f 100644 --- a/src/network/access/qnetworkreplyhttpimpl.cpp +++ b/src/network/access/qnetworkreplyhttpimpl.cpp @@ -627,7 +627,7 @@ void QNetworkReplyHttpImplPrivate::postRequest(const QNetworkRequest &newHttpReq httpRequest.setUrl(url); httpRequest.setRedirectCount(newHttpRequest.maximumRedirectsAllowed()); - QString scheme = url.scheme().toLower(); + QString scheme = url.scheme(); bool ssl = (scheme == QLatin1String("https") || scheme == QLatin1String("preconnect-https")); q->setAttribute(QNetworkRequest::ConnectionEncryptedAttribute, ssl); @@ -675,18 +675,19 @@ void QNetworkReplyHttpImplPrivate::postRequest(const QNetworkRequest &newHttpReq if (newHttpRequest.attribute(QNetworkRequest::FollowRedirectsAttribute).toBool()) httpRequest.setFollowRedirects(true); - bool loadedFromCache = false; httpRequest.setPriority(convert(newHttpRequest.priority())); switch (operation) { case QNetworkAccessManager::GetOperation: httpRequest.setOperation(QHttpNetworkRequest::Get); - loadedFromCache = loadFromCacheIfAllowed(httpRequest); + if (loadFromCacheIfAllowed(httpRequest)) + return; // no need to send the request! :) break; case QNetworkAccessManager::HeadOperation: httpRequest.setOperation(QHttpNetworkRequest::Head); - loadedFromCache = loadFromCacheIfAllowed(httpRequest); + if (loadFromCacheIfAllowed(httpRequest)) + return; // no need to send the request! :) break; case QNetworkAccessManager::PostOperation: @@ -718,16 +719,13 @@ void QNetworkReplyHttpImplPrivate::postRequest(const QNetworkRequest &newHttpReq break; // can't happen } - if (loadedFromCache) { - return; // no need to send the request! :) - } - QList<QByteArray> headers = newHttpRequest.rawHeaderList(); if (resumeOffset != 0) { - if (headers.contains("Range")) { + const int rangeIndex = headers.indexOf("Range"); + if (rangeIndex != -1) { // Need to adjust resume offset for user specified range - headers.removeOne("Range"); + headers.removeAt(rangeIndex); // We've already verified that requestRange starts with "bytes=", see canResume. QByteArray requestRange = newHttpRequest.rawHeader("Range").mid(6); @@ -749,10 +747,10 @@ void QNetworkReplyHttpImplPrivate::postRequest(const QNetworkRequest &newHttpReq foreach (const QByteArray &header, headers) httpRequest.setHeaderField(header, newHttpRequest.rawHeader(header)); - if (newHttpRequest.attribute(QNetworkRequest::HttpPipeliningAllowedAttribute).toBool() == true) + if (newHttpRequest.attribute(QNetworkRequest::HttpPipeliningAllowedAttribute).toBool()) httpRequest.setPipeliningAllowed(true); - if (request.attribute(QNetworkRequest::SpdyAllowedAttribute).toBool() == true) + if (request.attribute(QNetworkRequest::SpdyAllowedAttribute).toBool()) httpRequest.setSPDYAllowed(true); if (static_cast<QNetworkRequest::LoadControl> @@ -760,7 +758,7 @@ void QNetworkReplyHttpImplPrivate::postRequest(const QNetworkRequest &newHttpReq QNetworkRequest::Automatic).toInt()) == QNetworkRequest::Manual) httpRequest.setWithCredentials(false); - if (request.attribute(QNetworkRequest::EmitAllUploadProgressSignalsAttribute).toBool() == true) + if (request.attribute(QNetworkRequest::EmitAllUploadProgressSignalsAttribute).toBool()) emitAllUploadProgressSignals = true; @@ -1747,10 +1745,8 @@ void QNetworkReplyHttpImplPrivate::_q_startOperation() QMetaObject::invokeMethod(q, "_q_finished", synchronous ? Qt::DirectConnection : Qt::QueuedConnection); return; } -#endif if (!start(request)) { -#ifndef QT_NO_BEARERMANAGEMENT // backend failed to start because the session state is not Connected. // QNetworkAccessManager will call reply->backend->start() again for us when the session // state changes. @@ -1772,29 +1768,25 @@ void QNetworkReplyHttpImplPrivate::_q_startOperation() QMetaObject::invokeMethod(q, "_q_finished", synchronous ? Qt::DirectConnection : Qt::QueuedConnection); return; } + } else if (session) { + QObject::connect(session.data(), SIGNAL(stateChanged(QNetworkSession::State)), + q, SLOT(_q_networkSessionStateChanged(QNetworkSession::State)), + Qt::QueuedConnection); + } #else + if (!start(request)) { qWarning("Backend start failed"); QMetaObject::invokeMethod(q, "_q_error", synchronous ? Qt::DirectConnection : Qt::QueuedConnection, Q_ARG(QNetworkReply::NetworkError, QNetworkReply::UnknownNetworkError), Q_ARG(QString, QCoreApplication::translate("QNetworkReply", "backend start error."))); QMetaObject::invokeMethod(q, "_q_finished", synchronous ? Qt::DirectConnection : Qt::QueuedConnection); return; -#endif - } else { -#ifndef QT_NO_BEARERMANAGEMENT - if (session) - QObject::connect(session.data(), SIGNAL(stateChanged(QNetworkSession::State)), - q, SLOT(_q_networkSessionStateChanged(QNetworkSession::State)), Qt::QueuedConnection); -#endif } +#endif // QT_NO_BEARERMANAGEMENT if (synchronous) { state = Finished; q_func()->setFinished(true); - } else { - if (state != Finished) { - - } } } @@ -2138,15 +2130,18 @@ void QNetworkReplyHttpImplPrivate::_q_metaDataChanged() Q_Q(QNetworkReplyHttpImpl); // 1. do we have cookies? // 2. are we allowed to set them? - if (cookedHeaders.contains(QNetworkRequest::SetCookieHeader) && manager - && (static_cast<QNetworkRequest::LoadControl> - (request.attribute(QNetworkRequest::CookieSaveControlAttribute, - QNetworkRequest::Automatic).toInt()) == QNetworkRequest::Automatic)) { - QList<QNetworkCookie> cookies = - qvariant_cast<QList<QNetworkCookie> >(cookedHeaders.value(QNetworkRequest::SetCookieHeader)); - QNetworkCookieJar *jar = manager->cookieJar(); - if (jar) - jar->setCookiesFromUrl(cookies, url); + 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); + } + } } emit q->metaDataChanged(); } diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp index 0f57d1a73b..4203169cae 100644 --- a/src/network/access/qnetworkreplyimpl.cpp +++ b/src/network/access/qnetworkreplyimpl.cpp @@ -871,16 +871,20 @@ void QNetworkReplyImplPrivate::metaDataChanged() Q_Q(QNetworkReplyImpl); // 1. do we have cookies? // 2. are we allowed to set them? - if (cookedHeaders.contains(QNetworkRequest::SetCookieHeader) && !manager.isNull() - && (static_cast<QNetworkRequest::LoadControl> - (request.attribute(QNetworkRequest::CookieSaveControlAttribute, - QNetworkRequest::Automatic).toInt()) == QNetworkRequest::Automatic)) { - QList<QNetworkCookie> cookies = - qvariant_cast<QList<QNetworkCookie> >(cookedHeaders.value(QNetworkRequest::SetCookieHeader)); - QNetworkCookieJar *jar = manager->cookieJar(); - if (jar) - jar->setCookiesFromUrl(cookies, url); + if (!manager.isNull()) { + 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/access/qnetworkrequest.cpp b/src/network/access/qnetworkrequest.cpp index c188918024..f674cd5c2e 100644 --- a/src/network/access/qnetworkrequest.cpp +++ b/src/network/access/qnetworkrequest.cpp @@ -806,10 +806,10 @@ static QByteArray headerValue(QNetworkRequest::KnownHeaders header, const QVaria return QByteArray(); } -static QNetworkRequest::KnownHeaders parseHeaderName(const QByteArray &headerName) +static int parseHeaderName(const QByteArray &headerName) { if (headerName.isEmpty()) - return QNetworkRequest::KnownHeaders(-1); + return -1; switch (tolower(headerName.at(0))) { case 'c': @@ -841,7 +841,7 @@ static QNetworkRequest::KnownHeaders parseHeaderName(const QByteArray &headerNam break; } - return QNetworkRequest::KnownHeaders(-1); // nothing found + return -1; // nothing found } static QVariant parseHttpDate(const QByteArray &raw) @@ -1012,8 +1012,10 @@ void QNetworkHeadersPrivate::setRawHeaderInternal(const QByteArray &key, const Q void QNetworkHeadersPrivate::parseAndSetHeader(const QByteArray &key, const QByteArray &value) { // is it a known header? - QNetworkRequest::KnownHeaders parsedKey = parseHeaderName(key); - if (parsedKey != QNetworkRequest::KnownHeaders(-1)) { + const int parsedKeyAsInt = parseHeaderName(key); + if (parsedKeyAsInt != -1) { + const QNetworkRequest::KnownHeaders parsedKey + = static_cast<QNetworkRequest::KnownHeaders>(parsedKeyAsInt); if (value.isNull()) { cookedHeaders.remove(parsedKey); } else if (parsedKey == QNetworkRequest::ContentLengthHeader diff --git a/src/network/access/qspdyprotocolhandler.cpp b/src/network/access/qspdyprotocolhandler.cpp index f3073dcd3c..1a6dd04ecb 100644 --- a/src/network/access/qspdyprotocolhandler.cpp +++ b/src/network/access/qspdyprotocolhandler.cpp @@ -872,7 +872,8 @@ void QSpdyProtocolHandler::handleSYN_REPLY(char flags, quint32 /*length*/, const void QSpdyProtocolHandler::parseHttpHeaders(char flags, const QByteArray &frameData) { qint32 streamID = getStreamID(frameData.constData()); - if (!m_inFlightStreams.contains(streamID)) { + const auto it = m_inFlightStreams.constFind(streamID); + if (it == m_inFlightStreams.cend()) { sendRST_STREAM(streamID, RST_STREAM_INVALID_STREAM); return; } @@ -882,7 +883,7 @@ void QSpdyProtocolHandler::parseHttpHeaders(char flags, const QByteArray &frameD QByteArray headerValuePairs = frameData.mid(4); - HttpMessagePair pair = m_inFlightStreams.value(streamID); + HttpMessagePair pair = it.value(); QHttpNetworkReply *httpReply = pair.second; Q_ASSERT(httpReply != 0); @@ -1152,12 +1153,13 @@ void QSpdyProtocolHandler::handleWINDOW_UPDATE(char /*flags*/, quint32 /*length* qint32 streamID = getStreamID(frameData.constData()); qint32 deltaWindowSize = fourBytesToInt(frameData.constData() + 4); - if (!m_inFlightStreams.contains(streamID)) { + const auto it = m_inFlightStreams.constFind(streamID); + if (it == m_inFlightStreams.cend()) { sendRST_STREAM(streamID, RST_STREAM_INVALID_STREAM); return; } - QHttpNetworkReply *reply = m_inFlightStreams.value(streamID).second; + QHttpNetworkReply *reply = it.value().second; Q_ASSERT(reply); QHttpNetworkReplyPrivate *replyPrivate = reply->d_func(); Q_ASSERT(replyPrivate); @@ -1176,7 +1178,8 @@ void QSpdyProtocolHandler::handleDataFrame(const QByteArray &frameHeaders) Q_ASSERT(frameHeaders.count() >= 8); qint32 streamID = getStreamID(frameHeaders.constData()); - if (!m_inFlightStreams.contains(streamID)) { + const auto it = m_inFlightStreams.constFind(streamID); + if (it == m_inFlightStreams.cend()) { sendRST_STREAM(streamID, RST_STREAM_INVALID_STREAM); return; } @@ -1198,7 +1201,7 @@ void QSpdyProtocolHandler::handleDataFrame(const QByteArray &frameHeaders) m_waitingForCompleteStream = false; } - HttpMessagePair pair = m_inFlightStreams.value(streamID); + HttpMessagePair pair = it.value(); QHttpNetworkRequest httpRequest = pair.first; QHttpNetworkReply *httpReply = pair.second; Q_ASSERT(httpReply != 0); diff --git a/src/network/bearer/qbearerengine.cpp b/src/network/bearer/qbearerengine.cpp index dda1229a17..215cd3fddd 100644 --- a/src/network/bearer/qbearerengine.cpp +++ b/src/network/bearer/qbearerengine.cpp @@ -38,11 +38,30 @@ ****************************************************************************/ #include "qbearerengine_p.h" +#include <algorithm> #ifndef QT_NO_BEARERMANAGEMENT QT_BEGIN_NAMESPACE +static void cleanUpConfigurations(QHash<QString, QNetworkConfigurationPrivatePointer> &configurations) +{ + for (const auto &ptr : qAsConst(configurations)) { + ptr->isValid = false; + ptr->id.clear(); + } + configurations.clear(); +} + +static bool hasUsedConfiguration(const QHash<QString, QNetworkConfigurationPrivatePointer> &configurations) +{ + auto isUsed = [](const QNetworkConfigurationPrivatePointer &ptr) { + return ptr->ref.load() > 1; + }; + const auto end = configurations.end(); + return std::find_if(configurations.begin(), end, isUsed) != end; +} + QBearerEngine::QBearerEngine(QObject *parent) : QObject(parent), mutex(QMutex::Recursive) { @@ -50,28 +69,9 @@ QBearerEngine::QBearerEngine(QObject *parent) QBearerEngine::~QBearerEngine() { - QHash<QString, QNetworkConfigurationPrivatePointer>::Iterator it; - QHash<QString, QNetworkConfigurationPrivatePointer>::Iterator end; - - for (it = snapConfigurations.begin(), end = snapConfigurations.end(); it != end; ++it) { - it.value()->isValid = false; - it.value()->id.clear(); - } - snapConfigurations.clear(); - - for (it = accessPointConfigurations.begin(), end = accessPointConfigurations.end(); - it != end; ++it) { - it.value()->isValid = false; - it.value()->id.clear(); - } - accessPointConfigurations.clear(); - - for (it = userChoiceConfigurations.begin(), end = userChoiceConfigurations.end(); - it != end; ++it) { - it.value()->isValid = false; - it.value()->id.clear(); - } - userChoiceConfigurations.clear(); + cleanUpConfigurations(snapConfigurations); + cleanUpConfigurations(accessPointConfigurations); + cleanUpConfigurations(userChoiceConfigurations); } bool QBearerEngine::requiresPolling() const @@ -87,30 +87,10 @@ bool QBearerEngine::requiresPolling() const */ bool QBearerEngine::configurationsInUse() const { - QHash<QString, QNetworkConfigurationPrivatePointer>::ConstIterator it; - QHash<QString, QNetworkConfigurationPrivatePointer>::ConstIterator end; - QMutexLocker locker(&mutex); - - for (it = accessPointConfigurations.constBegin(), - end = accessPointConfigurations.constEnd(); it != end; ++it) { - if (it.value()->ref.load() > 1) - return true; - } - - for (it = snapConfigurations.constBegin(), - end = snapConfigurations.constEnd(); it != end; ++it) { - if (it.value()->ref.load() > 1) - return true; - } - - for (it = userChoiceConfigurations.constBegin(), - end = userChoiceConfigurations.constEnd(); it != end; ++it) { - if (it.value()->ref.load() > 1) - return true; - } - - return false; + return hasUsedConfiguration(accessPointConfigurations) + || hasUsedConfiguration(snapConfigurations) + || hasUsedConfiguration(userChoiceConfigurations); } #include "moc_qbearerengine_p.cpp" diff --git a/src/network/bearer/qnetworkconfigmanager_p.cpp b/src/network/bearer/qnetworkconfigmanager_p.cpp index 3101a98165..232875f43c 100644 --- a/src/network/bearer/qnetworkconfigmanager_p.cpp +++ b/src/network/bearer/qnetworkconfigmanager_p.cpp @@ -52,6 +52,8 @@ #include <QtCore/qbytearray.h> #include <QtCore/qglobal.h> +#include <utility> + #ifndef QT_NO_BEARERMANAGEMENT @@ -263,17 +265,18 @@ QNetworkConfiguration QNetworkConfigurationManagerPrivate::configurationFromIden foreach (QBearerEngine *engine, sessionEngines) { QMutexLocker locker(&engine->mutex); - - if (engine->accessPointConfigurations.contains(identifier)) - item.d = engine->accessPointConfigurations[identifier]; - else if (engine->snapConfigurations.contains(identifier)) - item.d = engine->snapConfigurations[identifier]; - else if (engine->userChoiceConfigurations.contains(identifier)) - item.d = engine->userChoiceConfigurations[identifier]; - else - continue; - - return item; + if (auto ptr = engine->accessPointConfigurations.value(identifier)) { + item.d = std::move(ptr); + break; + } + if (auto ptr = engine->snapConfigurations.value(identifier)) { + item.d = std::move(ptr); + break; + } + if (auto ptr = engine->userChoiceConfigurations.value(identifier)) { + item.d = std::move(ptr); + break; + } } return item; diff --git a/src/network/bearer/qsharednetworksession.cpp b/src/network/bearer/qsharednetworksession.cpp index e04c8cc953..fc01acb8b4 100644 --- a/src/network/bearer/qsharednetworksession.cpp +++ b/src/network/bearer/qsharednetworksession.cpp @@ -65,9 +65,10 @@ static void doDeleteLater(QObject* obj) QSharedPointer<QNetworkSession> QSharedNetworkSessionManager::getSession(const QNetworkConfiguration &config) { QSharedNetworkSessionManager *m(sharedNetworkSessionManager()); + const auto it = m->sessions.constFind(config); //if already have a session, return it - if (m->sessions.contains(config)) { - QSharedPointer<QNetworkSession> p = m->sessions.value(config).toStrongRef(); + if (it != m->sessions.cend()) { + QSharedPointer<QNetworkSession> p = it.value().toStrongRef(); if (!p.isNull()) return p; } diff --git a/src/network/kernel/kernel.pri b/src/network/kernel/kernel.pri index 841a71643a..811d8b6f0d 100644 --- a/src/network/kernel/kernel.pri +++ b/src/network/kernel/kernel.pri @@ -26,7 +26,10 @@ SOURCES += kernel/qauthenticator.cpp \ kernel/qnetworkproxy.cpp \ kernel/qnetworkinterface.cpp -unix:SOURCES += kernel/qdnslookup_unix.cpp kernel/qhostinfo_unix.cpp kernel/qnetworkinterface_unix.cpp +unix { + !integrity: SOURCES += kernel/qdnslookup_unix.cpp + SOURCES += kernel/qhostinfo_unix.cpp kernel/qnetworkinterface_unix.cpp +} android { SOURCES -= kernel/qdnslookup_unix.cpp @@ -47,7 +50,6 @@ win32: { kernel/qnetworkinterface_winrt.cpp } } -integrity:SOURCES += kernel/qdnslookup_unix.cpp kernel/qhostinfo_unix.cpp kernel/qnetworkinterface_unix.cpp mac { LIBS_PRIVATE += -framework SystemConfiguration -framework CoreFoundation diff --git a/src/network/kernel/qdnslookup_winrt.cpp b/src/network/kernel/qdnslookup_winrt.cpp index a0643c5daa..b459deb1ed 100644 --- a/src/network/kernel/qdnslookup_winrt.cpp +++ b/src/network/kernel/qdnslookup_winrt.cpp @@ -65,7 +65,7 @@ void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestN { // TODO: Add nameserver support for winRT if (!nameserver.isNull()) - qWarning() << "Ignoring nameserver as its currently not supported on WinRT"; + qWarning("Ignoring nameserver as its currently not supported on WinRT"); // TODO: is there any way to do "proper" dns lookup? if (requestType != QDnsLookup::A && requestType != QDnsLookup::AAAA diff --git a/src/network/kernel/qhostaddress.cpp b/src/network/kernel/qhostaddress.cpp index fc2038cf03..6ccf40680a 100644 --- a/src/network/kernel/qhostaddress.cpp +++ b/src/network/kernel/qhostaddress.cpp @@ -737,24 +737,17 @@ Q_IPV6ADDR QHostAddress::toIPv6Address() const QString QHostAddress::toString() const { QT_ENSURE_PARSED(this); + QString s; if (d->protocol == QAbstractSocket::IPv4Protocol || d->protocol == QAbstractSocket::AnyIPProtocol) { quint32 i = toIPv4Address(); - QString s; QIPAddressUtils::toString(s, i); - return s; - } - - if (d->protocol == QAbstractSocket::IPv6Protocol) { - QString s; + } else if (d->protocol == QAbstractSocket::IPv6Protocol) { QIPAddressUtils::toString(s, d->a6.c); - if (!d->scopeId.isEmpty()) s.append(QLatin1Char('%') + d->scopeId); - return s; } - - return QString(); + return s; } /*! diff --git a/src/network/kernel/qhostinfo.cpp b/src/network/kernel/qhostinfo.cpp index cba0ab65b6..293633d6bc 100644 --- a/src/network/kernel/qhostinfo.cpp +++ b/src/network/kernel/qhostinfo.cpp @@ -49,6 +49,8 @@ #include <qurl.h> #include <private/qnetworksession_p.h> +#include <algorithm> + #ifdef Q_OS_UNIX # include <unistd.h> #endif @@ -59,6 +61,26 @@ QT_BEGIN_NAMESPACE Q_GLOBAL_STATIC(QHostInfoLookupManager, theHostInfoLookupManager) +namespace { +struct ToBeLookedUpEquals { + typedef bool result_type; + explicit ToBeLookedUpEquals(const QString &toBeLookedUp) Q_DECL_NOTHROW : m_toBeLookedUp(toBeLookedUp) {} + result_type operator()(QHostInfoRunnable* lookup) const Q_DECL_NOTHROW + { + return m_toBeLookedUp == lookup->toBeLookedUp; + } +private: + QString m_toBeLookedUp; +}; + +// ### C++11: remove once we can use std::any_of() +template<class InputIt, class UnaryPredicate> +bool any_of(InputIt first, InputIt last, UnaryPredicate p) +{ + return std::find_if(first, last, p) != last; +} +} + /*! \class QHostInfo \brief The QHostInfo class provides static functions for host name lookups. @@ -496,17 +518,17 @@ void QHostInfoRunnable::run() // now also iterate through the postponed ones { QMutexLocker locker(&manager->mutex); - QMutableListIterator<QHostInfoRunnable*> iterator(manager->postponedLookups); - while (iterator.hasNext()) { - QHostInfoRunnable* postponed = iterator.next(); - if (toBeLookedUp == postponed->toBeLookedUp) { - // we can now emit - iterator.remove(); - hostInfo.setLookupId(postponed->id); - postponed->resultEmitter.emitResultsReady(hostInfo); - delete postponed; - } + const auto partitionBegin = std::stable_partition(manager->postponedLookups.rbegin(), manager->postponedLookups.rend(), + ToBeLookedUpEquals(toBeLookedUp)).base(); + const auto partitionEnd = manager->postponedLookups.end(); + for (auto it = partitionBegin; it != partitionEnd; ++it) { + QHostInfoRunnable* postponed = *it; + // we can now emit + hostInfo.setLookupId(postponed->id); + postponed->resultEmitter.emitResultsReady(hostInfo); + delete postponed; } + manager->postponedLookups.erase(partitionBegin, partitionEnd); } manager->lookupFinished(this); @@ -573,13 +595,7 @@ void QHostInfoLookupManager::work() QHostInfoRunnable* postponed = iterator.next(); // check if none of the postponed hostnames is currently running - bool alreadyRunning = false; - for (int i = 0; i < currentLookups.length(); i++) { - if (currentLookups.at(i)->toBeLookedUp == postponed->toBeLookedUp) { - alreadyRunning = true; - break; - } - } + const bool alreadyRunning = any_of(currentLookups.cbegin(), currentLookups.cend(), ToBeLookedUpEquals(postponed->toBeLookedUp)); if (!alreadyRunning) { iterator.remove(); scheduledLookups.prepend(postponed); // prepend! we want to finish it ASAP @@ -594,13 +610,11 @@ void QHostInfoLookupManager::work() QHostInfoRunnable *scheduled = iterator.next(); // check if a lookup for this host is already running, then postpone - for (int i = 0; i < currentLookups.size(); i++) { - if (currentLookups.at(i)->toBeLookedUp == scheduled->toBeLookedUp) { - iterator.remove(); - postponedLookups.append(scheduled); - scheduled = 0; - break; - } + const bool alreadyRunning = any_of(currentLookups.cbegin(), currentLookups.cend(), ToBeLookedUpEquals(scheduled->toBeLookedUp)); + if (alreadyRunning) { + iterator.remove(); + postponedLookups.append(scheduled); + scheduled = 0; } if (scheduled && currentLookups.size() < threadPool.maxThreadCount()) { diff --git a/src/network/kernel/qnetworkproxy_generic.cpp b/src/network/kernel/qnetworkproxy_generic.cpp index 272d6dfe8d..db1083f3e0 100644 --- a/src/network/kernel/qnetworkproxy_generic.cpp +++ b/src/network/kernel/qnetworkproxy_generic.cpp @@ -112,16 +112,17 @@ QList<QNetworkProxy> QNetworkProxyFactory::systemProxyForQuery(const QNetworkPro if (!proxy_env.isEmpty()) { QUrl url = QUrl(QString::fromLocal8Bit(proxy_env)); - if (url.scheme() == QLatin1String("socks5")) { + const QString scheme = url.scheme(); + if (scheme == QLatin1String("socks5")) { QNetworkProxy proxy(QNetworkProxy::Socks5Proxy, url.host(), url.port() ? url.port() : 1080, url.userName(), url.password()); proxyList << proxy; - } else if (url.scheme() == QLatin1String("socks5h")) { + } else if (scheme == QLatin1String("socks5h")) { QNetworkProxy proxy(QNetworkProxy::Socks5Proxy, url.host(), url.port() ? url.port() : 1080, url.userName(), url.password()); proxy.setCapabilities(QNetworkProxy::HostNameLookupCapability); proxyList << proxy; - } else if ((url.scheme() == QLatin1String("http") || url.scheme().isEmpty()) + } else if ((scheme.isEmpty() || scheme == QLatin1String("http")) && query.queryType() != QNetworkProxyQuery::UdpSocket && query.queryType() != QNetworkProxyQuery::TcpServer) { QNetworkProxy proxy(QNetworkProxy::HttpProxy, url.host(), diff --git a/src/network/network.pro b/src/network/network.pro index 4cced923f7..cdea190222 100644 --- a/src/network/network.pro +++ b/src/network/network.pro @@ -11,13 +11,8 @@ DEFINES += QT_NO_USING_NAMESPACE #DEFINES += QUDPSOCKET_DEBUG QUDPSERVER_DEBUG win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x64000000 -MODULE_PLUGIN_TYPES = \ - bearer - QMAKE_DOCS = $$PWD/doc/qtnetwork.qdocconf -load(qt_module) - include(access/access.pri) include(bearer/bearer.pri) include(kernel/kernel.pri) @@ -36,3 +31,7 @@ MODULE_PLUGIN_TYPES = \ bearer ANDROID_PERMISSIONS += \ android.permission.ACCESS_NETWORK_STATE + +MODULE_PLUGIN_TYPES = \ + bearer +load(qt_module) diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp index 0969d84180..3ce2d63a39 100644 --- a/src/network/socket/qabstractsocket.cpp +++ b/src/network/socket/qabstractsocket.cpp @@ -562,7 +562,6 @@ QAbstractSocketPrivate::QAbstractSocketPrivate() socketEngine(0), cachedSocketDescriptor(-1), readBufferMaxSize(0), - writeBuffer(QABSTRACTSOCKET_BUFFERSIZE), isBuffered(false), connectTimer(0), disconnectTimer(0), @@ -572,6 +571,7 @@ QAbstractSocketPrivate::QAbstractSocketPrivate() socketError(QAbstractSocket::UnknownSocketError), preferredNetworkLayerProtocol(QAbstractSocket::UnknownNetworkLayerProtocol) { + writeBufferChunkSize = QABSTRACTSOCKET_BUFFERSIZE; } /*! \internal @@ -852,15 +852,16 @@ bool QAbstractSocketPrivate::writeToSocket() written); #endif - // Remove what we wrote so far. - writeBuffer.free(written); if (written > 0) { + // Remove what we wrote so far. + writeBuffer.free(written); // Don't emit bytesWritten() recursively. if (!emittedBytesWritten) { QScopedValueRollback<bool> r(emittedBytesWritten); emittedBytesWritten = true; emit q->bytesWritten(written); } + emit q->channelBytesWritten(0, written); } if (writeBuffer.isEmpty() && socketEngine && !socketEngine->bytesToWrite()) @@ -1286,6 +1287,7 @@ void QAbstractSocketPrivate::emitReadyRead() emittedReadyRead = true; emit q->readyRead(); } + emit q->channelReadyRead(0); } /*! \internal @@ -1298,6 +1300,18 @@ void QAbstractSocketPrivate::fetchConnectionParameters() peerName = hostName; if (socketEngine) { + if (q->isReadable()) { + const int inboundStreamCount = socketEngine->inboundStreamCount(); + setReadChannelCount(qMax(1, inboundStreamCount)); + if (inboundStreamCount == 0) + readChannelCount = 0; + } + if (q->isWritable()) { + const int outboundStreamCount = socketEngine->outboundStreamCount(); + setWriteChannelCount(qMax(1, outboundStreamCount)); + if (outboundStreamCount == 0) + writeChannelCount = 0; + } socketEngine->setReadNotificationEnabled(true); socketEngine->setWriteNotificationEnabled(true); localPort = socketEngine->localPort(); @@ -1620,8 +1634,8 @@ void QAbstractSocket::connectToHost(const QString &hostName, quint16 port, d->preferredNetworkLayerProtocol = protocol; d->hostName = hostName; d->port = port; - d->buffer.clear(); - d->writeBuffer.clear(); + d->setReadChannelCount(0); + d->setWriteChannelCount(0); d->abortCalled = false; d->pendingClose = false; if (d->state != BoundState) { @@ -1654,6 +1668,8 @@ void QAbstractSocket::connectToHost(const QString &hostName, quint16 port, openMode |= QAbstractSocket::Unbuffered; // QUdpSocket QIODevice::open(openMode); + d->readChannelCount = d->writeChannelCount = 0; + d->state = HostLookupState; emit stateChanged(d->state); @@ -1716,11 +1732,11 @@ void QAbstractSocket::connectToHost(const QHostAddress &address, quint16 port, */ qint64 QAbstractSocket::bytesToWrite() const { - Q_D(const QAbstractSocket); + const qint64 pendingBytes = QIODevice::bytesToWrite(); #if defined(QABSTRACTSOCKET_DEBUG) - qDebug("QAbstractSocket::bytesToWrite() == %lld", d->writeBuffer.size()); + qDebug("QAbstractSocket::bytesToWrite() == %lld", pendingBytes); #endif - return d->writeBuffer.size(); + return pendingBytes; } /*! @@ -1859,8 +1875,8 @@ bool QAbstractSocket::setSocketDescriptor(qintptr socketDescriptor, SocketState Q_D(QAbstractSocket); d->resetSocketLayer(); - d->writeBuffer.clear(); - d->buffer.clear(); + d->setReadChannelCount(0); + d->setWriteChannelCount(0); d->socketEngine = QAbstractSocketEngine::createSocketEngine(socketDescriptor, this); if (!d->socketEngine) { d->setError(UnsupportedSocketOperationError, tr("Operation on socket is not supported")); @@ -1881,6 +1897,23 @@ bool QAbstractSocket::setSocketDescriptor(qintptr socketDescriptor, SocketState QIODevice::open(openMode); + if (socketState == ConnectedState) { + if (isReadable()) { + const int inboundStreamCount = d->socketEngine->inboundStreamCount(); + d->setReadChannelCount(qMax(1, inboundStreamCount)); + if (inboundStreamCount == 0) + d->readChannelCount = 0; + } + if (isWritable()) { + const int outboundStreamCount = d->socketEngine->outboundStreamCount(); + d->setWriteChannelCount(qMax(1, outboundStreamCount)); + if (outboundStreamCount == 0) + d->writeChannelCount = 0; + } + } else { + d->readChannelCount = d->writeChannelCount = 0; + } + if (d->state != socketState) { d->state = socketState; emit stateChanged(d->state); @@ -2138,8 +2171,10 @@ bool QAbstractSocket::waitForReadyRead(int msecs) return false; } - Q_ASSERT(d->socketEngine); do { + if (state() != ConnectedState) + return false; + bool readyToRead = false; bool readyToWrite = false; if (!d->socketEngine->waitForReadOrWrite(&readyToRead, &readyToWrite, true, !d->writeBuffer.isEmpty(), @@ -2161,9 +2196,6 @@ bool QAbstractSocket::waitForReadyRead(int msecs) if (readyToWrite) d->canWriteNotification(); - - if (state() != ConnectedState) - return false; } while (msecs == -1 || qt_subtract_from_timeout(msecs, stopWatch.elapsed()) > 0); return false; } @@ -2212,8 +2244,10 @@ bool QAbstractSocket::waitForBytesWritten(int msecs) forever { bool readyToRead = false; bool readyToWrite = false; - if (!d->socketEngine->waitForReadOrWrite(&readyToRead, &readyToWrite, true, !d->writeBuffer.isEmpty(), - qt_subtract_from_timeout(msecs, stopWatch.elapsed()))) { + if (!d->socketEngine->waitForReadOrWrite(&readyToRead, &readyToWrite, + !d->readBufferMaxSize || d->buffer.size() < d->readBufferMaxSize, + !d->writeBuffer.isEmpty(), + qt_subtract_from_timeout(msecs, stopWatch.elapsed()))) { #if defined (QABSTRACTSOCKET_DEBUG) qDebug("QAbstractSocket::waitForBytesWritten(%i) failed (%i, %s)", msecs, d->socketEngine->error(), d->socketEngine->errorString().toLatin1().constData()); @@ -2228,8 +2262,7 @@ bool QAbstractSocket::waitForBytesWritten(int msecs) #if defined (QABSTRACTSOCKET_DEBUG) qDebug("QAbstractSocket::waitForBytesWritten calls canReadNotification"); #endif - if(!d->canReadNotification()) - return false; + d->canReadNotification(); } @@ -2328,7 +2361,7 @@ void QAbstractSocket::abort() #if defined (QABSTRACTSOCKET_DEBUG) qDebug("QAbstractSocket::abort()"); #endif - d->writeBuffer.clear(); + d->setWriteChannelCount(0); if (d->state == UnconnectedState) return; #ifndef QT_NO_SSL @@ -2472,8 +2505,10 @@ qint64 QAbstractSocket::writeData(const char *data, qint64 size) qt_prettyDebug(data, qMin((int)size, 32), size).data(), size, written); #endif - if (written >= 0) + if (written >= 0) { emit bytesWritten(written); + emit channelBytesWritten(0, written); + } return written; } @@ -2724,7 +2759,7 @@ void QAbstractSocket::disconnectFromHost() d->peerPort = 0; d->localAddress.clear(); d->peerAddress.clear(); - d->writeBuffer.clear(); + d->setWriteChannelCount(0); #if defined(QABSTRACTSOCKET_DEBUG) qDebug("QAbstractSocket::disconnectFromHost() disconnected!"); diff --git a/src/network/socket/qabstractsocket_p.h b/src/network/socket/qabstractsocket_p.h index a5c3fb619b..ab642e039b 100644 --- a/src/network/socket/qabstractsocket_p.h +++ b/src/network/socket/qabstractsocket_p.h @@ -55,7 +55,6 @@ #include "QtCore/qbytearray.h" #include "QtCore/qlist.h" #include "QtCore/qtimer.h" -#include "private/qringbuffer_p.h" #include "private/qiodevice_p.h" #include "private/qabstractsocketengine_p.h" #include "qnetworkproxy.h" @@ -143,8 +142,6 @@ public: void setErrorAndEmit(QAbstractSocket::SocketError errorCode, const QString &errorString); qint64 readBufferMaxSize; - QRingBuffer writeBuffer; - bool isBuffered; QTimer *connectTimer; diff --git a/src/network/socket/qabstractsocketengine.cpp b/src/network/socket/qabstractsocketengine.cpp index d40a3a64a7..3fffff6d5a 100644 --- a/src/network/socket/qabstractsocketengine.cpp +++ b/src/network/socket/qabstractsocketengine.cpp @@ -83,6 +83,8 @@ QAbstractSocketEnginePrivate::QAbstractSocketEnginePrivate() , socketProtocol(QAbstractSocket::UnknownNetworkLayerProtocol) , localPort(0) , peerPort(0) + , inboundStreamCount(0) + , outboundStreamCount(0) , receiver(0) { } @@ -261,4 +263,14 @@ void QAbstractSocketEngine::setPeerPort(quint16 port) d_func()->peerPort = port; } +int QAbstractSocketEngine::inboundStreamCount() const +{ + return d_func()->inboundStreamCount; +} + +int QAbstractSocketEngine::outboundStreamCount() const +{ + return d_func()->outboundStreamCount; +} + QT_END_NAMESPACE diff --git a/src/network/socket/qabstractsocketengine_p.h b/src/network/socket/qabstractsocketengine_p.h index 945e205cfb..0073a8b1f2 100644 --- a/src/network/socket/qabstractsocketengine_p.h +++ b/src/network/socket/qabstractsocketengine_p.h @@ -174,6 +174,8 @@ public: quint16 localPort() const; QHostAddress peerAddress() const; quint16 peerPort() const; + int inboundStreamCount() const; + int outboundStreamCount() const; virtual bool isReadNotificationEnabled() const = 0; virtual void setReadNotificationEnabled(bool enable) = 0; @@ -227,6 +229,8 @@ public: quint16 localPort; QHostAddress peerAddress; quint16 peerPort; + int inboundStreamCount; + int outboundStreamCount; QAbstractSocketEngineReceiver *receiver; }; diff --git a/src/network/socket/qhttpsocketengine.cpp b/src/network/socket/qhttpsocketengine.cpp index 942d19c1b3..642c9bb10f 100644 --- a/src/network/socket/qhttpsocketengine.cpp +++ b/src/network/socket/qhttpsocketengine.cpp @@ -510,7 +510,7 @@ void QHttpSocketEngine::slotSocketConnected() data += "\r\n"; // qDebug() << ">>>>>>>> sending request" << this; // qDebug() << data; -// qDebug() << ">>>>>>>"; +// qDebug(">>>>>>>"); d->socket->write(data); d->state = ConnectSent; } @@ -576,6 +576,7 @@ void QHttpSocketEngine::slotSocketReadNotification() d->state = Connected; setLocalAddress(d->socket->localAddress()); setLocalPort(d->socket->localPort()); + d->inboundStreamCount = d->outboundStreamCount = 1; setState(QAbstractSocket::ConnectedState); d->authenticator.detach(); priv = QAuthenticatorPrivate::getPrivate(d->authenticator); diff --git a/src/network/socket/qlocalserver_win.cpp b/src/network/socket/qlocalserver_win.cpp index c2812e54f8..8cb3449343 100644 --- a/src/network/socket/qlocalserver_win.cpp +++ b/src/network/socket/qlocalserver_win.cpp @@ -198,6 +198,9 @@ bool QLocalServerPrivate::addListener() memset(&listener.overlapped, 0, sizeof(listener.overlapped)); listener.overlapped.hEvent = eventHandle; + + // Beware! ConnectNamedPipe will reset the eventHandle to non-signaled. + // Callers of addListener must check all listeners for connections. if (!ConnectNamedPipe(listener.handle, &listener.overlapped)) { switch (GetLastError()) { case ERROR_IO_PENDING: @@ -205,7 +208,6 @@ bool QLocalServerPrivate::addListener() break; case ERROR_PIPE_CONNECTED: listener.connected = true; - SetEvent(eventHandle); break; default: CloseHandle(listener.handle); @@ -241,7 +243,7 @@ bool QLocalServerPrivate::listen(const QString &name) { Q_Q(QLocalServer); - QString pipePath = QLatin1String("\\\\.\\pipe\\"); + const QLatin1String pipePath("\\\\.\\pipe\\"); if (name.startsWith(pipePath)) fullServerName = name; else @@ -257,6 +259,8 @@ bool QLocalServerPrivate::listen(const QString &name) for (int i = 0; i < SYSTEM_MAX_PENDING_SOCKETS; ++i) if (!addListener()) return false; + + _q_onNewConnection(); return true; } @@ -270,37 +274,43 @@ void QLocalServerPrivate::_q_onNewConnection() { Q_Q(QLocalServer); DWORD dummy; - - // Reset first, otherwise we could reset an event which was asserted - // immediately after we checked the conn status. - ResetEvent(eventHandle); - - // Testing shows that there is indeed absolutely no guarantee which listener gets - // a client connection first, so there is no way around polling all of them. - for (int i = 0; i < listeners.size(); ) { - HANDLE handle = listeners[i].handle; - if (listeners[i].connected - || GetOverlappedResult(handle, &listeners[i].overlapped, &dummy, FALSE)) - { - listeners.removeAt(i); - - addListener(); - - if (pendingConnections.size() > maxPendingConnections) - connectionEventNotifier->setEnabled(false); - - // Make this the last thing so connected slots can wreak the least havoc - q->incomingConnection((quintptr)handle); - } else { - if (GetLastError() != ERROR_IO_INCOMPLETE) { - q->close(); - setError(QLatin1String("QLocalServerPrivate::_q_onNewConnection")); - return; + bool tryAgain; + do { + tryAgain = false; + + // Reset first, otherwise we could reset an event which was asserted + // immediately after we checked the conn status. + ResetEvent(eventHandle); + + // Testing shows that there is indeed absolutely no guarantee which listener gets + // a client connection first, so there is no way around polling all of them. + for (int i = 0; i < listeners.size(); ) { + HANDLE handle = listeners[i].handle; + if (listeners[i].connected + || GetOverlappedResult(handle, &listeners[i].overlapped, &dummy, FALSE)) + { + listeners.removeAt(i); + + addListener(); + + if (pendingConnections.size() > maxPendingConnections) + connectionEventNotifier->setEnabled(false); + else + tryAgain = true; + + // Make this the last thing so connected slots can wreak the least havoc + q->incomingConnection((quintptr)handle); + } else { + if (GetLastError() != ERROR_IO_INCOMPLETE) { + q->close(); + setError(QLatin1String("QLocalServerPrivate::_q_onNewConnection")); + return; + } + + ++i; } - - ++i; } - } + } while (tryAgain); } void QLocalServerPrivate::closeServer() diff --git a/src/network/socket/qlocalsocket_win.cpp b/src/network/socket/qlocalsocket_win.cpp index 4e8ae41479..7f9b8a7b06 100644 --- a/src/network/socket/qlocalsocket_win.cpp +++ b/src/network/socket/qlocalsocket_win.cpp @@ -148,7 +148,7 @@ void QLocalSocket::connectToServer(OpenMode openMode) return; } - QString pipePath = QLatin1String("\\\\.\\pipe\\"); + const QLatin1String pipePath("\\\\.\\pipe\\"); if (d->serverName.startsWith(pipePath)) d->fullServerName = d->serverName; else @@ -220,7 +220,6 @@ qint64 QLocalSocket::writeData(const char *data, qint64 maxSize) d->pipeWriter = new QWindowsPipeWriter(d->handle, this); connect(d->pipeWriter, SIGNAL(canWrite()), this, SLOT(_q_canWrite())); connect(d->pipeWriter, SIGNAL(bytesWritten(qint64)), this, SIGNAL(bytesWritten(qint64))); - d->pipeWriter->start(); } return d->pipeWriter->write(data, maxSize); } diff --git a/src/network/socket/qnativesocketengine.cpp b/src/network/socket/qnativesocketengine.cpp index eefc0792aa..4063a225fb 100644 --- a/src/network/socket/qnativesocketengine.cpp +++ b/src/network/socket/qnativesocketengine.cpp @@ -922,6 +922,7 @@ void QNativeSocketEngine::close() d->localAddress.clear(); d->peerPort = 0; d->peerAddress.clear(); + d->inboundStreamCount = d->outboundStreamCount = 0; if (d->readNotifier) { qDeleteInEventHandler(d->readNotifier); d->readNotifier = 0; diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp index 1a3e2a5cae..de091753d2 100644 --- a/src/network/socket/qnativesocketengine_unix.cpp +++ b/src/network/socket/qnativesocketengine_unix.cpp @@ -1027,6 +1027,7 @@ bool QNativeSocketEnginePrivate::fetchConnectionParameters() localAddress.clear(); peerPort = 0; peerAddress.clear(); + inboundStreamCount = outboundStreamCount = 0; if (socketDescriptor == -1) return false; @@ -1077,8 +1078,10 @@ bool QNativeSocketEnginePrivate::fetchConnectionParameters() #endif // Determine the remote address - if (!::getpeername(socketDescriptor, &sa.a, &sockAddrSize)) + if (!::getpeername(socketDescriptor, &sa.a, &sockAddrSize)) { qt_socket_getPortAndAddress(&sa, &peerPort, &peerAddress); + inboundStreamCount = outboundStreamCount = 1; + } // Determine the socket type (UDP/TCP) int value = 0; @@ -1101,10 +1104,10 @@ bool QNativeSocketEnginePrivate::fetchConnectionParameters() else if (socketType == QAbstractSocket::UdpSocket) socketTypeStr = QStringLiteral("UdpSocket"); qDebug("QNativeSocketEnginePrivate::fetchConnectionParameters() local == %s:%i," - " peer == %s:%i, socket == %s - %s", + " peer == %s:%i, socket == %s - %s, inboundStreamCount == %i, outboundStreamCount == %i", localAddress.toString().toLatin1().constData(), localPort, peerAddress.toString().toLatin1().constData(), peerPort,socketTypeStr.toLatin1().constData(), - socketProtocolStr.toLatin1().constData()); + socketProtocolStr.toLatin1().constData(), inboundStreamCount, outboundStreamCount); #endif return true; } diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp index 20f7ab2622..648f2bf376 100644 --- a/src/network/socket/qnativesocketengine_win.cpp +++ b/src/network/socket/qnativesocketengine_win.cpp @@ -528,6 +528,7 @@ bool QNativeSocketEnginePrivate::fetchConnectionParameters() localAddress.clear(); peerPort = 0; peerAddress.clear(); + inboundStreamCount = outboundStreamCount = 0; if (socketDescriptor == -1) return false; @@ -576,6 +577,7 @@ bool QNativeSocketEnginePrivate::fetchConnectionParameters() memset(&sa, 0, sizeof(sa)); if (::getpeername(socketDescriptor, &sa.a, &sockAddrSize) == 0) { qt_socket_getPortAndAddress(socketDescriptor, &sa, &peerPort, &peerAddress); + inboundStreamCount = outboundStreamCount = 1; } else { WS_ERROR_DEBUG(WSAGetLastError()); } diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp index 68ee1e52d5..0f632abbb3 100644 --- a/src/network/socket/qnativesocketengine_winrt.cpp +++ b/src/network/socket/qnativesocketengine_winrt.cpp @@ -480,6 +480,7 @@ void QNativeSocketEngine::close() d->localAddress.clear(); d->peerPort = 0; d->peerAddress.clear(); + d->inboundStreamCount = d->outboundStreamCount = 0; } bool QNativeSocketEngine::joinMulticastGroup(const QHostAddress &groupAddress, const QNetworkInterface &iface) @@ -1082,6 +1083,7 @@ bool QNativeSocketEnginePrivate::fetchConnectionParameters() localAddress.clear(); peerPort = 0; peerAddress.clear(); + inboundStreamCount = outboundStreamCount = 0; HRESULT hr; if (socketType == QAbstractSocket::TcpSocket) { @@ -1117,6 +1119,7 @@ bool QNativeSocketEnginePrivate::fetchConnectionParameters() hr = info->get_RemotePort(tmpHString.GetAddressOf()); Q_ASSERT_SUCCEEDED(hr); peerPort = qt_QStringFromHString(tmpHString).toInt(); + inboundStreamCount = outboundStreamCount = 1; } } else if (socketType == QAbstractSocket::UdpSocket) { ComPtr<IHostName> hostName; @@ -1144,6 +1147,7 @@ bool QNativeSocketEnginePrivate::fetchConnectionParameters() hr = info->get_RemotePort(tmpHString.GetAddressOf()); Q_ASSERT_SUCCEEDED(hr); peerPort = qt_QStringFromHString(tmpHString).toInt(); + inboundStreamCount = outboundStreamCount = 1; } } return true; diff --git a/src/network/socket/qsocks5socketengine.cpp b/src/network/socket/qsocks5socketengine.cpp index c873cbdedc..0c15810a48 100644 --- a/src/network/socket/qsocks5socketengine.cpp +++ b/src/network/socket/qsocks5socketengine.cpp @@ -352,7 +352,7 @@ void QSocks5BindStore::add(qintptr socketDescriptor, QSocks5BindData *bindData) { QMutexLocker lock(&mutex); if (store.contains(socketDescriptor)) { - // qDebug() << "delete it"; + // qDebug("delete it"); } bindData->timeStamp.start(); store.insert(socketDescriptor, bindData); @@ -370,9 +370,11 @@ bool QSocks5BindStore::contains(qintptr socketDescriptor) QSocks5BindData *QSocks5BindStore::retrieve(qintptr socketDescriptor) { QMutexLocker lock(&mutex); - if (!store.contains(socketDescriptor)) + const auto it = store.constFind(socketDescriptor); + if (it == store.cend()) return 0; - QSocks5BindData *bindData = store.take(socketDescriptor); + QSocks5BindData *bindData = it.value(); + store.erase(it); if (bindData) { if (bindData->controlSocket->thread() != QThread::currentThread()) { qWarning("Can not access socks5 bind data from different thread"); @@ -887,6 +889,7 @@ void QSocks5SocketEnginePrivate::parseRequestMethodReply() localPort = port; if (mode == ConnectMode) { + inboundStreamCount = outboundStreamCount = 1; socks5State = Connected; // notify the upper layer that we're done q->setState(QAbstractSocket::ConnectedState); @@ -1047,6 +1050,7 @@ bool QSocks5SocketEngine::initialize(qintptr socketDescriptor, QAbstractSocket:: d->localAddress = bindData->localAddress; d->peerPort = bindData->peerPort; d->peerAddress = bindData->peerAddress; + d->inboundStreamCount = d->outboundStreamCount = 1; delete bindData; QObject::connect(d->data->controlSocket, SIGNAL(connected()), this, SLOT(_q_controlSocketConnected()), @@ -1187,7 +1191,7 @@ void QSocks5SocketEnginePrivate::_q_controlSocketReadNotification() case Connected: { QByteArray buf; if (!data->authenticator->unSeal(data->controlSocket, &buf)) { - // qDebug() << "unseal error maybe need to wait for more data"; + // qDebug("unseal error maybe need to wait for more data"); } if (buf.size()) { QSOCKS5_DEBUG << dump(buf); @@ -1486,6 +1490,7 @@ void QSocks5SocketEngine::close() } d->data->controlSocket->close(); } + d->inboundStreamCount = d->outboundStreamCount = 0; #ifndef QT_NO_UDPSOCKET if (d->udpData && d->udpData->udpSocket) d->udpData->udpSocket->close(); diff --git a/src/network/ssl/qsslcertificate.cpp b/src/network/ssl/qsslcertificate.cpp index b1ec1d06e2..96ba68089d 100644 --- a/src/network/ssl/qsslcertificate.cpp +++ b/src/network/ssl/qsslcertificate.cpp @@ -482,8 +482,9 @@ QList<QSslCertificate> QSslCertificate::fromPath(const QString &path, if (pos != -1) { // there was a special char in the path so cut of the part containing that char. pathPrefix = pathPrefix.left(pos); - if (pathPrefix.contains(QLatin1Char('/'))) - pathPrefix = pathPrefix.left(pathPrefix.lastIndexOf(QLatin1Char('/'))); + const int lastIndexOfSlash = pathPrefix.lastIndexOf(QLatin1Char('/')); + if (lastIndexOfSlash != -1) + pathPrefix = pathPrefix.left(lastIndexOfSlash); else pathPrefix.clear(); } else { diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp index f1fbc30424..bbc62c47ff 100644 --- a/src/network/ssl/qsslsocket.cpp +++ b/src/network/ssl/qsslsocket.cpp @@ -512,6 +512,8 @@ bool QSslSocket::setSocketDescriptor(qintptr socketDescriptor, SocketState state setPeerPort(d->plainSocket->peerPort()); setPeerAddress(d->plainSocket->peerAddress()); setPeerName(d->plainSocket->peerName()); + d->readChannelCount = d->plainSocket->readChannelCount(); + d->writeChannelCount = d->plainSocket->writeChannelCount(); return retVal; } @@ -1917,6 +1919,7 @@ void QSslSocket::connectToHost(const QString &hostName, quint16 port, OpenMode o d->plainSocket->setProxy(proxy()); #endif QIODevice::open(openMode); + d->readChannelCount = d->writeChannelCount = 0; d->plainSocket->connectToHost(hostName, port, openMode, d->preferredNetworkLayerProtocol); d->cachedSocketDescriptor = d->plainSocket->socketDescriptor(); } @@ -2263,9 +2266,15 @@ void QSslSocketPrivate::createPlainSocket(QIODevice::OpenMode openMode) q->connect(plainSocket, SIGNAL(readyRead()), q, SLOT(_q_readyReadSlot()), Qt::DirectConnection); + q->connect(plainSocket, SIGNAL(channelReadyRead(int)), + q, SLOT(_q_channelReadyReadSlot(int)), + Qt::DirectConnection); q->connect(plainSocket, SIGNAL(bytesWritten(qint64)), q, SLOT(_q_bytesWrittenSlot(qint64)), Qt::DirectConnection); + q->connect(plainSocket, SIGNAL(channelBytesWritten(int, qint64)), + q, SLOT(_q_channelBytesWrittenSlot(int, qint64)), + Qt::DirectConnection); #ifndef QT_NO_NETWORKPROXY q->connect(plainSocket, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), q, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); @@ -2319,6 +2328,7 @@ bool QSslSocketPrivate::bind(const QHostAddress &address, quint16 port, QAbstrac localPort = plainSocket->localPort(); localAddress = plainSocket->localAddress(); cachedSocketDescriptor = plainSocket->socketDescriptor(); + readChannelCount = writeChannelCount = 0; return ret; } @@ -2334,6 +2344,8 @@ void QSslSocketPrivate::_q_connectedSlot() q->setPeerAddress(plainSocket->peerAddress()); q->setPeerName(plainSocket->peerName()); cachedSocketDescriptor = plainSocket->socketDescriptor(); + readChannelCount = plainSocket->readChannelCount(); + writeChannelCount = plainSocket->writeChannelCount(); #ifdef QSSLSOCKET_DEBUG qCDebug(lcSsl) << "QSslSocket::_q_connectedSlot()"; @@ -2439,6 +2451,16 @@ void QSslSocketPrivate::_q_readyReadSlot() /*! \internal */ +void QSslSocketPrivate::_q_channelReadyReadSlot(int channel) +{ + Q_Q(QSslSocket); + if (mode == QSslSocket::UnencryptedMode) + emit q->channelReadyRead(channel); +} + +/*! + \internal +*/ void QSslSocketPrivate::_q_bytesWrittenSlot(qint64 written) { Q_Q(QSslSocket); @@ -2457,6 +2479,16 @@ void QSslSocketPrivate::_q_bytesWrittenSlot(qint64 written) /*! \internal */ +void QSslSocketPrivate::_q_channelBytesWrittenSlot(int channel, qint64 written) +{ + Q_Q(QSslSocket); + if (mode == QSslSocket::UnencryptedMode) + emit q->channelBytesWritten(channel, written); +} + +/*! + \internal +*/ void QSslSocketPrivate::_q_flushWriteBuffer() { Q_Q(QSslSocket); diff --git a/src/network/ssl/qsslsocket.h b/src/network/ssl/qsslsocket.h index dd4c8fec0b..1f2ed7687b 100644 --- a/src/network/ssl/qsslsocket.h +++ b/src/network/ssl/qsslsocket.h @@ -220,7 +220,9 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_stateChangedSlot(QAbstractSocket::SocketState)) Q_PRIVATE_SLOT(d_func(), void _q_errorSlot(QAbstractSocket::SocketError)) Q_PRIVATE_SLOT(d_func(), void _q_readyReadSlot()) + Q_PRIVATE_SLOT(d_func(), void _q_channelReadyReadSlot(int)) Q_PRIVATE_SLOT(d_func(), void _q_bytesWrittenSlot(qint64)) + Q_PRIVATE_SLOT(d_func(), void _q_channelBytesWrittenSlot(int, qint64)) Q_PRIVATE_SLOT(d_func(), void _q_flushWriteBuffer()) Q_PRIVATE_SLOT(d_func(), void _q_flushReadBuffer()) Q_PRIVATE_SLOT(d_func(), void _q_resumeImplementation()) diff --git a/src/network/ssl/qsslsocket_mac.cpp b/src/network/ssl/qsslsocket_mac.cpp index e09a197369..4122db4b65 100644 --- a/src/network/ssl/qsslsocket_mac.cpp +++ b/src/network/ssl/qsslsocket_mac.cpp @@ -646,6 +646,7 @@ void QSslSocketBackendPrivate::transmit() emit q->bytesWritten(totalBytesWritten); emittedBytesWritten = false; } + emit q->channelBytesWritten(0, totalBytesWritten); } } @@ -674,6 +675,7 @@ void QSslSocketBackendPrivate::transmit() if (readyReadEmittedPointer) *readyReadEmittedPointer = true; emit q->readyRead(); + emit q->channelReadyRead(0); } if (err == errSSLWouldBlock) diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index fea73edc63..e164e1be61 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -399,6 +399,10 @@ bool QSslSocketBackendPrivate::initSslContext() if (!ace.isEmpty() && !QHostAddress().setAddress(tlsHostName) && !(configuration.sslOptions & QSsl::SslOptionDisableServerNameIndication)) { + // We don't send the trailing dot from the host header if present see + // https://tools.ietf.org/html/rfc6066#section-3 + if (ace.endsWith('.')) + ace.chop(1); if (!q_SSL_ctrl(ssl, SSL_CTRL_SET_TLSEXT_HOSTNAME, TLSEXT_NAMETYPE_host_name, ace.data())) qCWarning(lcSsl, "could not set SSL_CTRL_SET_TLSEXT_HOSTNAME, Server Name Indication disabled"); } @@ -632,10 +636,12 @@ void QSslSocketPrivate::resetDefaultCiphers() // Unconditionally exclude ADH and AECDH ciphers since they offer no MITM protection if (!ciph.name().toLower().startsWith(QLatin1String("adh")) && !ciph.name().toLower().startsWith(QLatin1String("exp-adh")) && - !ciph.name().toLower().startsWith(QLatin1String("aecdh"))) + !ciph.name().toLower().startsWith(QLatin1String("aecdh"))) { ciphers << ciph; - if (ciph.usedBits() >= 128) - defaultCiphers << ciph; + + if (ciph.usedBits() >= 128) + defaultCiphers << ciph; + } } } } @@ -851,6 +857,7 @@ void QSslSocketBackendPrivate::transmit() emit q->bytesWritten(totalBytesWritten); emittedBytesWritten = false; } + emit q->channelBytesWritten(0, totalBytesWritten); } } @@ -954,6 +961,7 @@ void QSslSocketBackendPrivate::transmit() if (readyReadEmittedPointer) *readyReadEmittedPointer = true; emit q->readyRead(); + emit q->channelReadyRead(0); transmitting = true; continue; } diff --git a/src/network/ssl/qsslsocket_p.h b/src/network/ssl/qsslsocket_p.h index b96cf48d72..7f8dc375b6 100644 --- a/src/network/ssl/qsslsocket_p.h +++ b/src/network/ssl/qsslsocket_p.h @@ -179,7 +179,9 @@ public: void _q_stateChangedSlot(QAbstractSocket::SocketState); void _q_errorSlot(QAbstractSocket::SocketError); void _q_readyReadSlot(); + void _q_channelReadyReadSlot(int); void _q_bytesWrittenSlot(qint64); + void _q_channelBytesWrittenSlot(int, qint64); void _q_flushWriteBuffer(); void _q_flushReadBuffer(); void _q_resumeImplementation(); diff --git a/src/network/ssl/qsslsocket_winrt.cpp b/src/network/ssl/qsslsocket_winrt.cpp index dc5c9a8fac..045c89eb0e 100644 --- a/src/network/ssl/qsslsocket_winrt.cpp +++ b/src/network/ssl/qsslsocket_winrt.cpp @@ -306,6 +306,7 @@ void QSslSocketBackendPrivate::transmit() emit q->bytesWritten(totalBytesWritten); emittedBytesWritten = false; } + emit q->channelBytesWritten(0, totalBytesWritten); } } @@ -323,6 +324,7 @@ void QSslSocketBackendPrivate::transmit() if (readyReadEmittedPointer) *readyReadEmittedPointer = true; emit q->readyRead(); + emit q->channelReadyRead(0); } if (pendingClose) { |