File indexing completed on 2024-04-14 03:49:33

0001 /*
0002     This file is part of KDE.
0003 
0004     SPDX-FileCopyrightText: 1999 Matthias Kalle Dalheimer <kalle@kde.org>
0005     SPDX-FileCopyrightText: 2000 Charles Samuels <charles@kde.org>
0006     SPDX-FileCopyrightText: 2005 Joseph Wenninger <kde@jowenn.at>
0007     SPDX-FileCopyrightText: 2009 Frederik Gladhorn <gladhorn@kde.org>
0008 
0009     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0010 */
0011 
0012 #include "postfiledata.h"
0013 
0014 #include <QDateTime>
0015 #include <QDebug>
0016 #include <QRandomGenerator>
0017 
0018 namespace Attica
0019 {
0020 class PostFileDataPrivate
0021 {
0022 public:
0023     QByteArray buffer;
0024     QByteArray boundary;
0025     QUrl url;
0026     bool finished;
0027 
0028     PostFileDataPrivate()
0029         : finished(false)
0030     {
0031     }
0032 };
0033 
0034 PostFileData::PostFileData(const QUrl &url)
0035     : d(new PostFileDataPrivate)
0036 {
0037     d->url = url;
0038     d->boundary = "----------" + randomString(42 + 13).toLatin1();
0039 }
0040 
0041 PostFileData::~PostFileData()
0042 {
0043     delete d;
0044 }
0045 
0046 QString PostFileData::randomString(int length)
0047 {
0048     if (length <= 0) {
0049         return QString();
0050     }
0051 
0052     QString str;
0053     str.resize(length);
0054     int i = 0;
0055     auto *generator = QRandomGenerator::global();
0056     while (length--) {
0057         int r = generator->bounded(62);
0058         r += 48;
0059         if (r > 57) {
0060             r += 7;
0061         }
0062         if (r > 90) {
0063             r += 6;
0064         }
0065         str[i++] = QLatin1Char(char(r));
0066     }
0067     return str;
0068 }
0069 
0070 void PostFileData::addArgument(const QString &key, const QString &value)
0071 {
0072     if (d->finished) {
0073         qWarning() << "PostFileData::addFile: should not add data after calling request() or data()";
0074     }
0075     QByteArray data(
0076         "--" + d->boundary + "\r\n"
0077         "Content-Disposition: form-data; name=\"" + key.toLatin1() +
0078         "\"\r\n\r\n" + value.toUtf8() + "\r\n");
0079 
0080     d->buffer.append(data);
0081 }
0082 
0083 /*
0084 void PostFileData::addFile(const QString& fileName, QIODevice* file, const QString& mimeType)
0085 {
0086     if (d->finished) {
0087         qCDebug(ATTICA) << "PostFileData::addFile: should not add data after calling request() or data()";
0088     }
0089     QByteArray data = file->readAll();
0090     addFile(fileName, data, mimeType);
0091 }
0092 */
0093 
0094 void PostFileData::addFile(const QString &fileName, const QByteArray &file, const QString &mimeType, const QString &fieldName)
0095 {
0096     if (d->finished) {
0097         qWarning() << "PostFileData::addFile: should not add data after calling request() or data()";
0098     }
0099 
0100     QByteArray data(
0101         "--" + d->boundary + "\r\n"
0102         "Content-Disposition: form-data; name=\"");
0103     data.append(fieldName.toLatin1());
0104     data.append("\"; filename=\"" + fileName.toUtf8() + "\"\r\nContent-Type: " + mimeType.toLatin1() + "\r\n\r\n");
0105 
0106     d->buffer.append(data);
0107     d->buffer.append(file + QByteArray("\r\n"));
0108 }
0109 
0110 QNetworkRequest PostFileData::request()
0111 {
0112     if (!d->finished) {
0113         finish();
0114     }
0115     QNetworkRequest request;
0116     request.setUrl(d->url);
0117     request.setHeader(QNetworkRequest::ContentTypeHeader, QByteArray("multipart/form-data; boundary=" + d->boundary));
0118     request.setHeader(QNetworkRequest::ContentLengthHeader, d->buffer.length());
0119     return request;
0120 }
0121 
0122 QByteArray PostFileData::data()
0123 {
0124     if (!d->finished) {
0125         finish();
0126     }
0127     return d->buffer;
0128 }
0129 
0130 void PostFileData::finish()
0131 {
0132     Q_ASSERT(!d->finished);
0133     d->finished = true;
0134     d->buffer.append("--" + d->boundary + "--");
0135 }
0136 
0137 }