summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/network/access/qhttpnetworkconnectionchannel.cpp1
-rw-r--r--src/network/access/qhttpnetworkreply.cpp19
-rw-r--r--src/network/access/qhttpnetworkreply_p.h1
-rw-r--r--tests/auto/qnetworkreply/tst_qnetworkreply.cpp58
4 files changed, 75 insertions, 4 deletions
diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp
index 806452c..1d8224c 100644
--- a/src/network/access/qhttpnetworkconnectionchannel.cpp
+++ b/src/network/access/qhttpnetworkconnectionchannel.cpp
@@ -353,6 +353,7 @@ void QHttpNetworkConnectionChannel::_q_receiveReply()
replyPrivate->autoDecompress = false;
}
if (replyPrivate->statusCode == 100) {
+ replyPrivate->clearHttpLayerInformation();
replyPrivate->state = QHttpNetworkReplyPrivate::ReadingStatusState;
break; // ignore
}
diff --git a/src/network/access/qhttpnetworkreply.cpp b/src/network/access/qhttpnetworkreply.cpp
index 984f557..338236e 100644
--- a/src/network/access/qhttpnetworkreply.cpp
+++ b/src/network/access/qhttpnetworkreply.cpp
@@ -219,7 +219,7 @@ QHttpNetworkReplyPrivate::~QHttpNetworkReplyPrivate()
{
}
-void QHttpNetworkReplyPrivate::clear()
+void QHttpNetworkReplyPrivate::clearHttpLayerInformation()
{
state = NothingDoneState;
statusCode = 100;
@@ -229,18 +229,24 @@ void QHttpNetworkReplyPrivate::clear()
currentChunkSize = 0;
currentChunkRead = 0;
connectionCloseEnabled = true;
- connection = 0;
- connectionChannel = 0;
#ifndef QT_NO_COMPRESS
if (initInflate)
inflateEnd(&inflateStrm);
#endif
initInflate = false;
streamEnd = false;
- autoDecompress = false;
fields.clear();
}
+// TODO: Isn't everything HTTP layer related? We don't need to set connection and connectionChannel to 0 at all
+void QHttpNetworkReplyPrivate::clear()
+{
+ connection = 0;
+ connectionChannel = 0;
+ autoDecompress = false;
+ clearHttpLayerInformation();
+}
+
// QHttpNetworkReplyPrivate
qint64 QHttpNetworkReplyPrivate::bytesAvailable() const
{
@@ -539,6 +545,11 @@ qint64 QHttpNetworkReplyPrivate::readHeader(QAbstractSocket *socket)
|| fragment.endsWith("\r\n\n")
|| fragment.endsWith("\n\n"))
allHeaders = true;
+
+ // there is another case: We have no headers. Then the fragment equals just the line ending
+ if ((fragment.length() == 2 && fragment.endsWith("\r\n"))
+ || (fragment.length() == 1 && fragment.endsWith("\n")))
+ allHeaders = true;
}
}
} while (!allHeaders && haveRead > 0);
diff --git a/src/network/access/qhttpnetworkreply_p.h b/src/network/access/qhttpnetworkreply_p.h
index fa240ec..4011c78 100644
--- a/src/network/access/qhttpnetworkreply_p.h
+++ b/src/network/access/qhttpnetworkreply_p.h
@@ -172,6 +172,7 @@ public:
bool findChallenge(bool forProxy, QByteArray &challenge) const;
QAuthenticatorPrivate::Method authenticationMethod(bool isProxy) const;
void clear();
+ void clearHttpLayerInformation();
qint64 readReplyBodyRaw(QIODevice *in, QByteDataBuffer *out, qint64 size);
qint64 readReplyBodyChunked(QIODevice *in, QByteDataBuffer *out);
diff --git a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp
index 78b4d98..261e613 100644
--- a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp
+++ b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp
@@ -199,6 +199,10 @@ private Q_SLOTS:
#endif
void ioGetFromHttpBrokenServer_data();
void ioGetFromHttpBrokenServer();
+ void ioGetFromHttpStatus100_data();
+ void ioGetFromHttpStatus100();
+ void ioGetFromHttpNoHeaders_data();
+ void ioGetFromHttpNoHeaders();
void ioGetFromHttpWithCache_data();
void ioGetFromHttpWithCache();
@@ -2074,6 +2078,60 @@ void tst_QNetworkReply::ioGetFromHttpBrokenServer()
QVERIFY(reply->error() != QNetworkReply::NoError);
}
+void tst_QNetworkReply::ioGetFromHttpStatus100_data()
+{
+ QTest::addColumn<QByteArray>("dataToSend");
+ QTest::newRow("normal") << QByteArray("HTTP/1.1 100 Continue\r\n\r\nHTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n");
+ QTest::newRow("minimal") << QByteArray("HTTP/1.1 100 Continue\n\nHTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n");
+ QTest::newRow("minimal2") << QByteArray("HTTP/1.1 100 Continue\n\nHTTP/1.0 200 OK\r\n\r\n");
+ QTest::newRow("minimal3") << QByteArray("HTTP/1.1 100 Continue\n\nHTTP/1.0 200 OK\n\n");
+ QTest::newRow("with_headers") << QByteArray("HTTP/1.1 100 Continue\r\nBla: x\r\n\r\nHTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n");
+ QTest::newRow("with_headers2") << QByteArray("HTTP/1.1 100 Continue\nBla: x\n\nHTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n");
+}
+
+void tst_QNetworkReply::ioGetFromHttpStatus100()
+{
+ QFETCH(QByteArray, dataToSend);
+ MiniHttpServer server(dataToSend);
+ server.doClose = true;
+
+ 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());
+
+ QCOMPARE(reply->url(), request.url());
+ QCOMPARE(reply->error(), QNetworkReply::NoError);
+ QCOMPARE(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), 200);
+ QVERIFY(reply->rawHeader("bla").isNull());
+}
+
+void tst_QNetworkReply::ioGetFromHttpNoHeaders_data()
+{
+ QTest::addColumn<QByteArray>("dataToSend");
+ QTest::newRow("justStatus+noheaders+disconnect") << QByteArray("HTTP/1.0 200 OK\r\n\r\n");
+}
+
+void tst_QNetworkReply::ioGetFromHttpNoHeaders()
+{
+ QFETCH(QByteArray, dataToSend);
+ MiniHttpServer server(dataToSend);
+ server.doClose = true;
+
+ 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());
+
+ QCOMPARE(reply->url(), request.url());
+ QCOMPARE(reply->error(), QNetworkReply::NoError);
+ QCOMPARE(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), 200);
+}
+
void tst_QNetworkReply::ioGetFromHttpWithCache_data()
{
qRegisterMetaType<MyMemoryCache::CachedContent>();