From 6f7e8d28b46dea47c9179f4a69bc693e844f4d1b Mon Sep 17 00:00:00 2001 From: Mikhail Svetkin Date: Sat, 30 Mar 2019 12:48:47 +0300 Subject: Fix HTTP chunked request body handling Task: QTBUG-74843 Change-Id: I4978c80195246c99a5e6d1e608b3980f56b39207 Reviewed-by: Jesus Fernandez --- src/httpserver/qhttpserverrequest.cpp | 8 +++++- tests/auto/qhttpserver/tst_qhttpserver.cpp | 45 ++++++++++++++++++++++++++++-- 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/src/httpserver/qhttpserverrequest.cpp b/src/httpserver/qhttpserverrequest.cpp index f48864b..f6c52dd 100644 --- a/src/httpserver/qhttpserverrequest.cpp +++ b/src/httpserver/qhttpserverrequest.cpp @@ -209,7 +209,13 @@ int QHttpServerRequestPrivate::onBody(http_parser *httpParser, const char *at, s qCDebug(lc) << httpParser << QString::fromUtf8(at, int(length)); auto i = instance(httpParser); i->state = State::OnBody; - i->body = QByteArray(at, int(length)); + if (i->body.isEmpty()) { + i->body.reserve( + static_cast(httpParser->content_length) + + static_cast(length)); + } + + i->body.append(at, int(length)); return 0; } diff --git a/tests/auto/qhttpserver/tst_qhttpserver.cpp b/tests/auto/qhttpserver/tst_qhttpserver.cpp index 6193fb5..2934dc0 100644 --- a/tests/auto/qhttpserver/tst_qhttpserver.cpp +++ b/tests/auto/qhttpserver/tst_qhttpserver.cpp @@ -166,6 +166,12 @@ void tst_QHttpServer::initTestCase() httpserver.route("/check-custom-type/", [] (const CustomArg &customArg) { return QString("data = %1").arg(customArg.data); }); + + httpserver.route("/post-body", "POST", [] (const QHttpServerRequest &request) { + return request.body(); + }); + + urlBase = QStringLiteral("http://localhost:%1%2").arg(httpserver.listen()); } void tst_QHttpServer::routeGet_data() @@ -334,6 +340,38 @@ void tst_QHttpServer::routePost_data() << "text/html" << "" << "Hello world post"; + + QTest::addRow("post-and-get, post") + << "/post-and-get" + << 200 + << "text/html" + << "" + << "Hello world post"; + + QTest::addRow("any, post") + << "/any" + << 200 + << "text/html" + << "" + << "Post"; + + QTest::addRow("post-body") + << "/post-body" + << 200 + << "text/html" + << "some post data" + << "some post data"; + + QString body; + for (int i = 0; i < 10000; i++) + body.append(QString::number(i)); + + QTest::addRow("post-body - huge body, chunk test") + << "/post-body" + << 200 + << "text/html" + << body + << body; } void tst_QHttpServer::routePost() @@ -345,8 +383,11 @@ void tst_QHttpServer::routePost() QFETCH(QString, body); QNetworkAccessManager networkAccessManager; - const QUrl requestUrl(urlBase.arg(url)); - auto reply = networkAccessManager.post(QNetworkRequest(requestUrl), data.toUtf8()); + QNetworkRequest request(QUrl(urlBase.arg(url))); + if (data.size()) + request.setHeader(QNetworkRequest::ContentTypeHeader, "text/html"); + + auto reply = networkAccessManager.post(request, data.toUtf8()); QTRY_VERIFY(reply->isFinished()); -- cgit v1.2.3