summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarkus Goetz <Markus.Goetz@nokia.com>2011-03-14 16:28:15 (GMT)
committerMarkus Goetz <Markus.Goetz@nokia.com>2011-03-14 16:44:54 (GMT)
commitcdd52ad8acff0af2ecca1cef982228c6bb489feb (patch)
tree0ab4a7cafffe44591cc6e16e431ca0008f429dad
parent5f2eccbc8a392784868dd9919442642b4a9f9ef8 (diff)
downloadQt-cdd52ad8acff0af2ecca1cef982228c6bb489feb.zip
Qt-cdd52ad8acff0af2ecca1cef982228c6bb489feb.tar.gz
Qt-cdd52ad8acff0af2ecca1cef982228c6bb489feb.tar.bz2
QNAM HTTP: error() in case connection is closed unexpectedly
Task-number: QT-4658 Task-number: QT-3494 Reviewed-by: Peter Hartmann
-rw-r--r--src/network/access/qhttpnetworkconnectionchannel.cpp15
-rw-r--r--tests/auto/qnetworkreply/tst_qnetworkreply.cpp24
2 files changed, 31 insertions, 8 deletions
diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp
index 82b5ce3..700b455 100644
--- a/src/network/access/qhttpnetworkconnectionchannel.cpp
+++ b/src/network/access/qhttpnetworkconnectionchannel.cpp
@@ -963,8 +963,20 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket
} else {
errorCode = QNetworkReply::RemoteHostClosedError;
}
+ } else if (state == QHttpNetworkConnectionChannel::ReadingState) {
+ if (!reply->d_func()->expectContent()) {
+ // No content expected, this is a valid way to have the connection closed by the server
+ return;
+ }
+ if (reply->contentLength() == -1 && !reply->d_func()->isChunked()) {
+ // There was no content-length header and it's not chunked encoding,
+ // so this is a valid way to have the connection closed by the server
+ return;
+ }
+ // ok, we got a disconnect even though we did not expect it
+ errorCode = QNetworkReply::RemoteHostClosedError;
} else {
- return;
+ errorCode = QNetworkReply::RemoteHostClosedError;
}
break;
case QAbstractSocket::SocketTimeoutError:
@@ -992,6 +1004,7 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket
if (reply) {
reply->d_func()->errorString = errorString;
emit reply->finishedWithError(errorCode, errorString);
+ reply = 0;
}
// send the next request
QMetaObject::invokeMethod(that, "_q_startNextRequest", Qt::QueuedConnection);
diff --git a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp
index 8274140..39bb0fc 100644
--- a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp
+++ b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp
@@ -951,6 +951,7 @@ tst_QNetworkReply::tst_QNetworkReply()
qRegisterMetaType<QAuthenticator *>();
qRegisterMetaType<QNetworkProxy>();
qRegisterMetaType<QList<QSslError> >();
+ qRegisterMetaType<QNetworkReply::NetworkError>();
Q_SET_DEFAULT_IAP
@@ -2572,6 +2573,9 @@ void tst_QNetworkReply::ioGetFromHttpBrokenServer_data()
QTest::newRow("justHalfStatus+disconnect") << QByteArray("HTTP/1.1") << true;
QTest::newRow("justStatus+disconnect") << QByteArray("HTTP/1.1 200 OK\r\n") << true;
QTest::newRow("justStatusAndHalfHeaders+disconnect") << QByteArray("HTTP/1.1 200 OK\r\nContent-L") << true;
+
+ QTest::newRow("halfContent+disconnect") << QByteArray("HTTP/1.1 200 OK\r\nContent-Length: 4\r\n\r\nAB") << true;
+
}
void tst_QNetworkReply::ioGetFromHttpBrokenServer()
@@ -2583,29 +2587,35 @@ void tst_QNetworkReply::ioGetFromHttpBrokenServer()
QNetworkRequest request(QUrl("http://localhost:" + QString::number(server.serverPort())));
QNetworkReplyPtr reply = manager.get(request);
+ QSignalSpy spy(reply, SIGNAL(error(QNetworkReply::NetworkError)));
+
connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop()));
QTestEventLoop::instance().enterLoop(10);
QVERIFY(!QTestEventLoop::instance().timeout());
QCOMPARE(reply->url(), request.url());
+ QCOMPARE(spy.count(), 1);
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");
+ QTest::addColumn<int>("statusCode");
+ 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") << 200;
+ QTest::newRow("minimal") << QByteArray("HTTP/1.1 100 Continue\n\nHTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n") << 200;
+ QTest::newRow("minimal2") << QByteArray("HTTP/1.1 100 Continue\n\nHTTP/1.0 200 OK\r\n\r\n") << 200;
+ QTest::newRow("minimal3") << QByteArray("HTTP/1.1 100 Continue\n\nHTTP/1.0 200 OK\n\n") << 200;
+ QTest::newRow("minimal+404") << QByteArray("HTTP/1.1 100 Continue\n\nHTTP/1.0 204 No Content\r\n\r\n") << 204;
+ 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") << 200;
+ 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") << 200;
}
void tst_QNetworkReply::ioGetFromHttpStatus100()
{
QFETCH(QByteArray, dataToSend);
+ QFETCH(int, statusCode);
MiniHttpServer server(dataToSend);
server.doClose = true;
@@ -2618,7 +2628,7 @@ void tst_QNetworkReply::ioGetFromHttpStatus100()
QCOMPARE(reply->url(), request.url());
QCOMPARE(reply->error(), QNetworkReply::NoError);
- QCOMPARE(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), 200);
+ QCOMPARE(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), statusCode);
QVERIFY(reply->rawHeader("bla").isNull());
}