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 | |
17 | using namespace KIO; |
18 | |
19 | /** @internal */ |
20 | class KIO::DavJobPrivate : public KIO::TransferJobPrivate |
21 | { |
22 | public: |
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 | |
43 | DavJob::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 | |
62 | QByteArray DavJob::responseData() const |
63 | { |
64 | return d_func()->str_response; |
65 | } |
66 | |
67 | void 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 | |
77 | void 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 */ |
103 | DavJob *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 | |
110 | DavJob *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 | |
115 | DavJob *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 | |
127 | DavJob *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 | |