[Pkg-owncloud-commits] [owncloud-client] 14/27: Fix corruption while trying to resume and the server don't suport it

Sandro Knauß hefee-guest at moszumanska.debian.org
Tue Jul 29 16:23:58 UTC 2014


This is an automated email from the git hooks/post-receive script.

hefee-guest pushed a commit to branch master
in repository owncloud-client.

commit c35880d4f17a1263d5f1c75814d5edf707f2aa2f
Author: Olivier Goffart <ogoffart at woboq.com>
Date:   Fri Jul 18 12:02:57 2014 +0200

    Fix corruption while trying to resume and the server don't suport it
    
    Issue #1982
---
 src/mirall/propagator_legacy.cpp | 46 +++++++++++++++++++++++++++++++---------
 src/mirall/propagator_legacy.h   |  6 +++++-
 src/mirall/propagator_qnam.cpp   | 30 +++++++++++++++++++++++++-
 src/mirall/propagator_qnam.h     |  9 ++++----
 4 files changed, 75 insertions(+), 16 deletions(-)

diff --git a/src/mirall/propagator_legacy.cpp b/src/mirall/propagator_legacy.cpp
index 34ae55d..faf3cd1 100644
--- a/src/mirall/propagator_legacy.cpp
+++ b/src/mirall/propagator_legacy.cpp
@@ -397,24 +397,39 @@ void PropagateDownloadFileLegacy::install_content_reader( ne_request *req, void
 
     if (etag.isEmpty()) {
         qDebug() << Q_FUNC_INFO << "No E-Tag reply by server, considering it invalid" << ne_get_response_header(req, "etag");
-        that->errorString = tr("No E-Tag received from server, check Proxy/Gateway");
-        ne_set_error(that->_propagator->_session, "%s", that->errorString.toUtf8().data());
-        ne_add_response_body_reader( req, do_not_accept,
-                                     do_not_download_content_reader,
-                                     (void*) that );
+        that->abortTransfer(req, tr("No E-Tag received from server, check Proxy/Gateway"));
         return;
     } else if (!that->_expectedEtagForResume.isEmpty() && that->_expectedEtagForResume != etag) {
         qDebug() << Q_FUNC_INFO <<  "We received a different E-Tag for resuming!"
         << QString::fromLatin1(that->_expectedEtagForResume.data()) << "vs"
         << QString::fromLatin1(etag.data());
-        that->errorString = tr("We received a different E-Tag for resuming. Retrying next time.");
-        ne_set_error(that->_propagator->_session, "%s", that->errorString.toUtf8().data());
-        ne_add_response_body_reader( req, do_not_accept,
-                                     do_not_download_content_reader,
-                                     (void*) that );
+        that->abortTransfer(req, tr("We received a different E-Tag for resuming. Retrying next time."));
         return;
     }
 
+    quint64 start = 0;
+    QByteArray ranges = ne_get_response_header(req, "content-range");
+    if (!ranges.isEmpty()) {
+        QRegExp rx("bytes (\\d+)-");
+        if (rx.indexIn(ranges) >= 0) {
+            start = rx.cap(1).toULongLong();
+        }
+    }
+    if (start != that->_resumeStart) {
+        qDebug() << Q_FUNC_INFO <<  "Wrong content-range: "<< ranges << " while expecting start was" << that->_resumeStart;
+        if (start == 0) {
+            // device don't support range, just stry again from scratch
+            that->_file->close();
+            if (!that->_file->open(QIODevice::WriteOnly)) {
+                that->abortTransfer(req, that->_file->errorString());
+                return;
+            }
+        } else {
+            that->abortTransfer(req, tr("Server returned wrong content-range"));
+            return;
+        }
+    }
+
 
     const char *enc = ne_get_response_header( req, "Content-Encoding" );
     qDebug("Content encoding ist <%s> with status %d", enc ? enc : "empty",
@@ -431,6 +446,16 @@ void PropagateDownloadFileLegacy::install_content_reader( ne_request *req, void
     }
 }
 
+void PropagateDownloadFileLegacy::abortTransfer(ne_request* req, const QString& error)
+{
+    errorString = error;
+    ne_set_error(_propagator->_session, "%s", errorString.toUtf8().data());
+    ne_add_response_body_reader( req, do_not_accept,
+                                 do_not_download_content_reader,
+                                 this);
+}
+
+
 void PropagateDownloadFileLegacy::notify_status_cb(void* userdata, ne_session_status status,
                                              const ne_session_status_info* info)
 {
@@ -521,6 +546,7 @@ void PropagateDownloadFileLegacy::start()
             ne_add_request_header(req.data(), "Range", rangeRequest.constData());
             ne_add_request_header(req.data(), "Accept-Ranges", "bytes");
             qDebug() << "Retry with range " << rangeRequest;
+            _resumeStart = done;
         }
 
         /* hook called before the content is parsed to set the correct reader,
diff --git a/src/mirall/propagator_legacy.h b/src/mirall/propagator_legacy.h
index a624064..40cd5ec 100644
--- a/src/mirall/propagator_legacy.h
+++ b/src/mirall/propagator_legacy.h
@@ -53,13 +53,14 @@ class PropagateDownloadFileLegacy: public PropagateNeonJob {
     Q_OBJECT
 public:
     explicit PropagateDownloadFileLegacy(OwncloudPropagator* propagator,const SyncFileItem& item)
-        : PropagateNeonJob(propagator, item), _file(0) {}
+        : PropagateNeonJob(propagator, item), _file(0), _resumeStart(0) {}
     void start();
 private:
     QFile *_file;
     QScopedPointer<ne_decompress, ScopedPointerHelpers> _decompress;
     QString errorString;
     QByteArray _expectedEtagForResume;
+    quint64 _resumeStart;
 
     static int do_not_accept (void *userdata, ne_request *req, const ne_status *st)
     {
@@ -78,6 +79,9 @@ private:
     static void install_content_reader( ne_request *req, void *userdata, const ne_status *status );
     static void notify_status_cb(void* userdata, ne_session_status status,
                                     const ne_session_status_info* info);
+
+    /** To be called from install_content_reader if we want to abort the transfer */
+    void abortTransfer(ne_request *req, const QString &error);
 };
 
 }
