[frameworks/kdav] src/common: Make sure network replies are parented to the corresponding job
Kevin Ottens <[email protected]>
| Newsgroups | gmane.comp.kde.cvs |
|---|---|
| Message-ID | <[email protected]> |
Git commit cf782b4b37013dece8dbf2abfeadf4b8880acdca by Kevin Ottens, on behalf of Kevin Ottens.
Committed on 28/07/2026 at 19:57.
Pushed by ervin into branch 'master'.
Make sure network replies are parented to the corresponding job
Otherwise they are parented to the DavManager's QNetworkAccessManager by
default which would keep the replies alive and potentially leaked if the
job is destroyed too early.
M +1 -1 src/common/davcollectioncreatejob.cpp
M +1 -0 src/common/davcollectiondeletejob.cpp
M +1 -1 src/common/davcollectionmodifyjob.cpp
M +1 -1 src/common/davcollectionsfetchjob.cpp
M +1 -0 src/common/davitemcreatejob.cpp
M +1 -0 src/common/davitemdeletejob.cpp
M +1 -0 src/common/davitemfetchjob.cpp
M +1 -0 src/common/davitemmodifyjob.cpp
M +1 -1 src/common/davitemsfetchjob.cpp
M +2 -2 src/common/davitemslistjob.cpp
M +13 -10 src/common/davmanager.cpp
M +6 -5 src/common/davmanager_p.h
M +1 -1 src/common/davprincipalhomesetsfetchjob.cpp
M +2 -2 src/common/davprincipalsearchjob.cpp
https://invent.kde.org/frameworks/kdav/-/commit/cf782b4b37013dece8dbf2abfeadf4b8880acdca
diff --git a/src/common/davcollectioncreatejob.cpp b/src/common/davcollectioncreatejob.cpp
index 08f81ea..04dd4d6 100644
--- a/src/common/davcollectioncreatejob.cpp
+++ b/src/common/davcollectioncreatejob.cpp
@@ -58,7 +58,7 @@ void DavCollectionCreateJob::start()
Q_ASSERT(output.startsWith(QStringLiteral("<?xml version=\"1.0\"?>\n")));
output = output.mid(22);
- QNetworkReply *reply = DavManager::self()->createMkColJob(d->mCollection.url().url(), output);
+ QNetworkReply *reply = DavManager::self()->createMkColJob(this, d->mCollection.url().url(), output);
connect(reply, &QNetworkReply::finished, this, [d, reply]() {
d->davJobFinished(reply);
});
diff --git a/src/common/davcollectiondeletejob.cpp b/src/common/davcollectiondeletejob.cpp
index bb3ba03..edb340c 100644
--- a/src/common/davcollectiondeletejob.cpp
+++ b/src/common/davcollectiondeletejob.cpp
@@ -40,6 +40,7 @@ void DavCollectionDeleteJob::start()
request.setHeader(QNetworkRequest::UserAgentHeader, DavManager::self()->userAgent());
QNetworkReply *reply = DavManager::self()->networkAccessManager()->deleteResource(request);
+ reply->setParent(this);
connect(reply, &QNetworkReply::finished, this, [d, reply]() {
d->davJobFinished(reply);
});
diff --git a/src/common/davcollectionmodifyjob.cpp b/src/common/davcollectionmodifyjob.cpp
index dc146f8..e7b645d 100644
--- a/src/common/davcollectionmodifyjob.cpp
+++ b/src/common/davcollectionmodifyjob.cpp
@@ -107,7 +107,7 @@ void DavCollectionModifyJob::start()
}
}
- QNetworkReply *reply = DavManager::self()->createPropPatchJob(d->mUrl.url(), mQuery.toString());
+ QNetworkReply *reply = DavManager::self()->createPropPatchJob(this, d->mUrl.url(), mQuery.toString());
connect(reply, &QNetworkReply::finished, this, [d, reply]() {
d->davJobFinished(reply);
});
diff --git a/src/common/davcollectionsfetchjob.cpp b/src/common/davcollectionsfetchjob.cpp
index ce84441..af45d47 100644
--- a/src/common/davcollectionsfetchjob.cpp
+++ b/src/common/davcollectionsfetchjob.cpp
@@ -80,7 +80,7 @@ void DavCollectionsFetchJobPrivate::doCollectionsFetch(const QUrl &url)
const QDomDocument collectionQuery = DavManager::davProtocol(mUrl.protocol())->collectionsQuery()->buildQuery();
- QNetworkReply *reply = DavManager::self()->createPropFindJob(url, collectionQuery.toString());
+ QNetworkReply *reply = DavManager::self()->createPropFindJob(q_ptr, url, collectionQuery.toString());
QObject::connect(reply, &QNetworkReply::finished, q_ptr, [this, reply, url]() {
collectionsFetchFinished(reply, url);
});
diff --git a/src/common/davitemcreatejob.cpp b/src/common/davitemcreatejob.cpp
index b54ac55..cb599d3 100644
--- a/src/common/davitemcreatejob.cpp
+++ b/src/common/davitemcreatejob.cpp
@@ -49,6 +49,7 @@ void DavItemCreateJob::start()
request.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::ManualRedirectPolicy);
QNetworkReply *reply = DavManager::self()->networkAccessManager()->put(request, d->mItem.data());
+ reply->setParent(this);
connect(reply, &QNetworkReply::finished, this, [d, reply]() {
d->davJobFinished(reply);
});
diff --git a/src/common/davitemdeletejob.cpp b/src/common/davitemdeletejob.cpp
index a627e0b..2714496 100644
--- a/src/common/davitemdeletejob.cpp
+++ b/src/common/davitemdeletejob.cpp
@@ -45,6 +45,7 @@ void DavItemDeleteJob::start()
request.setHeader(QNetworkRequest::UserAgentHeader, DavManager::self()->userAgent());
QNetworkReply *reply = DavManager::self()->networkAccessManager()->deleteResource(request);
+ reply->setParent(this);
connect(reply, &QNetworkReply::finished, this, [d, reply]() {
d->davJobFinished(reply);
});
diff --git a/src/common/davitemfetchjob.cpp b/src/common/davitemfetchjob.cpp
index 60c011c..46dbca7 100644
--- a/src/common/davitemfetchjob.cpp
+++ b/src/common/davitemfetchjob.cpp
@@ -40,6 +40,7 @@ void DavItemFetchJob::start()
request.setHeader(QNetworkRequest::UserAgentHeader, DavManager::self()->userAgent());
QNetworkReply *reply = DavManager::self()->networkAccessManager()->get(request);
+ reply->setParent(this);
connect(reply, &QNetworkReply::finished, this, [d, reply]() {
d->davJobFinished(reply);
});
diff --git a/src/common/davitemmodifyjob.cpp b/src/common/davitemmodifyjob.cpp
index bcdc21d..b45d267 100644
--- a/src/common/davitemmodifyjob.cpp
+++ b/src/common/davitemmodifyjob.cpp
@@ -49,6 +49,7 @@ void DavItemModifyJob::start()
request.setHeader(QNetworkRequest::UserAgentHeader, DavManager::self()->userAgent());
QNetworkReply *reply = DavManager::self()->networkAccessManager()->put(request, d->mItem.data());
+ reply->setParent(this);
connect(reply, &QNetworkReply::finished, this, [d, reply]() {
d->davJobFinished(reply);
});
diff --git a/src/common/davitemsfetchjob.cpp b/src/common/davitemsfetchjob.cpp
index efd9442..b5469db 100644
--- a/src/common/davitemsfetchjob.cpp
+++ b/src/common/davitemsfetchjob.cpp
@@ -59,7 +59,7 @@ void DavItemsFetchJob::start()
// bug in Zoho Calendar which violates the RFC by honouring Depth: 0
// returning the collection resource itself instead of the explicitly
// requested item hrefs.
- QNetworkReply *reply = DavManager::self()->createReportJob(d->mCollectionUrl.url(), report.toString(), QStringLiteral("1"));
+ QNetworkReply *reply = DavManager::self()->createReportJob(this, d->mCollectionUrl.url(), report.toString(), QStringLiteral("1"));
connect(reply, &QNetworkReply::finished, this, [d, reply]() {
d->davJobFinished(reply);
});
diff --git a/src/common/davitemslistjob.cpp b/src/common/davitemslistjob.cpp
index 94154cf..1987a9a 100644
--- a/src/common/davitemslistjob.cpp
+++ b/src/common/davitemslistjob.cpp
@@ -85,14 +85,14 @@ void DavItemsListJob::start()
if (d->mMimeTypes.isEmpty() || d->mMimeTypes.contains(mimeType)) {
++d->mSubJobCount;
if (protocol->useReport()) {
- QNetworkReply *reply = DavManager::self()->createReportJob(d->mUrl.url(), props.toString());
+ QNetworkReply *reply = DavManager::self()->createReportJob(this, d->mUrl.url(), props.toString());
reply->setProperty("davType", QStringLiteral("report"));
reply->setProperty("itemsMimeType", mimeType);
connect(reply, &QNetworkReply::finished, this, [d, reply]() {
d->davJobFinished(reply);
});
} else {
- QNetworkReply *reply = DavManager::self()->createPropFindJob(d->mUrl.url(), props.toString());
+ QNetworkReply *reply = DavManager::self()->createPropFindJob(this, d->mUrl.url(), props.toString());
reply->setProperty("davType", QStringLiteral("propFind"));
reply->setProperty("itemsMimeType", mimeType);
connect(reply, &QNetworkReply::finished, this, [d, reply]() {
diff --git a/src/common/davmanager.cpp b/src/common/davmanager.cpp
index 67e9d5b..afdc7fb 100644
--- a/src/common/davmanager.cpp
+++ b/src/common/davmanager.cpp
@@ -6,6 +6,7 @@
#include "davmanager_p.h"
+#include "davjobbase.h"
#include "davssluiproxy.h"
#include "protocols/caldavprotocol_p.h"
#include "protocols/carddavprotocol_p.h"
@@ -58,24 +59,24 @@ DavManager *DavManager::self()
return &sSelf;
}
-QNetworkReply *DavManager::createPropFindJob(const QUrl &url, const QString &document, const QString &depth) const
+QNetworkReply *DavManager::createPropFindJob(DavJobBase *job, const QUrl &url, const QString &document, const QString &depth) const
{
- return sendDavRequest("PROPFIND", url, document, depth);
+ return sendDavRequest(job, "PROPFIND", url, document, depth);
}
-QNetworkReply *DavManager::createReportJob(const QUrl &url, const QString &document, const QString &depth) const
+QNetworkReply *DavManager::createReportJob(DavJobBase *job, const QUrl &url, const QString &document, const QString &depth) const
{
- return sendDavRequest("REPORT", url, document, depth);
+ return sendDavRequest(job, "REPORT", url, document, depth);
}
-QNetworkReply *DavManager::createPropPatchJob(const QUrl &url, const QString &document) const
+QNetworkReply *DavManager::createPropPatchJob(DavJobBase *job, const QUrl &url, const QString &document) const
{
- return sendDavRequest("PROPPATCH", url, document);
+ return sendDavRequest(job, "PROPPATCH", url, document);
}
-QNetworkReply *DavManager::createMkColJob(const QUrl &url, const QString &document) const
+QNetworkReply *DavManager::createMkColJob(DavJobBase *job, const QUrl &url, const QString &document) const
{
- return sendDavRequest("MKCOL", url, document);
+ return sendDavRequest(job, "MKCOL", url, document);
}
QNetworkAccessManager *DavManager::networkAccessManager() const
@@ -88,7 +89,7 @@ void DavManager::setSslUiProxy(std::unique_ptr<DavSslUiProxy> &&proxy)
mSslUiProxy = std::move(proxy);
}
-QNetworkReply *DavManager::sendDavRequest(const QByteArray &method, const QUrl &url, const QString &document, const QString &depth) const
+QNetworkReply *DavManager::sendDavRequest(DavJobBase *job, const QByteArray &method, const QUrl &url, const QString &document, const QString &depth) const
{
QNetworkRequest request(url);
request.setHeader(QNetworkRequest::ContentTypeHeader, u"text/xml; charset=utf-8"_s);
@@ -96,7 +97,9 @@ QNetworkReply *DavManager::sendDavRequest(const QByteArray &method, const QUrl &
request.setRawHeader("Depth", depth.toUtf8());
}
request.setHeader(QNetworkRequest::UserAgentHeader, userAgent());
- return mNam->sendCustomRequest(request, method, QByteArray("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n") + document.toUtf8());
+ auto reply = mNam->sendCustomRequest(request, method, QByteArray("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n") + document.toUtf8());
+ reply->setParent(job);
+ return reply;
}
const DavProtocolBase *DavManager::davProtocol(Protocol protocol)
diff --git a/src/common/davmanager_p.h b/src/common/davmanager_p.h
index 0e67474..3c90bcd 100644
--- a/src/common/davmanager_p.h
+++ b/src/common/davmanager_p.h
@@ -19,6 +19,7 @@ class QUrl;
namespace KDAV
{
+class DavJobBase;
class DavProtocolBase;
class DavSslUiProxy;
@@ -52,7 +53,7 @@ public:
*
* \a depth The Depth: value to send in the HTTP request
*/
- QNetworkReply *createPropFindJob(const QUrl &url, const QString &document, const QString &depth = QStringLiteral("1")) const;
+ QNetworkReply *createPropFindJob(DavJobBase *job, const QUrl &url, const QString &document, const QString &depth = QStringLiteral("1")) const;
/*!
* Sends a DAV REPORT request and returns the network reply.
@@ -61,7 +62,7 @@ public:
* \a document The query XML document.
* \a depth The Depth: value to send in the HTTP request
*/
- QNetworkReply *createReportJob(const QUrl &url, const QString &document, const QString &depth = QStringLiteral("1")) const;
+ QNetworkReply *createReportJob(DavJobBase *job, const QUrl &url, const QString &document, const QString &depth = QStringLiteral("1")) const;
/*!
* Sends a DAV PROPPATCH request and returns the network reply.
@@ -69,7 +70,7 @@ public:
* \a url The target URL of the request.
* \a document The query XML document.
*/
- QNetworkReply *createPropPatchJob(const QUrl &url, const QString &document) const;
+ QNetworkReply *createPropPatchJob(DavJobBase *job, const QUrl &url, const QString &document) const;
/*!
* Returns a preconfigured DAV MKCOL reply.
@@ -78,7 +79,7 @@ public:
*
* \a document The query XML document.
*/
- QNetworkReply *createMkColJob(const QUrl &url, const QString &document) const;
+ QNetworkReply *createMkColJob(DavJobBase *job, const QUrl &url, const QString &document) const;
/*!
* Returns the shared QNetworkAccessManager instance.
@@ -106,7 +107,7 @@ private:
*/
DavManager();
- QNetworkReply *sendDavRequest(const QByteArray &method, const QUrl &url, const QString &document, const QString &depth = {}) const;
+ QNetworkReply *sendDavRequest(DavJobBase *job, const QByteArray &method, const QUrl &url, const QString &document, const QString &depth = {}) const;
mutable std::unique_ptr<QNetworkAccessManager> mNam;
std::unique_ptr<DavSslUiProxy> mSslUiProxy;
diff --git a/src/common/davprincipalhomesetsfetchjob.cpp b/src/common/davprincipalhomesetsfetchjob.cpp
index 7d95142..abd91f2 100644
--- a/src/common/davprincipalhomesetsfetchjob.cpp
+++ b/src/common/davprincipalhomesetsfetchjob.cpp
@@ -75,7 +75,7 @@ void DavPrincipalHomeSetsFetchJobPrivate::fetchHomeSets(bool homeSetsOnly)
propElement.appendChild(document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("principal-URL")));
}
- QNetworkReply *reply = DavManager::self()->createPropFindJob(mUrl.url(), document.toString(), QStringLiteral("0"));
+ QNetworkReply *reply = DavManager::self()->createPropFindJob(q_ptr, mUrl.url(), document.toString(), QStringLiteral("0"));
QObject::connect(reply, &QNetworkReply::finished, q_ptr, [this, reply]() {
davJobFinished(reply);
});
diff --git a/src/common/davprincipalsearchjob.cpp b/src/common/davprincipalsearchjob.cpp
index 64a17f2..57e0b70 100644
--- a/src/common/davprincipalsearchjob.cpp
+++ b/src/common/davprincipalsearchjob.cpp
@@ -88,7 +88,7 @@ void DavPrincipalSearchJob::start()
prop.appendChild(principalCollectionSet);
qCDebug(KDAV_LOG) << "PROPFIND:" << d->mUrl.url().toDisplayString() << "query: " << query.toString();
- QNetworkReply *reply = DavManager::self()->createPropFindJob(d->mUrl.url(), query.toString());
+ QNetworkReply *reply = DavManager::self()->createPropFindJob(this, d->mUrl.url(), query.toString());
connect(reply, &QNetworkReply::finished, this, [d, reply]() {
d->principalCollectionSetSearchFinished(reply);
});
@@ -195,7 +195,7 @@ void DavPrincipalSearchJobPrivate::principalCollectionSetSearchFinished(QNetwork
QDomDocument principalPropertySearchQuery;
buildReportQuery(principalPropertySearchQuery);
qCDebug(KDAV_LOG) << "REPORT:" << url.toDisplayString() << "query:" << principalPropertySearchQuery.toString();
- QNetworkReply *reportReply = DavManager::self()->createReportJob(url, principalPropertySearchQuery.toString());
+ QNetworkReply *reportReply = DavManager::self()->createReportJob(q_ptr, url, principalPropertySearchQuery.toString());
QObject::connect(reportReply, &QNetworkReply::finished, q_ptr, [this, reportReply]() {
principalPropertySearchFinished(reportReply);
});