AbstractNetworkJob: Improve redirect handling #5555
authorChristian Kamm <mail@ckamm.de>
Fri, 3 Mar 2017 10:20:53 +0000 (11:20 +0100)
committerckamm <mail@ckamm.de>
Tue, 7 Mar 2017 12:18:01 +0000 (13:18 +0100)
* For requests:
  - reuse the original QNetworkRequest, so headers and attributes
    are the same as in the original request
  - determine the original http method from the reply and the request
    attributes
  - keep the original request body around such that it can be sent
    again in case the request is redirected

* Simplify the interface that is used for creating new requests in
  AbstractNetworkJob.

15 files changed:
src/gui/notificationconfirmjob.cpp
src/gui/ocsjob.cpp
src/gui/owncloudsetupwizard.cpp
src/gui/thumbnailjob.cpp
src/libsync/abstractnetworkjob.cpp
src/libsync/abstractnetworkjob.h
src/libsync/account.cpp
src/libsync/account.h
src/libsync/networkjobs.cpp
src/libsync/propagatedownload.cpp
src/libsync/propagateremotedelete.cpp
src/libsync/propagateremotemove.cpp
src/libsync/propagateupload.cpp
src/libsync/propagateupload.h
test/syncenginetestutils.h

index b3051827ebf754270fd1fa4293e4c9a79ba456f8..479c4238db5b269f113aab2c8967156f2bc3336f 100644 (file)
@@ -54,9 +54,7 @@ void NotificationConfirmJob::start()
     req.setRawHeader("Ocs-APIREQUEST", "true");
     req.setRawHeader("Content-Type", "application/x-www-form-urlencoded");
 
-    QIODevice *iodevice = 0;
-    setReply(davRequest(_verb, _link, req, iodevice));
-    setupConnections(reply());
+    sendRequest(_verb, _link, req);
 
     AbstractNetworkJob::start();
 }
index 8c4ca983f9c9881530470a3ca52606a6c1c68841..b6f9f4ece04f7d315415f1c89a211f4e382dcf5c 100644 (file)
@@ -93,9 +93,7 @@ void OcsJob::start()
     queryItems.append(qMakePair(QByteArray("format"), QByteArray("json")));
     url.setEncodedQueryItems(queryItems);
 
-    setReply(davRequest(_verb, url, req, buffer));
-    setupConnections(reply());
-    buffer->setParent(reply());
+    sendRequest(_verb, url, req, buffer);
     AbstractNetworkJob::start();
 }
 
index 53e360e414097c4e1a2cf206f15f83b3e99b97d5..22ac50b0ec233f26abc23a69ff0890e3b8bdf544 100644 (file)
@@ -594,9 +594,7 @@ DetermineAuthTypeJob::DetermineAuthTypeJob(AccountPtr account, QObject *parent)
 
 void DetermineAuthTypeJob::start()
 {
-    QNetworkReply *reply = getRequest(account()->davPath());
-    setReply(reply);
-    setupConnections(reply);
+    sendRequest("GET", account()->davUrl());
     AbstractNetworkJob::start();
 }
 
@@ -613,8 +611,7 @@ bool DetermineAuthTypeJob::finished()
         // do a new run
         _redirects++;
         resetTimeout();
