summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc Mutz <[email protected]>2024-05-29 14:04:02 +0200
committerMårten Nordheim <[email protected]>2024-06-01 00:14:35 +0000
commit5bf0c3d5d30bbd4a82142481c391dc35125accfd (patch)
tree12562fb1a2b62b68faeed07a647d7fd7c5d25b61
parentc4fc3a74b4525ad5d80e558707301a12e4d4cb19 (diff)
QFormDataPartBuilder: allow to override mime-type autodetection
If QT_CONFIG(mimetype) isn't set, this class was silently creating invalid output. If no mimetype is specified by the user and the type cannot be deduced then omit the content-type header. Change-Id: Iff15462b94fa1e992369df26f74b2bd64d523f31 Reviewed-by: Mårten Nordheim <[email protected]>
-rw-r--r--src/network/access/qformdatabuilder.cpp64
-rw-r--r--src/network/access/qformdatabuilder.h15
2 files changed, 62 insertions, 17 deletions
diff --git a/src/network/access/qformdatabuilder.cpp b/src/network/access/qformdatabuilder.cpp
index 3111c6e4ce8..dbbb3a49a6e 100644
--- a/src/network/access/qformdatabuilder.cpp
+++ b/src/network/access/qformdatabuilder.cpp
@@ -3,6 +3,7 @@
#include "qformdatabuilder.h"
+#include <QtCore/private/qstringconverter_p.h>
#if QT_CONFIG(mimetype)
#include "QtCore/qmimedatabase.h"
#endif
@@ -86,10 +87,35 @@ static auto encodeFileName(QStringView view)
return R{encoding, needsUtf8 ? view.toUtf8() : view.toLatin1()};
}
+static void convertInto_impl(QByteArray &dst, QUtf8StringView in)
+{
+ dst.clear();
+ dst += QByteArrayView{in}; // it's ASCII, anyway
+}
+
+static void convertInto_impl(QByteArray &dst, QLatin1StringView in)
+{
+ dst.clear();
+ dst += QByteArrayView{in}; // it's ASCII, anyway
+}
+
+static void convertInto_impl(QByteArray &dst, QStringView in)
+{
+ dst.resize(in.size());
+ (void)QLatin1::convertFromUnicode(dst.data(), in);
+}
+
+static void convertInto(QByteArray &dst, QAnyStringView in)
+{
+ in.visit([&dst](auto in) { convertInto_impl(dst, in); });
+}
+
QFormDataPartBuilder &QFormDataPartBuilder::setBodyHelper(const QByteArray &data,
- QAnyStringView fileName)
+ QAnyStringView name,
+ QAnyStringView mimeType)
{
- m_originalBodyName = fileName.toString();
+ m_originalBodyName = name.toString();
+ convertInto(m_mimeType, mimeType);
m_body = data;
return *this;
}
@@ -98,6 +124,9 @@ QFormDataPartBuilder &QFormDataPartBuilder::setBodyHelper(const QByteArray &data
Sets \a data as the body of this MIME part and, if given, \a fileName as the
file name parameter in the content disposition header.
+ If \a mimeType is not given (is empty), then QFormDataPartBuilder tries to
+ auto-detect the mime-type of \a data using QMimeDatabase.
+
A subsequent call to setBodyDevice() discards the body and the device will
be used instead.
@@ -108,15 +137,19 @@ QFormDataPartBuilder &QFormDataPartBuilder::setBodyHelper(const QByteArray &data
*/
QFormDataPartBuilder &QFormDataPartBuilder::setBody(QByteArrayView data,
- QAnyStringView fileName)
+ QAnyStringView fileName,
+ QAnyStringView mimeType)
{
- return setBody(data.toByteArray(), fileName);
+ return setBody(data.toByteArray(), fileName, mimeType);
}
/*!
Sets \a body as the body device of this part and \a fileName as the file
name parameter in the content disposition header.
+ If \a mimeType is not given (is empty), then QFormDataPartBuilder tries to
+ auto-detect the mime-type of \a body using QMimeDatabase.
+
A subsequent call to setBody() discards the body device and the data set by
setBody() will be used instead.
@@ -131,9 +164,11 @@ QFormDataPartBuilder &QFormDataPartBuilder::setBody(QByteArrayView data,
\sa setBody(), QHttpPart::setBodyDevice()
*/
-QFormDataPartBuilder &QFormDataPartBuilder::setBodyDevice(QIODevice *body, QAnyStringView fileName)
+QFormDataPartBuilder &QFormDataPartBuilder::setBodyDevice(QIODevice *body, QAnyStringView fileName,
+ QAnyStringView mimeType)
{
m_originalBodyName = fileName.toString();
+ convertInto(m_mimeType, mimeType);
m_body = body;
return *this;
}
@@ -170,18 +205,23 @@ QHttpPart QFormDataPartBuilder::build()
}
#if QT_CONFIG(mimetype)
- QMimeDatabase db;
- QMimeType mimeType = std::visit([&](auto &arg) {
- return db.mimeTypeForFileNameAndData(m_originalBodyName, arg);
- }, m_body);
+ if (m_mimeType.isEmpty()) {
+ // auto-detect
+ QMimeDatabase db;
+ convertInto(m_mimeType, std::visit([&](auto &arg) {
+ return db.mimeTypeForFileNameAndData(m_originalBodyName, arg);
+ }, m_body).name());
+ }
#endif
+
for (qsizetype i = 0; i < m_httpHeaders.size(); i++) {
httpPart.setRawHeader(QByteArrayView(m_httpHeaders.nameAt(i)).toByteArray(),
m_httpHeaders.valueAt(i).toByteArray());
}
-#if QT_CONFIG(mimetype)
- httpPart.setHeader(QNetworkRequest::ContentTypeHeader, mimeType.name());
-#endif
+
+ if (!m_mimeType.isEmpty())
+ httpPart.setHeader(QNetworkRequest::ContentTypeHeader, m_mimeType);
+
httpPart.setHeader(QNetworkRequest::ContentDispositionHeader, m_headerValue);
if (auto d = std::get_if<QIODevice*>(&m_body))
diff --git a/src/network/access/qformdatabuilder.h b/src/network/access/qformdatabuilder.h
index b3db2727720..68f9f3742c3 100644
--- a/src/network/access/qformdatabuilder.h
+++ b/src/network/access/qformdatabuilder.h
@@ -57,22 +57,27 @@ public:
Q_NETWORK_EXPORT ~QFormDataPartBuilder();
Q_WEAK_OVERLOAD QFormDataPartBuilder &setBody(const QByteArray &data,
- QAnyStringView fileName = {})
- { return setBodyHelper(data, fileName); }
+ QAnyStringView fileName = {},
+ QAnyStringView mimeType = {})
+ { return setBodyHelper(data, fileName, mimeType); }
Q_NETWORK_EXPORT QFormDataPartBuilder &setBody(QByteArrayView data,
- QAnyStringView fileName = {});
+ QAnyStringView fileName = {},
+ QAnyStringView mimeType = {});
Q_NETWORK_EXPORT QFormDataPartBuilder &setBodyDevice(QIODevice *body,
- QAnyStringView fileName = {});
+ QAnyStringView fileName = {},
+ QAnyStringView mimeType = {});
Q_NETWORK_EXPORT QFormDataPartBuilder &setHeaders(const QHttpHeaders &headers);
private:
Q_DISABLE_COPY(QFormDataPartBuilder)
Q_NETWORK_EXPORT QFormDataPartBuilder &setBodyHelper(const QByteArray &data,
- QAnyStringView fileName = {});
+ QAnyStringView fileName,
+ QAnyStringView mimeType);
Q_NETWORK_EXPORT QHttpPart build();
QByteArray m_headerValue;
+ QByteArray m_mimeType;
QString m_originalBodyName;
QHttpHeaders m_httpHeaders;
std::variant<QIODevice*, QByteArray> m_body;