Add setAutoDeleteReplies to QNetworkAccessManager
Following the introduction of AutoDeleteReplyOnFinishAttribute to QNetworkRequest it seems natural to make it easy to enable for all replies created with the current QNetworkAccessManager. [ChangeLog][QtNetwork][QNetworkAccessManager] Added setAutoDeleteReplies to QNetworkAccessManager to enable the AutoDeleteReplyOnFinishAttribute attribute for all QNetworkRequests that are passed to QNetworkAccessManager. Change-Id: I7f96dd1fc9a899328e89732be17780b4e710c2a2 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Markus Goetz (Woboq GmbH) <markus@woboq.com> Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
parent
927eba344c
commit
cd816d4b6a
|
|
@ -1402,6 +1402,11 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera
|
|||
req.setAttribute(QNetworkRequest::RedirectPolicyAttribute, redirectPolicy());
|
||||
}
|
||||
|
||||
if (autoDeleteReplies()
|
||||
&& req.attribute(QNetworkRequest::AutoDeleteReplyOnFinishAttribute).isNull()) {
|
||||
req.setAttribute(QNetworkRequest::AutoDeleteReplyOnFinishAttribute, true);
|
||||
}
|
||||
|
||||
bool isLocalFile = req.url().isLocalFile();
|
||||
QString scheme = req.url().scheme();
|
||||
|
||||
|
|
@ -1672,6 +1677,40 @@ void QNetworkAccessManager::clearConnectionCache()
|
|||
QNetworkAccessManagerPrivate::clearConnectionCache(this);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\since 5.14
|
||||
|
||||
Returns the true if QNetworkAccessManager is currently configured
|
||||
to automatically delete QNetworkReplies, false otherwise.
|
||||
|
||||
\sa setAutoDeleteReplies,
|
||||
QNetworkRequest::AutoDeleteReplyOnFinishAttribute
|
||||
*/
|
||||
bool QNetworkAccessManager::autoDeleteReplies()
|
||||
{
|
||||
return d_func()->autoDeleteReplies;
|
||||
}
|
||||
|
||||
/*!
|
||||
\since 5.14
|
||||
|
||||
Enables or disables automatic deletion of \l {QNetworkReply} {QNetworkReplies}.
|
||||
|
||||
Setting \a shouldAutoDelete to true is the same as setting the
|
||||
QNetworkRequest::AutoDeleteReplyOnFinishAttribute attribute to
|
||||
true on all \e{future} \l {QNetworkRequest} {QNetworkRequests}
|
||||
passed to this instance of QNetworkAccessManager unless the
|
||||
attribute was already explicitly set on the QNetworkRequest.
|
||||
|
||||
\sa autoDeleteReplies,
|
||||
QNetworkRequest::AutoDeleteReplyOnFinishAttribute
|
||||
*/
|
||||
void QNetworkAccessManager::setAutoDeleteReplies(bool shouldAutoDelete)
|
||||
{
|
||||
d_func()->autoDeleteReplies = shouldAutoDelete;
|
||||
}
|
||||
|
||||
void QNetworkAccessManagerPrivate::_q_replyFinished()
|
||||
{
|
||||
Q_Q(QNetworkAccessManager);
|
||||
|
|
|
|||
|
|
@ -167,6 +167,9 @@ public:
|
|||
void setRedirectPolicy(QNetworkRequest::RedirectPolicy policy);
|
||||
QNetworkRequest::RedirectPolicy redirectPolicy() const;
|
||||
|
||||
bool autoDeleteReplies();
|
||||
void setAutoDeleteReplies(bool autoDelete);
|
||||
|
||||
Q_SIGNALS:
|
||||
#ifndef QT_NO_NETWORKPROXY
|
||||
void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator);
|
||||
|
|
|
|||
|
|
@ -227,6 +227,8 @@ public:
|
|||
bool stsEnabled = false;
|
||||
mutable QNetworkStatusMonitor statusMonitor;
|
||||
|
||||
bool autoDeleteReplies = false;
|
||||
|
||||
#ifndef QT_NO_BEARERMANAGEMENT
|
||||
Q_AUTOTEST_EXPORT static const QWeakPointer<const QNetworkSession> getNetworkSession(const QNetworkAccessManager *manager);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -505,6 +505,8 @@ private Q_SLOTS:
|
|||
|
||||
void autoDeleteRepliesAttribute_data();
|
||||
void autoDeleteRepliesAttribute();
|
||||
void autoDeleteReplies_data();
|
||||
void autoDeleteReplies();
|
||||
|
||||
// NOTE: This test must be last!
|
||||
void parentingRepliesToTheApp();
|
||||
|
|
@ -9241,6 +9243,95 @@ void tst_QNetworkReply::autoDeleteRepliesAttribute()
|
|||
}
|
||||
}
|
||||
|
||||
void tst_QNetworkReply::autoDeleteReplies_data()
|
||||
{
|
||||
autoDeleteRepliesAttribute_data();
|
||||
}
|
||||
|
||||
void tst_QNetworkReply::autoDeleteReplies()
|
||||
{
|
||||
QFETCH(QUrl, destination);
|
||||
manager.setAutoDeleteReplies(true);
|
||||
auto cleanup = qScopeGuard([this] { manager.setAutoDeleteReplies(false); });
|
||||
{
|
||||
// Get
|
||||
QNetworkRequest request(destination);
|
||||
QNetworkReply *reply = manager.get(request);
|
||||
QSignalSpy finishedSpy(reply, &QNetworkReply::finished);
|
||||
QSignalSpy destroyedSpy(reply, &QObject::destroyed);
|
||||
QVERIFY(finishedSpy.wait());
|
||||
QCOMPARE(destroyedSpy.count(), 0);
|
||||
QVERIFY(destroyedSpy.wait());
|
||||
}
|
||||
{
|
||||
// Post
|
||||
QNetworkRequest request(destination);
|
||||
QNetworkReply *reply = manager.post(request, QByteArrayLiteral("datastring"));
|
||||
QSignalSpy finishedSpy(reply, &QNetworkReply::finished);
|
||||
QSignalSpy destroyedSpy(reply, &QObject::destroyed);
|
||||
QVERIFY(finishedSpy.wait());
|
||||
QCOMPARE(destroyedSpy.count(), 0);
|
||||
QVERIFY(destroyedSpy.wait());
|
||||
}
|
||||
// Here we repeat the test, but override the auto-deletion in the QNetworkRequest
|
||||
// We need two calls to processEvents to test that the QNetworkReply doesn't get deleted.
|
||||
// The first call executes a metacall event which adds the deleteLater meta event which
|
||||
// would be executed in the second call. But that shouldn't happen in this case.
|
||||
{
|
||||
// Get
|
||||
QNetworkRequest request(destination);
|
||||
request.setAttribute(QNetworkRequest::AutoDeleteReplyOnFinishAttribute, false);
|
||||
QScopedPointer<QNetworkReply> reply(manager.get(request));
|
||||
QSignalSpy finishedSpy(reply.data(), &QNetworkReply::finished);
|
||||
QSignalSpy destroyedSpy(reply.data(), &QObject::destroyed);
|
||||
QVERIFY(finishedSpy.wait());
|
||||
QCOMPARE(destroyedSpy.count(), 0);
|
||||
QCoreApplication::processEvents();
|
||||
QCoreApplication::processEvents();
|
||||
QCOMPARE(destroyedSpy.count(), 0);
|
||||
}
|
||||
{
|
||||
// Post
|
||||
QNetworkRequest request(destination);
|
||||
request.setAttribute(QNetworkRequest::AutoDeleteReplyOnFinishAttribute, false);
|
||||
QScopedPointer<QNetworkReply> reply(manager.post(request, QByteArrayLiteral("datastring")));
|
||||
QSignalSpy finishedSpy(reply.data(), &QNetworkReply::finished);
|
||||
QSignalSpy destroyedSpy(reply.data(), &QObject::destroyed);
|
||||
QVERIFY(finishedSpy.wait());
|
||||
QCOMPARE(destroyedSpy.count(), 0);
|
||||
QCoreApplication::processEvents();
|
||||
QCoreApplication::processEvents();
|
||||
QCOMPARE(destroyedSpy.count(), 0);
|
||||
}
|
||||
// Now we repeat the test with autoDeleteReplies set to false
|
||||
cleanup.dismiss();
|
||||
manager.setAutoDeleteReplies(false);
|
||||
{
|
||||
// Get
|
||||
QNetworkRequest request(destination);
|
||||
QScopedPointer<QNetworkReply> reply(manager.get(request));
|
||||
QSignalSpy finishedSpy(reply.data(), &QNetworkReply::finished);
|
||||
QSignalSpy destroyedSpy(reply.data(), &QObject::destroyed);
|
||||
QVERIFY(finishedSpy.wait());
|
||||
QCOMPARE(destroyedSpy.count(), 0);
|
||||
QCoreApplication::processEvents();
|
||||
QCoreApplication::processEvents();
|
||||
QCOMPARE(destroyedSpy.count(), 0);
|
||||
}
|
||||
{
|
||||
// Post
|
||||
QNetworkRequest request(destination);
|
||||
QScopedPointer<QNetworkReply> reply(manager.post(request, QByteArrayLiteral("datastring")));
|
||||
QSignalSpy finishedSpy(reply.data(), &QNetworkReply::finished);
|
||||
QSignalSpy destroyedSpy(reply.data(), &QObject::destroyed);
|
||||
QVERIFY(finishedSpy.wait());
|
||||
QCOMPARE(destroyedSpy.count(), 0);
|
||||
QCoreApplication::processEvents();
|
||||
QCoreApplication::processEvents();
|
||||
QCOMPARE(destroyedSpy.count(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: This test must be last testcase in tst_qnetworkreply!
|
||||
void tst_QNetworkReply::parentingRepliesToTheApp()
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue