1// -*- c++ -*-
2/*
3 This file is part of the KDE libraries
4 SPDX-FileCopyrightText: 2002 Jan-Pascal van Best <janpascal@vanbest.org>
5
6 SPDX-License-Identifier: LGPL-2.0-or-later
7*/
8
9#include "davjob.h"
10
11#include <QDataStream>
12#include <QDomDocument>
13
14#include "httpmethod_p.h"
15#include "job_p.h"
16
17using namespace KIO;
18
19/** @internal */
20class KIO::DavJobPrivate : public KIO::TransferJobPrivate
21{
22public:
23 explicit DavJobPrivate(const QUrl &url)
24 : TransferJobPrivate(url, KIO::CMD_SPECIAL, QByteArray(), QByteArray())
25 {
26 }
27 QByteArray savedStaticData;
28 QByteArray str_response;
29
30 Q_DECLARE_PUBLIC(DavJob)
31
32 static inline DavJob *newJob(const QUrl &url, int method, const QString &request, JobFlags flags)
33 {
34 DavJob *job = new DavJob(*new DavJobPrivate(url), method, request);
35 job->setUiDelegate(KIO::createDefaultJobUiDelegate());
36 if (!(flags & HideProgressInfo)) {
37 KIO::getJobTracker()->registerJob(job);
38 }
39 return job;
40 }
41};
42
43DavJob::DavJob(DavJobPrivate &dd, int method, const QString &request)
44 : TransferJob(dd)
45{
46 // We couldn't set the args when calling the parent constructor,
47 // so do it now.
48 Q_D(DavJob);
49 QDataStream stream(&d->m_packedArgs, QIODevice::WriteOnly);
50 stream << (int)7 << d->m_url << method;
51 // Same for static data
52 if (!request.isEmpty()) {
53 d->staticData = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n" + request.toUtf8();
54 d->staticData.chop(n: 1);
55 d->savedStaticData = d->staticData;
56 stream << static_cast<qint64>(d->staticData.size());
57 } else {
58 stream << static_cast<qint64>(-1);
59 }
60}
61
62QByteArray DavJob::responseData() const
63{
64 return d_func()->str_response;
65}
66
67void DavJob::slotData(const QByteArray &data)
68{
69 Q_D(DavJob);
70 if (d->m_redirectionURL.isEmpty() || !d->m_redirectionURL.isValid() || error()) {
71 unsigned int oldSize = d->str_response.size();
72 d->str_response.resize(size: oldSize + data.size());
73 memcpy(dest: d->str_response.data() + oldSize, src: data.data(), n: data.size());
74 }
75}
76
77void DavJob::slotFinished()
78{
79 Q_D(DavJob);
80 // qDebug() << d->str_response;
81 if (!d->m_redirectionURL.isEmpty() && d->m_redirectionURL.isValid() && (d->m_command == CMD_SPECIAL)) {
82 QDataStream istream(d->m_packedArgs);
83 int s_cmd;
84 int s_method;
85 qint64 s_size;
86 QUrl s_url;
87 istream >> s_cmd;
88 istream >> s_url;
89 istream >> s_method;
90 istream >> s_size;
91 // PROPFIND
92 if ((s_cmd == 7) && (s_method == (int)KIO::DAV_PROPFIND)) {
93 d->m_packedArgs.truncate(pos: 0);
94 QDataStream stream(&d->m_packedArgs, QIODevice::WriteOnly);
95 stream << (int)7 << d->m_redirectionURL << (int)KIO::DAV_PROPFIND << s_size;
96 }
97 }
98 TransferJob::slotFinished();
99 d->staticData = d->savedStaticData; // Need to send DAV request to this host too
100}
101
102/* Convenience methods */
103DavJob *KIO::davPropFind(const QUrl &url, const QString &properties, const QString &depth, JobFlags flags)
104{
105 DavJob *job = DavJobPrivate::newJob(url, method: (int)KIO::DAV_PROPFIND, request: properties, flags);
106 job->addMetaData(QStringLiteral("davDepth"), value: depth);
107 return job;
108}
109
110DavJob *KIO::davPropPatch(const QUrl &url, const QString &properties, JobFlags flags)
111{
112 return DavJobPrivate::newJob(url, method: (int)KIO::DAV_PROPPATCH, request: properties, flags);
113}
114
115DavJob *KIO::davSearch(const QUrl &url, const QString &nsURI, const QString &qName, const QString &query, JobFlags flags)
116{
117 QDomDocument doc;
118 QDomElement searchrequest = doc.createElementNS(QStringLiteral("DAV:"), QStringLiteral("searchrequest"));
119 QDomElement searchelement = doc.createElementNS(nsURI, qName);
120 QDomText text = doc.createTextNode(data: query);
121 searchelement.appendChild(newChild: text);
122 searchrequest.appendChild(newChild: searchelement);
123 doc.appendChild(newChild: searchrequest);
124 return DavJobPrivate::newJob(url, method: KIO::DAV_SEARCH, request: doc.toString(), flags);
125}
126
127DavJob *KIO::davReport(const QUrl &url, const QString &report, const QString &depth, JobFlags flags)
128{
129 DavJob *job = DavJobPrivate::newJob(url, method: (int)KIO::DAV_REPORT, request: report, flags);
130 job->addMetaData(QStringLiteral("davDepth"), value: depth);
131 return job;
132}
133
134#include "moc_davjob.cpp"
135

source code of kio/src/core/davjob.cpp