Details
-
Bug
-
Resolution: Out of scope
-
P3: Somewhat important
-
None
-
5.15.14
Description
QNetworkAccessManager opens QNetworkRequest for you so you don't need to call QNetworkRequest::open() explicitly, yes. But doing so shouldn't cause data loss I believe.
Data loss did not happen to old Qt versions, e.g. 5.7, nor new versions, e.g. 6.5. But 5.15 suffers such issue. A simple reproducer is below. Give it an URL as argument, e.g. https://qt.io, and run it.
#include <QCoreApplication> #include <QEventLoop> #include <QNetworkAccessManager> #include <QNetworkReply> #include <QNetworkRequest> #include <QUrl> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); QString urlString = a.arguments().value(1); QUrl url(urlString); if (urlString.isEmpty() || !url.isValid()) { qCritical("Syntax:"); qCritical(" %s <URL>", qPrintable(a.applicationName())); return 1; } QNetworkAccessManager manager; QNetworkRequest request(url); QNetworkReply* reply = manager.get(request); QEventLoop eventLoop; QObject::connect(reply, &QNetworkReply::finished, &eventLoop, &QEventLoop::quit); QObject::connect(reply, &QNetworkReply::errorOccurred, &eventLoop, &QEventLoop::quit); QObject::connect(reply, &QNetworkReply::sslErrors, [=](const QList<QSslError>& e) { reply->ignoreSslErrors(e); }); QObject::connect(reply, &QNetworkReply::downloadProgress, [=](qint64 r, qint64 t) { qInfo("%lld/%lld", r, t); }); eventLoop.exec(); if (reply->error() != QNetworkReply::NetworkError::NoError) { qWarning("Error Occurred: %s", qPrintable(reply->errorString())); return 1; } QString urlDisplayString = url.toString(QUrl::UrlFormattingOption::RemoveQuery); if (url.hasQuery()) { urlDisplayString.append("?<REDACTED>"); } qInfo("Reply Received from %s", qPrintable(urlDisplayString)); qInfo("Bytes Available: %lld", reply->bytesAvailable()); QByteArray body; if (reply->open(QIODevice::ReadOnly)) { qInfo("Reply opened. Bytes available is %d now", reply->bytesAvailable()); body = reply->readAll(); } if (body.isEmpty()) { qWarning("Response Body is Empty"); } else { qInfo("Response Body Length: %d", body.length()); } return 0; }
Notice how reply->bytesAvailable() returns 298 (in case of Qt website) at the first place but 0 after reply->open(QIODevice::ReadOnly). Then nothing can be read.
Problem is gone if reply->readAll() is called without opening. But as aforementioned, I think opening it again should not cause any harm.