diff options
author | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2019-10-30 01:00:32 +0100 |
---|---|---|
committer | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2019-10-30 01:00:33 +0100 |
commit | cd04181b2ba20e98a29a1782b3736539f70f6607 (patch) | |
tree | a5c82740a2145599d3d9a70598180f0cbe046ad9 /src/network | |
parent | 3ea6a13a01f513ab491f698109fdf189e6264203 (diff) | |
parent | b56e856d218976bf39d981468267337d8d6223f5 (diff) |
Merge remote-tracking branch 'origin/5.15' into dev
Change-Id: I7f11733bda960196a96c6452bdabeb7072a8430d
Diffstat (limited to 'src/network')
-rw-r--r-- | src/network/access/qnetworkreplyhttpimpl.cpp | 36 | ||||
-rw-r--r-- | src/network/access/qnetworkreplyhttpimpl_p.h | 7 | ||||
-rw-r--r-- | src/network/access/qnetworkrequest.cpp | 50 | ||||
-rw-r--r-- | src/network/access/qnetworkrequest.h | 6 | ||||
-rw-r--r-- | src/network/kernel/qnetworkproxy_mac.cpp | 7 |
5 files changed, 98 insertions, 8 deletions
diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp index 0bd7825186..f4b8661fe7 100644 --- a/src/network/access/qnetworkreplyhttpimpl.cpp +++ b/src/network/access/qnetworkreplyhttpimpl.cpp @@ -461,6 +461,7 @@ QNetworkReplyHttpImplPrivate::QNetworkReplyHttpImplPrivate() , preMigrationDownloaded(-1) , bytesDownloaded(0) , bytesBuffered(0) + , transferTimeout(nullptr) , downloadBufferReadPosition(0) , downloadBufferCurrentSize(0) , downloadZerocopyBuffer(nullptr) @@ -1064,6 +1065,7 @@ void QNetworkReplyHttpImplPrivate::replyDownloadData(QByteArray d) if (!isHttpRedirectResponse()) { buffer.append(d); bytesDownloaded += d.size(); + setupTransferTimeout(); } bytesBuffered += d.size(); @@ -1389,6 +1391,7 @@ void QNetworkReplyHttpImplPrivate::replyDownloadProgressSlot(qint64 bytesReceive return; bytesDownloaded = bytesReceived; + setupTransferTimeout(); downloadBufferCurrentSize = bytesReceived; @@ -1845,7 +1848,6 @@ bool QNetworkReplyHttpImplPrivate::startWaitForSession(QSharedPointer<QNetworkSe void QNetworkReplyHttpImplPrivate::_q_startOperation() { Q_Q(QNetworkReplyHttpImpl); - if (state == Working) // ensure this function is only being called once return; @@ -1885,6 +1887,7 @@ void QNetworkReplyHttpImplPrivate::_q_startOperation() } #endif // QT_NO_BEARERMANAGEMENT + setupTransferTimeout(); if (synchronous) { state = Finished; q_func()->setFinished(true); @@ -2021,6 +2024,31 @@ void QNetworkReplyHttpImplPrivate::_q_bufferOutgoingData() } } +void QNetworkReplyHttpImplPrivate::_q_transferTimedOut() +{ + Q_Q(QNetworkReplyHttpImpl); + q->abort(); +} + +void QNetworkReplyHttpImplPrivate::setupTransferTimeout() +{ + Q_Q(QNetworkReplyHttpImpl); + if (!transferTimeout) { + transferTimeout = new QTimer(q); + QObject::connect(transferTimeout, SIGNAL(timeout()), + q, SLOT(_q_transferTimedOut()), + Qt::QueuedConnection); + } + transferTimeout->stop(); + if (request.transferTimeout()) { + transferTimeout->setSingleShot(true); + transferTimeout->setInterval(request.transferTimeout()); + QMetaObject::invokeMethod(transferTimeout, "start", + Qt::QueuedConnection); + + } +} + #ifndef QT_NO_BEARERMANAGEMENT void QNetworkReplyHttpImplPrivate::_q_networkSessionConnected() { @@ -2103,6 +2131,8 @@ void QNetworkReplyHttpImplPrivate::emitReplyUploadProgress(qint64 bytesSent, qin if (isFinished) return; + setupTransferTimeout(); + if (!emitAllUploadProgressSignals) { //choke signal emissions, except the first and last signals which are unconditional if (uploadProgressSignalChoke.isValid()) { @@ -2114,7 +2144,6 @@ void QNetworkReplyHttpImplPrivate::emitReplyUploadProgress(qint64 bytesSent, qin uploadProgressSignalChoke.start(); } } - emit q->uploadProgress(bytesSent, bytesTotal); } @@ -2147,7 +2176,8 @@ void QNetworkReplyHttpImplPrivate::_q_finished() void QNetworkReplyHttpImplPrivate::finished() { Q_Q(QNetworkReplyHttpImpl); - + if (transferTimeout) + transferTimeout->stop(); if (state == Finished || state == Aborted || state == WaitingForSession) return; diff --git a/src/network/access/qnetworkreplyhttpimpl_p.h b/src/network/access/qnetworkreplyhttpimpl_p.h index ef69ce0653..dec0c4c589 100644 --- a/src/network/access/qnetworkreplyhttpimpl_p.h +++ b/src/network/access/qnetworkreplyhttpimpl_p.h @@ -59,6 +59,7 @@ #include "QtCore/qdatetime.h" #include "QtCore/qsharedpointer.h" #include "QtCore/qscopedpointer.h" +#include "QtCore/qtimer.h" #include "qatomic.h" #include <QtNetwork/QNetworkCacheMetaData> @@ -100,6 +101,7 @@ public: Q_PRIVATE_SLOT(d_func(), void _q_cacheLoadReadyRead()) Q_PRIVATE_SLOT(d_func(), void _q_bufferOutgoingData()) Q_PRIVATE_SLOT(d_func(), void _q_bufferOutgoingDataFinished()) + Q_PRIVATE_SLOT(d_func(), void _q_transferTimedOut()) #ifndef QT_NO_BEARERMANAGEMENT Q_PRIVATE_SLOT(d_func(), void _q_networkSessionConnected()) Q_PRIVATE_SLOT(d_func(), void _q_networkSessionFailed()) @@ -181,6 +183,9 @@ public: void _q_cacheSaveDeviceAboutToClose(); + void _q_transferTimedOut(); + void setupTransferTimeout(); + #ifndef QT_NO_BEARERMANAGEMENT void _q_networkSessionConnected(); void _q_networkSessionFailed(); @@ -250,6 +255,8 @@ public: qint64 bytesDownloaded; qint64 bytesBuffered; + QTimer *transferTimeout; + // Only used when the "zero copy" style is used. // Please note that the whole "zero copy" download buffer API is private right now. Do not use it. qint64 downloadBufferReadPosition; diff --git a/src/network/access/qnetworkrequest.cpp b/src/network/access/qnetworkrequest.cpp index 1deaa03f71..06ba3a96da 100644 --- a/src/network/access/qnetworkrequest.cpp +++ b/src/network/access/qnetworkrequest.cpp @@ -407,6 +407,18 @@ QT_BEGIN_NAMESPACE based on some app-specific configuration. */ +/*! + \enum QNetworkRequest::TransferTimeoutConstant + \since 5.15 + + A constant that can be used for enabling transfer + timeouts with a preset value. + + \value TransferTimeoutPreset The transfer timeout in milliseconds. + Used if setTimeout() is called + without an argument. + */ + class QNetworkRequestPrivate: public QSharedData, public QNetworkHeadersPrivate { public: @@ -417,6 +429,7 @@ public: , sslConfiguration(0) #endif , maxRedirectsAllowed(maxRedirectCount) + , transferTimeout(0) { qRegisterMetaType<QNetworkRequest>(); } ~QNetworkRequestPrivate() { @@ -441,6 +454,7 @@ public: #if QT_CONFIG(http) h2Configuration = other.h2Configuration; #endif + transferTimeout = other.transferTimeout; } inline bool operator==(const QNetworkRequestPrivate &other) const @@ -454,6 +468,7 @@ public: #if QT_CONFIG(http) && h2Configuration == other.h2Configuration #endif + && transferTimeout == other.transferTimeout ; // don't compare cookedHeaders } @@ -468,6 +483,7 @@ public: #if QT_CONFIG(http) QHttp2Configuration h2Configuration; #endif + int transferTimeout; }; /*! @@ -891,6 +907,40 @@ void QNetworkRequest::setHttp2Configuration(const QHttp2Configuration &configura { d->h2Configuration = configuration; } + +/*! + \since 5.15 + + Returns the timeout used for transfers, in milliseconds. + + This timeout is zero if setTransferTimeout hasn't been + called, which means that the timeout is not used. + + \sa setTransferTimeout +*/ +int QNetworkRequest::transferTimeout() +{ + return d->transferTimeout; +} + +/*! + \since 5.15 + + Sets \a timeout as the transfer timeout in milliseconds. + + Transfers are aborted if no bytes are transferred before + the timeout expires. Zero means no timer is set. If no + argument is provided, the timeout is + QNetworkRequest::TransferTimeoutPreset. If this function + is not called, the timeout is disabled and has the + value zero. + + \sa transferTimeout +*/ +void QNetworkRequest::setTransferTimeout(int timeout) +{ + d->transferTimeout = timeout; +} #endif // QT_CONFIG(http) || defined(Q_CLANG_QDOC) static QByteArray headerName(QNetworkRequest::KnownHeaders header) diff --git a/src/network/access/qnetworkrequest.h b/src/network/access/qnetworkrequest.h index 95b5dc89b5..e9098accd9 100644 --- a/src/network/access/qnetworkrequest.h +++ b/src/network/access/qnetworkrequest.h @@ -126,6 +126,9 @@ public: UserVerifiedRedirectPolicy }; + enum TransferTimeoutConstant { + TransferTimeoutPreset = 30000 + }; QNetworkRequest(); explicit QNetworkRequest(const QUrl &url); @@ -177,6 +180,9 @@ public: #if QT_CONFIG(http) || defined(Q_CLANG_QDOC) QHttp2Configuration http2Configuration() const; void setHttp2Configuration(const QHttp2Configuration &configuration); + + int transferTimeout(); + void setTransferTimeout(int timeout = TransferTimeoutPreset); #endif // QT_CONFIG(http) || defined(Q_CLANG_QDOC) private: QSharedDataPointer<QNetworkRequestPrivate> d; diff --git a/src/network/kernel/qnetworkproxy_mac.cpp b/src/network/kernel/qnetworkproxy_mac.cpp index 92f91956b9..67fda24ea6 100644 --- a/src/network/kernel/qnetworkproxy_mac.cpp +++ b/src/network/kernel/qnetworkproxy_mac.cpp @@ -210,16 +210,14 @@ QList<QNetworkProxy> macQueryInternal(const QNetworkProxyQuery &query) QList<QNetworkProxy> result; // obtain a dictionary to the proxy settings: - CFDictionaryRef dict = SCDynamicStoreCopyProxies(NULL); + const QCFType<CFDictionaryRef> dict = SCDynamicStoreCopyProxies(NULL); if (!dict) { qWarning("QNetworkProxyFactory::systemProxyForQuery: SCDynamicStoreCopyProxies returned NULL"); return result; // failed } - if (isHostExcluded(dict, query.peerHostName())) { - CFRelease(dict); + if (isHostExcluded(dict, query.peerHostName())) return result; // no proxy for this host - } // is there a PAC enabled? If so, use it first. CFNumberRef pacEnabled; @@ -329,7 +327,6 @@ QList<QNetworkProxy> macQueryInternal(const QNetworkProxyQuery &query) result << https; } - CFRelease(dict); return result; } |