diff --git a/src/mirall/propagator_qnam.cpp b/src/mirall/propagator_qnam.cpp
index a4acd5d..e3a6a91 100644
--- a/src/mirall/propagator_qnam.cpp
+++ b/src/mirall/propagator_qnam.cpp
@@ -438,6 +438,34 @@ void GETFileJob::slotMetaDataChanged()
         reply()->abort();
         return;
     }
+
+    quint64 start = 0;
+    QByteArray ranges = parseEtag(reply()->rawHeader("Content-Range"));
+    if (!ranges.isEmpty()) {
+        QRegExp rx("bytes (\\d+)-");
+        if (rx.indexIn(ranges) >= 0) {
+            start = rx.cap(1).toULongLong();
+        }
+    }
+    if (start != _resumeStart) {
+        qDebug() << Q_FUNC_INFO <<  "Wrong content-range: "<< ranges << " while expecting start was" << _resumeStart;
+        if (start == 0) {
+            // device don't support range, just stry again from scratch
+            _device->close();
+            if (!_device->open(QIODevice::WriteOnly)) {
+                _errorString = _device->errorString();
+                _errorStatus = SyncFileItem::NormalError;
+                reply()->abort();
+                return;
+            }
+        } else {
+            _errorString = tr("Server returned wrong content-range");
+            _errorStatus = SyncFileItem::NormalError;
+            reply()->abort();
+            return;
+        }
+    }
+
 }
 
 void GETFileJob::slotReadyRead()
@@ -544,7 +572,7 @@ void PropagateDownloadFileQNAM::start()
 
     _job = new GETFileJob(AccountManager::instance()->account(),
                           _propagator->_remoteFolder + _item._file,
-                          &_tmpFile, headers, expectedEtagForResume);
+                          &_tmpFile, headers, expectedEtagForResume, _startSize);
     _job->setTimeout(_propagator->httpTimeout() * 1000);
     connect(_job, SIGNAL(finishedSignal()), this, SLOT(slotGetFinished()));
     connect(_job, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(slotDownloadProgress(qint64,qint64)));
diff --git a/src/mirall/propagator_qnam.h b/src/mirall/propagator_qnam.h
index 6df32a6..7c92b8d 100644
--- a/src/mirall/propagator_qnam.h
+++ b/src/mirall/propagator_qnam.h
@@ -105,20 +105,21 @@ private slots:
 
 class GETFileJob : public AbstractNetworkJob {
     Q_OBJECT
-    QIODevice* _device;
+    QFile* _device;
     QMap<QByteArray, QByteArray> _headers;
     QString _errorString;
     QByteArray _expectedEtagForResume;
+    quint64 _resumeStart;
     SyncFileItem::Status _errorStatus;
 public:
 
     // DOES NOT take owncership of the device.
-    explicit GETFileJob(Account* account, const QString& path, QIODevice *device,
+    explicit GETFileJob(Account* account, const QString& path, QFile *device,
                         const QMap<QByteArray, QByteArray> &headers, QByteArray expectedEtagForResume,
-                        QObject* parent = 0)
+                        quint64 resumeStart, QObject* parent = 0)
     : AbstractNetworkJob(account, path, parent),
       _device(device), _headers(headers), _expectedEtagForResume(expectedEtagForResume),
-      _errorStatus(SyncFileItem::NoStatus) {}
+      _resumeStart(resumeStart), _errorStatus(SyncFileItem::NoStatus) {}
 
     virtual void start();
     virtual bool finished() {

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-owncloud/owncloud-client.git



More information about the Pkg-owncloud-commits mailing list