File indexing completed on 2024-04-28 15:26:15

0001 // -*- c++ -*-
0002 /*
0003     This file is part of the KDE libraries
0004     SPDX-FileCopyrightText: 2002 Jan-Pascal van Best <janpascal@vanbest.org>
0005 
0006     SPDX-License-Identifier: LGPL-2.0-or-later
0007 */
0008 
0009 #include "davjob.h"
0010 
0011 #include <QDataStream>
0012 #include <QDomDocument>
0013 
0014 #include "httpmethod_p.h"
0015 
0016 #include "job.h"
0017 #include "job_p.h"
0018 #include "jobclasses.h"
0019 
0020 using namespace KIO;
0021 
0022 /** @internal */
0023 class KIO::DavJobPrivate : public KIO::TransferJobPrivate
0024 {
0025 public:
0026     explicit DavJobPrivate(const QUrl &url)
0027         : TransferJobPrivate(url, KIO::CMD_SPECIAL, QByteArray(), QByteArray())
0028     {
0029     }
0030     QByteArray savedStaticData;
0031     QByteArray str_response;
0032 #if KIOCORE_BUILD_DEPRECATED_SINCE(5, 86)
0033     QDomDocument m_response;
0034 #endif
0035     // TransferJob *m_subJob;
0036     // bool m_suspended;
0037 
0038     Q_DECLARE_PUBLIC(DavJob)
0039 
0040     static inline DavJob *newJob(const QUrl &url, int method, const QString &request, JobFlags flags)
0041     {
0042         DavJob *job = new DavJob(*new DavJobPrivate(url), method, request);
0043         job->setUiDelegate(KIO::createDefaultJobUiDelegate());
0044         if (!(flags & HideProgressInfo)) {
0045             KIO::getJobTracker()->registerJob(job);
0046         }
0047         return job;
0048     }
0049 };
0050 
0051 DavJob::DavJob(DavJobPrivate &dd, int method, const QString &request)
0052     : TransferJob(dd)
0053 {
0054     // We couldn't set the args when calling the parent constructor,
0055     // so do it now.
0056     Q_D(DavJob);
0057     QDataStream stream(&d->m_packedArgs, QIODevice::WriteOnly);
0058     stream << (int)7 << d->m_url << method;
0059     // Same for static data
0060     if (!request.isEmpty()) {
0061         d->staticData = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n" + request.toUtf8();
0062         d->staticData.chop(1);
0063         d->savedStaticData = d->staticData;
0064         stream << static_cast<qint64>(d->staticData.size());
0065     } else {
0066         stream << static_cast<qint64>(-1);
0067     }
0068 }
0069 
0070 QByteArray DavJob::responseData() const
0071 {
0072     return d_func()->str_response;
0073 }
0074 
0075 #if KIOCORE_BUILD_DEPRECATED_SINCE(5, 86)
0076 QDomDocument &DavJob::response()
0077 {
0078     return d_func()->m_response;
0079 }
0080 #endif
0081 
0082 void DavJob::slotData(const QByteArray &data)
0083 {
0084     Q_D(DavJob);
0085     if (d->m_redirectionURL.isEmpty() || !d->m_redirectionURL.isValid() || error()) {
0086         unsigned int oldSize = d->str_response.size();
0087         d->str_response.resize(oldSize + data.size());
0088         memcpy(d->str_response.data() + oldSize, data.data(), data.size());
0089     }
0090 }
0091 
0092 void DavJob::slotFinished()
0093 {
0094     Q_D(DavJob);
0095     // qDebug() << d->str_response;
0096     if (!d->m_redirectionURL.isEmpty() && d->m_redirectionURL.isValid() && (d->m_command == CMD_SPECIAL)) {
0097         QDataStream istream(d->m_packedArgs);
0098         int s_cmd;
0099         int s_method;
0100         qint64 s_size;
0101         QUrl s_url;
0102         istream >> s_cmd;
0103         istream >> s_url;
0104         istream >> s_method;
0105         istream >> s_size;
0106         // PROPFIND
0107         if ((s_cmd == 7) && (s_method == (int)KIO::DAV_PROPFIND)) {
0108             d->m_packedArgs.truncate(0);
0109             QDataStream stream(&d->m_packedArgs, QIODevice::WriteOnly);
0110             stream << (int)7 << d->m_redirectionURL << (int)KIO::DAV_PROPFIND << s_size;
0111         }
0112     }
0113 #if KIOCORE_BUILD_DEPRECATED_SINCE(5, 86)
0114     else if (!d->m_response.setContent(d->str_response, true)) {
0115         // An error occurred parsing the XML response
0116         QDomElement root = d->m_response.createElementNS(QStringLiteral("DAV:"), QStringLiteral("error-report"));
0117         d->m_response.appendChild(root);
0118 
0119         QDomElement el = d->m_response.createElementNS(QStringLiteral("DAV:"), QStringLiteral("offending-response"));
0120         QDomText textnode = d->m_response.createTextNode(QString::fromUtf8(d->str_response));
0121         el.appendChild(textnode);
0122         root.appendChild(el);
0123     }
0124     // qDebug() << d->m_response.toString();
0125 #endif
0126     TransferJob::slotFinished();
0127     d->staticData = d->savedStaticData; // Need to send DAV request to this host too
0128 }
0129 
0130 /* Convenience methods */
0131 DavJob *KIO::davPropFind(const QUrl &url, const QString &properties, const QString &depth, JobFlags flags)
0132 {
0133     DavJob *job = DavJobPrivate::newJob(url, (int)KIO::DAV_PROPFIND, properties, flags);
0134     job->addMetaData(QStringLiteral("davDepth"), depth);
0135     return job;
0136 }
0137 
0138 DavJob *KIO::davPropPatch(const QUrl &url, const QString &properties, JobFlags flags)
0139 {
0140     return DavJobPrivate::newJob(url, (int)KIO::DAV_PROPPATCH, properties, flags);
0141 }
0142 
0143 #if KIOCORE_BUILD_DEPRECATED_SINCE(5, 84)
0144 DavJob *KIO::davPropFind(const QUrl &url, const QDomDocument &properties, const QString &depth, JobFlags flags)
0145 {
0146     return davPropFind(url, properties.toString(), depth, flags);
0147 }
0148 #endif
0149 
0150 #if KIOCORE_BUILD_DEPRECATED_SINCE(5, 84)
0151 DavJob *KIO::davPropPatch(const QUrl &url, const QDomDocument &properties, JobFlags flags)
0152 {
0153     return davPropPatch(url, properties.toString(), flags);
0154 }
0155 #endif
0156 
0157 DavJob *KIO::davSearch(const QUrl &url, const QString &nsURI, const QString &qName, const QString &query, JobFlags flags)
0158 {
0159     QDomDocument doc;
0160     QDomElement searchrequest = doc.createElementNS(QStringLiteral("DAV:"), QStringLiteral("searchrequest"));
0161     QDomElement searchelement = doc.createElementNS(nsURI, qName);
0162     QDomText text = doc.createTextNode(query);
0163     searchelement.appendChild(text);
0164     searchrequest.appendChild(searchelement);
0165     doc.appendChild(searchrequest);
0166     return DavJobPrivate::newJob(url, KIO::DAV_SEARCH, doc.toString(), flags);
0167 }
0168 
0169 DavJob *KIO::davReport(const QUrl &url, const QString &report, const QString &depth, JobFlags flags)
0170 {
0171     DavJob *job = DavJobPrivate::newJob(url, (int)KIO::DAV_REPORT, report, flags);
0172     job->addMetaData(QStringLiteral("davDepth"), depth);
0173     return job;
0174 }
0175 
0176 #include "moc_davjob.cpp"