diff --git a/src/common/utility.cpp b/src/common/utility.cpp index 7df0d7d73b085..c1ada05e36868 100644 --- a/src/common/utility.cpp +++ b/src/common/utility.cpp @@ -151,16 +151,17 @@ static QLatin1String platform() #endif } -QByteArray Utility::userAgentString() -{ - return QStringLiteral("Mozilla/5.0 (%1) mirall/%2 (%3, %4-%5 ClientArchitecture: %6 OsArchitecture: %7)") - .arg(platform(), - QStringLiteral(MIRALL_VERSION_STRING), - qApp->applicationName(), - QSysInfo::productType(), - QSysInfo::kernelVersion(), - QSysInfo::buildCpuArchitecture(), - QSysInfo::currentCpuArchitecture()) +QByteArray Utility::userAgentString(const QString &synchronizationType) +{ + return QStringLiteral("Mozilla/5.0 (%1) mirall/%2 (%3, %4-%5 ClientArchitecture: %6 OsArchitecture: %7 SyncType: %8)") + .arg(platform(), + QStringLiteral(MIRALL_VERSION_STRING), + qApp->applicationName(), + QSysInfo::productType(), + QSysInfo::kernelVersion(), + QSysInfo::buildCpuArchitecture(), + QSysInfo::currentCpuArchitecture(), + synchronizationType) .toLatin1(); } diff --git a/src/common/utility.h b/src/common/utility.h index dc51338ea146a..4176553dc10d2 100644 --- a/src/common/utility.h +++ b/src/common/utility.h @@ -68,7 +68,7 @@ namespace Utility { OCSYNC_EXPORT bool writeRandomFile(const QString &fname, int size = -1); OCSYNC_EXPORT QString octetsToString(const qint64 octets); - OCSYNC_EXPORT QByteArray userAgentString(); + OCSYNC_EXPORT QByteArray userAgentString(const QString &synchronizationType); OCSYNC_EXPORT QByteArray friendlyUserAgentString(); /** * @brief Return whether launch on startup is enabled system wide. diff --git a/src/gui/creds/webflowcredentials.cpp b/src/gui/creds/webflowcredentials.cpp index 9f77b69ff5c88..b9bfeda5b57b3 100644 --- a/src/gui/creds/webflowcredentials.cpp +++ b/src/gui/creds/webflowcredentials.cpp @@ -46,6 +46,7 @@ class WebFlowCredentialsAccessManager : public AccessManager : AccessManager(parent) , _cred(cred) { + setSynchronizationType(QStringLiteral("login")); } protected: diff --git a/src/gui/systray.cpp b/src/gui/systray.cpp index 6ed0b78399682..e075f337fd73e 100644 --- a/src/gui/systray.cpp +++ b/src/gui/systray.cpp @@ -972,6 +972,7 @@ AccessManagerFactory::AccessManagerFactory() QNetworkAccessManager* AccessManagerFactory::create(QObject *parent) { const auto am = new AccessManager(parent); + am->setSynchronizationType(QStringLiteral("Systray")); const auto diskCache = new QNetworkDiskCache(am); diskCache->setCacheDirectory(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)); am->setCache(diskCache); diff --git a/src/gui/updater/ocupdater.cpp b/src/gui/updater/ocupdater.cpp index febe136816168..03455cd92f0c2 100644 --- a/src/gui/updater/ocupdater.cpp +++ b/src/gui/updater/ocupdater.cpp @@ -81,6 +81,7 @@ OCUpdater::OCUpdater(const QUrl &url) , _accessManager(new AccessManager(this)) , _timeoutWatchdog(new QTimer(this)) { + _accessManager->setSynchronizationType(QStringLiteral("updater")); } void OCUpdater::setUpdateUrl(const QUrl &url) @@ -248,6 +249,10 @@ bool OCUpdater::updateSucceeded() const return currentVersion >= targetVersionInt; } +QNetworkAccessManager *OCUpdater::qnam() const { + return _accessManager; +} + void OCUpdater::slotVersionInfoArrived() { qCDebug(lcUpdater) << "received a reply"; diff --git a/src/gui/updater/ocupdater.h b/src/gui/updater/ocupdater.h index 25c477b6864dd..c5498e5a6e360 100644 --- a/src/gui/updater/ocupdater.h +++ b/src/gui/updater/ocupdater.h @@ -73,6 +73,8 @@ private slots: QTimer _updateCheckTimer; /** Timer for the regular update check. */ }; +class AccessManager; + /** * @brief Class that uses an ownCloud proprietary XML format to fetch update information * @ingroup gui @@ -126,13 +128,13 @@ private slots: protected: virtual void versionInfoArrived(const UpdateInfo &info) = 0; [[nodiscard]] bool updateSucceeded() const; - [[nodiscard]] QNetworkAccessManager *qnam() const { return _accessManager; } + [[nodiscard]] QNetworkAccessManager *qnam() const; [[nodiscard]] UpdateInfo updateInfo() const { return _updateInfo; } private: QUrl _updateUrl; int _state = Unknown; - QNetworkAccessManager *_accessManager; + AccessManager *_accessManager; QTimer *_timeoutWatchdog; /** Timer to guard the timeout of an individual network request */ UpdateInfo _updateInfo; }; diff --git a/src/gui/wizard/webview.cpp b/src/gui/wizard/webview.cpp index 8e661a0b6a82d..3fdb170b63359 100644 --- a/src/gui/wizard/webview.cpp +++ b/src/gui/wizard/webview.cpp @@ -88,7 +88,7 @@ WebView::WebView(QWidget *parent) _interceptor = new WebViewPageUrlRequestInterceptor(this); _schemeHandler = new WebViewPageUrlSchemeHandler(this); - const QString userAgent(Utility::userAgentString()); + const QString userAgent(Utility::userAgentString(QStringLiteral("login"))); _profile->setHttpUserAgent(userAgent); QWebEngineProfile::defaultProfile()->setHttpUserAgent(userAgent); _profile->setUrlRequestInterceptor(_interceptor); diff --git a/src/libsync/accessmanager.cpp b/src/libsync/accessmanager.cpp index 6ad08940ad03f..67c9f8f833ae9 100644 --- a/src/libsync/accessmanager.cpp +++ b/src/libsync/accessmanager.cpp @@ -38,6 +38,16 @@ AccessManager::AccessManager(QObject *parent) }); } +const QString &AccessManager::synchronizationType() const +{ + return _synchronizationType; +} + +void AccessManager::setSynchronizationType(const QString &type) +{ + _synchronizationType = type; +} + QByteArray AccessManager::generateRequestId() { return QUuid::createUuid().toByteArray(QUuid::WithoutBraces); @@ -49,7 +59,8 @@ QNetworkReply *AccessManager::createRequest(QNetworkAccessManager::Operation op, // Respect request specific user agent if any if (!newRequest.header(QNetworkRequest::UserAgentHeader).isValid()) { - newRequest.setHeader(QNetworkRequest::UserAgentHeader, Utility::userAgentString()); + Q_ASSERT(!_synchronizationType.isEmpty()); + newRequest.setHeader(QNetworkRequest::UserAgentHeader, Utility::userAgentString(_synchronizationType)); } // Some firewalls reject requests that have a "User-Agent" but no "Accept" header diff --git a/src/libsync/accessmanager.h b/src/libsync/accessmanager.h index 7b2a16e05f531..afd86addba2ee 100644 --- a/src/libsync/accessmanager.h +++ b/src/libsync/accessmanager.h @@ -28,8 +28,15 @@ class OWNCLOUDSYNC_EXPORT AccessManager : public QNetworkAccessManager AccessManager(QObject *parent = nullptr); + [[nodiscard]] const QString& synchronizationType() const; + + void setSynchronizationType(const QString &type); + protected: QNetworkReply *createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest &request, QIODevice *outgoingData = nullptr) override; + +private: + QString _synchronizationType; }; } // namespace OCC diff --git a/src/libsync/account.cpp b/src/libsync/account.cpp index fa620bb25fc1d..99ae6403de106 100644 --- a/src/libsync/account.cpp +++ b/src/libsync/account.cpp @@ -284,6 +284,11 @@ void Account::setCredentials(AbstractCredentials *cred) // processing slotHandleSslErrors(). _networkAccessManager = QSharedPointer(_credentials->createQNAM(), &QObject::deleteLater); + const auto accessManager = qobject_cast(_networkAccessManager.get()); + if (accessManager) { + accessManager->setSynchronizationType(QStringLiteral("account")); + } + if (jar) { _networkAccessManager->setCookieJar(jar); } @@ -414,6 +419,11 @@ void Account::resetNetworkAccessManager() // Make it call deleteLater to make sure that we can return to any QNAM stack frames safely. _networkAccessManager = QSharedPointer(_credentials->createQNAM(), &QObject::deleteLater); + const auto accessManager = qobject_cast(_networkAccessManager.get()); + if (accessManager) { + accessManager->setSynchronizationType(QStringLiteral("account")); + } + _networkAccessManager->setCookieJar(jar); // takes ownership of the old cookie jar _networkAccessManager->setProxy(proxy); // Remember proxy (issue #2108) @@ -1132,6 +1142,16 @@ void Account::setEncryptionCertificateFingerprint(const QByteArray &fingerprint) Q_EMIT wantsAccountSaved(sharedFromThis()); } +const QString &Account::synchronizationType() const +{ + return static_cast(_networkAccessManager.get())->synchronizationType(); +} + +void Account::setSynchronizationType(const QString &type) +{ + static_cast(_networkAccessManager.get())->setSynchronizationType(type); +} + void Account::setAskUserForMnemonic(const bool ask) { _e2eAskUserForMnemonic = ask; diff --git a/src/libsync/account.h b/src/libsync/account.h index eaa636b3ad0e3..144fce44ca73d 100644 --- a/src/libsync/account.h +++ b/src/libsync/account.h @@ -418,6 +418,10 @@ class OWNCLOUDSYNC_EXPORT Account : public QObject [[nodiscard]] QByteArray encryptionCertificateFingerprint() const; void setEncryptionCertificateFingerprint(const QByteArray &fingerprint); + [[nodiscard]] const QString& synchronizationType() const; + + void setSynchronizationType(const QString &type); + public slots: /// Used when forgetting credentials void clearQNAMCache(); diff --git a/src/libsync/syncengine.cpp b/src/libsync/syncengine.cpp index 23dd4b9f26b80..d784952641efa 100644 --- a/src/libsync/syncengine.cpp +++ b/src/libsync/syncengine.cpp @@ -583,7 +583,18 @@ void SyncEngine::startSync() verStr.append(" SSL library ").append(QSslSocket::sslLibraryVersionString().toUtf8().data()); verStr.append(" on ").append(Utility::platformName()); - qCInfo(lcEngine) << verStr; + qCInfo(lcEngine) << verStr << "vfs mode: " << _syncOptions._vfs->mode(); + + switch (_syncOptions._vfs->mode()) + { + case Vfs::Off: + _account->setSynchronizationType(QStringLiteral("classical")); + case Vfs::WithSuffix: + case Vfs::WindowsCfApi: + case Vfs::XAttr: + _account->setSynchronizationType(QStringLiteral("virtual")); + break; + } // This creates the DB if it does not exist yet. if (!_journal->open()) {