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 <marten.nordheim@qt.io>
This commit is contained in:
parent
c4fc3a74b4
commit
5bf0c3d5d3
@ -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()};
|
||||
}
|
||||
|
||||
QFormDataPartBuilder &QFormDataPartBuilder::setBodyHelper(const QByteArray &data,
|
||||
QAnyStringView fileName)
|
||||
static void convertInto_impl(QByteArray &dst, QUtf8StringView in)
|
||||
{
|
||||
m_originalBodyName = fileName.toString();
|
||||
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 name,
|
||||
QAnyStringView mimeType)
|
||||
{
|
||||
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))
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user