File indexing completed on 2024-04-28 04:44:40

0001 #include <QAuthenticator>
0002 #include <QByteArray>
0003 #include <QDebug>
0004 #include <QHttpMultiPart>
0005 #include <QList>
0006 #include <QMap>
0007 #include <QNetworkAccessManager>
0008 #include <QNetworkReply>
0009 #include <QRegularExpression>
0010 #include <QSslError>
0011 #include <string>
0012 
0013 #include "WebDAV.hpp"
0014 #include "utils/NetworkHelper.hpp"
0015 #include "utils/WebDAVReply.hpp"
0016 
0017 WebDAV::WebDAV(QString host, QString username, QString password) {
0018   this->networkHelper = new NetworkHelper(host, username, password);
0019   this->xmlHelper = new XMLHelper();
0020 
0021   // TODO: Check for Timeout error in case of wrong host
0022 }
0023 
0024 WebDAVReply* WebDAV::testConnection() {
0025   QMap<QString, QString> headers;
0026   WebDAVReply* reply = new WebDAVReply();
0027   QNetworkReply* testConnectionReply =
0028       this->networkHelper->makeRequest("PROPFIND", headers);
0029 
0030   connect(testConnectionReply, &QNetworkReply::finished, [=]() {
0031     if (testConnectionReply->error()) {
0032       reply->sendTestConnectionResponseSignal(false);
0033       this->errorReplyHandler(reply, testConnectionReply->error());
0034     } else {
0035       reply->sendTestConnectionResponseSignal(true);
0036     }
0037   });
0038   connect(testConnectionReply,
0039           QOverload<QNetworkReply::NetworkError>::of(&QNetworkReply::error),
0040           [=](QNetworkReply::NetworkError err) {
0041             reply->sendTestConnectionResponseSignal(false);
0042             this->errorReplyHandler(reply, err);
0043           });
0044 
0045   return reply;
0046 }
0047 
0048 WebDAVReply* WebDAV::listDir(QString path) {
0049   return this->listDir(path, ListDepthEnum::Infinity);
0050 }
0051 
0052 WebDAVReply* WebDAV::listDir(QString path, ListDepthEnum depth) {
0053   WebDAVReply* reply = new WebDAVReply();
0054   QString depthVal;
0055   QMap<QString, QString> headers;
0056   QNetworkReply* listDirReply;
0057 
0058   switch (depth) {
0059     case ListDepthEnum::Zero:
0060       depthVal = "0";
0061       break;
0062 
0063     case ListDepthEnum::One:
0064       depthVal = "1";
0065       break;
0066 
0067     case ListDepthEnum::Two:
0068       depthVal = "2";
0069       break;
0070 
0071     case ListDepthEnum::Infinity:
0072       depthVal = "infinity";
0073       break;
0074 
0075     default:
0076       break;
0077   }
0078 
0079   headers.insert("Depth", depthVal);
0080 
0081   listDirReply =
0082       this->networkHelper->makeRequest(QString("PROPFIND"), path, headers);
0083 
0084   connect(listDirReply, &QNetworkReply::finished, [=]() {
0085     reply->sendListDirResponseSignal(
0086         listDirReply,
0087         this->xmlHelper->parseListDirResponse(this, listDirReply->readAll()));
0088   });
0089   connect(listDirReply,
0090           QOverload<QNetworkReply::NetworkError>::of(&QNetworkReply::error),
0091           [=](QNetworkReply::NetworkError err) {
0092             this->errorReplyHandler(reply, err);
0093           });
0094 
0095   return reply;
0096 }
0097 
0098 WebDAVReply* WebDAV::downloadFrom(QString path) {
0099   return this->downloadFrom(path, 0, -1);
0100 }
0101 
0102 WebDAVReply* WebDAV::downloadFrom(QString path, qint64 startByte,
0103                                   qint64 endByte) {
0104   WebDAVReply* reply = new WebDAVReply();
0105   QString rangeVal;
0106   QTextStream stream(&rangeVal);
0107   QMap<QString, QString> headers;
0108   QNetworkReply* downloadReply;
0109 
0110   stream << "bytes=" << startByte << "-" << endByte;
0111 
0112   headers.insert("Range", rangeVal);
0113 
0114   downloadReply = this->networkHelper->makeRequest("GET", path, headers);
0115 
0116   connect(downloadReply, &QNetworkReply::finished,
0117           [=]() { reply->sendDownloadResponseSignal(downloadReply); });
0118   connect(
0119       downloadReply, &QNetworkReply::downloadProgress,
0120       [=](qint64 bytesReceived, qint64 bytesTotal) {
0121         if (bytesTotal == -1) {
0122           QString contentRange = QString(downloadReply->rawHeader(
0123               QByteArray::fromStdString("Content-Range")));
0124           QRegularExpression re("bytes (\\d*)-(\\d*)/(\\d*)");
0125           QRegularExpressionMatch match = re.match(contentRange);
0126           qint64 contentSize =
0127               match.captured(2).toInt() - match.captured(1).toInt();
0128 
0129           reply->sendDownloadProgressResponseSignal(bytesReceived, contentSize);
0130         } else {
0131           reply->sendDownloadProgressResponseSignal(bytesReceived, bytesTotal);
0132         }
0133       });
0134   connect(downloadReply,
0135           QOverload<QNetworkReply::NetworkError>::of(&QNetworkReply::error),
0136           [=](QNetworkReply::NetworkError err) {
0137             this->errorReplyHandler(reply, err);
0138           });
0139 
0140   return reply;
0141 }
0142 
0143 WebDAVReply* WebDAV::uploadTo(QString path, QString filename, QIODevice* file) {
0144   WebDAVReply* reply = new WebDAVReply();
0145   QMap<QString, QString> headers;
0146   QNetworkReply* uploadReply;
0147 
0148   uploadReply =
0149       this->networkHelper->makePutRequest(path + "/" + filename, headers, file);
0150 
0151   connect(uploadReply, &QNetworkReply::finished,
0152           [=]() { reply->sendUploadFinishedResponseSignal(uploadReply); });
0153 
0154   connect(uploadReply,
0155           QOverload<QNetworkReply::NetworkError>::of(&QNetworkReply::error),
0156           [=](QNetworkReply::NetworkError err) {
0157             this->errorReplyHandler(reply, err);
0158           });
0159 
0160   return reply;
0161 }
0162 
0163 WebDAVReply* WebDAV::createDir(QString path, QString dirName) {
0164   WebDAVReply* reply = new WebDAVReply();
0165   QMap<QString, QString> headers;
0166   QNetworkReply* createDirReply;
0167 
0168   createDirReply =
0169       this->networkHelper->makeRequest("MKCOL", path + "/" + dirName, headers);
0170 
0171   connect(createDirReply, &QNetworkReply::finished,
0172           [=]() { reply->sendDirCreatedResponseSignal(createDirReply); });
0173 
0174   connect(createDirReply,
0175           QOverload<QNetworkReply::NetworkError>::of(&QNetworkReply::error),
0176           [=](QNetworkReply::NetworkError err) {
0177             this->errorReplyHandler(reply, err);
0178           });
0179 
0180   return reply;
0181 }
0182 
0183 WebDAVReply* WebDAV::copy(QString source, QString destination) {
0184   WebDAVReply* reply = new WebDAVReply();
0185   QMap<QString, QString> headers;
0186   QNetworkReply* copyReply;
0187 
0188   headers.insert("Destination", destination);
0189 
0190   copyReply = this->networkHelper->makeRequest("COPY", source, headers);
0191 
0192   connect(copyReply, &QNetworkReply::finished,
0193           [=]() { reply->sendCopyResponseSignal(copyReply); });
0194 
0195   connect(copyReply,
0196           QOverload<QNetworkReply::NetworkError>::of(&QNetworkReply::error),
0197           [=](QNetworkReply::NetworkError err) {
0198             this->errorReplyHandler(reply, err);
0199           });
0200 
0201   return reply;
0202 }
0203 
0204 WebDAVReply* WebDAV::move(QString source, QString destination, bool overwrite) {
0205   WebDAVReply* reply = new WebDAVReply();
0206   QMap<QString, QString> headers;
0207   QNetworkReply* moveReply;
0208   QString overwriteVal = overwrite ? "T" : "F";
0209 
0210   headers.insert("Destination", destination);
0211   headers.insert("Overwrite", overwriteVal);
0212 
0213   moveReply = this->networkHelper->makeRequest("MOVE", source, headers);
0214 
0215   connect(moveReply, &QNetworkReply::finished,
0216           [=]() { reply->sendMoveResponseSignal(moveReply); });
0217 
0218   connect(moveReply,
0219           QOverload<QNetworkReply::NetworkError>::of(&QNetworkReply::error),
0220           [=](QNetworkReply::NetworkError err) {
0221             this->errorReplyHandler(reply, err);
0222           });
0223 
0224   return reply;
0225 }
0226 
0227 WebDAVReply* WebDAV::remove(QString path) {
0228   WebDAVReply* reply = new WebDAVReply();
0229   QMap<QString, QString> headers;
0230   QNetworkReply* removeReply;
0231 
0232   removeReply = this->networkHelper->makeRequest("DELETE", path, headers);
0233 
0234   connect(removeReply, &QNetworkReply::finished,
0235           [=]() { reply->sendRemoveResponseSignal(removeReply); });
0236 
0237   connect(removeReply,
0238           QOverload<QNetworkReply::NetworkError>::of(&QNetworkReply::error),
0239           [=](QNetworkReply::NetworkError err) {
0240             this->errorReplyHandler(reply, err);
0241           });
0242 
0243   return reply;
0244 }
0245 
0246 void WebDAV::errorReplyHandler(WebDAVReply* reply,
0247                                QNetworkReply::NetworkError err) {
0248   reply->sendError(err);
0249 }
0250 
0251 WebDAV::~WebDAV() {
0252   this->networkHelper->deleteLater();
0253   delete this->xmlHelper;
0254 }