From 669a48e5ae6bcc051b71a0de09dd489275fb74aa Mon Sep 17 00:00:00 2001 From: Juha Vuolle Date: Tue, 8 Aug 2023 11:51:36 +0300 Subject: [PATCH] Functions for setting request transfer timeouts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added to both QNetworkRequestFactory and QRestAccessManager Task-number: QTBUG-114717 Change-Id: Ibca55bba548a034a0da7ea60550642c150b63dc2 Reviewed-by: Ivan Solovev Reviewed-by: Marc Mutz Reviewed-by: MÃ¥rten Nordheim --- src/network/access/qnetworkrequestfactory.cpp | 28 +++++++++++++++++++ src/network/access/qnetworkrequestfactory.h | 5 ++++ src/network/access/qnetworkrequestfactory_p.h | 1 + src/network/access/qrestaccessmanager.cpp | 24 ++++++++++++++++ src/network/access/qrestaccessmanager.h | 5 ++++ .../tst_qnetworkrequestfactory.cpp | 18 ++++++++++++ .../qrestaccessmanager/httptestserver.cpp | 1 + .../tst_qrestaccessmanager.cpp | 16 +++++++++++ 8 files changed, 98 insertions(+) diff --git a/src/network/access/qnetworkrequestfactory.cpp b/src/network/access/qnetworkrequestfactory.cpp index 3f039515cb1..e97fe1c68bf 100644 --- a/src/network/access/qnetworkrequestfactory.cpp +++ b/src/network/access/qnetworkrequestfactory.cpp @@ -349,6 +349,32 @@ void QNetworkRequestFactory::clearBearerToken() d->bearerToken.clear(); } +/*! + Sets \a timeout used for transfers. + + \sa transferTimeout(), QNetworkRequest::setTransferTimeout(), + QRestAccessManager::setTransferTimeout() +*/ +void QNetworkRequestFactory::setTransferTimeout(std::chrono::milliseconds timeout) +{ + if (d->transferTimeout == timeout) + return; + + d.detach(); + d->transferTimeout = timeout; +} + +/*! + Returns the timeout used for transfers. + + \sa setTransferTimeout(), QNetworkRequest::transferTimeout(), + QRestAccessManager::transferTimeout() +*/ +std::chrono::milliseconds QNetworkRequestFactory::transferTimeout() const +{ + return d->transferTimeout; +} + /*! Returns query parameters that are added to individual requests' query parameters. The query parameters are added to any potential query @@ -426,6 +452,7 @@ QNetworkRequest QNetworkRequestFactoryPrivate::newRequest(const QUrl &url) const if (!bearerToken.isEmpty()) request.setRawHeader("Authorization"_ba, Bearer + bearerToken); + request.setTransferTimeout(transferTimeout); return request; } @@ -485,6 +512,7 @@ bool QNetworkRequestFactoryPrivate::equals( const QNetworkRequestFactoryPrivate &other) const noexcept { return + transferTimeout == other.transferTimeout && #if QT_CONFIG(ssl) sslConfig == other.sslConfig && #endif diff --git a/src/network/access/qnetworkrequestfactory.h b/src/network/access/qnetworkrequestfactory.h index 901a61decc5..b84fa0a39bc 100644 --- a/src/network/access/qnetworkrequestfactory.h +++ b/src/network/access/qnetworkrequestfactory.h @@ -12,6 +12,8 @@ #include #include +#include + QT_BEGIN_NAMESPACE #if QT_CONFIG(ssl) @@ -56,6 +58,9 @@ public: Q_NETWORK_EXPORT void setBearerToken(const QByteArray &token); Q_NETWORK_EXPORT void clearBearerToken(); + Q_NETWORK_EXPORT void setTransferTimeout(std::chrono::milliseconds timeout); + Q_NETWORK_EXPORT std::chrono::milliseconds transferTimeout() const; + Q_NETWORK_EXPORT QUrlQuery queryParameters() const; Q_NETWORK_EXPORT void setQueryParameters(const QUrlQuery &query); Q_NETWORK_EXPORT void clearQueryParameters(); diff --git a/src/network/access/qnetworkrequestfactory_p.h b/src/network/access/qnetworkrequestfactory_p.h index d90d83361bc..8378669ce90 100644 --- a/src/network/access/qnetworkrequestfactory_p.h +++ b/src/network/access/qnetworkrequestfactory_p.h @@ -43,6 +43,7 @@ public: QHttpHeaders headers; QByteArray bearerToken; QUrlQuery queryParameters; + std::chrono::milliseconds transferTimeout{0}; }; QT_END_NAMESPACE diff --git a/src/network/access/qrestaccessmanager.cpp b/src/network/access/qrestaccessmanager.cpp index c4efa846a2d..be5c64a2dcd 100644 --- a/src/network/access/qrestaccessmanager.cpp +++ b/src/network/access/qrestaccessmanager.cpp @@ -542,6 +542,30 @@ void QRestAccessManager::abortRequests() req->abort(); } +/*! + Sets \a timeout used for transfers. + + \sa QNetworkAccessManager::setTransferTimeout(), transferTimeout(), + QNetworkRequestFactory::setTransferTimeout() +*/ +void QRestAccessManager::setTransferTimeout(std::chrono::milliseconds timeout) +{ + Q_D(QRestAccessManager); + d->qnam->setTransferTimeout(timeout); +} + +/*! + Returns the timeout used for transfers. + + \sa setTransferTimeout(), QNetworkAccessManager::transferTimeoutAsDuration(), + QNetworkRequestFactory::transferTimeout() +*/ +std::chrono::milliseconds QRestAccessManager::transferTimeout() const +{ + Q_D(const QRestAccessManager); + return d->qnam->transferTimeoutAsDuration(); +} + /*! Returns the underlying QNetworkAccessManager instance. The instance can be used for accessing less-frequently used features and configurations. diff --git a/src/network/access/qrestaccessmanager.h b/src/network/access/qrestaccessmanager.h index 7b67486a2e4..6cfca383b4e 100644 --- a/src/network/access/qrestaccessmanager.h +++ b/src/network/access/qrestaccessmanager.h @@ -6,6 +6,8 @@ #include +#include + QT_BEGIN_NAMESPACE class QRestReply; @@ -69,6 +71,9 @@ public: bool deletesRepliesOnFinished() const; void setDeletesRepliesOnFinished(bool autoDelete); + void setTransferTimeout(std::chrono::milliseconds timeout); + std::chrono::milliseconds transferTimeout() const; + void abortRequests(); QREST_METHOD_NO_DATA(deleteResource) diff --git a/tests/auto/network/access/qnetworkrequestfactory/tst_qnetworkrequestfactory.cpp b/tests/auto/network/access/qnetworkrequestfactory/tst_qnetworkrequestfactory.cpp index 2413065920f..332c09cdf9a 100644 --- a/tests/auto/network/access/qnetworkrequestfactory/tst_qnetworkrequestfactory.cpp +++ b/tests/auto/network/access/qnetworkrequestfactory/tst_qnetworkrequestfactory.cpp @@ -10,6 +10,7 @@ #include using namespace Qt::StringLiterals; +using namespace std::chrono_literals; class tst_QNetworkRequestFactory : public QObject { @@ -23,6 +24,7 @@ private Q_SLOTS: void headers(); void bearerToken(); void operators(); + void timeout(); private: const QUrl url1{u"http://foo.io"_s}; @@ -310,5 +312,21 @@ void tst_QNetworkRequestFactory::operators() QCOMPARE(factory5.baseUrl(), url1); } +void tst_QNetworkRequestFactory::timeout() +{ + constexpr auto defaultTimeout = 0ms; + constexpr auto timeout = 150ms; + + QNetworkRequestFactory factory; + QNetworkRequest request = factory.request(); + QCOMPARE(factory.transferTimeout(), defaultTimeout); + QCOMPARE(request.transferTimeoutAsDuration(), defaultTimeout); + + factory.setTransferTimeout(timeout); + request = factory.request(); + QCOMPARE(factory.transferTimeout(), timeout); + QCOMPARE(request.transferTimeoutAsDuration(), timeout); +} + QTEST_MAIN(tst_QNetworkRequestFactory) #include "tst_qnetworkrequestfactory.moc" diff --git a/tests/auto/network/access/qrestaccessmanager/httptestserver.cpp b/tests/auto/network/access/qrestaccessmanager/httptestserver.cpp index 6e2f82a217b..ac58834812b 100644 --- a/tests/auto/network/access/qrestaccessmanager/httptestserver.cpp +++ b/tests/auto/network/access/qrestaccessmanager/httptestserver.cpp @@ -6,6 +6,7 @@ #include #include + #include using namespace Qt::StringLiterals; diff --git a/tests/auto/network/access/qrestaccessmanager/tst_qrestaccessmanager.cpp b/tests/auto/network/access/qrestaccessmanager/tst_qrestaccessmanager.cpp index 9834818ad79..960984be1cf 100644 --- a/tests/auto/network/access/qrestaccessmanager/tst_qrestaccessmanager.cpp +++ b/tests/auto/network/access/qrestaccessmanager/tst_qrestaccessmanager.cpp @@ -19,6 +19,7 @@ #include using namespace Qt::StringLiterals; +using namespace std::chrono_literals; class tst_QRestAccessManager : public QObject { @@ -40,6 +41,7 @@ private slots: void text(); void download(); void upload(); + void timeout(); private: void memberHandler(QRestReply *reply); @@ -893,5 +895,19 @@ void tst_QRestAccessManager::upload() QCOMPARE(last.at(0).toLongLong(), expectedData.size()); } +void tst_QRestAccessManager::timeout() +{ + constexpr auto defaultTimeout = 0ms; + constexpr auto timeout = 150ms; + + QRestAccessManager manager; + QCOMPARE(manager.transferTimeout(), defaultTimeout); + QCOMPARE(manager.networkAccessManager()->transferTimeoutAsDuration(), defaultTimeout); + + manager.setTransferTimeout(timeout); + QCOMPARE(manager.transferTimeout(), timeout); + QCOMPARE(manager.networkAccessManager()->transferTimeoutAsDuration(), timeout); +} + QTEST_MAIN(tst_QRestAccessManager) #include "tst_qrestaccessmanager.moc"