-        setReply(getRequest(redirection));
-        setupConnections(reply());
+        sendRequest("GET", redirection);
         return false; // don't discard
     } else {
 #ifndef NO_SHIBBOLETH
index d3e92cb42c32e1afce6ee547e5c71728471c5767..5ffe6c2918eaf1efec9d346aea7390b71710e4e3 100644 (file)
@@ -27,8 +27,7 @@ ThumbnailJob::ThumbnailJob(const QString &path, AccountPtr account, QObject* par
 
 void ThumbnailJob::start()
 {
-    setReply(getRequest(path()));
-    setupConnections(reply());
+    sendRequest("GET", makeAccountUrl(path()));
     AbstractNetworkJob::start();
 }
 
index eb865456be03a1eb27a1e8533f0caae3d9cb84a2..fcd2928372c8ffe0156e8834da0be0abe8c04d9f 100644 (file)
@@ -122,40 +122,49 @@ QNetworkReply* AbstractNetworkJob::addTimer(QNetworkReply *reply)
     return reply;
 }
 
-QNetworkReply* AbstractNetworkJob::davRequest(const QByteArray &verb, const QString &relPath,
-                                              QNetworkRequest req, QIODevice *data)
+QNetworkReply *AbstractNetworkJob::sendRequest(const QByteArray &verb, const QUrl &url,
+                                               QNetworkRequest req, QIODevice *requestBody)
 {
-    return addTimer(_account->davRequest(verb, relPath, req, data));
-}
-
-QNetworkReply *AbstractNetworkJob::davRequest(const QByteArray &verb, const QUrl &url, QNetworkRequest req, QIODevice *data)
-{
-    return addTimer(_account->davRequest(verb, url, req, data));
-}
-
-QNetworkReply* AbstractNetworkJob::getRequest(const QString &relPath)
-{
-    return addTimer(_account->getRequest(relPath));
-}
-
-QNetworkReply *AbstractNetworkJob::getRequest(const QUrl &url)
-{
-    return addTimer(_account->getRequest(url));
+    auto reply = _account->sendRequest(verb, url, req, requestBody);
+    _requestBody = requestBody;
+    if (_requestBody) {
+        _requestBody->setParent(reply);
+    }
+    addTimer(reply);
+    setReply(reply);
+    setupConnections(reply);
+    return reply;
 }
 
-QNetworkReply *AbstractNetworkJob::headRequest(const QString &relPath)
+QUrl AbstractNetworkJob::makeAccountUrl(const QString& relativePath) const
 {
-    return addTimer(_account->headRequest(relPath));
+    return Utility::concatUrlPath(_account->url(), relativePath);
 }
 
-QNetworkReply *AbstractNetworkJob::headRequest(const QUrl &url)
+QUrl AbstractNetworkJob::makeDavUrl(const QString& relativePath) const
 {
-    return addTimer(_account->headRequest(url));
+    return Utility::concatUrlPath(_account->davUrl(), relativePath);
 }
 
-QNetworkReply *AbstractNetworkJob::deleteRequest(const QUrl &url)
+QByteArray AbstractNetworkJob::requestVerb(QNetworkReply* reply)
 {
-    return addTimer(_account->deleteRequest(url));
+    switch (reply->operation()) {
+    case QNetworkAccessManager::HeadOperation:
+        return "HEAD";
+    case QNetworkAccessManager::GetOperation:
+        return "GET";
+    case QNetworkAccessManager::PutOperation:
+        return "PUT";
+    case QNetworkAccessManager::PostOperation:
+        return "POST";
+    case QNetworkAccessManager::DeleteOperation:
+        return "DELETE";
+    case QNetworkAccessManager::CustomOperation:
+        return reply->request().attribute(QNetworkRequest::CustomVerbAttribute).toByteArray();
+    case QNetworkAccessManager::UnknownOperation:
+        break;
+    }
+    return QByteArray();
 }
 
 void AbstractNetworkJob::slotFinished()
@@ -178,24 +187,36 @@ void AbstractNetworkJob::slotFinished()
     // get the Date timestamp from reply
     _responseTimestamp = _reply->rawHeader("Date");
 
-    if (_followRedirects) {
-        // ### the qWarnings here should be exported via displayErrors() so they
+    QUrl requestedUrl = reply()->request().url();
+    QUrl redirectUrl = reply()->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
+    if (_followRedirects && !redirectUrl.isEmpty()) {
+        _redirectCount++;
+
+        // ### some of the qWarnings here should be exported via displayErrors() so they
         // ### can be presented to the user if the job executor has a GUI
-        QUrl requestedUrl = reply()->request().url();
-        QUrl redirectUrl = reply()->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
-        if (!redirectUrl.isEmpty()) {
-            _redirectCount++;
-            if (requestedUrl.scheme() == QLatin1String("https") &&
-                    redirectUrl.scheme() == QLatin1String("http")) {
-                qWarning() << this << "HTTPS->HTTP downgrade detected!";
-            } else if (requestedUrl == redirectUrl || _redirectCount >= maxRedirects()) {
-                qWarning() << this << "Redirect loop detected!";
-            } else {
-                resetTimeout();
-                setReply(getRequest(redirectUrl));
-                setupConnections(reply());
-                return;
+        QByteArray verb = requestVerb(reply());
+        if (requestedUrl.scheme() == QLatin1String("https") &&
+                redirectUrl.scheme() == QLatin1String("http")) {
+            qWarning() << this << "HTTPS->HTTP downgrade detected!";
+        } else if (requestedUrl == redirectUrl || _redirectCount >= maxRedirects()) {
+            qWarning() << this << "Redirect loop detected!";
+        } else if (_requestBody && _requestBody->isSequential()) {
+            qWarning() << this << "cannot redirect request with sequential body";
+        } else if (verb.isEmpty()) {
+            qWarning() << this << "cannot redirect request: could not detect original verb";
+        } else {
+            // Create the redirected request and send it
+            qDebug() << "Redirecting" << verb << requestedUrl << redirectUrl;
+            resetTimeout();
+            if (_requestBody) {
+                _requestBody->seek(0);
             }
+            sendRequest(
+                    verb,
+                    redirectUrl,
+                    reply()->request(),
+                    _requestBody);
+            return;
         }
     }
 
index 272ee604f4748726ab3034e5fd5ba2cacf0d0161..a2ec226bbd4b565cd2cb39e2bd0b9159e9411937 100644 (file)
@@ -78,17 +78,29 @@ signals:
     void networkActivity();
 protected:
     void setupConnections(QNetworkReply *reply);
-    QNetworkReply* davRequest(const QByteArray& verb, const QString &relPath,
-                              QNetworkRequest req = QNetworkRequest(),
-                              QIODevice *data = 0);
-    QNetworkReply* davRequest(const QByteArray& verb, const QUrl &url,
-                              QNetworkRequest req = QNetworkRequest(),
-                              QIODevice *data = 0);
-    QNetworkReply* getRequest(const QString &relPath);
-    QNetworkReply* getRequest(const QUrl &url);
-    QNetworkReply* headRequest(const QString &relPath);
-    QNetworkReply* headRequest(const QUrl &url);
-    QNetworkReply* deleteRequest(const QUrl &url);
+
+    /** Initiate a network request, returning a QNetworkReply.
+     *
+     * Calls setReply() and setupConnections() on it.
+     *
+     * Takes ownership of the requestBody (to allow redirects).
+     */
+    QNetworkReply* sendRequest(const QByteArray& verb, const QUrl &url,
+                               QNetworkRequest req = QNetworkRequest(),
+                               QIODevice *requestBody = 0);
+
+    // sendRequest does not take a relative path instead of an url,
+    // but the old API allowed that. We have this undefined overload
+    // to help catch usage errors
+    QNetworkReply* sendRequest(const QByteArray& verb, const QString &relativePath,
+                               QNetworkRequest req = QNetworkRequest(),
+                               QIODevice *requestBody = 0);
+
+    /// Creates a url for the account from a relative path
+    QUrl makeAccountUrl(const QString& relativePath) const;
+
+    /// Like makeAccountUrl() but uses the account's dav base path
+    QUrl makeDavUrl(const QString& relativePath) const;
 
     int maxRedirects() const { return 10; }
     virtual bool finished() = 0;
@@ -99,12 +111,19 @@ protected:
     // GET requests that don't set up any HTTP body or other flags.
     bool          _followRedirects;
 
+    /** Helper to construct the HTTP verb used in the request
+     *
+     * Returns an empty QByteArray for UnknownOperation.
+     */
+    static QByteArray requestVerb(QNetworkReply* reply);
+
 private slots:
     void slotFinished();
     virtual void slotTimeout();
 
 protected:
     AccountPtr _account;
+
 private:
     QNetworkReply* addTimer(QNetworkReply *reply);
     bool _ignoreCredentialFailure;
@@ -112,6 +131,12 @@ private:
     QString _path;
     QTimer _timer;
     int _redirectCount;
+
+    // Set by the xyzRequest() functions and needed to be able to redirect
+    // requests, should it be required.
+    //
+    // Reparented to the currently running QNetworkReply.
+    QPointer<QIODevice> _requestBody;
 };
 
 /**
index 8dc93aea5545db0c290766a742f2ac1c51cb4492..2918d2a39200c3670262d2b1511d1d4bab3b0bdc 100644 (file)
@@ -202,54 +202,23 @@ QNetworkAccessManager *Account::networkAccessManager()
     return _am.data();
 }
 
-QNetworkReply *Account::headRequest(const QString &relPath)
-{
-    return headRequest(Utility::concatUrlPath(url(), relPath));
-}
-
-QNetworkReply *Account::headRequest(const QUrl &url)
-{
-    QNetworkRequest request(url);
-#if QT_VERSION > QT_VERSION_CHECK(4, 8, 4)
-    request.setSslConfiguration(this->getOrCreateSslConfig());
-#endif
-    return _am->head(request);
-}
-
-QNetworkReply *Account::getRequest(const QString &relPath)
-{
-    return getRequest(Utility::concatUrlPath(url(), relPath));
-}
-
-QNetworkReply *Account::getRequest(const QUrl &url)
-{
-    QNetworkRequest request(url);
-#if QT_VERSION > QT_VERSION_CHECK(4, 8, 4)
-    request.setSslConfiguration(this->getOrCreateSslConfig());
-#endif
-    return _am->get(request);
-}
-
-QNetworkReply *Account::deleteRequest( const QUrl &url)
-{
-    QNetworkRequest request(url);
-#if QT_VERSION > QT_VERSION_CHECK(4, 8, 4)
-    request.setSslConfiguration(this->getOrCreateSslConfig());
-#endif
-    return _am->deleteResource(request);
-}
-
-QNetworkReply *Account::davRequest(const QByteArray &verb, const QString &relPath, QNetworkRequest req, QIODevice *data)
-{
-    return davRequest(verb, Utility::concatUrlPath(davUrl(), relPath), req, data);
-}
-
-QNetworkReply *Account::davRequest(const QByteArray &verb, const QUrl &url, QNetworkRequest req, QIODevice *data)
+QNetworkReply *Account::sendRequest(const QByteArray &verb, const QUrl &url, QNetworkRequest req, QIODevice *data)
 {
     req.setUrl(url);
 #if QT_VERSION > QT_VERSION_CHECK(4, 8, 4)
     req.setSslConfiguration(this->getOrCreateSslConfig());
 #endif
+    if (verb == "HEAD" && !data) {
+        return _am->head(req);
+    } else if (verb == "GET" && !data) {
+        return _am->get(req);
+    } else if (verb == "POST") {
+        return _am->post(req, data);
+    } else if (verb == "PUT") {
+        return _am->put(req, data);
+    } else if (verb == "DELETE" && !data) {
+        return _am->deleteResource(req);
+    }
     return _am->sendCustomRequest(req, verb, data);
 }
 
index 823bfa6d61092a690bad1e9aba7daa290773f8b6..5e5ab4944391ea21a80074c2571701b2801a480b 100644 (file)
@@ -106,14 +106,10 @@ public:
 
 
     // For creating various network requests
-    QNetworkReply* headRequest(const QString &relPath);
-    QNetworkReply* headRequest(const QUrl &url);
-    QNetworkReply* getRequest(const QString &relPath);
-    QNetworkReply* getRequest(const QUrl &url);
-    QNetworkReply* deleteRequest( const QUrl &url);
-    QNetworkReply* davRequest(const QByteArray &verb, const QString &relPath, QNetworkRequest req, QIODevice *data = 0);
-    QNetworkReply* davRequest(const QByteArray &verb, const QUrl &url, QNetworkRequest req, QIODevice *data = 0);
-
+    QNetworkReply* sendRequest(const QByteArray &verb,
+                               const QUrl &url,
+                               QNetworkRequest req = QNetworkRequest(),
+                               QIODevice *data = 0);
 
     /** The ssl configuration during the first connection */
     QSslConfiguration getOrCreateSslConfig();
index 4cc5801ae7c6de535b15ad8be7991e3b40106e98..b12c65a8e161e3ebc539be8a17b76d3069e6b304 100644 (file)
@@ -67,9 +67,7 @@ void RequestEtagJob::start()
     buf->setData(xml);
     buf->open(QIODevice::ReadOnly);
     // assumes ownership
-    setReply(davRequest("PROPFIND", path(), req, buf));
-    buf->setParent(reply());
-    setupConnections(reply());
+    sendRequest("PROPFIND", makeDavUrl(path()), req, buf);
 
     if( reply()->error() != QNetworkReply::NoError ) {
         qDebug() << "getting etag: request network error: " << reply()->errorString();
@@ -122,10 +120,11 @@ void MkColJob::start()
    }
 
    // assumes ownership
-   QNetworkReply *reply = _url.isValid() ?  davRequest("MKCOL", _url, req)
-        : davRequest("MKCOL", path(), req);
-   setReply(reply);
-   setupConnections(reply);
+   if (_url.isValid()) {
+       sendRequest("MKCOL", _url, req);
+   } else {
+       sendRequest("MKCOL", makeDavUrl(path()), req);
+   }
    AbstractNetworkJob::start();
 }
 
@@ -322,11 +321,11 @@ void LsColJob::start()
     QBuffer *buf = new QBuffer(this);
     buf->setData(xml);
     buf->open(QIODevice::ReadOnly);
-    QNetworkReply *reply = _url.isValid() ?  davRequest("PROPFIND", _url, req, buf)
-        : davRequest("PROPFIND", path(), req, buf);
-    buf->setParent(reply);
-    setReply(reply);
-    setupConnections(reply);
+    if (_url.isValid()) {
+        sendRequest("PROPFIND", _url, req, buf);
+    } else {
+        sendRequest("PROPFIND", makeDavUrl(path()), req, buf);
+    }
     AbstractNetworkJob::start();
 }
 
@@ -380,8 +379,7 @@ CheckServerJob::CheckServerJob(AccountPtr account, QObject *parent)
 
 void CheckServerJob::start()
 {
-    setReply(getRequest(path()));
-    setupConnections(reply());
+    sendRequest("GET", makeAccountUrl(path()));
     connect(reply(), SIGNAL(metaDataChanged()), this, SLOT(metaDataChangedSlot()));
     connect(reply(), SIGNAL(encrypted()), this, SLOT(encryptedSlot()));
     AbstractNetworkJob::start();
@@ -529,9 +527,7 @@ void PropfindJob::start()
     QBuffer *buf = new QBuffer(this);
     buf->setData(xml);
     buf->open(QIODevice::ReadOnly);
-    setReply(davRequest("PROPFIND", path(), req, buf));
-    buf->setParent(reply());
-    setupConnections(reply());
+    sendRequest("PROPFIND", makeDavUrl(path()), req, buf);
     AbstractNetworkJob::start();
 }
 
@@ -632,9 +628,7 @@ void ProppatchJob::start()
     QBuffer *buf = new QBuffer(this);
     buf->setData(xml);
     buf->open(QIODevice::ReadOnly);
-    setReply(davRequest("PROPPATCH", path(), req, buf));
-    buf->setParent(reply());
-    setupConnections(reply());
+    sendRequest("PROPPATCH", makeDavUrl(path()), req, buf);
     AbstractNetworkJob::start();
 }
 
