QGIS API Documentation 3.29.0-Master (53715c36dc)
qgsnetworkaccessmanager.h
Go to the documentation of this file.
1/***************************************************************************
2 qgsnetworkaccessmanager.h - description
3 -------------------
4 begin : 2010-05-08
5 copyright : (C) 2010 by Juergen E. Fischer
6 email : jef at norbit dot de
7 ***************************************************************************/
8
9/***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
18#ifndef QGSNETWORKACCESSMANAGER_H
19#define QGSNETWORKACCESSMANAGER_H
20
21#include <QList>
22#include "qgsnetworkreply.h"
23#include "qgis_sip.h"
24#include <QStringList>
25#include <QNetworkAccessManager>
26#include <QNetworkCookie>
27#include <QNetworkCookieJar>
28#include <QNetworkProxy>
29#include <QNetworkRequest>
30#include <QMutex>
31#include <QWaitCondition>
32#include <QSemaphore>
33#include <memory>
34
35#include "qgis_core.h"
36#include "qgis_sip.h"
38
39class QgsFeedback;
40
41#ifndef SIP_RUN
42#include "qgsconfig.h"
43constexpr int sFilePrefixLength = CMAKE_SOURCE_DIR[sizeof( CMAKE_SOURCE_DIR ) - 1] == '/' ? sizeof( CMAKE_SOURCE_DIR ) + 1 : sizeof( CMAKE_SOURCE_DIR );
44
45#define QgsSetRequestInitiatorClass(request, _class) request.setAttribute( static_cast< QNetworkRequest::Attribute >( QgsNetworkRequestParameters::AttributeInitiatorClass ), _class ); request.setAttribute( static_cast< QNetworkRequest::Attribute >( QgsNetworkRequestParameters::AttributeInitiatorRequestId ), QString(QString( __FILE__ ).mid( sFilePrefixLength ) + ':' + QString::number( __LINE__ ) + " (" + __FUNCTION__ + ")") );
46#define QgsSetRequestInitiatorId(request, str) request.setAttribute( static_cast< QNetworkRequest::Attribute >( QgsNetworkRequestParameters::AttributeInitiatorRequestId ), QString(QString( __FILE__ ).mid( sFilePrefixLength ) + ':' + QString::number( __LINE__ ) + " (" + __FUNCTION__ + "): " + str) );
47#endif
48
56{
57 public:
58
61 {
62 AttributeInitiatorClass = QNetworkRequest::User + 3000,
64 };
65
70
75 QgsNetworkRequestParameters( QNetworkAccessManager::Operation operation,
76 const QNetworkRequest &request,
77 int requestId,
78 const QByteArray &content = QByteArray() );
79
83 QNetworkAccessManager::Operation operation() const { return mOperation; }
84
91 QNetworkRequest request() const { return mRequest; }
92
96 QString originatingThreadId() const { return mOriginatingThreadId; }
97
101 int requestId() const { return mRequestId; }
102
107 QByteArray content() const { return mContent; }
108
117 QString initiatorClassName() const { return mInitiatorClass; }
118
128 QVariant initiatorRequestId() const { return mInitiatorRequestId; }
129
130 private:
131
132 QNetworkAccessManager::Operation mOperation;
133 QNetworkRequest mRequest;
134 QString mOriginatingThreadId;
135 int mRequestId = 0;
136 QByteArray mContent;
137 QString mInitiatorClass;
138 QVariant mInitiatorRequestId;
139};
140
142
143#ifndef SIP_RUN
144
173class CORE_EXPORT QgsSslErrorHandler
174{
175
176 public:
177
178 virtual ~QgsSslErrorHandler() = default;
179
190 virtual void handleSslErrors( QNetworkReply *reply, const QList<QSslError> &errors );
191
192};
193
218{
219
220 public:
221
223
232 virtual void handleAuthRequest( QNetworkReply *reply, QAuthenticator *auth );
233
239 virtual void handleAuthRequestOpenBrowser( const QUrl &url );
240
246 virtual void handleAuthRequestCloseBrowser();
247
248};
249#endif
250
251
269class CORE_EXPORT QgsNetworkAccessManager : public QNetworkAccessManager
270{
271 Q_OBJECT
272
273 public:
274
293 static QgsNetworkAccessManager *instance( Qt::ConnectionType connectionType = Qt::BlockingQueuedConnection );
294
295 QgsNetworkAccessManager( QObject *parent = nullptr );
296
297#ifndef SIP_RUN
298
315 void setSslErrorHandler( std::unique_ptr< QgsSslErrorHandler > handler );
316
333 void setAuthHandler( std::unique_ptr< QgsNetworkAuthenticationHandler > handler );
334#endif
335
344 void insertProxyFactory( QNetworkProxyFactory *factory SIP_TRANSFER );
345
352 void removeProxyFactory( QNetworkProxyFactory *factory SIP_TRANSFERBACK );
353
360 const QList<QNetworkProxyFactory *> proxyFactories() const;
361
370 const QNetworkProxy &fallbackProxy() const;
371
381 QStringList excludeList() const;
382
392 QStringList noProxyList() const;
393
405 void setFallbackProxyAndExcludes( const QNetworkProxy &proxy, const QStringList &excludes, const QStringList &noProxyURLs );
406
412 static QString cacheLoadControlName( QNetworkRequest::CacheLoadControl control );
413
419 static QNetworkRequest::CacheLoadControl cacheLoadControlFromName( const QString &name );
420
428 void setupDefaultProxyAndCache( Qt::ConnectionType connectionType = Qt::BlockingQueuedConnection );
429
430#ifndef SIP_RUN
431
439 bool cacheDisabled() const { return mCacheDisabled; }
440
451 void setCacheDisabled( bool disabled ) { mCacheDisabled = disabled; }
452#endif
453
457 bool useSystemProxy() const { return mUseSystemProxy; }
458
465 static int timeout();
466
474 static void setTimeout( int time );
475
496 static QgsNetworkReplyContent blockingGet( QNetworkRequest &request, const QString &authCfg = QString(), bool forceRefresh = false, QgsFeedback *feedback = nullptr );
497
518 static QgsNetworkReplyContent blockingPost( QNetworkRequest &request, const QByteArray &data, const QString &authCfg = QString(), bool forceRefresh = false, QgsFeedback *feedback = nullptr );
519
531#ifndef SIP_RUN
532 static QString setRequestPreprocessor( const std::function< void( QNetworkRequest *request )> &processor );
533#else
534 static QString setRequestPreprocessor( SIP_PYCALLABLE / AllowNone / );
535 % MethodCode
536 PyObject *s = 0;
537 Py_BEGIN_ALLOW_THREADS
538 Py_XINCREF( a0 );
539 QString id = QgsNetworkAccessManager::setRequestPreprocessor( [a0]( QNetworkRequest *arg )->QString
540 {
541 QString res;
542 SIP_BLOCK_THREADS
543 PyObject *s = sipCallMethod( NULL, a0, "D", arg, sipType_QNetworkRequest, NULL );
544 int state;
545 int sipIsError = 0;
546 QString *t1 = reinterpret_cast<QString *>( sipConvertToType( s, sipType_QString, 0, SIP_NOT_NONE, &state, &sipIsError ) );
547 if ( sipIsError == 0 )
548 {
549 res = QString( *t1 );
550 }
551 sipReleaseType( t1, sipType_QString, state );
552 SIP_UNBLOCK_THREADS
553 return res;
554 } );
555
556 s = sipConvertFromNewType( new QString( id ), sipType_QString, 0 );
557 Py_END_ALLOW_THREADS
558 return s;
559 % End
560#endif
561
572#ifndef SIP_RUN
573 static bool removeRequestPreprocessor( const QString &id );
574#else
575 static void removeRequestPreprocessor( const QString &id );
576 % MethodCode
578 {
579 PyErr_SetString( PyExc_KeyError, QStringLiteral( "No processor with id %1 exists." ).arg( *a0 ).toUtf8().constData() );
580 sipIsErr = 1;
581 }
582 % End
583#endif
584
596#ifndef SIP_RUN
597 static QString setReplyPreprocessor( const std::function<void ( const QNetworkRequest &, QNetworkReply * )> &processor );
598#else
599 static QString setReplyPreprocessor( SIP_PYCALLABLE / AllowNone / );
600 % MethodCode
601 PyObject *s = 0;
602 Py_BEGIN_ALLOW_THREADS
603 Py_XINCREF( a0 );
604 QString id = QgsNetworkAccessManager::setReplyPreprocessor( [a0]( const QNetworkRequest &request, QNetworkReply *reply )
605 {
606 SIP_BLOCK_THREADS
607 Py_XDECREF( sipCallMethod( NULL, a0, "ND", new QNetworkRequest( request ), sipType_QNetworkRequest, NULL, reply, sipType_QNetworkReply, NULL ) );
608 SIP_UNBLOCK_THREADS
609 } );
610
611 s = sipConvertFromNewType( new QString( id ), sipType_QString, 0 );
612 Py_END_ALLOW_THREADS
613 return s;
614 % End
615#endif
616
627#ifndef SIP_RUN
628 static bool removeReplyPreprocessor( const QString &id );
629#else
630 static void removeReplyPreprocessor( const QString &id );
631 % MethodCode
633 {
634 PyErr_SetString( PyExc_KeyError, QStringLiteral( "No processor with id %1 exists." ).arg( *a0 ).toUtf8().constData() );
635 sipIsErr = 1;
636 }
637 % End
638#endif
639
646 void requestAuthOpenBrowser( const QUrl &url ) const;
647
654 void requestAuthCloseBrowser() const;
655
662 void abortAuthBrowser();
663
664
665#ifndef SIP_RUN
667 static const inline QgsSettingsEntryInteger settingsNetworkTimeout = QgsSettingsEntryInteger( QStringLiteral( "networkTimeout" ), QgsSettings::Prefix::QGIS_NETWORKANDPROXY, 60000, QObject::tr( "Network timeout" ) );
668#endif
669
675 void preprocessRequest( QNetworkRequest *req ) const;
676
677 signals:
678
682 Q_DECL_DEPRECATED void requestAboutToBeCreated( QNetworkAccessManager::Operation, const QNetworkRequest &, QIODevice * ) SIP_DEPRECATED;
683
696
712
725
740 void downloadProgress( int requestId, qint64 bytesReceived, qint64 bytesTotal );
741
757 void requestRequiresAuth( int requestId, const QString &realm );
758
774 void requestAuthDetailsAdded( int requestId, const QString &realm, const QString &user, const QString &password );
775
776#ifndef QT_NO_SSL
777
792 void requestEncounteredSslErrors( int requestId, const QList<QSslError> &errors );
793
794#ifndef SIP_RUN
796 // these signals are for internal use only - it's not safe to connect by external code
797 void sslErrorsOccurred( QNetworkReply *, const QList<QSslError> &errors );
798 void sslErrorsHandled( QNetworkReply *reply );
800#endif
801
802#endif
803
807 Q_DECL_DEPRECATED void requestCreated( QNetworkReply * ) SIP_DEPRECATED;
808
809 void requestTimedOut( QNetworkReply * );
810
811#ifndef SIP_RUN
813 // these signals are for internal use only - it's not safe to connect by external code
814 void authRequestOccurred( QNetworkReply *, QAuthenticator *auth );
815 void authRequestHandled( QNetworkReply *reply );
817#endif
818
825
831 void cookiesChanged( const QList<QNetworkCookie> &cookies );
832
833 private slots:
834 void abortRequest();
835
836 void onReplyFinished( QNetworkReply *reply );
837
838 void onReplyDownloadProgress( qint64 bytesReceived, qint64 bytesTotal );
839#ifndef QT_NO_SSL
840 void onReplySslErrors( const QList<QSslError> &errors );
841
842 void handleSslErrors( QNetworkReply *reply, const QList<QSslError> &errors );
843#endif
844
845 void onAuthRequired( QNetworkReply *reply, QAuthenticator *auth );
846 void handleAuthRequest( QNetworkReply *reply, QAuthenticator *auth );
847
848 void syncCookies( const QList<QNetworkCookie> &cookies );
849
850 protected:
851 QNetworkReply *createRequest( QNetworkAccessManager::Operation op, const QNetworkRequest &req, QIODevice *outgoingData = nullptr ) override;
852
853 private:
854#ifndef QT_NO_SSL
855 void afterSslErrorHandled( QNetworkReply *reply );
856#endif
857
858 void afterAuthRequestHandled( QNetworkReply *reply );
859
860 void pauseTimeout( QNetworkReply *reply );
861 void restartTimeout( QNetworkReply *reply );
862 static int getRequestId( QNetworkReply *reply );
863
864 QList<QNetworkProxyFactory *> mProxyFactories;
865 QNetworkProxy mFallbackProxy;
866 QStringList mExcludedURLs;
867 QStringList mNoProxyURLs;
868 bool mUseSystemProxy = false;
869 bool mInitialized = false;
870 bool mCacheDisabled = false;
871 static QgsNetworkAccessManager *sMainNAM;
872 // ssl error handler, will be set for main thread ONLY
873 std::unique_ptr< QgsSslErrorHandler > mSslErrorHandler;
874 // Used by worker threads to wait for ssl error handler run in main thread
875 QSemaphore mSslErrorHandlerSemaphore;
876
877 // auth request handler, will be set for main thread ONLY
878 std::unique_ptr< QgsNetworkAuthenticationHandler > mAuthHandler;
879 // Used by worker threads to wait for authentication handler run in main thread
880 QSemaphore mAuthRequestHandlerSemaphore;
881};
882
883#endif // QGSNETWORKACCESSMANAGER_H
Base class for feedback objects to be used for cancellation of something running in a worker thread.
Definition: qgsfeedback.h:45
network access manager for QGIS
void finished(QgsNetworkReplyContent reply)
Emitted whenever a pending network reply is finished.
void cookiesChanged(const QList< QNetworkCookie > &cookies)
Emitted when the cookies changed.
void setCacheDisabled(bool disabled)
Sets whether all network caching should be disabled.
void downloadProgress(int requestId, qint64 bytesReceived, qint64 bytesTotal)
Emitted when a network reply receives a progress report.
void requestEncounteredSslErrors(int requestId, const QList< QSslError > &errors)
Emitted when a network request encounters SSL errors.
void requestTimedOut(QNetworkReply *)
void requestAboutToBeCreated(QgsNetworkRequestParameters request)
Emitted when a network request is about to be created.
static QString setReplyPreprocessor(const std::function< void(const QNetworkRequest &, QNetworkReply *)> &processor)
Sets a reply pre-processor function, which allows manipulation of QNetworkReply objects after they ar...
static bool removeRequestPreprocessor(const QString &id)
Removes the custom request pre-processor function with matching id.
void requestAuthDetailsAdded(int requestId, const QString &realm, const QString &user, const QString &password)
Emitted when network authentication details have been added to a request.
bool cacheDisabled() const
Returns true if all network caching is disabled.
void requestRequiresAuth(int requestId, const QString &realm)
Emitted when a network request prompts an authentication request.
static QString setRequestPreprocessor(const std::function< void(QNetworkRequest *request)> &processor)
Sets a request pre-processor function, which allows manipulation of a network request before it is pr...
Q_DECL_DEPRECATED void requestCreated(QNetworkReply *)
static bool removeReplyPreprocessor(const QString &id)
Removes the custom reply pre-processor function with matching id.
Q_DECL_DEPRECATED void requestAboutToBeCreated(QNetworkAccessManager::Operation, const QNetworkRequest &, QIODevice *)
void authBrowserAborted()
Emitted when external browser logins are to be aborted.
void requestTimedOut(QgsNetworkRequestParameters request)
Emitted when a network request has timed out.
bool useSystemProxy() const
Returns whether the system proxy should be used.
Network authentication handler, used for responding to network authentication requests during network...
virtual ~QgsNetworkAuthenticationHandler()=default
Encapsulates a network reply within a container which is inexpensive to copy and safe to pass between...
Encapsulates parameters and properties of a network request.
int requestId() const
Returns a unique ID identifying the request.
RequestAttributes
Custom request attributes.
@ AttributeInitiatorRequestId
Internal ID used by originator object to identify requests.
QgsNetworkRequestParameters()=default
Default constructor.
QNetworkAccessManager::Operation operation() const
Returns the request operation, e.g.
QNetworkRequest request() const
Returns the network request.
QString originatingThreadId() const
Returns a string identifying the thread which the request originated from.
QString initiatorClassName() const
Returns the class name of the object which initiated this request.
QByteArray content() const
Returns the request's content.
QVariant initiatorRequestId() const
Returns the internal ID used by the object which initiated this request to identify individual reques...
An integer settings entry.
static const char * QGIS_NETWORKANDPROXY
Definition: qgssettings.h:104
SSL error handler, used for responding to SSL errors encountered during network requests.
virtual ~QgsSslErrorHandler()=default
#define SIP_DEPRECATED
Definition: qgis_sip.h:106
#define SIP_TRANSFER
Definition: qgis_sip.h:36
#define SIP_TRANSFERBACK
Definition: qgis_sip.h:48
constexpr int sFilePrefixLength