summaryrefslogtreecommitdiffstats
path: root/tests/auto/qnetworkreply
diff options
context:
space:
mode:
authorTomasz Duda <tomaszduda23@gmail.com>2012-09-19 17:42:11 (GMT)
committerThe Qt Project <gerrit-noreply@qt-project.org>2012-09-25 13:35:09 (GMT)
commit872d6aff3ea96d548e0bad99def669b803368a36 (patch)
tree6a7fdcbc26fab50bf0ba81b2bd47516a5fb09481 /tests/auto/qnetworkreply
parent87cd2d3530dfd3d7dc78b7dab50aefde87ca3b16 (diff)
downloadQt-872d6aff3ea96d548e0bad99def669b803368a36.zip
Qt-872d6aff3ea96d548e0bad99def669b803368a36.tar.gz
Qt-872d6aff3ea96d548e0bad99def669b803368a36.tar.bz2
HTTP header may be damaged - fix, unit test
"HTTP/1.1 100 CONTINUE\r\n" If the header from a server is splitted between two packets the first packet contains "HTTP/1.1 100" and the second one contains " CONTINUE\r\n", one space (0x20) is skipped. After processing the line looks in this way "HTTP/1.1 100CONTINUE". QHttpNetworkReplyPrivate::readStatus(QAbstractSocket *socket) is called twice, if a http header is splitted as above. The function always removes whitespace from the beginning of a packet, even if it is the second part of a http header QHttpNetworkReply returns QNetworkReply::RemoteHostClosedError due to damaged http header during processing. Task-number: QTBUG-27161 Backported qtbase/60f4fc8b706db9cbeacd5dc4886a7aa347daafc0 Change-Id: I07ec43641bbb9966285a8a1f57a51fb27d2643d4 Reviewed-by: Shane Kearns <shane.kearns@accenture.com>
Diffstat (limited to 'tests/auto/qnetworkreply')
-rw-r--r--tests/auto/qnetworkreply/tst_qnetworkreply.cpp76
1 files changed, 76 insertions, 0 deletions
diff --git a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp
index 49bcf12..591ff55 100644
--- a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp
+++ b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp
@@ -371,6 +371,9 @@ private Q_SLOTS:
void qtbug18232gzipContentLengthZero();
void nb279420gzipNoContentLengthEmptyContentDisconnect();
+ void qtbug27161httpHeaderMayBeDamaged_data();
+ void qtbug27161httpHeaderMayBeDamaged();
+
void synchronousRequest_data();
void synchronousRequest();
#ifndef QT_NO_OPENSSL
@@ -6428,6 +6431,79 @@ void tst_QNetworkReply::nb279420gzipNoContentLengthEmptyContentDisconnect()
QCOMPARE(reply->readAll(), QByteArray());
}
+class QtBug27161Helper : public QObject {
+ Q_OBJECT
+public:
+ QtBug27161Helper(MiniHttpServer & server, const QByteArray & data):
+ m_server(server),
+ m_data(data)
+ {
+ connect(&m_server, SIGNAL(newConnection()), this, SLOT(newConnectionSlot()));
+ }
+public slots:
+ void newConnectionSlot(){
+ connect(m_server.client, SIGNAL(bytesWritten(qint64)), this, SLOT(bytesWrittenSlot()));
+ }
+
+ void bytesWrittenSlot(){
+ disconnect(m_server.client, SIGNAL(bytesWritten(qint64)), this, SLOT(bytesWrittenSlot()));
+ m_Timer.singleShot(100, this, SLOT(timeoutSlot()));
+ }
+
+ void timeoutSlot(){
+ m_server.doClose = true;
+ // we need to emulate the bytesWrittenSlot call if the data is empty.
+ if (m_data.size() == 0)
+ QMetaObject::invokeMethod(&m_server, "bytesWrittenSlot", Qt::QueuedConnection);
+ else
+ m_server.client->write(m_data);
+ }
+
+private:
+ MiniHttpServer & m_server;
+ QByteArray m_data;
+ QTimer m_Timer;
+};
+
+void tst_QNetworkReply::qtbug27161httpHeaderMayBeDamaged_data(){
+ QByteArray response("HTTP/1.0 200 OK\r\nServer: bogus\r\nContent-Length: 3\r\n\r\nABC");
+ QTest::addColumn<QByteArray>("firstPacket");
+ QTest::addColumn<QByteArray>("secondPacket");
+
+ for (int i = 1; i < response.size(); i++){
+ QByteArray dataTag("Iteration: ");
+ dataTag.append(QByteArray::number(i - 1));
+ QTest::newRow(dataTag.constData()) << response.left(i) << response.mid(i);
+ }
+}
+
+/*
+ * Purpose of this test is to check whether a content from server is parsed correctly
+ * if it is splitted into two parts.
+ */
+void tst_QNetworkReply::qtbug27161httpHeaderMayBeDamaged(){
+ QFETCH(QByteArray, firstPacket);
+ QFETCH(QByteArray, secondPacket);
+ MiniHttpServer server(firstPacket);
+ server.doClose = false;
+ QtBug27161Helper helper(server, secondPacket);
+
+ QNetworkRequest request(QUrl("http://localhost:" + QString::number(server.serverPort())));
+ QNetworkReplyPtr reply(manager.get(request));
+
+ connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop()));
+ QTestEventLoop::instance().enterLoop(10);
+ QVERIFY(!QTestEventLoop::instance().timeout());
+
+ QVERIFY(reply->isFinished());
+ QCOMPARE(reply->error(), QNetworkReply::NoError);
+ QCOMPARE(reply->size(), qint64(3));
+ QCOMPARE(reply->header(QNetworkRequest::ContentLengthHeader).toLongLong(), qint64(3));
+ QCOMPARE(reply->rawHeader("Content-length"), QByteArray("3"));
+ QCOMPARE(reply->rawHeader("Server"), QByteArray("bogus"));
+ QCOMPARE(reply->readAll(), QByteArray("ABC"));
+}
+
void tst_QNetworkReply::synchronousRequest_data()
{
QTest::addColumn<QUrl>("url");