diff options
author | Marc Mutz <[email protected]> | 2024-05-29 14:04:02 +0200 |
---|---|---|
committer | Mårten Nordheim <[email protected]> | 2024-06-01 00:14:35 +0000 |
commit | 5bf0c3d5d30bbd4a82142481c391dc35125accfd (patch) | |
tree | 12562fb1a2b62b68faeed07a647d7fd7c5d25b61 | |
parent | c4fc3a74b4525ad5d80e558707301a12e4d4cb19 (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.cpp | 64 | ||||
-rw-r--r-- | src/network/access/qformdatabuilder.h | 15 |
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; |