From 36f68e4fc999e7c6b037a67a2410ac4fb7dc8ce3 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Tue, 19 Jan 2021 16:12:43 +1000 Subject: [PATCH] Add mechanism for temporarily disabling all network caching to QgsNetworkAccessManager, and add a checkbox in the network logger panel to allow users to temporarily disable the network cache This can be VERY useful when debugging QGIS network activity, or when using QGIS to test server side changes. This is a transient setting only, and is forgotten as soon as QGIS is closed. That's by design -- we don't want users to accidentally leave this enabled and cause unnecessary server load. --- .../network/qgsnetworkaccessmanager.sip.in | 1 + .../qgsnetworkloggerpanelwidget.cpp | 13 ++++++++++ src/core/network/qgsnetworkaccessmanager.cpp | 10 ++++++++ src/core/network/qgsnetworkaccessmanager.h | 25 +++++++++++++++++++ 4 files changed, 49 insertions(+) diff --git a/python/core/auto_generated/network/qgsnetworkaccessmanager.sip.in b/python/core/auto_generated/network/qgsnetworkaccessmanager.sip.in index ff0ea913ebd..fa0e6f2db9d 100644 --- a/python/core/auto_generated/network/qgsnetworkaccessmanager.sip.in +++ b/python/core/auto_generated/network/qgsnetworkaccessmanager.sip.in @@ -250,6 +250,7 @@ need to be handled on the main thread. See in-depth discussion in the documentat for the constructor of this class. %End + bool useSystemProxy() const; %Docstring Returns whether the system proxy should be used. diff --git a/src/app/devtools/networklogger/qgsnetworkloggerpanelwidget.cpp b/src/app/devtools/networklogger/qgsnetworkloggerpanelwidget.cpp index c6644fe8425..b046a5f8c7d 100644 --- a/src/app/devtools/networklogger/qgsnetworkloggerpanelwidget.cpp +++ b/src/app/devtools/networklogger/qgsnetworkloggerpanelwidget.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include @@ -217,4 +218,16 @@ QgsNetworkLoggerPanelWidget::QgsNetworkLoggerPanelWidget( QgsNetworkLogger *logg settingsMenu->addAction( mActionShowSuccessful ); settingsMenu->addAction( mActionShowTimeouts ); + + mToolbar->addSeparator(); + QCheckBox *disableCacheCheck = new QCheckBox( tr( "Disable cache" ) ); + connect( disableCacheCheck, &QCheckBox::toggled, this, [ = ]( bool checked ) + { + // note -- we deliberately do NOT store this as a permanent setting in QSettings + // as it is designed to be a temporary debugging tool only and we don't want + // users to accidentally leave this enabled and cause unnecessary server load... + QgsNetworkAccessManager::instance()->setCacheDisabled( checked ); + } ); + + mToolbar->addWidget( disableCacheCheck ); } diff --git a/src/core/network/qgsnetworkaccessmanager.cpp b/src/core/network/qgsnetworkaccessmanager.cpp index 6e05c00a6d9..94a17440704 100644 --- a/src/core/network/qgsnetworkaccessmanager.cpp +++ b/src/core/network/qgsnetworkaccessmanager.cpp @@ -127,7 +127,10 @@ QgsNetworkAccessManager *QgsNetworkAccessManager::instance( Qt::ConnectionType c sMainNAM = nam; if ( !nam->mInitialized ) + { nam->setupDefaultProxyAndCache( connectionType ); + nam->setCacheDisabled( sMainNAM->cacheDisabled() ); + } return nam; } @@ -249,6 +252,13 @@ QNetworkReply *QgsNetworkAccessManager::createRequest( QNetworkAccessManager::Op } #endif + if ( sMainNAM->mCacheDisabled ) + { + // if caching is disabled then we override whatever the request actually has set! + pReq->setAttribute( QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::AlwaysNetwork ); + pReq->setAttribute( QNetworkRequest::CacheSaveControlAttribute, false ); + } + static QAtomicInt sRequestId = 0; const int requestId = ++sRequestId; QByteArray content; diff --git a/src/core/network/qgsnetworkaccessmanager.h b/src/core/network/qgsnetworkaccessmanager.h index a7b066f7259..e9f7713b2f0 100644 --- a/src/core/network/qgsnetworkaccessmanager.h +++ b/src/core/network/qgsnetworkaccessmanager.h @@ -409,6 +409,30 @@ class CORE_EXPORT QgsNetworkAccessManager : public QNetworkAccessManager */ void setupDefaultProxyAndCache( Qt::ConnectionType connectionType = Qt::BlockingQueuedConnection ); +#ifndef SIP_RUN + + /** + * Returns TRUE if all network caching is disabled. + * + * \see setCacheDisabled() + * \note Not available in Python bindings. + * \since QGIS 3.18 + */ + bool cacheDisabled() const { return mCacheDisabled; } + + /** + * Sets whether all network caching should be disabled. + * + * If \a disabled is TRUE then all caching will be disabled, causing all requests + * to be retrieved from the network regardless of the request's attributes. + * + * \see cacheDisabled() + * \note Not available in Python bindings. + * \since QGIS 3.18 + */ + void setCacheDisabled( bool disabled ) { mCacheDisabled = disabled; } +#endif + /** * Returns whether the system proxy should be used. */ @@ -655,6 +679,7 @@ class CORE_EXPORT QgsNetworkAccessManager : public QNetworkAccessManager QStringList mNoProxyURLs; bool mUseSystemProxy = false; bool mInitialized = false; + bool mCacheDisabled = false; static QgsNetworkAccessManager *sMainNAM; // ssl error handler, will be set for main thread ONLY std::unique_ptr< QgsSslErrorHandler > mSslErrorHandler;