File indexing completed on 2024-04-14 03:52:50

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 #include "job_p.h"
0016 
0017 using namespace KIO;
0018 
0019 /** @internal */
0020 class KIO::DavJobPrivate : public KIO::TransferJobPrivate
0021 {
0022 public:
0023     explicit DavJobPrivate(const QUrl &url)
0024         : TransferJobPrivate(url, KIO::CMD_SPECIAL, QByteArray(), QByteArray())
0025     {
0026     }
0027     QByteArray savedStaticData;
0028     QByteArray str_response;
0029 
0030     Q_DECLARE_PUBLIC(DavJob)
0031 
0032     static inline DavJob *newJob(const QUrl &url, int method, const QString &request, JobFlags flags)
0033     {
0034         DavJob *job = new DavJob(*new DavJobPrivate(url), method, request);
0035         job->setUiDelegate(KIO::createDefaultJobUiDelegate());
0036         if (!(flags & HideProgressInfo)) {
0037             KIO::getJobTracker()->registerJob(job);
0038         }
0039         return job;
0040     }
0041 };
0042 
0043 DavJob::DavJob(DavJobPrivate &dd, int method, const QString &request)
0044     : TransferJob(dd)
0045 {
0046     // We couldn't set the args when calling the parent constructor,
0047     // so do it now.
0048     Q_D(DavJob);
0049     QDataStream stream(&d->m_packedArgs, QIODevice::WriteOnly);
0050     stream << (int)7 << d->m_url << method;
0051     // Same for static data
0052     if (!request.isEmpty()) {
0053         d->staticData = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n" + request.toUtf8();
0054         d->staticData.chop(1);
0055         d->savedStaticData = d->staticData;
0056         stream << static_cast<qint64>(d->staticData.size());
0057     } else {
0058         stream << static_cast<qint64>(-1);
0059     }
0060 }
0061 
0062 QByteArray DavJob::responseData() const
0063 {
0064     return d_func()->str_response;
0065 }
0066 
0067 void DavJob::slotData(const QByteArray &data)
0068 {
0069     Q_D(DavJob);
0070     if (d->m_redirectionURL.isEmpty() || !d->m_redirectionURL.isValid() || error()) {
0071         unsigned int oldSize = d->str_response.size();
0072         d->str_response.resize(oldSize + data.size());
0073         memcpy(d->str_response.data() + oldSize, data.data(), data.size());
0074     }
0075 }
0076 
0077 void DavJob::slotFinished()
0078 {
0079     Q_D(DavJob);
0080     // qDebug() << d->str_response;
0081     if (!d->m_redirectionURL.isEmpty() && d->m_redirectionURL.isValid() && (d->m_command == CMD_SPECIAL)) {
0082         QDataStream istream(d->m_packedArgs);
0083         int s_cmd;
0084         int s_method;
0085         qint64 s_size;
0086         QUrl s_url;
0087         istream >> s_cmd;
0088         istream >> s_url;
0089         istream >> s_method;
0090         istream >> s_size;
0091         // PROPFIND
0092         if ((s_cmd == 7) && (s_method == (int)KIO::DAV_PROPFIND)) {
0093             d->m_packedArgs.truncate(0);
0094             QDataStream stream(&d->m_packedArgs, QIODevice::WriteOnly);
0095             stream << (int)7 << d->m_redirectionURL << (int)KIO::DAV_PROPFIND << s_size;
0096         }
0097     }
0098     TransferJob::slotFinished();
0099     d->staticData = d->savedStaticData; // Need to send DAV request to this host too
0100 }
0101 
0102 /* Convenience methods */
0103 DavJob *KIO::davPropFind(const QUrl &url, const QString &properties, const QString &depth, JobFlags flags)
0104 {
0105     DavJob *job = DavJobPrivate::newJob(url, (int)KIO::DAV_PROPFIND, properties, flags);
0106     job->addMetaData(QStringLiteral("davDepth"), depth);
0107     return job;
0108 }
0109 
0110 DavJob *KIO::davPropPatch(const QUrl &url, const QString &properties, JobFlags flags)
0111 {
0112     return DavJobPrivate::newJob(url, (int)KIO::DAV_PROPPATCH, properties, flags);
0113 }
0114 
0115 DavJob *KIO::davSearch(const QUrl &url, const QString &nsURI, const QString &qName, const QString &query, JobFlags flags)
0116 {
0117     QDomDocument doc;
0118     QDomElement searchrequest = doc.createElementNS(QStringLiteral("DAV:"), QStringLiteral("searchrequest"));
0119     QDomElement searchelement = doc.createElementNS(nsURI, qName);
0120     QDomText text = doc.createTextNode(query);
0121     searchelement.appendChild(text);
0122     searchrequest.appendChild(searchelement);
0123     doc.appendChild(searchrequest);
0124     return DavJobPrivate::newJob(url, KIO::DAV_SEARCH, doc.toString(), flags);
0125 }
0126 
0127 DavJob *KIO::davReport(const QUrl &url, const QString &report, const QString &depth, JobFlags flags)
0128 {
0129     DavJob *job = DavJobPrivate::newJob(url, (int)KIO::DAV_REPORT, report, flags);
0130     job->addMetaData(QStringLiteral("davDepth"), depth);
0131     return job;
0132 }
0133 
0134 #include "moc_davjob.cpp"