Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qformdatabuilder.cpp
Go to the documentation of this file.
1// Copyright (C) 2024 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qformdatabuilder.h"
5
6#include <QtCore/private/qstringconverter_p.h>
7#if QT_CONFIG(mimetype)
8#include "QtCore/qmimedatabase.h"
9#endif
10
11#include <vector>
12
14
34{
35 return view.toUtf8();
36}
37
39{
41 return view.toString().toUtf8(); // ### optimize
42
43 return QByteArray::fromRawData(view.data(), view.size());
44}
45
50
52{
53 for (auto c : src) {
54 if (c == '"' || c == '\\')
55 dst += '\\';
56 dst += c;
57 }
58}
59
65{
66 static_assert(std::is_nothrow_move_constructible_v<decltype(m_body)>);
67 static_assert(std::is_nothrow_move_assignable_v<decltype(m_body)>);
68
69 const auto enc = name.visit([](auto name) { return nameToByteArray(name); });
70
71 m_headerValue += "form-data; name=\"";
72 escapeNameAndAppend(m_headerValue, enc);
73 m_headerValue += "\"";
74}
75
94 = default;
95
97{
98 dst.clear();
99 dst += QByteArrayView{in}; // it's ASCII, anyway
100}
101
103{
104 dst.clear();
105 dst += QByteArrayView{in}; // it's ASCII, anyway
106}
107
109{
110 dst.resize(in.size());
112}
113
115{
116 in.visit([&dst](auto in) { convertInto_impl(dst, in); });
117}
118
119QFormDataPartBuilder &QFormDataPartBuilder::setBodyHelper(const QByteArray &data,
122{
123 m_originalBodyName = name.toString();
124 convertInto(m_mimeType, mimeType);
125 m_body = data;
126 return *this;
127}
128
151
179{
180 m_originalBodyName = fileName.toString();
181 convertInto(m_mimeType, mimeType);
182 m_body = body;
183 return *this;
184}
185
194{
195 m_httpHeaders = headers;
196 return *this;
197}
198
209QHttpPart QFormDataPartBuilder::build()
210{
211 QHttpPart httpPart;
212
213 if (!m_originalBodyName.isNull()) {
214 const bool utf8 = !QtPrivate::isAscii(m_originalBodyName);
215 const auto enc = utf8 ? m_originalBodyName.toUtf8() : m_originalBodyName.toLatin1();
216 m_headerValue += "; filename=\"";
217 escapeNameAndAppend(m_headerValue, enc);
218 m_headerValue += "\"";
219 if (utf8) {
220 // For 'filename*' production see
221 // https://datatracker.ietf.org/doc/html/rfc5987#section-3.2.1
222 // For providing both filename and filename* parameters see
223 // https://datatracker.ietf.org/doc/html/rfc6266#section-4.3 and
224 // https://datatracker.ietf.org/doc/html/rfc8187#section-4.2
225 m_headerValue += "; filename*=UTF-8''" + enc.toPercentEncoding();
226 }
227 }
228
229#if QT_CONFIG(mimetype)
230 if (m_mimeType.isEmpty()) {
231 // auto-detect
233 convertInto(m_mimeType, std::visit([&](auto &arg) {
234 return db.mimeTypeForFileNameAndData(m_originalBodyName, arg);
235 }, m_body).name());
236 }
237#endif
238
239 for (qsizetype i = 0; i < m_httpHeaders.size(); i++) {
240 httpPart.setRawHeader(QByteArrayView(m_httpHeaders.nameAt(i)).toByteArray(),
241 m_httpHeaders.valueAt(i).toByteArray());
242 }
243
244 if (!m_mimeType.isEmpty())
245 httpPart.setHeader(QNetworkRequest::ContentTypeHeader, m_mimeType);
246
247 httpPart.setHeader(QNetworkRequest::ContentDispositionHeader, m_headerValue);
248
249 if (auto d = std::get_if<QIODevice*>(&m_body))
250 httpPart.setBodyDevice(*d);
251 else if (auto b = std::get_if<QByteArray>(&m_body))
252 httpPart.setBody(*b);
253 else
254 Q_UNREACHABLE();
255
256 return httpPart;
257}
258
293{
294public:
295 std::vector<QFormDataPartBuilder> parts;
296};
297
307
313{
314 delete d_ptr;
315}
316
343{
344 Q_D(QFormDataBuilder);
345
346 return d->parts.emplace_back(name, QFormDataPartBuilder::PrivateConstructor());
347}
348
355std::unique_ptr<QHttpMultiPart> QFormDataBuilder::buildMultiPart()
356{
357 Q_D(QFormDataBuilder);
358
359 auto multiPart = std::make_unique<QHttpMultiPart>(QHttpMultiPart::FormDataType);
360
361 for (auto &part : d->parts)
362 multiPart->append(part.build());
363
364 return multiPart;
365}
366
\inmodule QtCore
QByteArray toByteArray() const
Definition qbytearray.h:797
\inmodule QtCore
Definition qbytearray.h:57
QByteArray toPercentEncoding(const QByteArray &exclude=QByteArray(), const QByteArray &include=QByteArray(), char percent='%') const
bool isEmpty() const noexcept
Returns true if the byte array has size 0; otherwise returns false.
Definition qbytearray.h:107
static QByteArray fromRawData(const char *data, qsizetype size)
Constructs a QByteArray that uses the first size bytes of the data array.
Definition qbytearray.h:410
std::vector< QFormDataPartBuilder > parts
The QFormDataBuilder class is a convenience class to simplify the construction of QHttpMultiPart obje...
Q_NETWORK_EXPORT QFormDataBuilder()
Constructs an empty QFormDataBuilder object.
Q_NETWORK_EXPORT std::unique_ptr< QHttpMultiPart > buildMultiPart()
Constructs and returns a pointer to a QHttpMultipart object.
Q_NETWORK_EXPORT ~QFormDataBuilder()
Destroys the QFormDataBuilder object.
Q_NETWORK_EXPORT QFormDataPartBuilder & part(QAnyStringView name)
Constructs and returns a reference to a QFormDataPartBuilder object and sets name as the name paramet...
The QFormDataPartBuilder class is a convenience class to simplify the construction of QHttpPart objec...
Q_NETWORK_EXPORT QFormDataPartBuilder & setHeaders(const QHttpHeaders &headers)
Sets the headers specified in headers.
Q_WEAK_OVERLOAD QFormDataPartBuilder & setBody(const QByteArray &data, QAnyStringView fileName={}, QAnyStringView mimeType={})
Q_NETWORK_EXPORT QFormDataPartBuilder(QAnyStringView name, PrivateConstructor)
Constructs a QFormDataPartBuilder object and sets name as the name parameter of the form-data.
Q_NETWORK_EXPORT QFormDataPartBuilder & setBodyDevice(QIODevice *body, QAnyStringView fileName={}, QAnyStringView mimeType={})
Sets body as the body device of this part and fileName as the file name parameter in the content disp...
Q_NETWORK_EXPORT ~QFormDataPartBuilder()
Destroys the QFormDataPartBuilder object.
Q_NETWORK_EXPORT qsizetype size() const noexcept
Returns the number of header entries.
Q_NETWORK_EXPORT QLatin1StringView nameAt(qsizetype i) const noexcept
Returns the header name at index i.
Q_NETWORK_EXPORT QByteArrayView valueAt(qsizetype i) const noexcept
Returns the header value at index i.
void append(const QHttpPart &httpPart)
Appends httpPart to this multipart.
The QHttpPart class holds a body part to be used inside a HTTP multipart MIME message.
\inmodule QtCore \reentrant
Definition qiodevice.h:34
\inmodule QtCore
QMimeType mimeTypeForFileNameAndData(const QString &fileName, QIODevice *device) const
Returns a MIME type for the given fileName and device data.
\inmodule QtCore
Definition qstringview.h:78
QByteArray toLatin1() const &
Definition qstring.h:630
bool isNull() const
Returns true if this string is null; otherwise returns false.
Definition qstring.h:994
QByteArray toUtf8() const &
Definition qstring.h:634
Combined button and popup list for selecting options.
Q_CORE_EXPORT Q_DECL_PURE_FUNCTION bool isAscii(QLatin1StringView s) noexcept
Definition qstring.cpp:850
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage void
const char * mimeType
static void convertInto_impl(QByteArray &dst, QUtf8StringView in)
static void convertInto(QByteArray &dst, QAnyStringView in)
static void escapeNameAndAppend(QByteArray &dst, QByteArrayView src)
static QByteArray nameToByteArray(QStringView view)
GLboolean GLboolean GLboolean b
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum src
GLenum GLenum dst
GLuint name
const GLubyte * c
GLuint in
SSL_CTX int void * arg
ptrdiff_t qsizetype
Definition qtypes.h:165
QMimeDatabase db
[0]
QHttpMultiPart * multiPart
[0]
QQuickView * view
[0]
static char * convertFromUnicode(char *out, QStringView in, QStringConverter::State *state) noexcept