fix(http): Send multipart body for PUT (#6746)
This commit is contained in:
@@ -89,6 +89,7 @@
|
||||
- Dev: Refactored types used for emoji parsing. (#6714)
|
||||
- Dev: `LinkParser` now parses `QStringView`s. (#6715)
|
||||
- Dev: Cleaned up `AccountController` connections. (#6735)
|
||||
- Dev: Send multipart body for HTTP `PUT` requests. (#6746)
|
||||
- Dev: Removed unused variables. (#6748)
|
||||
|
||||
## 2.5.4
|
||||
|
||||
@@ -87,12 +87,24 @@ QNetworkReply *NetworkTask::createReply()
|
||||
case NetworkRequestType::Get:
|
||||
return accessManager->get(request);
|
||||
|
||||
case NetworkRequestType::Put:
|
||||
return accessManager->put(request, data->payload);
|
||||
|
||||
case NetworkRequestType::Delete:
|
||||
return accessManager->deleteResource(data->request);
|
||||
|
||||
case NetworkRequestType::Put:
|
||||
if (data->multiPartPayload)
|
||||
{
|
||||
assert(data->payload.isNull());
|
||||
|
||||
return accessManager->put(request,
|
||||
data->multiPartPayload.get());
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(data->multiPartPayload == nullptr);
|
||||
|
||||
return accessManager->put(request, data->payload);
|
||||
}
|
||||
|
||||
case NetworkRequestType::Post:
|
||||
if (data->multiPartPayload)
|
||||
{
|
||||
@@ -103,8 +115,11 @@ QNetworkReply *NetworkTask::createReply()
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(data->multiPartPayload == nullptr);
|
||||
|
||||
return accessManager->post(request, data->payload);
|
||||
}
|
||||
|
||||
case NetworkRequestType::Patch:
|
||||
if (data->multiPartPayload)
|
||||
{
|
||||
@@ -115,6 +130,8 @@ QNetworkReply *NetworkTask::createReply()
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(data->multiPartPayload == nullptr);
|
||||
|
||||
return NetworkManager::accessManager->sendCustomRequest(
|
||||
request, "PATCH", data->payload);
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "common/network/NetworkResult.hpp"
|
||||
#include "NetworkHelpers.hpp"
|
||||
#include "Test.hpp"
|
||||
#include "util/QMagicEnum.hpp"
|
||||
|
||||
#include <QCoreApplication>
|
||||
|
||||
@@ -25,6 +26,24 @@ QString getDelayURL(int delay)
|
||||
return QString("%1/delay/%2").arg(HTTPBIN_BASE_URL).arg(delay);
|
||||
}
|
||||
|
||||
QString getHttpbinUrl(QStringView path)
|
||||
{
|
||||
return QString("%1/%2").arg(HTTPBIN_BASE_URL, path);
|
||||
}
|
||||
|
||||
QHttpMultiPart *makeMultipart()
|
||||
{
|
||||
auto *multipart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
|
||||
|
||||
QHttpPart part;
|
||||
part.setHeader(QNetworkRequest::ContentDispositionHeader,
|
||||
QVariant("form-data; name=\"text\""));
|
||||
part.setBody("my text");
|
||||
|
||||
multipart->append(part);
|
||||
return multipart;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST(NetworkRequest, Success)
|
||||
@@ -281,3 +300,86 @@ TEST(NetworkRequest, BatchedTimeouts)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(NetworkRequest, HttpGetHeaders)
|
||||
{
|
||||
EXPECT_TRUE(NetworkManager::workerThread->isRunning());
|
||||
|
||||
RequestWaiter waiter;
|
||||
NetworkRequest(getHttpbinUrl(u"headers"), NetworkRequestType::Get)
|
||||
.timeout(1000)
|
||||
.onSuccess([&](const NetworkResult &result) {
|
||||
// make sure we don't attempt to send a body
|
||||
auto body = QString::fromUtf8(result.getData());
|
||||
EXPECT_FALSE(body.contains("content-length", Qt::CaseInsensitive));
|
||||
waiter.requestDone();
|
||||
})
|
||||
.execute();
|
||||
|
||||
waiter.waitForRequest();
|
||||
}
|
||||
|
||||
TEST(NetworkRequest, HttpBody)
|
||||
{
|
||||
EXPECT_TRUE(NetworkManager::workerThread->isRunning());
|
||||
|
||||
for (auto ty : std::array{
|
||||
NetworkRequestType::Post,
|
||||
NetworkRequestType::Put,
|
||||
NetworkRequestType::Patch,
|
||||
})
|
||||
{
|
||||
auto path = qmagicenum::enumNameString(ty).toLower();
|
||||
RequestWaiter waiter;
|
||||
bool success = false;
|
||||
NetworkRequest(getHttpbinUrl(path), ty)
|
||||
.timeout(1000)
|
||||
.payload("foobar")
|
||||
.header("Content-Type", "text/plain")
|
||||
.onSuccess([&](const NetworkResult &result) {
|
||||
EXPECT_EQ(result.getData(), "foobar") << path;
|
||||
success = true;
|
||||
})
|
||||
.finally([&] {
|
||||
waiter.requestDone();
|
||||
})
|
||||
.execute();
|
||||
|
||||
waiter.waitForRequest();
|
||||
ASSERT_TRUE(success) << path;
|
||||
}
|
||||
}
|
||||
|
||||
TEST(NetworkRequest, HttpBodyMultipart)
|
||||
{
|
||||
EXPECT_TRUE(NetworkManager::workerThread->isRunning());
|
||||
|
||||
for (auto ty : std::array{
|
||||
NetworkRequestType::Post,
|
||||
NetworkRequestType::Put,
|
||||
NetworkRequestType::Patch,
|
||||
})
|
||||
{
|
||||
auto path = qmagicenum::enumNameString(ty).toLower();
|
||||
RequestWaiter waiter;
|
||||
bool success = false;
|
||||
NetworkRequest(getHttpbinUrl(path), ty)
|
||||
.timeout(1000)
|
||||
.multiPart(makeMultipart())
|
||||
.onSuccess([&](const NetworkResult &result) {
|
||||
auto body = QString::fromUtf8(result.getData());
|
||||
EXPECT_TRUE(body.contains("Content-Disposition: form-data; "
|
||||
"name=\"text\"\r\n\r\nmy text",
|
||||
Qt::CaseInsensitive))
|
||||
<< "Path:" << path << "Body:" << body;
|
||||
success = true;
|
||||
})
|
||||
.finally([&] {
|
||||
waiter.requestDone();
|
||||
})
|
||||
.execute();
|
||||
|
||||
waiter.waitForRequest();
|
||||
ASSERT_TRUE(success) << path;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user