1/*
2 This file is part of KDE.
3
4 SPDX-FileCopyrightText: 1999 Matthias Kalle Dalheimer <kalle@kde.org>
5 SPDX-FileCopyrightText: 2000 Charles Samuels <charles@kde.org>
6 SPDX-FileCopyrightText: 2005 Joseph Wenninger <kde@jowenn.at>
7 SPDX-FileCopyrightText: 2009 Frederik Gladhorn <gladhorn@kde.org>
8
9 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
10*/
11
12#include "postfiledata.h"
13
14#include <QDateTime>
15#include <QDebug>
16#include <QRandomGenerator>
17
18namespace Attica
19{
20class PostFileDataPrivate
21{
22public:
23 QByteArray buffer;
24 QByteArray boundary;
25 QUrl url;
26 bool finished = false;
27};
28
29PostFileData::PostFileData(const QUrl &url)
30 : d(std::make_unique<PostFileDataPrivate>())
31{
32 d->url = url;
33 d->boundary = "----------" + randomString(length: 42 + 13).toLatin1();
34}
35
36PostFileData::~PostFileData() = default;
37
38QString PostFileData::randomString(int length)
39{
40 if (length <= 0) {
41 return QString();
42 }
43
44 QString str;
45 str.resize(size: length);
46 int i = 0;
47 auto *generator = QRandomGenerator::global();
48 while (length--) {
49 int r = generator->bounded(highest: 62);
50 r += 48;
51 if (r > 57) {
52 r += 7;
53 }
54 if (r > 90) {
55 r += 6;
56 }
57 str[i++] = QLatin1Char(char(r));
58 }
59 return str;
60}
61
62void PostFileData::addArgument(const QString &key, const QString &value)
63{
64 if (d->finished) {
65 qWarning() << "PostFileData::addFile: should not add data after calling request() or data()";
66 }
67 QByteArray data(
68 "--" + d->boundary + "\r\n"
69 "Content-Disposition: form-data; name=\"" + key.toLatin1() +
70 "\"\r\n\r\n" + value.toUtf8() + "\r\n");
71
72 d->buffer.append(a: data);
73}
74
75/*
76void PostFileData::addFile(const QString& fileName, QIODevice* file, const QString& mimeType)
77{
78 if (d->finished) {
79 qCDebug(ATTICA) << "PostFileData::addFile: should not add data after calling request() or data()";
80 }
81 QByteArray data = file->readAll();
82 addFile(fileName, data, mimeType);
83}
84*/
85
86void PostFileData::addFile(const QString &fileName, const QByteArray &file, const QString &mimeType, const QString &fieldName)
87{
88 if (d->finished) {
89 qWarning() << "PostFileData::addFile: should not add data after calling request() or data()";
90 }
91
92 QByteArray data(
93 "--" + d->boundary + "\r\n"
94 "Content-Disposition: form-data; name=\"");
95 data.append(a: fieldName.toLatin1());
96 data.append(a: "\"; filename=\"" + fileName.toUtf8() + "\"\r\nContent-Type: " + mimeType.toLatin1() + "\r\n\r\n");
97
98 d->buffer.append(a: data);
99 d->buffer.append(a: file + QByteArray("\r\n"));
100}
101
102QNetworkRequest PostFileData::request()
103{
104 if (!d->finished) {
105 finish();
106 }
107 QNetworkRequest request;
108 request.setUrl(d->url);
109 request.setHeader(header: QNetworkRequest::ContentTypeHeader, value: QByteArray("multipart/form-data; boundary=" + d->boundary));
110 request.setHeader(header: QNetworkRequest::ContentLengthHeader, value: d->buffer.length());
111 return request;
112}
113
114QByteArray PostFileData::data()
115{
116 if (!d->finished) {
117 finish();
118 }
119 return d->buffer;
120}
121
122void PostFileData::finish()
123{
124 Q_ASSERT(!d->finished);
125 d->finished = true;
126 d->buffer.append(a: "--" + d->boundary + "--");
127}
128
129}
130

source code of attica/src/postfiledata.cpp