@@ -671,8 +665,7 @@ EntityExistsJob::EntityExistsJob(AccountPtr account, const QString &path, QObjec
 
 void EntityExistsJob::start()
 {
-    setReply(headRequest(path()));
-    setupConnections(reply());
+    sendRequest("HEAD", makeAccountUrl(path()));
     AbstractNetworkJob::start();
 }
 
@@ -700,8 +693,7 @@ void JsonApiJob::start()
     QList<QPair<QString, QString> > params = _additionalParams;
     params << qMakePair(QString::fromLatin1("format"), QString::fromLatin1("json"));
     url.setQueryItems(params);
-    setReply(davRequest("GET", url, req));
-    setupConnections(reply());
+    sendRequest("GET", url, req);
     AbstractNetworkJob::start();
 }
 
index 030826c0b022e22c2fa904e61386117594293d45..51a3ab319eac19268f79e8f17f84403d709dba00 100644 (file)
@@ -100,12 +100,11 @@ void GETFileJob::start() {
     }
 
     if (_directDownloadUrl.isEmpty()) {
-        setReply(davRequest("GET", path(), req));
+        sendRequest("GET", makeDavUrl(path()), req);
     } else {
         // Use direct URL
-        setReply(davRequest("GET", _directDownloadUrl, req));
+        sendRequest("GET", _directDownloadUrl, req);
     }
