From dd5ddf21667dd5690e633834d76509a89cfc1e22 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 17 Jun 2015 17:29:11 +0200 Subject: [PATCH] AbstractNetworkJob: move to its own file --- src/libsync/CMakeLists.txt | 1 + src/libsync/abstractnetworkjob.cpp | 284 +++++++++++++++++++++++++++++ src/libsync/abstractnetworkjob.h | 129 +++++++++++++ src/libsync/networkjobs.cpp | 245 ------------------------- src/libsync/networkjobs.h | 105 +---------- 5 files changed, 415 insertions(+), 349 deletions(-) create mode 100644 src/libsync/abstractnetworkjob.cpp create mode 100644 src/libsync/abstractnetworkjob.h diff --git a/src/libsync/CMakeLists.txt b/src/libsync/CMakeLists.txt index cbf11f06f..a596c26a6 100644 --- a/src/libsync/CMakeLists.txt +++ b/src/libsync/CMakeLists.txt @@ -43,6 +43,7 @@ set(libsync_SRCS logger.cpp accessmanager.cpp configfile.cpp + abstractnetworkjob.cpp networkjobs.cpp owncloudpropagator.cpp owncloudtheme.cpp diff --git a/src/libsync/abstractnetworkjob.cpp b/src/libsync/abstractnetworkjob.cpp new file mode 100644 index 000000000..d085c6fcf --- /dev/null +++ b/src/libsync/abstractnetworkjob.cpp @@ -0,0 +1,284 @@ +/* + * Copyright (C) by Klaas Freitag + * Copyright (C) by Daniel Molkentin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "json.h" + +#include "networkjobs.h" +#include "account.h" +#include "owncloudpropagator.h" + +#include "creds/abstractcredentials.h" + +Q_DECLARE_METATYPE(QTimer*) + +namespace OCC { + + +AbstractNetworkJob::AbstractNetworkJob(AccountPtr account, const QString &path, QObject *parent) + : QObject(parent) + , _timedout(false) + , _followRedirects(false) + , _ignoreCredentialFailure(false) + , _reply(0) + , _account(account) + , _path(path) + , _redirectCount(0) +{ + _timer.setSingleShot(true); + _timer.setInterval(OwncloudPropagator::httpTimeout() * 1000); // default to 5 minutes. + connect(&_timer, SIGNAL(timeout()), this, SLOT(slotTimeout())); + + connect(this, SIGNAL(networkActivity()), SLOT(resetTimeout())); + + // Network activity on the propagator jobs (GET/PUT) keeps all requests alive. + // This is a workaround for OC instances which only support one + // parallel up and download + if (_account) { + connect(_account.data(), SIGNAL(propagatorNetworkActivity()), SLOT(resetTimeout())); + } +} + +void AbstractNetworkJob::setReply(QNetworkReply *reply) +{ + if (reply) + reply->setProperty("doNotHandleAuth", true); + + QNetworkReply *old = _reply; + _reply = reply; + delete old; +} + +void AbstractNetworkJob::setTimeout(qint64 msec) +{ + qDebug() << Q_FUNC_INFO << msec; + + _timer.start(msec); +} + +void AbstractNetworkJob::resetTimeout() +{ + qint64 interval = _timer.interval(); + _timer.stop(); + _timer.start(interval); +} + +void AbstractNetworkJob::setIgnoreCredentialFailure(bool ignore) +{ + _ignoreCredentialFailure = ignore; +} + +void AbstractNetworkJob::setPath(const QString &path) +{ + _path = path; +} + +void AbstractNetworkJob::setupConnections(QNetworkReply *reply) +{ + connect(reply, SIGNAL(finished()), SLOT(slotFinished())); +#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0) + connect(reply, SIGNAL(encrypted()), SIGNAL(networkActivity())); +#endif + connect(reply->manager(), SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), SIGNAL(networkActivity())); + connect(reply, SIGNAL(sslErrors(QList)), SIGNAL(networkActivity())); + connect(reply, SIGNAL(metaDataChanged()), SIGNAL(networkActivity())); + connect(reply, SIGNAL(downloadProgress(qint64,qint64)), SIGNAL(networkActivity())); + connect(reply, SIGNAL(uploadProgress(qint64,qint64)), SIGNAL(networkActivity())); +} + +QNetworkReply* AbstractNetworkJob::addTimer(QNetworkReply *reply) +{ + reply->setProperty("timer", QVariant::fromValue(&_timer)); + return reply; +} + +QNetworkReply* AbstractNetworkJob::davRequest(const QByteArray &verb, const QString &relPath, + QNetworkRequest req, QIODevice *data) +{ + 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)); +} + +QNetworkReply *AbstractNetworkJob::headRequest(const QString &relPath) +{ + return addTimer(_account->headRequest(relPath)); +} + +QNetworkReply *AbstractNetworkJob::headRequest(const QUrl &url) +{ + return addTimer(_account->headRequest(url)); +} + +void AbstractNetworkJob::slotFinished() +{ + _timer.stop(); + + if( _reply->error() == QNetworkReply::SslHandshakeFailedError ) { + qDebug() << "SslHandshakeFailedError: " << reply()->errorString() << " : can be caused by a webserver wanting SSL client certificates"; + } + + if( _reply->error() != QNetworkReply::NoError ) { + qDebug() << Q_FUNC_INFO << _reply->error() << _reply->errorString(); + if (_reply->error() == QNetworkReply::ProxyAuthenticationRequiredError) { + qDebug() << Q_FUNC_INFO << _reply->rawHeader("Proxy-Authenticate"); + } + emit networkError(_reply); + } + + // get the Date timestamp from reply + _responseTimestamp = _reply->rawHeader("Date"); + _duration = _durationTimer.elapsed(); + + if (_followRedirects) { + // ### 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; + } + } + } + + AbstractCredentials *creds = _account->credentials(); + if (!creds->stillValid(_reply) && ! _ignoreCredentialFailure) { + _account->handleInvalidCredentials(); + } + + bool discard = finished(); + if (discard) { + deleteLater(); + } +} + +quint64 AbstractNetworkJob::duration() +{ + return _duration; +} + +QByteArray AbstractNetworkJob::responseTimestamp() +{ + return _responseTimestamp; +} + +AbstractNetworkJob::~AbstractNetworkJob() +{ + setReply(0); +} + +void AbstractNetworkJob::start() +{ + _timer.start(); + _durationTimer.start(); + _duration = 0; + + const QUrl url = account()->url(); + const QString displayUrl = QString( "%1://%2%3").arg(url.scheme()).arg(url.host()).arg(url.path()); + + qDebug() << "!!!" << metaObject()->className() << "created for" << displayUrl << "+" << path(); +} + +void AbstractNetworkJob::slotTimeout() +{ + _timedout = true; + qDebug() << this << "Timeout"; + if (reply()) { + reply()->abort(); + } else { + qDebug() << "reply was NULL"; + } +} + + +NetworkJobTimeoutPauser::NetworkJobTimeoutPauser(QNetworkReply *reply) +{ + _timer = reply->property("timer").value(); + if(!_timer.isNull()) { + _timer->stop(); + } +} + +NetworkJobTimeoutPauser::~NetworkJobTimeoutPauser() +{ + if(!_timer.isNull()) { + _timer->start(); + } +} + +QString extractErrorMessage(const QByteArray& errorResponse) +{ + QXmlStreamReader reader(errorResponse); + reader.readNextStartElement(); + if (reader.name() != "error") { + return QString::null; + } + + while (!reader.atEnd() && reader.error() == QXmlStreamReader::NoError) { + reader.readNextStartElement(); + if (reader.name() == QLatin1String("message")) { + return reader.readElementText(); + } + } + return QString::null; +} + +QString errorMessage(const QString& baseError, const QByteArray& body) +{ + QString msg = baseError; + QString extra = extractErrorMessage(body); + if (!extra.isEmpty()) { + msg += QString::fromLatin1(" (%1)").arg(extra); + } + return msg; +} + +} // namespace OCC diff --git a/src/libsync/abstractnetworkjob.h b/src/libsync/abstractnetworkjob.h new file mode 100644 index 000000000..c9f11c112 --- /dev/null +++ b/src/libsync/abstractnetworkjob.h @@ -0,0 +1,129 @@ +/* + * Copyright (C) by Klaas Freitag + * Copyright (C) by Daniel Molkentin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#pragma once + +#include "owncloudlib.h" +#include +#include +#include +#include +#include +#include +#include +#include "accountfwd.h" + +class QUrl; + +namespace OCC { + +class AbstractSslErrorHandler; + +/** + * @brief The AbstractNetworkJob class + */ +class OWNCLOUDSYNC_EXPORT AbstractNetworkJob : public QObject { + Q_OBJECT +public: + explicit AbstractNetworkJob(AccountPtr account, const QString &path, QObject* parent = 0); + virtual ~AbstractNetworkJob(); + + virtual void start(); + + AccountPtr account() const { return _account; } + + void setPath(const QString &path); + QString path() const { return _path; } + + void setReply(QNetworkReply *reply); + QNetworkReply* reply() const { return _reply; } + + void setIgnoreCredentialFailure(bool ignore); + bool ignoreCredentialFailure() const { return _ignoreCredentialFailure; } + + QByteArray responseTimestamp(); + quint64 duration(); + +public slots: + void setTimeout(qint64 msec); + void resetTimeout(); +signals: + void networkError(QNetworkReply *reply); + 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); + + int maxRedirects() const { return 10; } + virtual bool finished() = 0; + QByteArray _responseTimestamp; + QElapsedTimer _durationTimer; + quint64 _duration; + bool _timedout; // set to true when the timeout slot is recieved + + // Automatically follows redirects. Note that this only works for + // GET requests that don't set up any HTTP body or other flags. + bool _followRedirects; + +private slots: + void slotFinished(); + virtual void slotTimeout(); + +private: + QNetworkReply* addTimer(QNetworkReply *reply); + bool _ignoreCredentialFailure; + QPointer _reply; // (QPointer because the NetworkManager may be destroyed before the jobs at exit) + AccountPtr _account; + QString _path; + QTimer _timer; + int _redirectCount; +}; + +/** + * @brief Internal Helper class + */ +class NetworkJobTimeoutPauser { +public: + NetworkJobTimeoutPauser(QNetworkReply *reply); + ~NetworkJobTimeoutPauser(); +private: + QPointer _timer; +}; + + +/** Gets the SabreDAV-style error message from an error response. + * + * This assumes the response is XML with a 'error' tag that has a + * 'message' tag that contains the data to extract. + * + * Returns a null string if no message was found. + */ +QString OWNCLOUDSYNC_EXPORT extractErrorMessage(const QByteArray& errorResponse); + +/** Builds a error message based on the error and the reply body. */ +QString OWNCLOUDSYNC_EXPORT errorMessage(const QString& baseError, const QByteArray& body); + +} // namespace OCC + + diff --git a/src/libsync/networkjobs.cpp b/src/libsync/networkjobs.cpp index c2f2dab15..4a670de2f 100644 --- a/src/libsync/networkjobs.cpp +++ b/src/libsync/networkjobs.cpp @@ -35,211 +35,8 @@ #include "creds/abstractcredentials.h" -Q_DECLARE_METATYPE(QTimer*) - namespace OCC { - -AbstractNetworkJob::AbstractNetworkJob(AccountPtr account, const QString &path, QObject *parent) - : QObject(parent) - , _timedout(false) - , _followRedirects(false) - , _ignoreCredentialFailure(false) - , _reply(0) - , _account(account) - , _path(path) - , _redirectCount(0) -{ - _timer.setSingleShot(true); - _timer.setInterval(OwncloudPropagator::httpTimeout() * 1000); // default to 5 minutes. - connect(&_timer, SIGNAL(timeout()), this, SLOT(slotTimeout())); - - connect(this, SIGNAL(networkActivity()), SLOT(resetTimeout())); - - // Network activity on the propagator jobs (GET/PUT) keeps all requests alive. - // This is a workaround for OC instances which only support one - // parallel up and download - if (_account) { - connect(_account.data(), SIGNAL(propagatorNetworkActivity()), SLOT(resetTimeout())); - } -} - -void AbstractNetworkJob::setReply(QNetworkReply *reply) -{ - if (reply) - reply->setProperty("doNotHandleAuth", true); - - QNetworkReply *old = _reply; - _reply = reply; - delete old; -} - -void AbstractNetworkJob::setTimeout(qint64 msec) -{ - qDebug() << Q_FUNC_INFO << msec; - - _timer.start(msec); -} - -void AbstractNetworkJob::resetTimeout() -{ - qint64 interval = _timer.interval(); - _timer.stop(); - _timer.start(interval); -} - -void AbstractNetworkJob::setIgnoreCredentialFailure(bool ignore) -{ - _ignoreCredentialFailure = ignore; -} - -void AbstractNetworkJob::setPath(const QString &path) -{ - _path = path; -} - -void AbstractNetworkJob::setupConnections(QNetworkReply *reply) -{ - connect(reply, SIGNAL(finished()), SLOT(slotFinished())); -#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0) - connect(reply, SIGNAL(encrypted()), SIGNAL(networkActivity())); -#endif - connect(reply->manager(), SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), SIGNAL(networkActivity())); - connect(reply, SIGNAL(sslErrors(QList)), SIGNAL(networkActivity())); - connect(reply, SIGNAL(metaDataChanged()), SIGNAL(networkActivity())); - connect(reply, SIGNAL(downloadProgress(qint64,qint64)), SIGNAL(networkActivity())); - connect(reply, SIGNAL(uploadProgress(qint64,qint64)), SIGNAL(networkActivity())); -} - -QNetworkReply* AbstractNetworkJob::addTimer(QNetworkReply *reply) -{ - reply->setProperty("timer", QVariant::fromValue(&_timer)); - return reply; -} - -QNetworkReply* AbstractNetworkJob::davRequest(const QByteArray &verb, const QString &relPath, - QNetworkRequest req, QIODevice *data) -{ - 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)); -} - -QNetworkReply *AbstractNetworkJob::headRequest(const QString &relPath) -{ - return addTimer(_account->headRequest(relPath)); -} - -QNetworkReply *AbstractNetworkJob::headRequest(const QUrl &url) -{ - return addTimer(_account->headRequest(url)); -} - -void AbstractNetworkJob::slotFinished() -{ - _timer.stop(); - - if( _reply->error() == QNetworkReply::SslHandshakeFailedError ) { - qDebug() << "SslHandshakeFailedError: " << reply()->errorString() << " : can be caused by a webserver wanting SSL client certificates"; - } - - if( _reply->error() != QNetworkReply::NoError ) { - qDebug() << Q_FUNC_INFO << _reply->error() << _reply->errorString(); - if (_reply->error() == QNetworkReply::ProxyAuthenticationRequiredError) { - qDebug() << Q_FUNC_INFO << _reply->rawHeader("Proxy-Authenticate"); - } - emit networkError(_reply); - } - - // get the Date timestamp from reply - _responseTimestamp = _reply->rawHeader("Date"); - _duration = _durationTimer.elapsed(); - - if (_followRedirects) { - // ### 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; - } - } - } - - AbstractCredentials *creds = _account->credentials(); - if (!creds->stillValid(_reply) && ! _ignoreCredentialFailure) { - _account->handleInvalidCredentials(); - } - - bool discard = finished(); - if (discard) { - deleteLater(); - } -} - -quint64 AbstractNetworkJob::duration() -{ - return _duration; -} - -QByteArray AbstractNetworkJob::responseTimestamp() -{ - return _responseTimestamp; -} - -AbstractNetworkJob::~AbstractNetworkJob() -{ - setReply(0); -} - -void AbstractNetworkJob::start() -{ - _timer.start(); - _durationTimer.start(); - _duration = 0; - - const QUrl url = account()->url(); - const QString displayUrl = QString( "%1://%2%3").arg(url.scheme()).arg(url.host()).arg(url.path()); - - qDebug() << "!!!" << metaObject()->className() << "created for" << displayUrl << "+" << path(); -} - -void AbstractNetworkJob::slotTimeout() -{ - _timedout = true; - qDebug() << this << "Timeout"; - if (reply()) { - reply()->abort(); - } else { - qDebug() << "reply was NULL"; - } -} - -/*********************************************************************************************/ - RequestEtagJob::RequestEtagJob(AccountPtr account, const QString &path, QObject *parent) : AbstractNetworkJob(account, path, parent) { @@ -806,21 +603,6 @@ bool CheckQuotaJob::finished() return true; } -NetworkJobTimeoutPauser::NetworkJobTimeoutPauser(QNetworkReply *reply) -{ - _timer = reply->property("timer").value(); - if(!_timer.isNull()) { - _timer->stop(); - } -} - -NetworkJobTimeoutPauser::~NetworkJobTimeoutPauser() -{ - if(!_timer.isNull()) { - _timer->start(); - } -} - JsonApiJob::JsonApiJob(const AccountPtr &account, const QString& path, QObject* parent): AbstractNetworkJob(account, path, parent) { } @@ -857,31 +639,4 @@ bool JsonApiJob::finished() return true; } -QString extractErrorMessage(const QByteArray& errorResponse) -{ - QXmlStreamReader reader(errorResponse); - reader.readNextStartElement(); - if (reader.name() != "error") { - return QString::null; - } - - while (!reader.atEnd() && reader.error() == QXmlStreamReader::NoError) { - reader.readNextStartElement(); - if (reader.name() == QLatin1String("message")) { - return reader.readElementText(); - } - } - return QString::null; -} - -QString errorMessage(const QString& baseError, const QByteArray& body) -{ - QString msg = baseError; - QString extra = extractErrorMessage(body); - if (!extra.isEmpty()) { - msg += QString::fromLatin1(" (%1)").arg(extra); - } - return msg; -} - } // namespace OCC diff --git a/src/libsync/networkjobs.h b/src/libsync/networkjobs.h index 4f16994f9..c0c8ca782 100644 --- a/src/libsync/networkjobs.h +++ b/src/libsync/networkjobs.h @@ -16,103 +16,12 @@ #ifndef NETWORKJOBS_H #define NETWORKJOBS_H -#include "owncloudlib.h" -#include -#include -#include -#include -#include -#include -#include -#include "accountfwd.h" +#include "abstractnetworkjob.h" class QUrl; namespace OCC { -class AbstractSslErrorHandler; - - -/** - * @brief Internal Helper class - */ -class NetworkJobTimeoutPauser { -public: - NetworkJobTimeoutPauser(QNetworkReply *reply); - ~NetworkJobTimeoutPauser(); -private: - QPointer _timer; -}; - -/** - * @brief The AbstractNetworkJob class - */ -class OWNCLOUDSYNC_EXPORT AbstractNetworkJob : public QObject { - Q_OBJECT -public: - explicit AbstractNetworkJob(AccountPtr account, const QString &path, QObject* parent = 0); - virtual ~AbstractNetworkJob(); - - virtual void start(); - - AccountPtr account() const { return _account; } - - void setPath(const QString &path); - QString path() const { return _path; } - - void setReply(QNetworkReply *reply); - QNetworkReply* reply() const { return _reply; } - - void setIgnoreCredentialFailure(bool ignore); - bool ignoreCredentialFailure() const { return _ignoreCredentialFailure; } - - QByteArray responseTimestamp(); - quint64 duration(); - -public slots: - void setTimeout(qint64 msec); - void resetTimeout(); -signals: - void networkError(QNetworkReply *reply); - 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); - - int maxRedirects() const { return 10; } - virtual bool finished() = 0; - QByteArray _responseTimestamp; - QElapsedTimer _durationTimer; - quint64 _duration; - bool _timedout; // set to true when the timeout slot is recieved - - // Automatically follows redirects. Note that this only works for - // GET requests that don't set up any HTTP body or other flags. - bool _followRedirects; - -private slots: - void slotFinished(); - virtual void slotTimeout(); - -private: - QNetworkReply* addTimer(QNetworkReply *reply); - bool _ignoreCredentialFailure; - QPointer _reply; // (QPointer because the NetworkManager may be destroyed before the jobs at exit) - AccountPtr _account; - QString _path; - QTimer _timer; - int _redirectCount; -}; - /** * @brief The EntityExistsJob class */ @@ -314,18 +223,6 @@ signals: void jsonRecieved(const QVariantMap &json); }; -/** Gets the SabreDAV-style error message from an error response. - * - * This assumes the response is XML with a 'error' tag that has a - * 'message' tag that contains the data to extract. - * - * Returns a null string if no message was found. - */ -QString OWNCLOUDSYNC_EXPORT extractErrorMessage(const QByteArray& errorResponse); - -/** Builds a error message based on the error and the reply body. */ -QString OWNCLOUDSYNC_EXPORT errorMessage(const QString& baseError, const QByteArray& body); - } // namespace OCC #endif // NETWORKJOBS_H