Skip to content
Permalink
Browse files

Add custom QNetworkRequest::Attributes for initiator network request …

…class name and internal id

And allow these to be retrieved from QgsNetworkRequestParameters.
This allows logging code to identify the area of code where a request
originated from, making debugging much easier!

Tag all requests created with appropriate class name and IDs
  • Loading branch information
nyalldawson committed Jan 25, 2019
1 parent a491e90 commit ca06d407a09e9ba4f96f40c7dd45908a6f598a75
@@ -10,6 +10,7 @@




class QgsNetworkRequestParameters
{
%Docstring
@@ -23,6 +24,12 @@ Encapsulates parameters and properties of a network request.
%End
public:

enum RequestAttributes
{
AttributeInitiatorClass,
AttributeInitiatorRequestId,
};

QgsNetworkRequestParameters();
%Docstring
Default constructor.
@@ -64,6 +71,27 @@ Returns a unique ID identifying the request.
%Docstring
Returns the request's content. This is only used for POST or PUT operation
requests.
%End

QString initiatorClassName() const;
%Docstring
Returns the class name of the object which initiated this request.

This is only available for QNetworkRequests which have had the
QgsNetworkRequestParameters.AttributeInitiatorClass attribute set.

.. seealso:: :py:func:`initiatorRequestId`
%End

QVariant initiatorRequestId() const;
%Docstring
Returns the internal ID used by the object which initiated this request to identify
individual requests.

This is only available for QNetworkRequests which have had the
QgsNetworkRequestParameters.AttributeInitiatorRequestId attribute set.

.. seealso:: :py:func:`initiatorClassName`
%End

};
@@ -32,7 +32,7 @@
from qgis.PyQt.QtNetwork import QNetworkRequest

import qgis
from qgis.core import Qgis, QgsApplication, QgsNetworkAccessManager, QgsSettings
from qgis.core import Qgis, QgsApplication, QgsNetworkAccessManager, QgsSettings, QgsNetworkRequestParameters
from qgis.gui import QgsMessageBar, QgsPasswordLineEdit
from qgis.utils import (iface, startPlugin, unloadPlugin, loadPlugin,
reloadPlugin, updateAvailablePlugins)
@@ -527,6 +527,8 @@ def sendVote(self, plugin_id, vote):
url = "http://plugins.qgis.org/plugins/RPC2/"
params = {"id": "djangorpc", "method": "plugin.vote", "params": [str(plugin_id), str(vote)]}
req = QNetworkRequest(QUrl(url))
req.setAttribute(QNetworkRequest.Attribute(QgsNetworkRequestParameters.AttributeInitiatorClass), "QgsPluginInstaller")
req.setAttribute(QNetworkRequest.Attribute(QgsNetworkRequestParameters.AttributeInitiatorRequestId), "sendVote")
req.setRawHeader(b"Content-Type", b"application/json")
QgsNetworkAccessManager.instance().post(req, bytes(json.dumps(params), "utf-8"))
return True
@@ -28,7 +28,7 @@
QLocale, QByteArray)
from qgis.PyQt.QtXml import QDomDocument
from qgis.PyQt.QtNetwork import QNetworkRequest, QNetworkReply
from qgis.core import Qgis, QgsSettings
from qgis.core import Qgis, QgsSettings, QgsNetworkRequestParameters
import sys
import os
import codecs
@@ -322,6 +322,7 @@ def requestFetching(self, key, url=None, redirectionCounter=0):
# url.addQueryItem('qgis', '.'.join([str(int(s)) for s in [v[0], v[1:3]]]) ) # don't include the bugfix version!