-    setupConnections(reply());
 
     reply()->setReadBufferSize(16 * 1024); // keep low so we can easier limit the bandwidth
     qDebug() << Q_FUNC_INFO << _bandwidthManager << _bandwidthChoked << _bandwidthLimited;
index ff9d863eb10c7d73065c8eed6bd8e3b616ad9f93..a85d73c281384786a54b41f2cc6f1822cdf6a8e3 100644 (file)
@@ -30,8 +30,11 @@ DeleteJob::DeleteJob(AccountPtr account, const QUrl& url, QObject* parent)
 void DeleteJob::start()
 {
     QNetworkRequest req;
-    setReply(_url.isValid() ? davRequest("DELETE", _url, req) : davRequest("DELETE", path(), req));
-    setupConnections(reply());
+    if (_url.isValid()) {
+        sendRequest("DELETE", _url, req);
+    } else {
+        sendRequest("DELETE", makeDavUrl(path()), req);
+    }
 
     if( reply()->error() != QNetworkReply::NoError ) {
         qWarning() << Q_FUNC_INFO << " Network error: " << reply()->errorString();
index 11370d573c8e2bfa9e938ce9327fc9cbb91ee288..5a59f91244c60b05ec4b10310e82cd6fc9095a04 100644 (file)
@@ -43,8 +43,11 @@ void MoveJob::start()
     for(auto it = _extraHeaders.constBegin(); it != _extraHeaders.constEnd(); ++it) {
         req.setRawHeader(it.key(), it.value());
     }
-    setReply(_url.isValid() ? davRequest("MOVE", _url, req) : davRequest("MOVE", path(), req));
-    setupConnections(reply());
+    if (_url.isValid()) {
+        sendRequest("MOVE", _url, req);
+    } else {
+        sendRequest("MOVE", makeDavUrl(path()), req);
+    }
 
     if( reply()->error() != QNetworkReply::NoError ) {
         qWarning() << Q_FUNC_INFO << " Network error: " << reply()->errorString();
index 2f8c544fb7d329c4d5af2ab7ce683f6c9a201213..0ad02c09ac2c5d58983c4973672f8ddd8e68ada7 100644 (file)
@@ -73,9 +73,11 @@ void PUTFileJob::start() {
         req.setRawHeader(it.key(), it.value());
     }
 
-    setReply(_url.isValid() ?  davRequest("PUT", _url, req, _device.data())
-        : davRequest("PUT", path(), req, _device.data()));
-    setupConnections(reply());
+    if (_url.isValid()) {
+        sendRequest("PUT", _url, req, _device);
+    } else {
+        sendRequest("PUT", makeDavUrl(path()), req, _device);
+    }
 
     if( reply()->error() != QNetworkReply::NoError ) {
         qWarning() << Q_FUNC_INFO << " Network error: " << reply()->errorString();
@@ -89,10 +91,10 @@ void PUTFileJob::start() {
     // (workaround disabled on windows and mac because the binaries we ship have patched qt)
 #if QT_VERSION < QT_VERSION_CHECK(4, 8, 7)
     if (QLatin1String(qVersion()) < QLatin1String("4.8.7"))
-        connect(_device.data(), SIGNAL(wasReset()), this, SLOT(slotSoftAbort()));
+        connect(_device, SIGNAL(wasReset()), this, SLOT(slotSoftAbort()));
 #elif QT_VERSION > QT_VERSION_CHECK(5, 0, 0) && QT_VERSION < QT_VERSION_CHECK(5, 4, 2) && !defined Q_OS_WIN && !defined Q_OS_MAC
     if (QLatin1String(qVersion()) < QLatin1String("5.4.2"))
-        connect(_device.data(), SIGNAL(wasReset()), this, SLOT(slotSoftAbort()));
+        connect(_device, SIGNAL(wasReset()), this, SLOT(slotSoftAbort()));
 #endif
 
     AbstractNetworkJob::start();
@@ -119,8 +121,7 @@ void PollJob::start()
     QUrl accountUrl = account()->url();
     QUrl finalUrl = QUrl::fromUserInput(accountUrl.scheme() + QLatin1String("://") +  accountUrl.authority()
         + (path().startsWith('/') ? QLatin1String("") : QLatin1String("/")) + path());
-    setReply(getRequest(finalUrl));
-    setupConnections(reply());
+    sendRequest("GET", finalUrl);
     connect(reply(), SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(resetTimeout()));
     AbstractNetworkJob::start();
 }
index 31e9067d6400608c03de92ca753a7d239eaf2007..3a7224a7019bde4caeffb14c2f36d3bcd13ff871 100644 (file)
@@ -86,7 +86,7 @@ class PUTFileJob : public AbstractNetworkJob {
     Q_OBJECT
 
 private:
-    QScopedPointer<QIODevice> _device;
+    QIODevice* _device;
     QMap<QByteArray, QByteArray> _headers;
     QString _errorString;
     QUrl _url;
@@ -95,11 +95,17 @@ public:
     // Takes ownership of the device
     explicit PUTFileJob(AccountPtr account, const QString& path, QIODevice *device,
                         const QMap<QByteArray, QByteArray> &headers, int chunk, QObject* parent = 0)
-        : AbstractNetworkJob(account, path, parent), _device(device), _headers(headers), _chunk(chunk) {}
+        : AbstractNetworkJob(account, path, parent), _device(device), _headers(headers), _chunk(chunk)
+    {
+        _device->setParent(this);
+    }
     explicit PUTFileJob(AccountPtr account, const QUrl& url, QIODevice *device,
                         const QMap<QByteArray, QByteArray> &headers, int chunk, QObject* parent = 0)
         : AbstractNetworkJob(account, QString(), parent), _device(device), _headers(headers)
-        , _url(url), _chunk(chunk) {}
+        , _url(url), _chunk(chunk)
+    {
+        _device->setParent(this);
+    }
     ~PUTFileJob();
 
     int _chunk;
index 937bf35fda4b6ae808346c77bd86afd49d43f215..64b06328402b14610d953afbef9886433b916539 100644 (file)
@@ -730,13 +730,13 @@ protected:
         if (verb == QLatin1String("PROPFIND"))
             // Ignore outgoingData always returning somethign good enough, works for now.
             return new FakePropfindReply{info, op, request, this};
-        else if (verb == QLatin1String("GET"))
+        else if (verb == QLatin1String("GET") || op == QNetworkAccessManager::GetOperation)
             return new FakeGetReply{info, op, request, this};
-        else if (verb == QLatin1String("PUT"))
+        else if (verb == QLatin1String("PUT") || op == QNetworkAccessManager::PutOperation)
             return new FakePutReply{info, op, request, outgoingData->readAll(), this};
         else if (verb == QLatin1String("MKCOL"))
             return new FakeMkcolReply{info, op, request, this};
-        else if (verb == QLatin1String("DELETE"))
+        else if (verb == QLatin1String("DELETE") || op == QNetworkAccessManager::DeleteOperation)
             return new FakeDeleteReply{info, op, request, this};
         else if (verb == QLatin1String("MOVE") && !isUpload)
             return new FakeMoveReply{info, op, request, this};