network: finish all pending replies upon error
... and not only one. This was a problem e.g. when there were several requests to the same host and the host was not reachable; only one reply would get an error signal in case we suppressed other errors in "happy eyeballs" host lookup style. Task-number: QTBUG-36890 Change-Id: I1b5757498bd644b0d773cf6c43e4950620949c5c Reviewed-by: Richard J. Moore <rich@kde.org>
This commit is contained in:
parent
362c75f7c1
commit
9c2ecf89eb
@ -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
|
||||
|
@ -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()
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user