summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimur Pocheptsov <timur.pocheptsov@qt.io>2017-08-31 11:34:24 +0200
committerTimur Pocheptsov <timur.pocheptsov@qt.io>2017-09-04 12:11:11 +0000
commit6a0f59f9c1c7a0a1a28988b89025145d81f3a6aa (patch)
tree1348e63aad4ecad2eecd44502527153834fdfa73
parent3f1ac5899476307923686166705812c24a2e3578 (diff)
Fix MiniHttpServer (POST/PUT requests processing)
Teach our MiniHttpServer to better handle POST and PUT requests: read the POST/PUT data too (not headers only), before replying and flushing. The original comment says MiniHttpServer does not support POST/PUT requests, it's not true anymore - we can handle them (perhaps the simplest/shortest ones). Task-number: QTBUG-62844 Change-Id: I80260f8ede1bb1b0b9d6042ecd59558bb7e9a998 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
-rw-r--r--tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp48
1 files changed, 47 insertions, 1 deletions
diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
index 855b1f9041..906566483d 100644
--- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
+++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
@@ -30,6 +30,7 @@
#include <QtTest/QtTest>
#include <QtCore/QCryptographicHash>
#include <QtCore/QDataStream>
+#include <QtCore/QTextStream>
#include <QtCore/QUrl>
#include <QtCore/QEventLoop>
#include <QtCore/QFile>
@@ -527,7 +528,9 @@ static void setupSslServer(QSslSocket* serverSocket)
}
#endif
-// Does not work for POST/PUT!
+// NOTE: MiniHttpServer has a very limited support of PUT/POST requests! Make
+// sure you understand the server's code before PUTting/POSTing data (and
+// probably you'll have to update the logic).
class MiniHttpServer: public QTcpServer
{
Q_OBJECT
@@ -541,6 +544,7 @@ public:
bool ipv6;
bool multiple;
int totalConnections;
+ bool parseHeaders = false;
MiniHttpServer(const QByteArray &data, bool ssl = false, QThread *thread = 0, bool useipv6 = false)
: dataToTransmit(data), doClose(true), doSsl(ssl), ipv6(useipv6),
@@ -566,6 +570,12 @@ public:
dataToTransmit = data;
}
+ void clearHeaderParserState()
+ {
+ expectPayload = false;
+ receivedData.clear();
+ }
+
protected:
void incomingConnection(qintptr socketDescriptor)
{
@@ -635,13 +645,29 @@ private slots:
}
public slots:
+
void readyReadSlot()
{
Q_ASSERT(!client.isNull());
+ if (expectPayload) {
+ // NOTE: this works only for the test using POST/PUT requests to this
+ // local HTTP server, fortunately we know that data is very small
+ // (7 bytes) and we can safely read/discard it here:
+ client->readAll();
+ return reply();
+ }
+
receivedData += client->readAll();
int doubleEndlPos = receivedData.indexOf("\r\n\r\n");
if (doubleEndlPos != -1) {
+ if (parseHeaders) {
+ parseRequest();
+ if (expectPayload && doubleEndlPos + 4 == receivedData.size()) {
+ // Wait for more incoming (POST/PUT) data.
+ return;
+ }
+ }
// multiple requests incoming. remove the bytes of the current one
if (multiple)
receivedData.remove(0, doubleEndlPos+4);
@@ -664,6 +690,18 @@ public slots:
{
ready.release();
}
+
+private:
+ void parseRequest()
+ {
+ Q_ASSERT(parseHeaders);
+ QTextStream parser(receivedData, QIODevice::ReadOnly);
+ const QString line(parser.readLine());
+ expectPayload = line.startsWith(QLatin1Literal("POST"))
+ || line.startsWith(QLatin1Literal("PUT"));
+ }
+
+ bool expectPayload = false;
};
class MyCookieJar: public QNetworkCookieJar
@@ -7219,6 +7257,7 @@ void tst_QNetworkReply::qtbug28035browserDoesNotLoadQtProjectOrgCorrectly() {
manager.setCache(diskCache);
MiniHttpServer server(getReply);
+ server.parseHeaders = true;
QNetworkRequest request(QUrl("http://localhost:" + QString::number(server.serverPort())));
QNetworkReplyPtr reply(manager.get(request));
@@ -7230,6 +7269,7 @@ void tst_QNetworkReply::qtbug28035browserDoesNotLoadQtProjectOrgCorrectly() {
QCOMPARE(reply->readAll(), QByteArray("GET"));
QCOMPARE(reply->attribute(QNetworkRequest::SourceIsFromCacheAttribute).toBool(), false);
+ server.clearHeaderParserState();
server.setDataToTransmit(getReply);
reply.reset(manager.get(request));
QVERIFY2(waitForFinish(reply) == Success, msgWaitForFinished(reply));
@@ -7239,6 +7279,7 @@ void tst_QNetworkReply::qtbug28035browserDoesNotLoadQtProjectOrgCorrectly() {
QCOMPARE(reply->readAll(), QByteArray("GET"));
QCOMPARE(reply->attribute(QNetworkRequest::SourceIsFromCacheAttribute).toBool(), true);
+ server.clearHeaderParserState();
server.setDataToTransmit(postReply);
request.setRawHeader("Content-Type", "text/plain");
reply.reset(manager.post(request, postData));
@@ -7251,6 +7292,7 @@ void tst_QNetworkReply::qtbug28035browserDoesNotLoadQtProjectOrgCorrectly() {
QCOMPARE(reply->readAll(), QByteArray("POST"));
QCOMPARE(reply->attribute(QNetworkRequest::SourceIsFromCacheAttribute).toBool(), false);
+ server.clearHeaderParserState();
server.setDataToTransmit(getReply);
reply.reset(manager.get(request));
@@ -7261,6 +7303,7 @@ void tst_QNetworkReply::qtbug28035browserDoesNotLoadQtProjectOrgCorrectly() {
QCOMPARE(reply->readAll(), QByteArray("GET"));
QCOMPARE(reply->attribute(QNetworkRequest::SourceIsFromCacheAttribute).toBool(), false);
+ server.clearHeaderParserState();
server.setDataToTransmit(getReply);
reply.reset(manager.get(request));
@@ -7271,6 +7314,7 @@ void tst_QNetworkReply::qtbug28035browserDoesNotLoadQtProjectOrgCorrectly() {
QCOMPARE(reply->readAll(), QByteArray("GET"));
QCOMPARE(reply->attribute(QNetworkRequest::SourceIsFromCacheAttribute).toBool(), true);
+ server.clearHeaderParserState();
server.setDataToTransmit(putReply);
reply.reset(manager.put(request, postData));
@@ -7280,6 +7324,7 @@ void tst_QNetworkReply::qtbug28035browserDoesNotLoadQtProjectOrgCorrectly() {
QCOMPARE(reply->error(), QNetworkReply::NoError);
QCOMPARE(reply->attribute(QNetworkRequest::SourceIsFromCacheAttribute).toBool(), false);
+ server.clearHeaderParserState();
server.setDataToTransmit(getReply);
reply.reset(manager.get(request));
@@ -7290,6 +7335,7 @@ void tst_QNetworkReply::qtbug28035browserDoesNotLoadQtProjectOrgCorrectly() {
QCOMPARE(reply->readAll(), QByteArray("GET"));
QCOMPARE(reply->attribute(QNetworkRequest::SourceIsFromCacheAttribute).toBool(), false);
+ server.clearHeaderParserState();
server.setDataToTransmit(getReply);
reply.reset(manager.get(request));