PropagateDownload: Don't discard the body of error message
authorOlivier Goffart <ogoffart@woboq.com>
Wed, 30 May 2018 14:29:29 +0000 (16:29 +0200)
committerKevin Ottens <kevin.ottens@nextcloud.com>
Tue, 15 Dec 2020 09:57:55 +0000 (10:57 +0100)
We want to keep the body so we can get the message from it
(Issue #6459)

TestDownload::testErrorMessage did not fail because the FakeErrorReply
did not emit readyRead and did not implement bytesAvailable.

Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
src/libsync/propagatedownload.cpp
test/syncenginetestutils.h

index a7b32bc767f631d7b0e2d430a54b940f8eff6a1a..c6a42137141dbf1316771d1f5e721cd7736f0e8a 100644 (file)
@@ -164,6 +164,9 @@ void GETFileJob::slotMetaDataChanged()
     // If the status code isn't 2xx, don't write the reply body to the file.
     // For any error: handle it when the job is finished, not here.
     if (httpStatus / 100 != 2) {
+        // Disable the buffer limit, as we don't limit the bandwidth for error messages.
+        // (We are only going to do a readAll() at the end.)
+        reply()->setReadBufferSize(0);
         return;
     }
     if (reply()->error() != QNetworkReply::NoError) {
@@ -266,7 +269,7 @@ void GETFileJob::slotReadyRead()
     int bufferSize = qMin(1024 * 8ll, reply()->bytesAvailable());
     QByteArray buffer(bufferSize, Qt::Uninitialized);
 
-    while (reply()->bytesAvailable() > 0) {
+    while (reply()->bytesAvailable() > 0 && _saveBodyToFile) {
         if (_bandwidthChoked) {
             qCWarning(lcGetJob) << "Download choked";
             break;
@@ -290,17 +293,19 @@ void GETFileJob::slotReadyRead()
             return;
         }
 
-        qint64 w = _device->write(buffer.constData(), r);
-        if (w != r) {
-            _errorString = _device->errorString();
-            _errorStatus = SyncFileItem::NormalError;
-            qCWarning(lcGetJob) << "Error while writing to file" << w << r << _errorString;
-            reply()->abort();
-            return;
+        if (_device->isOpen()) {
+            qint64 w = _device->write(buffer.constData(), r);
+            if (w != r) {
+                _errorString = _device->errorString();
+                _errorStatus = SyncFileItem::NormalError;
+                qCWarning(lcGetJob) << "Error while writing to file" << w << r << _errorString;
+                reply()->abort();
+                return;
+            }
         }
     }
 
-    if (reply()->isFinished() && reply()->bytesAvailable() == 0) {
+    if (reply()->isFinished() && (reply()->bytesAvailable() == 0 || !_saveBodyToFile)) {
         qCDebug(lcGetJob) << "Actually finished!";
         if (_bandwidthManager) {
             _bandwidthManager->unregisterDownloadJob(this);
index 7bf6306fc3254fa1585e02ccf756f73c6c7a1162..db85fb9a79f25f149a71e1fe43e59afbcb3ff960 100644 (file)
@@ -734,7 +734,7 @@ public:
         // finishing can come strictly after readyRead was called
         QTimer::singleShot(5, this, &FakeErrorReply::slotSetFinished);
     }
-    
+
     // make public to give tests easy interface
     using QNetworkReply::setError;
     using QNetworkReply::setAttribute;
@@ -753,6 +753,9 @@ public:
         _body = _body.mid(max);
         return max;
     }
+    qint64 bytesAvailable() const override {
+        return _body.size();
+    }
 
     int _httpErrorCode;
     QByteArray _body;