From 5d8f9f53463245ac22a7f0f727baa4f32cc25292 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 19 Jun 2013 18:16:43 +0200 Subject: [PATCH 1/6] Silent clang warning --- src/mirall/csyncthread.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mirall/csyncthread.cpp b/src/mirall/csyncthread.cpp index b9d5ff52b8..ff751b578b 100644 --- a/src/mirall/csyncthread.cpp +++ b/src/mirall/csyncthread.cpp @@ -248,8 +248,8 @@ int CSyncThread::treewalkError(TREE_WALK_FILE* file) return 0; if( file && - file->instruction == CSYNC_INSTRUCTION_STAT_ERROR || - file->instruction == CSYNC_INSTRUCTION_ERROR ) { + (file->instruction == CSYNC_INSTRUCTION_STAT_ERROR || + file->instruction == CSYNC_INSTRUCTION_ERROR) ) { _mutex.lock(); _syncedItems[indx]._instruction = file->instruction; _mutex.unlock(); From a8707b681dea759f27174a0bc7226fb133955d67 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 19 Jun 2013 18:17:32 +0200 Subject: [PATCH 2/6] Report proper error when csync_init fails Fix mirall issue #705 --- src/mirall/csyncthread.cpp | 2 ++ src/mirall/csyncthread.h | 2 +- src/mirall/owncloudfolder.cpp | 11 ++++++++++- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/mirall/csyncthread.cpp b/src/mirall/csyncthread.cpp index ff751b578b..09397d2fa9 100644 --- a/src/mirall/csyncthread.cpp +++ b/src/mirall/csyncthread.cpp @@ -58,6 +58,8 @@ CSyncThread::~CSyncThread() } +//Convert an error code from csync to a user readable string. +// Keep that function thread safe as it can be called from the sync thread or the main thread QString CSyncThread::csyncErrorToString( CSYNC_ERROR_CODE err, const char *errString ) { QString errStr; diff --git a/src/mirall/csyncthread.h b/src/mirall/csyncthread.h index 78e3f60606..c6caadb5a6 100644 --- a/src/mirall/csyncthread.h +++ b/src/mirall/csyncthread.h @@ -38,7 +38,7 @@ public: CSyncThread(CSYNC *); ~CSyncThread(); - QString csyncErrorToString( CSYNC_ERROR_CODE, const char * ); + static QString csyncErrorToString( CSYNC_ERROR_CODE, const char * ); Q_INVOKABLE void startSync(); diff --git a/src/mirall/owncloudfolder.cpp b/src/mirall/owncloudfolder.cpp index a01572d943..076b3f0a18 100644 --- a/src/mirall/owncloudfolder.cpp +++ b/src/mirall/owncloudfolder.cpp @@ -98,7 +98,9 @@ ownCloudFolder::ownCloudFolder(const QString &alias, csync_set_auth_callback( _csync_ctx, getauth ); if( csync_init( _csync_ctx ) < 0 ) { - qDebug() << "Could not initialize csync!"; + qDebug() << "Could not initialize csync!" << csync_get_error(_csync_ctx) << csync_get_error_string(_csync_ctx); + slotCSyncError(CSyncThread::csyncErrorToString(csync_get_error(_csync_ctx), csync_get_error_string(_csync_ctx))); + csync_destroy(_csync_ctx); _csync_ctx = 0; } setProxy(); @@ -259,6 +261,13 @@ void ownCloudFolder::startSync() void ownCloudFolder::startSync(const QStringList &pathList) { + if (!_csync_ctx) { + qDebug() << Q_FUNC_INFO << "_csync_ctx is empty. probably because csync_init has failed."; + // the error should already be set + QMetaObject::invokeMethod(this, "slotCSyncFinished", Qt::QueuedConnection); + return; + } + if (_thread && _thread->isRunning()) { qCritical() << "* ERROR csync is still running and new sync requested."; return; From 905f70a1867433d3631444d7f36aaf9f87d0c60a Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Thu, 20 Jun 2013 16:56:25 +0200 Subject: [PATCH 3/6] Do not store the redirected URL in the config file. Because it may be a temporary URL. Especially anoying in captive portal Fix issue #368 --- src/mirall/application.cpp | 2 +- src/mirall/connectionvalidator.cpp | 2 +- src/mirall/folderman.cpp | 5 +- src/mirall/mirallconfigfile.cpp | 13 ----- src/mirall/mirallconfigfile.h | 2 - src/mirall/owncloudfolder.cpp | 10 ++-- src/mirall/owncloudinfo.cpp | 85 +++++++++++++++--------------- src/mirall/owncloudinfo.h | 19 ++++--- src/mirall/owncloudsetupwizard.cpp | 2 +- 9 files changed, 63 insertions(+), 77 deletions(-) diff --git a/src/mirall/application.cpp b/src/mirall/application.cpp index cc2ec308fe..2f6f6b7bcd 100644 --- a/src/mirall/application.cpp +++ b/src/mirall/application.cpp @@ -321,7 +321,7 @@ void Application::slotCheckAuthentication() this,SLOT(slotAuthCheck(QString,QNetworkReply*))); qDebug() << "# checking for authentication settings."; - ownCloudInfo::instance()->getRequest(QLatin1String("/"), true ); // this call needs to be authenticated. + ownCloudInfo::instance()->getWebDAVPath(QLatin1String("/") ); // this call needs to be authenticated. // simply GET the webdav root, will fail if credentials are wrong. // continue in slotAuthCheck here :-) } diff --git a/src/mirall/connectionvalidator.cpp b/src/mirall/connectionvalidator.cpp index 5303998acd..f034363dec 100644 --- a/src/mirall/connectionvalidator.cpp +++ b/src/mirall/connectionvalidator.cpp @@ -163,7 +163,7 @@ void ConnectionValidator::slotCheckAuthentication() this, SLOT(slotAuthCheck(QString,QNetworkReply*))); qDebug() << "# checking for authentication settings."; - ownCloudInfo::instance()->getRequest(QLatin1String("/"), true ); // this call needs to be authenticated. + ownCloudInfo::instance()->getWebDAVPath(QLatin1String("/") ); // this call needs to be authenticated. // simply GET the webdav root, will fail if credentials are wrong. // continue in slotAuthCheck here :-) } diff --git a/src/mirall/folderman.cpp b/src/mirall/folderman.cpp index 3dfe406f32..d999a87964 100644 --- a/src/mirall/folderman.cpp +++ b/src/mirall/folderman.cpp @@ -18,6 +18,7 @@ #include "mirall/syncresult.h" #include "mirall/inotify.h" #include "mirall/theme.h" +#include "owncloudinfo.h" #ifdef Q_OS_MAC #include @@ -249,10 +250,8 @@ Folder* FolderMan::setupFolderFromConfigFile(const QString &file) { if (!backend.isEmpty()) { if( backend == QLatin1String("owncloud") ) { - MirallConfigFile cfgFile; - // assemble the owncloud url to pass to csync, incl. webdav - QString oCUrl = cfgFile.ownCloudUrl( QString::null, true ); + QString oCUrl = ownCloudInfo::instance()->webdavUrl( ); // cut off the leading slash, oCUrl always has a trailing. if( targetPath.startsWith(QLatin1Char('/')) ) { diff --git a/src/mirall/mirallconfigfile.cpp b/src/mirall/mirallconfigfile.cpp index e25b6cd6c5..cafd7f5838 100644 --- a/src/mirall/mirallconfigfile.cpp +++ b/src/mirall/mirallconfigfile.cpp @@ -228,19 +228,6 @@ bool MirallConfigFile::writePassword( const QString& passwd, const QString& conn return true; } -// set the url, called from redirect handling. -void MirallConfigFile::setOwnCloudUrl( const QString& connection, const QString & url ) -{ - const QString file = configFile(); - - QSettings settings( file, QSettings::IniFormat); - settings.setIniCodec( "UTF-8" ); - settings.beginGroup( connection ); - settings.setValue( QLatin1String("url"), url ); - - settings.sync(); -} - QByteArray MirallConfigFile::caCerts( ) { QSettings settings( configFile(), QSettings::IniFormat ); diff --git a/src/mirall/mirallconfigfile.h b/src/mirall/mirallconfigfile.h index df91393834..29258aa23d 100644 --- a/src/mirall/mirallconfigfile.h +++ b/src/mirall/mirallconfigfile.h @@ -58,8 +58,6 @@ public: QString ownCloudUser( const QString& connection = QString() ) const; QString ownCloudUrl( const QString& connection = QString(), bool webdav = false ) const; - void setOwnCloudUrl(const QString &connection, const QString& ); - // the certs do not depend on a connection. QByteArray caCerts(); void setCaCerts( const QByteArray& ); diff --git a/src/mirall/owncloudfolder.cpp b/src/mirall/owncloudfolder.cpp index 076b3f0a18..ad3c7f8813 100644 --- a/src/mirall/owncloudfolder.cpp +++ b/src/mirall/owncloudfolder.cpp @@ -124,17 +124,16 @@ void ownCloudFolder::setProxy() { if( _csync_ctx ) { /* Store proxy */ - MirallConfigFile cfgFile; - QUrl proxyUrl(cfgFile.ownCloudUrl()); + QUrl proxyUrl(ownCloudInfo::instance()->webdavUrl()); QList proxies = QNetworkProxyFactory::proxyForQuery(proxyUrl); // We set at least one in Application Q_ASSERT(proxies.count() > 0); QNetworkProxy proxy = proxies.first(); if (proxy.type() == QNetworkProxy::NoProxy) { - qDebug() << "Passing NO proxy to csync for" << cfgFile.ownCloudUrl(); + qDebug() << "Passing NO proxy to csync for" << proxyUrl; } else { qDebug() << "Passing" << proxy.hostName() << "of proxy type " << proxy.type() - << " to csync for" << cfgFile.ownCloudUrl(); + << " to csync for" << proxyUrl; } int proxyPort = proxy.port(); @@ -241,8 +240,7 @@ bool ownCloudFolder::isBusy() const QString ownCloudFolder::secondPath() const { QString re(Folder::secondPath()); - MirallConfigFile cfg; - QString ocUrl = cfg.ownCloudUrl(QString::null, true); + QString ocUrl = ownCloudInfo::instance()->webdavUrl(); if (ocUrl.endsWith(QLatin1Char('/'))) ocUrl.chop(1); diff --git a/src/mirall/owncloudinfo.cpp b/src/mirall/owncloudinfo.cpp index 35e4e8d4f4..68e3792b31 100644 --- a/src/mirall/owncloudinfo.cpp +++ b/src/mirall/owncloudinfo.cpp @@ -116,28 +116,32 @@ bool ownCloudInfo::isConfigured() QNetworkReply *ownCloudInfo::checkInstallation() { + _redirectCount = 0; + MirallConfigFile cfgFile( _configHandle ); + QUrl url ( cfgFile.ownCloudUrl( _connection ) + QLatin1String("status.php") ); /* No authentication required for this. */ - return getRequest( QLatin1String("status.php"), false ); + return getRequest(url); } QNetworkReply* ownCloudInfo::getWebDAVPath( const QString& path ) { - return getRequest( path, true ); + _redirectCount = 0; + QUrl url ( webdavUrl( _connection ) + path ); + QNetworkReply *reply = getRequest(url); + _directories[reply] = path; + return reply; } -QNetworkReply* ownCloudInfo::getRequest( const QString& path, bool webdav ) +QNetworkReply* ownCloudInfo::getRequest( const QUrl& url ) { - qDebug() << "Get Request to " << path; + qDebug() << "Get Request to " << url; - MirallConfigFile cfgFile( _configHandle ); - QString url = cfgFile.ownCloudUrl( _connection, webdav ) + path; QNetworkRequest request; - request.setUrl( QUrl( url ) ); + request.setUrl( url ); setupHeaders( request, 0 ); QNetworkReply *reply = _manager->get( request ); connect( reply, SIGNAL(finished()), SLOT(slotReplyFinished())); - _directories[reply] = path; if( !_configHandle.isEmpty() ) { qDebug() << "Setting config handle " << _configHandle; @@ -155,7 +159,7 @@ QNetworkReply* ownCloudInfo::mkdirRequest( const QString& dir ) qDebug() << "OCInfo Making dir " << dir; MirallConfigFile cfgFile( _configHandle ); - QUrl url = QUrl( cfgFile.ownCloudUrl( _connection, true ) + dir ); + QUrl url = QUrl( webdavUrl(_connection) + dir ); QHttp::ConnectionMode conMode = QHttp::ConnectionModeHttp; if (url.scheme() == "https") conMode = QHttp::ConnectionModeHttps; @@ -320,20 +324,6 @@ QList ownCloudInfo::certificateChain() const return _certificateChain; } -QUrl ownCloudInfo::redirectUrl(const QUrl& possibleRedirectUrl, - const QUrl& oldRedirectUrl) const { - QUrl redirectUrl; - /* - * Check if the URL is empty and - * that we aren't being fooled into a infinite redirect loop. - */ - if(!possibleRedirectUrl.isEmpty() && - possibleRedirectUrl != oldRedirectUrl) { - redirectUrl = possibleRedirectUrl; - } - return redirectUrl; -} - // // There have been problems with the finish-signal coming from the networkmanager. // To avoid that, the reply-signals were connected and the data is taken from the @@ -354,12 +344,17 @@ void ownCloudInfo::slotReplyFinished() } // Detect redirect url - QVariant possibleRedirUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute); + QUrl possibleRedirUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl(); /* We'll deduct if the redirection is valid in the redirectUrl function */ - _urlRedirectedTo = redirectUrl( possibleRedirUrl.toUrl(), - _urlRedirectedTo ); - if(!_urlRedirectedTo.isEmpty()) { + + if (!possibleRedirUrl.isEmpty() && _redirectCount++ > 10) { + // Are we in a redirect loop + qDebug() << "Redirect loop while redirecting to" << possibleRedirUrl; + possibleRedirUrl.clear(); + } + + if(!possibleRedirUrl.isEmpty()) { QString configHandle; qDebug() << "Redirected to " << possibleRedirUrl; @@ -374,22 +369,21 @@ void ownCloudInfo::slotReplyFinished() QString path = _directories[reply]; qDebug() << "This path was redirected: " << path; - MirallConfigFile cfgFile( configHandle ); - QString newUrl = _urlRedirectedTo.toString(); + QString newUrl = possibleRedirUrl.toString(); if( newUrl.endsWith( path )) { // cut off the trailing path newUrl.chop( path.length() ); - cfgFile.setOwnCloudUrl( _connection, newUrl ); - - qDebug() << "Update the config file url to " << newUrl; - getRequest( path, false ); // FIXME: Redirect for webdav! - reply->deleteLater(); - return; + _urlRedirectedTo = newUrl; + qDebug() << "Updated url to" << newUrl; } else { qDebug() << "WRN: Path is not part of the redirect URL. NO redirect."; } + getRequest( possibleRedirUrl ); + reply->deleteLater(); + _directories.remove(reply); + _configHandleMap.remove(reply); + return; } - _urlRedirectedTo.clear(); // TODO: check if this is always the correct encoding const QString version = QString::fromUtf8( reply->readAll() ); @@ -455,15 +449,13 @@ void ownCloudInfo::slotReplyFinished() QString dir(QLatin1String("unknown")); if( _directories.contains(reply) ) { dir = _directories[reply]; - _directories.remove(reply); } emit ownCloudDirExists( dir, reply ); } - if( _configHandleMap.contains(reply)) { - _configHandleMap.remove(reply); - } reply->deleteLater(); + _directories.remove(reply); + _configHandleMap.remove(reply); } void ownCloudInfo::resetSSLUntrust() @@ -536,9 +528,7 @@ void ownCloudInfo::setCredentials( const QString& user, const QString& passwd, // ============================================================================ void ownCloudInfo::setupHeaders( QNetworkRequest & req, quint64 size ) { - MirallConfigFile cfgFile(_configHandle ); - - QUrl url( cfgFile.ownCloudUrl( QString::null, false ) ); + QUrl url( webdavUrl() ); qDebug() << "Setting up host header: " << url.host(); req.setRawHeader( QByteArray("Host"), url.host().toUtf8() ); req.setRawHeader( QByteArray("User-Agent"), Utility::userAgentString()); @@ -572,5 +562,14 @@ QNetworkReply* ownCloudInfo::davRequest(const QString& reqVerb, QNetworkRequest } } #endif + +QString ownCloudInfo::webdavUrl(const QString &connection) +{ + if (!_urlRedirectedTo.isEmpty()) + return _urlRedirectedTo.toString(); + + MirallConfigFile cfgFile(_configHandle ); + return cfgFile.ownCloudUrl( connection, true ); } +} diff --git a/src/mirall/owncloudinfo.h b/src/mirall/owncloudinfo.h index 3f4f9c26a9..243ee8529f 100644 --- a/src/mirall/owncloudinfo.h +++ b/src/mirall/owncloudinfo.h @@ -47,12 +47,6 @@ public: */ QNetworkReply* checkInstallation(); - /** - * a general GET request to the ownCloud. If the second bool parameter is - * true, the WebDAV server is queried. - */ - QNetworkReply* getRequest( const QString&, bool ); - /** * convenience: GET request to the WebDAV server. */ @@ -110,6 +104,12 @@ public: void setCredentials( const QString&, const QString&, const QString& configHandle = QString::null ); + /** + * returns the owncloud webdav url. + * It may be different from the one in the config if there was a HTTP redirection + */ + QString webdavUrl(const QString& connection = QString()); + signals: // result signal with url- and version string. void ownCloudInfoFound( const QString&, const QString&, const QString&, const QString& ); @@ -138,7 +138,11 @@ protected slots: private: explicit ownCloudInfo(); - QUrl redirectUrl(const QUrl&, const QUrl& ) const; + /** + * a general GET request to the ownCloud WebDAV. + */ + QNetworkReply* getRequest( const QUrl &url); + ~ownCloudInfo(); @@ -161,6 +165,7 @@ private: int _authAttempts; QMap _credentials; QMutex _certChainMutex; + int _redirectCount; }; }; diff --git a/src/mirall/owncloudsetupwizard.cpp b/src/mirall/owncloudsetupwizard.cpp index 6645239e47..ae19272419 100644 --- a/src/mirall/owncloudsetupwizard.cpp +++ b/src/mirall/owncloudsetupwizard.cpp @@ -329,7 +329,7 @@ void OwncloudSetupWizard::checkRemoteFolder() qDebug() << "# checking for authentication settings."; ownCloudInfo::instance()->setCustomConfigHandle(_configHandle); - _checkRemoteFolderRequest = ownCloudInfo::instance()->getRequest(_remoteFolder, true ); // this call needs to be authenticated. + _checkRemoteFolderRequest = ownCloudInfo::instance()->getWebDAVPath(_remoteFolder ); // this call needs to be authenticated. // continue in slotAuthCheckReply } From 0bc9b6f44ecdfdaa191cb6ff1c9ee0cb1033e96e Mon Sep 17 00:00:00 2001 From: Daniel Molkentin Date: Thu, 20 Jun 2013 19:50:34 +0200 Subject: [PATCH 4/6] Revert "Do not store the redirected URL in the config file." This reverts commit 905f70a1867433d3631444d7f36aaf9f87d0c60a. Patch still has issues, defer until after Beta 4 --- src/mirall/application.cpp | 2 +- src/mirall/connectionvalidator.cpp | 2 +- src/mirall/folderman.cpp | 5 +- src/mirall/mirallconfigfile.cpp | 13 +++++ src/mirall/mirallconfigfile.h | 2 + src/mirall/owncloudfolder.cpp | 10 ++-- src/mirall/owncloudinfo.cpp | 85 +++++++++++++++--------------- src/mirall/owncloudinfo.h | 19 +++---- src/mirall/owncloudsetupwizard.cpp | 2 +- 9 files changed, 77 insertions(+), 63 deletions(-) diff --git a/src/mirall/application.cpp b/src/mirall/application.cpp index 2f6f6b7bcd..cc2ec308fe 100644 --- a/src/mirall/application.cpp +++ b/src/mirall/application.cpp @@ -321,7 +321,7 @@ void Application::slotCheckAuthentication() this,SLOT(slotAuthCheck(QString,QNetworkReply*))); qDebug() << "# checking for authentication settings."; - ownCloudInfo::instance()->getWebDAVPath(QLatin1String("/") ); // this call needs to be authenticated. + ownCloudInfo::instance()->getRequest(QLatin1String("/"), true ); // this call needs to be authenticated. // simply GET the webdav root, will fail if credentials are wrong. // continue in slotAuthCheck here :-) } diff --git a/src/mirall/connectionvalidator.cpp b/src/mirall/connectionvalidator.cpp index f034363dec..5303998acd 100644 --- a/src/mirall/connectionvalidator.cpp +++ b/src/mirall/connectionvalidator.cpp @@ -163,7 +163,7 @@ void ConnectionValidator::slotCheckAuthentication() this, SLOT(slotAuthCheck(QString,QNetworkReply*))); qDebug() << "# checking for authentication settings."; - ownCloudInfo::instance()->getWebDAVPath(QLatin1String("/") ); // this call needs to be authenticated. + ownCloudInfo::instance()->getRequest(QLatin1String("/"), true ); // this call needs to be authenticated. // simply GET the webdav root, will fail if credentials are wrong. // continue in slotAuthCheck here :-) } diff --git a/src/mirall/folderman.cpp b/src/mirall/folderman.cpp index d999a87964..3dfe406f32 100644 --- a/src/mirall/folderman.cpp +++ b/src/mirall/folderman.cpp @@ -18,7 +18,6 @@ #include "mirall/syncresult.h" #include "mirall/inotify.h" #include "mirall/theme.h" -#include "owncloudinfo.h" #ifdef Q_OS_MAC #include @@ -250,8 +249,10 @@ Folder* FolderMan::setupFolderFromConfigFile(const QString &file) { if (!backend.isEmpty()) { if( backend == QLatin1String("owncloud") ) { + MirallConfigFile cfgFile; + // assemble the owncloud url to pass to csync, incl. webdav - QString oCUrl = ownCloudInfo::instance()->webdavUrl( ); + QString oCUrl = cfgFile.ownCloudUrl( QString::null, true ); // cut off the leading slash, oCUrl always has a trailing. if( targetPath.startsWith(QLatin1Char('/')) ) { diff --git a/src/mirall/mirallconfigfile.cpp b/src/mirall/mirallconfigfile.cpp index cafd7f5838..e25b6cd6c5 100644 --- a/src/mirall/mirallconfigfile.cpp +++ b/src/mirall/mirallconfigfile.cpp @@ -228,6 +228,19 @@ bool MirallConfigFile::writePassword( const QString& passwd, const QString& conn return true; } +// set the url, called from redirect handling. +void MirallConfigFile::setOwnCloudUrl( const QString& connection, const QString & url ) +{ + const QString file = configFile(); + + QSettings settings( file, QSettings::IniFormat); + settings.setIniCodec( "UTF-8" ); + settings.beginGroup( connection ); + settings.setValue( QLatin1String("url"), url ); + + settings.sync(); +} + QByteArray MirallConfigFile::caCerts( ) { QSettings settings( configFile(), QSettings::IniFormat ); diff --git a/src/mirall/mirallconfigfile.h b/src/mirall/mirallconfigfile.h index 29258aa23d..df91393834 100644 --- a/src/mirall/mirallconfigfile.h +++ b/src/mirall/mirallconfigfile.h @@ -58,6 +58,8 @@ public: QString ownCloudUser( const QString& connection = QString() ) const; QString ownCloudUrl( const QString& connection = QString(), bool webdav = false ) const; + void setOwnCloudUrl(const QString &connection, const QString& ); + // the certs do not depend on a connection. QByteArray caCerts(); void setCaCerts( const QByteArray& ); diff --git a/src/mirall/owncloudfolder.cpp b/src/mirall/owncloudfolder.cpp index ad3c7f8813..076b3f0a18 100644 --- a/src/mirall/owncloudfolder.cpp +++ b/src/mirall/owncloudfolder.cpp @@ -124,16 +124,17 @@ void ownCloudFolder::setProxy() { if( _csync_ctx ) { /* Store proxy */ - QUrl proxyUrl(ownCloudInfo::instance()->webdavUrl()); + MirallConfigFile cfgFile; + QUrl proxyUrl(cfgFile.ownCloudUrl()); QList proxies = QNetworkProxyFactory::proxyForQuery(proxyUrl); // We set at least one in Application Q_ASSERT(proxies.count() > 0); QNetworkProxy proxy = proxies.first(); if (proxy.type() == QNetworkProxy::NoProxy) { - qDebug() << "Passing NO proxy to csync for" << proxyUrl; + qDebug() << "Passing NO proxy to csync for" << cfgFile.ownCloudUrl(); } else { qDebug() << "Passing" << proxy.hostName() << "of proxy type " << proxy.type() - << " to csync for" << proxyUrl; + << " to csync for" << cfgFile.ownCloudUrl(); } int proxyPort = proxy.port(); @@ -240,7 +241,8 @@ bool ownCloudFolder::isBusy() const QString ownCloudFolder::secondPath() const { QString re(Folder::secondPath()); - QString ocUrl = ownCloudInfo::instance()->webdavUrl(); + MirallConfigFile cfg; + QString ocUrl = cfg.ownCloudUrl(QString::null, true); if (ocUrl.endsWith(QLatin1Char('/'))) ocUrl.chop(1); diff --git a/src/mirall/owncloudinfo.cpp b/src/mirall/owncloudinfo.cpp index 68e3792b31..35e4e8d4f4 100644 --- a/src/mirall/owncloudinfo.cpp +++ b/src/mirall/owncloudinfo.cpp @@ -116,32 +116,28 @@ bool ownCloudInfo::isConfigured() QNetworkReply *ownCloudInfo::checkInstallation() { - _redirectCount = 0; - MirallConfigFile cfgFile( _configHandle ); - QUrl url ( cfgFile.ownCloudUrl( _connection ) + QLatin1String("status.php") ); /* No authentication required for this. */ - return getRequest(url); + return getRequest( QLatin1String("status.php"), false ); } QNetworkReply* ownCloudInfo::getWebDAVPath( const QString& path ) { - _redirectCount = 0; - QUrl url ( webdavUrl( _connection ) + path ); - QNetworkReply *reply = getRequest(url); - _directories[reply] = path; - return reply; + return getRequest( path, true ); } -QNetworkReply* ownCloudInfo::getRequest( const QUrl& url ) +QNetworkReply* ownCloudInfo::getRequest( const QString& path, bool webdav ) { - qDebug() << "Get Request to " << url; + qDebug() << "Get Request to " << path; + MirallConfigFile cfgFile( _configHandle ); + QString url = cfgFile.ownCloudUrl( _connection, webdav ) + path; QNetworkRequest request; - request.setUrl( url ); + request.setUrl( QUrl( url ) ); setupHeaders( request, 0 ); QNetworkReply *reply = _manager->get( request ); connect( reply, SIGNAL(finished()), SLOT(slotReplyFinished())); + _directories[reply] = path; if( !_configHandle.isEmpty() ) { qDebug() << "Setting config handle " << _configHandle; @@ -159,7 +155,7 @@ QNetworkReply* ownCloudInfo::mkdirRequest( const QString& dir ) qDebug() << "OCInfo Making dir " << dir; MirallConfigFile cfgFile( _configHandle ); - QUrl url = QUrl( webdavUrl(_connection) + dir ); + QUrl url = QUrl( cfgFile.ownCloudUrl( _connection, true ) + dir ); QHttp::ConnectionMode conMode = QHttp::ConnectionModeHttp; if (url.scheme() == "https") conMode = QHttp::ConnectionModeHttps; @@ -324,6 +320,20 @@ QList ownCloudInfo::certificateChain() const return _certificateChain; } +QUrl ownCloudInfo::redirectUrl(const QUrl& possibleRedirectUrl, + const QUrl& oldRedirectUrl) const { + QUrl redirectUrl; + /* + * Check if the URL is empty and + * that we aren't being fooled into a infinite redirect loop. + */ + if(!possibleRedirectUrl.isEmpty() && + possibleRedirectUrl != oldRedirectUrl) { + redirectUrl = possibleRedirectUrl; + } + return redirectUrl; +} + // // There have been problems with the finish-signal coming from the networkmanager. // To avoid that, the reply-signals were connected and the data is taken from the @@ -344,17 +354,12 @@ void ownCloudInfo::slotReplyFinished() } // Detect redirect url - QUrl possibleRedirUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl(); + QVariant possibleRedirUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute); /* We'll deduct if the redirection is valid in the redirectUrl function */ + _urlRedirectedTo = redirectUrl( possibleRedirUrl.toUrl(), + _urlRedirectedTo ); - - if (!possibleRedirUrl.isEmpty() && _redirectCount++ > 10) { - // Are we in a redirect loop - qDebug() << "Redirect loop while redirecting to" << possibleRedirUrl; - possibleRedirUrl.clear(); - } - - if(!possibleRedirUrl.isEmpty()) { + if(!_urlRedirectedTo.isEmpty()) { QString configHandle; qDebug() << "Redirected to " << possibleRedirUrl; @@ -369,21 +374,22 @@ void ownCloudInfo::slotReplyFinished() QString path = _directories[reply]; qDebug() << "This path was redirected: " << path; - QString newUrl = possibleRedirUrl.toString(); + MirallConfigFile cfgFile( configHandle ); + QString newUrl = _urlRedirectedTo.toString(); if( newUrl.endsWith( path )) { // cut off the trailing path newUrl.chop( path.length() ); - _urlRedirectedTo = newUrl; - qDebug() << "Updated url to" << newUrl; + cfgFile.setOwnCloudUrl( _connection, newUrl ); + + qDebug() << "Update the config file url to " << newUrl; + getRequest( path, false ); // FIXME: Redirect for webdav! + reply->deleteLater(); + return; } else { qDebug() << "WRN: Path is not part of the redirect URL. NO redirect."; } - getRequest( possibleRedirUrl ); - reply->deleteLater(); - _directories.remove(reply); - _configHandleMap.remove(reply); - return; } + _urlRedirectedTo.clear(); // TODO: check if this is always the correct encoding const QString version = QString::fromUtf8( reply->readAll() ); @@ -449,13 +455,15 @@ void ownCloudInfo::slotReplyFinished() QString dir(QLatin1String("unknown")); if( _directories.contains(reply) ) { dir = _directories[reply]; + _directories.remove(reply); } emit ownCloudDirExists( dir, reply ); } + if( _configHandleMap.contains(reply)) { + _configHandleMap.remove(reply); + } reply->deleteLater(); - _directories.remove(reply); - _configHandleMap.remove(reply); } void ownCloudInfo::resetSSLUntrust() @@ -528,7 +536,9 @@ void ownCloudInfo::setCredentials( const QString& user, const QString& passwd, // ============================================================================ void ownCloudInfo::setupHeaders( QNetworkRequest & req, quint64 size ) { - QUrl url( webdavUrl() ); + MirallConfigFile cfgFile(_configHandle ); + + QUrl url( cfgFile.ownCloudUrl( QString::null, false ) ); qDebug() << "Setting up host header: " << url.host(); req.setRawHeader( QByteArray("Host"), url.host().toUtf8() ); req.setRawHeader( QByteArray("User-Agent"), Utility::userAgentString()); @@ -562,14 +572,5 @@ QNetworkReply* ownCloudInfo::davRequest(const QString& reqVerb, QNetworkRequest } } #endif - -QString ownCloudInfo::webdavUrl(const QString &connection) -{ - if (!_urlRedirectedTo.isEmpty()) - return _urlRedirectedTo.toString(); - - MirallConfigFile cfgFile(_configHandle ); - return cfgFile.ownCloudUrl( connection, true ); } -} diff --git a/src/mirall/owncloudinfo.h b/src/mirall/owncloudinfo.h index 243ee8529f..3f4f9c26a9 100644 --- a/src/mirall/owncloudinfo.h +++ b/src/mirall/owncloudinfo.h @@ -47,6 +47,12 @@ public: */ QNetworkReply* checkInstallation(); + /** + * a general GET request to the ownCloud. If the second bool parameter is + * true, the WebDAV server is queried. + */ + QNetworkReply* getRequest( const QString&, bool ); + /** * convenience: GET request to the WebDAV server. */ @@ -104,12 +110,6 @@ public: void setCredentials( const QString&, const QString&, const QString& configHandle = QString::null ); - /** - * returns the owncloud webdav url. - * It may be different from the one in the config if there was a HTTP redirection - */ - QString webdavUrl(const QString& connection = QString()); - signals: // result signal with url- and version string. void ownCloudInfoFound( const QString&, const QString&, const QString&, const QString& ); @@ -138,11 +138,7 @@ protected slots: private: explicit ownCloudInfo(); - /** - * a general GET request to the ownCloud WebDAV. - */ - QNetworkReply* getRequest( const QUrl &url); - + QUrl redirectUrl(const QUrl&, const QUrl& ) const; ~ownCloudInfo(); @@ -165,7 +161,6 @@ private: int _authAttempts; QMap _credentials; QMutex _certChainMutex; - int _redirectCount; }; }; diff --git a/src/mirall/owncloudsetupwizard.cpp b/src/mirall/owncloudsetupwizard.cpp index ae19272419..6645239e47 100644 --- a/src/mirall/owncloudsetupwizard.cpp +++ b/src/mirall/owncloudsetupwizard.cpp @@ -329,7 +329,7 @@ void OwncloudSetupWizard::checkRemoteFolder() qDebug() << "# checking for authentication settings."; ownCloudInfo::instance()->setCustomConfigHandle(_configHandle); - _checkRemoteFolderRequest = ownCloudInfo::instance()->getWebDAVPath(_remoteFolder ); // this call needs to be authenticated. + _checkRemoteFolderRequest = ownCloudInfo::instance()->getRequest(_remoteFolder, true ); // this call needs to be authenticated. // continue in slotAuthCheckReply } From 3bff5a061bfa56fc530b2064e2ddfee8bc5b94cc Mon Sep 17 00:00:00 2001 From: Daniel Molkentin Date: Thu, 20 Jun 2013 20:02:25 +0200 Subject: [PATCH 5/6] Network: Display actual error message next to code. --- src/mirall/owncloudinfo.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/mirall/owncloudinfo.cpp b/src/mirall/owncloudinfo.cpp index 35e4e8d4f4..fd28ee0a83 100644 --- a/src/mirall/owncloudinfo.cpp +++ b/src/mirall/owncloudinfo.cpp @@ -483,7 +483,10 @@ bool ownCloudInfo::certsUntrusted() void ownCloudInfo::slotError( QNetworkReply::NetworkError err) { - qDebug() << "ownCloudInfo Network Error: " << err; + QNetworkReply *reply = qobject_cast(sender()); + + qDebug() << "ownCloudInfo Network Error" + << err << ":" << reply->errorString(); switch (err) { case QNetworkReply::ProxyConnectionRefusedError: From b206a3b8e26bfaf8f27cfe083591db0ea674007f Mon Sep 17 00:00:00 2001 From: Daniel Molkentin Date: Thu, 20 Jun 2013 21:01:38 +0200 Subject: [PATCH 6/6] Beta4 --- VERSION.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION.cmake b/VERSION.cmake index 7c55c1120c..4fb5a162ee 100644 --- a/VERSION.cmake +++ b/VERSION.cmake @@ -1,6 +1,6 @@ set( VERSION_MAJOR 1 ) set( VERSION_MINOR 3 ) set( VERSION_PATCH 0 ) -set( VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}${VERSION_SUFFIX}beta3) +set( VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}${VERSION_SUFFIX}beta4) set( SOVERSION 0 )