File indexing completed on 2024-04-21 03:53:52
0001 /* 0002 SPDX-FileCopyrightText: 2010 Tobias Koenig <tokoe@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "davitemcreatejob.h" 0008 #include "davjobbase_p.h" 0009 0010 #include "daverror.h" 0011 #include "davitemfetchjob.h" 0012 0013 #include <KIO/DavJob> 0014 #include <KIO/StoredTransferJob> 0015 0016 using namespace KDAV; 0017 0018 namespace KDAV 0019 { 0020 class DavItemCreateJobPrivate : public DavJobBasePrivate 0021 { 0022 public: 0023 void davJobFinished(KJob *job); 0024 void itemRefreshed(KJob *job); 0025 0026 DavItem mItem; 0027 int mRedirectCount = 0; 0028 0029 Q_DECLARE_PUBLIC(DavItemCreateJob) 0030 }; 0031 } 0032 0033 DavItemCreateJob::DavItemCreateJob(const DavItem &item, QObject *parent) 0034 : DavJobBase(new DavItemCreateJobPrivate, parent) 0035 { 0036 Q_D(DavItemCreateJob); 0037 d->mItem = item; 0038 } 0039 0040 void DavItemCreateJob::start() 0041 { 0042 Q_D(DavItemCreateJob); 0043 QString headers = QStringLiteral("Content-Type: "); 0044 headers += d->mItem.contentType(); 0045 headers += QLatin1String("\r\n"); 0046 headers += QLatin1String("If-None-Match: *"); 0047 0048 KIO::StoredTransferJob *job = KIO::storedPut(d->mItem.data(), itemUrl(), -1, KIO::HideProgressInfo | KIO::DefaultFlags); 0049 job->addMetaData(QStringLiteral("PropagateHttpHeader"), QStringLiteral("true")); 0050 job->addMetaData(QStringLiteral("customHTTPHeader"), headers); 0051 job->addMetaData(QStringLiteral("cookies"), QStringLiteral("none")); 0052 job->addMetaData(QStringLiteral("no-auth-prompt"), QStringLiteral("true")); 0053 job->setRedirectionHandlingEnabled(false); 0054 0055 connect(job, &KIO::StoredTransferJob::result, this, [d](KJob *job) { 0056 d->davJobFinished(job); 0057 }); 0058 } 0059 0060 DavItem DavItemCreateJob::item() const 0061 { 0062 Q_D(const DavItemCreateJob); 0063 return d->mItem; 0064 } 0065 0066 QUrl DavItemCreateJob::itemUrl() const 0067 { 0068 Q_D(const DavItemCreateJob); 0069 return d->mItem.url().url(); 0070 } 0071 0072 void DavItemCreateJobPrivate::davJobFinished(KJob *job) 0073 { 0074 Q_Q(DavItemCreateJob); 0075 KIO::StoredTransferJob *storedJob = qobject_cast<KIO::StoredTransferJob *>(job); 0076 const QString responseCodeStr = storedJob->queryMetaData(QStringLiteral("responsecode")); 0077 const int responseCode = responseCodeStr.isEmpty() ? 0 : responseCodeStr.toInt(); 0078 if (storedJob->error()) { 0079 setLatestResponseCode(responseCode); 0080 setError(ERR_ITEMCREATE); 0081 setJobErrorText(storedJob->errorText()); 0082 setJobError(storedJob->error()); 0083 setErrorTextFromDavError(); 0084 0085 emitResult(); 0086 return; 0087 } 0088 0089 // The 'Location:' HTTP header is used to indicate the new URL 0090 const QStringList allHeaders = storedJob->queryMetaData(QStringLiteral("HTTP-Headers")).split(QLatin1Char('\n')); 0091 QString location; 0092 for (const QString &header : allHeaders) { 0093 if (header.startsWith(QLatin1String("location:"), Qt::CaseInsensitive)) { 0094 location = header.section(QLatin1Char(' '), 1); 0095 } 0096 } 0097 0098 QUrl url; 0099 if (location.isEmpty()) { 0100 url = storedJob->url(); 0101 } else if (location.startsWith(QLatin1Char('/'))) { 0102 url = storedJob->url(); 0103 url.setPath(location, QUrl::TolerantMode); 0104 } else { 0105 url = QUrl::fromUserInput(location); 0106 } 0107 0108 if (responseCode == 301 || responseCode == 302 || responseCode == 307 || responseCode == 308) { 0109 if (mRedirectCount > 4) { 0110 setLatestResponseCode(responseCode); 0111 setError(DavItemCreateJob::UserDefinedError + responseCode); 0112 emitResult(); 0113 } else { 0114 QUrl _itemUrl(url); 0115 _itemUrl.setUserInfo(q->itemUrl().userInfo()); 0116 mItem.setUrl(DavUrl(_itemUrl, mItem.url().protocol())); 0117 0118 ++mRedirectCount; 0119 q->start(); 0120 } 0121 0122 return; 0123 } 0124 0125 url.setUserInfo(q->itemUrl().userInfo()); 0126 mItem.setUrl(DavUrl(url, mItem.url().protocol())); 0127 0128 DavItemFetchJob *fetchJob = new DavItemFetchJob(mItem); 0129 QObject::connect(fetchJob, &DavItemFetchJob::result, q, [this](KJob *job) { 0130 itemRefreshed(job); 0131 }); 0132 fetchJob->start(); 0133 } 0134 0135 void DavItemCreateJobPrivate::itemRefreshed(KJob *job) 0136 { 0137 if (!job->error()) { 0138 DavItemFetchJob *fetchJob = qobject_cast<DavItemFetchJob *>(job); 0139 mItem.setEtag(fetchJob->item().etag()); 0140 } 0141 emitResult(); 0142 } 0143 0144 #include "moc_davitemcreatejob.cpp"