self.mRepositories[key]["QRequest"] = QNetworkRequest(url)
self.mRepositories[key]["QRequest"].setAttribute(QNetworkRequest.Attribute(QgsNetworkRequestParameters.AttributeInitiatorClass), "Relay")
authcfg = self.mRepositories[key]["authcfg"]
if authcfg and isinstance(authcfg, str):
if not QgsApplication.authManager().updateNetworkRequest(
@@ -30,7 +30,7 @@
from qgis.PyQt.QtNetwork import QNetworkRequest, QNetworkReply

import qgis
from qgis.core import QgsNetworkAccessManager, QgsApplication
from qgis.core import QgsNetworkAccessManager, QgsApplication, QgsNetworkRequestParameters

from .ui_qgsplugininstallerinstallingbase import Ui_QgsPluginInstallerInstallingDialogBase
from .installer_data import removeDir, repositories
@@ -62,6 +62,7 @@ def __init__(self, parent, plugin):

def requestDownloading(self):
self.request = QNetworkRequest(self.url)
self.request.setAttribute(QNetworkRequest.Attribute(QgsNetworkRequestParameters.AttributeInitiatorClass), "QgsPluginInstallerInstallingDialog")
authcfg = repositories.all()[self.plugin["zip_repository"]]["authcfg"]
if authcfg and isinstance(authcfg, str):
if not QgsApplication.authManager().updateNetworkRequest(
@@ -1119,6 +1119,7 @@ void QgsAuthOAuth2Edit::registerSoftStatement( const QString &registrationUrl )
bool res = false;
QByteArray json = QJsonWrapper::toJson( QVariant( mSoftwareStatement ), &res, &errStr );
QNetworkRequest registerRequest( regUrl );
QgsSetRequestInitiatorClass( registerRequest, QStringLiteral( "QgsAuthOAuth2Edit" ) );
registerRequest.setHeader( QNetworkRequest::ContentTypeHeader, QLatin1Literal( "application/json" ) );
QNetworkReply *registerReply;
// For testability: use GET if protocol is file://
@@ -1142,6 +1143,7 @@ void QgsAuthOAuth2Edit::getSoftwareStatementConfig()
QString config = leSoftwareStatementConfigUrl->text();
QUrl configUrl( config );
QNetworkRequest configRequest( configUrl );
QgsSetRequestInitiatorClass( configRequest, QStringLiteral( "QgsAuthOAuth2Edit" ) );
QNetworkReply *configReply = QgsNetworkAccessManager::instance()->get( configRequest );
mDownloading = true;
connect( configReply, &QNetworkReply::finished, this, &QgsAuthOAuth2Edit::configReplyFinished, Qt::QueuedConnection );
@@ -20,6 +20,7 @@
#include "qgsapplication.h"
#include "qgsauthoauth2config.h"
#include "qgslogger.h"
#include "qgsnetworkaccessmanager.h"

#include <QDir>
#include <QSettings>
@@ -230,6 +231,7 @@ void QgsO2::link()

QUrl url( tokenUrl_ );
QNetworkRequest tokenRequest( url );
QgsSetRequestInitiatorClass( tokenRequest, QStringLiteral( "QgsO2" ) );
tokenRequest.setHeader( QNetworkRequest::ContentTypeHeader, QLatin1Literal( "application/x-www-form-urlencoded" ) );
QNetworkReply *tokenReply = manager_->post( tokenRequest, payload );

@@ -291,6 +293,7 @@ void QgsO2::onVerificationReceived( QMap<QString, QString> response )
if ( !apiKey_.isEmpty() )
query = QStringLiteral( "?=%1" ).arg( QString( O2_OAUTH2_API_KEY ), apiKey_ );
QNetworkRequest tokenRequest( QUrl( tokenUrl_.toString() + query ) );
QgsSetRequestInitiatorClass( tokenRequest, QStringLiteral( "QgsO2" ) );
tokenRequest.setHeader( QNetworkRequest::ContentTypeHeader, O2_MIME_TYPE_XFORM );
QMap<QString, QString> parameters;
parameters.insert( O2_OAUTH2_GRANT_TYPE_CODE, code() );
@@ -185,7 +185,7 @@ void QgsGeoNodeRequest::replyFinished()
else
{
QNetworkRequest request( toUrl );

QgsSetRequestInitiatorClass( request, QStringLiteral( "QgsGeoNodeRequest" ) );
request.setAttribute( QNetworkRequest::CacheLoadControlAttribute, mForceRefresh ? QNetworkRequest::AlwaysNetwork : QNetworkRequest::PreferCache );
request.setAttribute( QNetworkRequest::CacheSaveControlAttribute, true );

@@ -519,6 +519,7 @@ bool QgsGeoNodeRequest::requestBlocking( const QString &endPoint )
QNetworkReply *QgsGeoNodeRequest::requestUrl( const QString &url )
{
QNetworkRequest request( url );
QgsSetRequestInitiatorClass( request, QStringLiteral( "QgsGeoNodeRequest" ) );
// Add authentication check here

request.setAttribute( QNetworkRequest::CacheLoadControlAttribute, mForceRefresh ? QNetworkRequest::AlwaysNetwork : QNetworkRequest::PreferCache );
@@ -23,6 +23,7 @@
#include "qgslogger.h"
#include "qgsmessagelog.h"
#include "qgsapplication.h"
#include "qgsnetworkaccessmanager.h"

#include <QObject>
#include <QMutex>
@@ -322,6 +323,7 @@ class CORE_EXPORT QgsAbstractContentCache : public QgsAbstractContentCacheBase
mPendingRemoteUrls.insert( path );
//fire up task to fetch content in background
QNetworkRequest request( url );
QgsSetRequestInitiatorClass( request, QStringLiteral( "QgsAbstractContentCache<%1>" ).arg( mTypeString ) );
request.setAttribute( QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache );
request.setAttribute( QNetworkRequest::CacheSaveControlAttribute, true );

@@ -51,6 +51,7 @@ void QgsFileDownloader::startDownload()
QgsNetworkAccessManager *nam = QgsNetworkAccessManager::instance();

QNetworkRequest request( mUrl );
QgsSetRequestInitiatorClass( request, QStringLiteral( "QgsFileDownloader" ) );
if ( !mAuthCfg.isEmpty() )
{
QgsApplication::authManager()->updateNetworkRequest( request, mAuthCfg );
@@ -61,6 +61,8 @@ int QgsGml::getFeatures( const QString &uri, QgsWkbTypes::Type *wkbType, QgsRect
mExtent.setMinimal();

QNetworkRequest request( uri );
QgsSetRequestInitiatorClass( request, QStringLiteral( "QgsGml" ) );

if ( !authcfg.isEmpty() )
{
if ( !QgsApplication::authManager()->updateNetworkRequest( request, authcfg ) )
@@ -450,5 +450,7 @@ QgsNetworkRequestParameters::QgsNetworkRequestParameters( QNetworkAccessManager:
, mOriginatingThreadId( QStringLiteral( "0x%2" ).arg( reinterpret_cast<quintptr>( QThread::currentThread() ), 2 * QT_POINTER_SIZE, 16, QLatin1Char( '0' ) ) )
, mRequestId( requestId )
, mContent( content )
, mInitiatorClass( request.attribute( static_cast< QNetworkRequest::Attribute >( QgsNetworkRequestParameters::AttributeInitiatorClass ) ).toString() )
, mInitiatorRequestId( request.attribute( static_cast< QNetworkRequest::Attribute >( QgsNetworkRequestParameters::AttributeInitiatorRequestId ) ) )
{
}
@@ -29,6 +29,14 @@
#include "qgis_core.h"
#include "qgis_sip.h"

#ifndef SIP_RUN
#include "qgsconfig.h"
constexpr int sFilePrefixLength = CMAKE_SOURCE_DIR[sizeof( CMAKE_SOURCE_DIR ) - 1] == '/' ? sizeof( CMAKE_SOURCE_DIR ) + 1 : sizeof( CMAKE_SOURCE_DIR );

#define QgsSetRequestInitiatorClass(request, _class) request.setAttribute( static_cast< QNetworkRequest::Attribute >( QgsNetworkRequestParameters::AttributeInitiatorClass ), _class ); request.setAttribute( static_cast< QNetworkRequest::Attribute >( QgsNetworkRequestParameters::AttributeInitiatorRequestId ), QString( __FILE__ ).mid( sFilePrefixLength ) + ':' + QString::number( __LINE__ ) + " (" + __FUNCTION__ + ")" );
#define QgsSetRequestInitiatorId(request, str) request.setAttribute( static_cast< QNetworkRequest::Attribute >( QgsNetworkRequestParameters::AttributeInitiatorRequestId ), QString( __FILE__ ).mid( sFilePrefixLength ) + ':' + QString::number( __LINE__ ) + " (" + __FUNCTION__ + "): " + str );
#endif

/**
* \class QgsNetworkRequestParameters
* \ingroup core
@@ -39,6 +47,13 @@ class CORE_EXPORT QgsNetworkRequestParameters
{
public:

//! Custom request attributes
enum RequestAttributes
{
AttributeInitiatorClass = QNetworkRequest::User + 3000, //!< Class name of original object which created the request
AttributeInitiatorRequestId, //!< Internal ID used by originator object to identify requests
};

/**
* Default constructor.
*/
@@ -82,13 +97,36 @@ class CORE_EXPORT QgsNetworkRequestParameters
*/
QByteArray content() const { return mContent; }

/**
* Returns the class name of the object which initiated this request.
*
* This is only available for QNetworkRequests which have had the
* QgsNetworkRequestParameters::AttributeInitiatorClass attribute set.
*
* \see initiatorRequestId()
*/
QString initiatorClassName() const { return mInitiatorClass; }

/**
* Returns the internal ID used by the object which initiated this request to identify
* individual requests.
*
* This is only available for QNetworkRequests which have had the
* QgsNetworkRequestParameters::AttributeInitiatorRequestId attribute set.
*
* \see initiatorClassName()
*/
QVariant initiatorRequestId() const { return mInitiatorRequestId; }

private:

QNetworkAccessManager::Operation mOperation;
QNetworkRequest mRequest;
QString mOriginatingThreadId;
int mRequestId = 0;
QByteArray mContent;
QString mInitiatorClass;
QVariant mInitiatorRequestId;
};

/**
@@ -476,6 +476,7 @@ QByteArray QgsArcGisRestUtils::queryService( const QUrl &u, const QString &authc
QUrl url = parseUrl( u );

QNetworkRequest request( url );
QgsSetRequestInitiatorClass( request, QStringLiteral( "QgsArcGisRestUtils" ) );
for ( auto it = requestHeaders.constBegin(); it != requestHeaders.constEnd(); ++it )
{
request.setRawHeader( it.key().toUtf8(), it.value().toUtf8() );
@@ -1136,6 +1137,7 @@ void QgsArcGisAsyncQuery::start( const QUrl &url, QByteArray *result, bool allow
{
mResult = result;
QNetworkRequest request( url );
QgsSetRequestInitiatorClass( request, QStringLiteral( "QgsArcGisAsyncQuery" ) );
if ( allowCache )
{
request.setAttribute( QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache );
@@ -1161,6 +1163,7 @@ void QgsArcGisAsyncQuery::handleReply()
if ( !redirect.isNull() )
{
QNetworkRequest request = mReply->request();
QgsSetRequestInitiatorClass( request, QStringLiteral( "QgsArcGisAsyncQuery" ) );
QgsDebugMsg( "redirecting to " + redirect.toUrl().toString() );
request.setUrl( redirect.toUrl() );
mReply = QgsNetworkAccessManager::instance()->get( request );
@@ -1188,6 +1191,8 @@ void QgsArcGisAsyncParallelQuery::start( const QVector<QUrl> &urls, QVector<QByt
for ( int i = 0, n = urls.size(); i < n; ++i )
{
QNetworkRequest request( urls[i] );
QgsSetRequestInitiatorClass( request, QStringLiteral( "QgsArcGisAsyncParallelQuery" ) );
QgsSetRequestInitiatorId( request, QString::number( i ) );
request.setAttribute( QNetworkRequest::HttpPipeliningAllowedAttribute, true );
if ( allowCache )
{
@@ -1217,6 +1222,7 @@ void QgsArcGisAsyncParallelQuery::handleReply()
{
// Handle HTTP redirects
QNetworkRequest request = reply->request();
QgsSetRequestInitiatorClass( request, QStringLiteral( "QgsArcGisAsyncParallelQuery" ) );
QgsDebugMsg( "redirecting to " + redirect.toUrl().toString() );
request.setUrl( redirect.toUrl() );
reply = QgsNetworkAccessManager::instance()->get( request );
@@ -130,6 +130,7 @@ bool QgsWcsCapabilities::sendRequest( QString const &url )
QgsDebugMsg( "url = " + url );
mError.clear();
QNetworkRequest request( url );
QgsSetRequestInitiatorClass( request, QStringLiteral( "QgsWcsCapabilities" ) );
if ( !setAuthorization( request ) )
{
mError = tr( "Download of capabilities failed: network request update failed for authentication config" );
@@ -347,6 +348,7 @@ void QgsWcsCapabilities::capabilitiesReplyFinished()
emit statusChanged( tr( "Capabilities request redirected." ) );

QNetworkRequest request( redirect.toUrl() );
QgsSetRequestInitiatorClass( request, QStringLiteral( "QgsWcsCapabilities" ) );
if ( !setAuthorization( request ) )
{
mCapabilitiesResponse.clear();
@@ -387,6 +389,7 @@ void QgsWcsCapabilities::capabilitiesReplyFinished()
{
// Resend request if AlwaysCache
QNetworkRequest request = mCapabilitiesReply->request();
QgsSetRequestInitiatorClass( request, QStringLiteral( "QgsWcsCapabilities" ) );
if ( request.attribute( QNetworkRequest::CacheLoadControlAttribute ).toInt() == QNetworkRequest::AlwaysCache )
{
QgsDebugMsg( QStringLiteral( "Resend request with PreferCache" ) );
@@ -1626,6 +1626,7 @@ QgsWcsDownloadHandler::QgsWcsDownloadHandler( const QUrl &url, QgsWcsAuthorizati
}

QNetworkRequest request( url );
QgsSetRequestInitiatorClass( request, QStringLiteral( "QgsWcsDownloadHandler" ) );
if ( !mAuth.setAuthorization( request ) )
{
QgsMessageLog::logMessage( tr( "Network request update failed for authentication config" ),
@@ -1676,6 +1677,7 @@ void QgsWcsDownloadHandler::cacheReplyFinished()

QgsDebugMsg( QStringLiteral( "redirected getmap: %1" ).arg( redirect.toString() ) );
QNetworkRequest request( redirect.toUrl() );
QgsSetRequestInitiatorClass( request, QStringLiteral( "QgsWcsDownloadHandler" ) );
if ( !mAuth.setAuthorization( request ) )
{
QgsMessageLog::logMessage( tr( "Network request update failed for authentication config" ),
@@ -1851,6 +1853,7 @@ void QgsWcsDownloadHandler::cacheReplyFinished()
{
// Resend request if AlwaysCache
QNetworkRequest request = mCacheReply->request();
QgsSetRequestInitiatorClass( request, QStringLiteral( "QgsWcsDownloadHandler" ) );
if ( request.attribute( QNetworkRequest::CacheLoadControlAttribute ).toInt() == QNetworkRequest::AlwaysCache )
{
QgsDebugMsg( QStringLiteral( "Resend request with PreferCache" ) );
@@ -114,6 +114,7 @@ bool QgsWfsRequest::sendGET( const QUrl &url, bool synchronous, bool forceRefres
QgsDebugMsgLevel( QStringLiteral( "Calling: %1" ).arg( modifiedUrl.toDisplayString( ) ), 4 );

QNetworkRequest request( modifiedUrl );
QgsSetRequestInitiatorClass( request, QStringLiteral( "QgsWfsRequest" ) );
if ( !mUri.auth().setAuthorization( request ) )
{
mErrorCode = QgsWfsRequest::NetworkError;
@@ -252,6 +253,7 @@ bool QgsWfsRequest::sendPOST( const QUrl &url, const QString &contentTypeHeader,
}

QNetworkRequest request( url );
QgsSetRequestInitiatorClass( request, QStringLiteral( "QgsWfsRequest" ) );
if ( !mUri.auth().setAuthorization( request ) )
{
mErrorCode = QgsWfsRequest::NetworkError;
@@ -336,6 +338,7 @@ void QgsWfsRequest::replyFinished()
else
{
QNetworkRequest request( toUrl );
QgsSetRequestInitiatorClass( request, QStringLiteral( "QgsWfsRequest" ) );
if ( !mUri.auth().setAuthorization( request ) )
{
mResponse.clear();
@@ -1948,6 +1948,7 @@ bool QgsWmsCapabilitiesDownload::downloadCapabilities()
mError.clear();

QNetworkRequest request( url );
QgsSetRequestInitiatorClass( request, QStringLiteral( "QgsWmsCapabilitiesDownload" ) );
if ( !mAuth.setAuthorization( request ) )
{
mError = tr( "Download of capabilities failed: network request update failed for authentication config" );
@@ -2016,6 +2017,7 @@ void QgsWmsCapabilitiesDownload::capabilitiesReplyFinished()
else
{
QNetworkRequest request( toUrl );
QgsSetRequestInitiatorClass( request, QStringLiteral( "QgsWmsCapabilitiesDownload" ) );
if ( !mAuth.setAuthorization( request ) )
{
mHttpCapabilitiesResponse.clear();

0 comments on commit ca06d40

Please sign in to comment.
You can’t perform that action at this time.