refactor disconnectFromFtp to remove cached entries when necessary
In cases where a cached ftp connection fails to connect, or a file transfer has failed, we should removed the cached connection. Since qnam has an idea of a single internal QFtp per full operation, when file transfers failed previously the cached connection would be reused for subsequent connections and thus fail. [ChangeLog][QtNetwork][QNetworkAccessManager] QNetworkAccessManager now properly handles FTP transfer failures by removing failed cached ftp connections. Task-number: QTBUG-40797 Change-Id: Ie090a39ceddd7e58a0d8baf7d01f2a08c70162e5 Reviewed-by: Richard J. Moore <rich@kde.org>bb10
parent
f630eb1120
commit
45cbbe56bc
|
|
@ -211,7 +211,7 @@ void QNetworkAccessFtpBackend::ftpConnectionReady(QNetworkAccessCache::Cacheable
|
|||
// no, defer the actual operation until after we've logged in
|
||||
}
|
||||
|
||||
void QNetworkAccessFtpBackend::disconnectFromFtp()
|
||||
void QNetworkAccessFtpBackend::disconnectFromFtp(CacheCleanupMode mode)
|
||||
{
|
||||
state = Disconnecting;
|
||||
|
||||
|
|
@ -219,7 +219,12 @@ void QNetworkAccessFtpBackend::disconnectFromFtp()
|
|||
disconnect(ftp, 0, this, 0);
|
||||
|
||||
QByteArray key = makeCacheKey(url());
|
||||
QNetworkAccessManagerPrivate::getObjectCache(this)->releaseEntry(key);
|
||||
if (mode == RemoveCachedConnection) {
|
||||
QNetworkAccessManagerPrivate::getObjectCache(this)->removeEntry(key);
|
||||
ftp->dispose();
|
||||
} else {
|
||||
QNetworkAccessManagerPrivate::getObjectCache(this)->releaseEntry(key);
|
||||
}
|
||||
|
||||
ftp = 0;
|
||||
}
|
||||
|
|
@ -274,14 +279,7 @@ void QNetworkAccessFtpBackend::ftpDone()
|
|||
}
|
||||
|
||||
// we're not connected, so remove the cache entry:
|
||||
QByteArray key = makeCacheKey(url());
|
||||
QNetworkAccessManagerPrivate::getObjectCache(this)->removeEntry(key);
|
||||
|
||||
disconnect(ftp, 0, this, 0);
|
||||
ftp->dispose();
|
||||
ftp = 0;
|
||||
|
||||
state = Disconnecting;
|
||||
disconnectFromFtp(RemoveCachedConnection);
|
||||
finished();
|
||||
return;
|
||||
}
|
||||
|
|
@ -301,7 +299,7 @@ void QNetworkAccessFtpBackend::ftpDone()
|
|||
else
|
||||
error(QNetworkReply::ContentAccessDenied, msg);
|
||||
|
||||
disconnectFromFtp();
|
||||
disconnectFromFtp(RemoveCachedConnection);
|
||||
finished();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -90,7 +90,12 @@ public:
|
|||
|
||||
virtual void downstreamReadyWrite();
|
||||
|
||||
void disconnectFromFtp();
|
||||
enum CacheCleanupMode {
|
||||
ReleaseCachedConnection,
|
||||
RemoveCachedConnection
|
||||
};
|
||||
|
||||
void disconnectFromFtp(CacheCleanupMode mode = ReleaseCachedConnection);
|
||||
|
||||
public slots:
|
||||
void ftpConnectionReady(QNetworkAccessCache::CacheableObject *object);
|
||||
|
|
|
|||
|
|
@ -206,6 +206,7 @@ private Q_SLOTS:
|
|||
void getFromFileSpecial();
|
||||
void getFromFtp_data();
|
||||
void getFromFtp();
|
||||
void getFromFtpAfterError(); // QTBUG-40797
|
||||
void getFromHttp_data();
|
||||
void getFromHttp();
|
||||
void getErrors_data();
|
||||
|
|
@ -1753,6 +1754,26 @@ void tst_QNetworkReply::getFromFtp()
|
|||
QCOMPARE(reply->readAll(), reference.readAll());
|
||||
}
|
||||
|
||||
void tst_QNetworkReply::getFromFtpAfterError()
|
||||
{
|
||||
QNetworkRequest invalidRequest(QUrl("ftp://" + QtNetworkSettings::serverName() + "/qtest/invalid.txt"));
|
||||
QNetworkReplyPtr invalidReply;
|
||||
invalidReply.reset(manager.get(invalidRequest));
|
||||
QSignalSpy spy(invalidReply.data(), SIGNAL(error(QNetworkReply::NetworkError)));
|
||||
QVERIFY(spy.wait());
|
||||
QCOMPARE(invalidReply->error(), QNetworkReply::ContentNotFoundError);
|
||||
|
||||
QFile reference(testDataDir + "/rfc3252.txt");
|
||||
QVERIFY(reference.open(QIODevice::ReadOnly));
|
||||
QNetworkRequest validRequest(QUrl("ftp://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt"));
|
||||
QNetworkReplyPtr validReply;
|
||||
RUN_REQUEST(runSimpleRequest(QNetworkAccessManager::GetOperation, validRequest, validReply));
|
||||
QCOMPARE(validReply->url(), validRequest.url());
|
||||
QCOMPARE(validReply->error(), QNetworkReply::NoError);
|
||||
QCOMPARE(validReply->header(QNetworkRequest::ContentLengthHeader).toLongLong(), reference.size());
|
||||
QCOMPARE(validReply->readAll(), reference.readAll());
|
||||
}
|
||||
|
||||
void tst_QNetworkReply::getFromHttp_data()
|
||||
{
|
||||
QTest::addColumn<QString>("referenceName");
|
||||
|
|
|
|||
Loading…
Reference in New Issue