summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/network/access/qhttpnetworkconnectionchannel.cpp27
-rw-r--r--tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp40
2 files changed, 56 insertions, 11 deletions
diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp
index fb40958178..169124e9f4 100644
--- a/src/network/access/qhttpnetworkconnectionchannel.cpp
+++ b/src/network/access/qhttpnetworkconnectionchannel.cpp
@@ -873,18 +873,23 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket
if (!connection->d_func()->shouldEmitChannelError(socket))
return;
- // Need to dequeu the request so that we can emit the error.
- if (!reply)
- connection->d_func()->dequeueRequest(socket);
- if (reply) {
- reply->d_func()->errorString = errorString;
- emit reply->finishedWithError(errorCode, errorString);
- reply = 0;
- if (protocolHandler)
- protocolHandler->setReply(0);
- }
+ // emit error for all waiting replies
+ do {
+ // Need to dequeu the request so that we can emit the error.
+ if (!reply)
+ connection->d_func()->dequeueRequest(socket);
+
+ if (reply) {
+ reply->d_func()->errorString = errorString;
+ emit reply->finishedWithError(errorCode, errorString);
+ reply = 0;
+ if (protocolHandler)
+ protocolHandler->setReply(0);
+ }
+ } while (!connection->d_func()->highPriorityQueue.isEmpty()
+ || !connection->d_func()->lowPriorityQueue.isEmpty());
#ifndef QT_NO_SSL
- else if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeSPDY) {
+ if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeSPDY) {
QList<HttpMessagePair> spdyPairs = spdyRequestsToSend.values();
for (int a = 0; a < spdyPairs.count(); ++a) {
// emit error for all replies
diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
index 11ea8aebc8..fbac7dc77c 100644
--- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
+++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
@@ -177,6 +177,7 @@ public Q_SLOTS:
void authenticationRequired(QNetworkReply*,QAuthenticator*);
void proxyAuthenticationRequired(const QNetworkProxy &,QAuthenticator*);
void pipeliningHelperSlot();
+ void emitErrorForAllRepliesSlot();
#ifndef QT_NO_SSL
void sslErrors(QNetworkReply*,const QList<QSslError> &);
@@ -449,6 +450,8 @@ private Q_SLOTS:
void ftpAuthentication_data();
void ftpAuthentication();
+ void emitErrorForAllReplies(); // QTBUG-36890
+
#ifdef QT_BUILD_INTERNAL
void backgroundRequest_data();
void backgroundRequest();
@@ -7465,6 +7468,12 @@ void tst_QNetworkReply::pipeliningHelperSlot() {
}
}
+void tst_QNetworkReply::emitErrorForAllRepliesSlot() {
+ static int a = 0;
+ if (++a == 3)
+ QTestEventLoop::instance().exitLoop();
+}
+
void tst_QNetworkReply::closeDuringDownload_data()
{
QTest::addColumn<QUrl>("url");
@@ -7513,6 +7522,37 @@ void tst_QNetworkReply::ftpAuthentication()
QCOMPARE(reply->error(), QNetworkReply::NetworkError(error));
}
+void tst_QNetworkReply::emitErrorForAllReplies() // QTBUG-36890
+{
+ // port 100 is not well-known and should be closed
+ QList<QUrl> urls = QList<QUrl>() << QUrl("http://localhost:100/request1")
+ << QUrl("http://localhost:100/request2")
+ << QUrl("http://localhost:100/request3");
+ QList<QNetworkReply *> replies;
+ QList<QSignalSpy *> errorSpies;
+ QList<QSignalSpy *> finishedSpies;
+ for (int a = 0; a < urls.count(); ++a) {
+ QNetworkRequest request(urls.at(a));
+ QNetworkReply *reply = manager.get(request);
+ replies.append(reply);
+ QSignalSpy *errorSpy = new QSignalSpy(reply, SIGNAL(error(QNetworkReply::NetworkError)));
+ errorSpies.append(errorSpy);
+ QSignalSpy *finishedSpy = new QSignalSpy(reply, SIGNAL(finished()));
+ finishedSpies.append(finishedSpy);
+ QObject::connect(reply, SIGNAL(finished()), SLOT(emitErrorForAllRepliesSlot()));
+ }
+ QTestEventLoop::instance().enterLoop(10);
+ QVERIFY(!QTestEventLoop::instance().timeout());
+ for (int a = 0; a < urls.count(); ++a) {
+ QVERIFY(replies.at(a)->isFinished());
+ QCOMPARE(errorSpies.at(a)->count(), 1);
+ errorSpies.at(a)->deleteLater();
+ QCOMPARE(finishedSpies.at(a)->count(), 1);
+ finishedSpies.at(a)->deleteLater();
+ replies.at(a)->deleteLater();
+ }
+}
+
#ifdef QT_BUILD_INTERNAL
void tst_QNetworkReply::backgroundRequest_data()
{