QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
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"
37 #include "qgssettingsentryimpl.h"
38 
39 class QgsFeedback;
40 
41 #ifndef SIP_RUN
42 #include "qgsconfig.h"
43 constexpr 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 
55 class CORE_EXPORT QgsNetworkRequestParameters
56 {
57  public:
58 
61  {
62  AttributeInitiatorClass = QNetworkRequest::User + 3000,
64  };
65 
69  QgsNetworkRequestParameters() = default;
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 
173 class 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 
222  virtual ~QgsNetworkAuthenticationHandler() = default;
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 
269 class 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
666  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 
695  void requestAboutToBeCreated( QgsNetworkRequestParameters request );
696 
711  void finished( QgsNetworkReplyContent reply );
712 
724  void requestTimedOut( QgsNetworkRequestParameters request );
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
795  // 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
812  // 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 
824  void authBrowserAborted();
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 unlockAfterSslErrorHandled();
856  void afterSslErrorHandled( QNetworkReply *reply );
857 #endif
858 
859  void afterAuthRequestHandled( QNetworkReply *reply );
860 
861  void pauseTimeout( QNetworkReply *reply );
862  void restartTimeout( QNetworkReply *reply );
863  static int getRequestId( QNetworkReply *reply );
864 
865  QList<QNetworkProxyFactory *> mProxyFactories;
866  QNetworkProxy mFallbackProxy;
867  QStringList mExcludedURLs;
868  QStringList mNoProxyURLs;
869  bool mUseSystemProxy = false;
870  bool mInitialized = false;
871  bool mCacheDisabled = false;
872  static QgsNetworkAccessManager *sMainNAM;
873  // ssl error handler, will be set for main thread ONLY
874  std::unique_ptr< QgsSslErrorHandler > mSslErrorHandler;
875  // only in use by worker threads, unused in main thread
876  QMutex mSslErrorHandlerMutex;
877  // only in use by worker threads, unused in main thread
878  QWaitCondition mSslErrorWaitCondition;
879 
880  // auth request handler, will be set for main thread ONLY
881  std::unique_ptr< QgsNetworkAuthenticationHandler > mAuthHandler;
882  // Used by worker threads to wait for authentication handler run in main thread
883  QSemaphore mAuthRequestHandlerSemaphore;
884 };
885 
886 #endif // QGSNETWORKACCESSMANAGER_H
QgsNetworkAccessManager::setReplyPreprocessor
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...
Definition: qgsnetworkaccessmanager.cpp:831
QgsNetworkRequestParameters::requestId
int requestId() const
Returns a unique ID identifying the request.
Definition: qgsnetworkaccessmanager.h:101
QgsNetworkAuthenticationHandler
Network authentication handler, used for responding to network authentication requests during network...
Definition: qgsnetworkaccessmanager.h:217
QgsNetworkRequestParameters::request
QNetworkRequest request() const
Returns the network request.
Definition: qgsnetworkaccessmanager.h:91
QgsNetworkRequestParameters::content
QByteArray content() const
Returns the request's content.
Definition: qgsnetworkaccessmanager.h:107
QgsNetworkRequestParameters::initiatorClassName
QString initiatorClassName() const
Returns the class name of the object which initiated this request.
Definition: qgsnetworkaccessmanager.h:117
QgsNetworkRequestParameters::RequestAttributes
RequestAttributes
Custom request attributes.
Definition: qgsnetworkaccessmanager.h:60
QgsSettingsEntryInteger
An integer settings entry.
Definition: qgssettingsentryimpl.h:299
SIP_TRANSFERBACK
#define SIP_TRANSFERBACK
Definition: qgis_sip.h:48
QgsSettings::Prefix::QGIS_NETWORKANDPROXY
static const char * QGIS_NETWORKANDPROXY
Definition: qgssettings.h:104
QgsNetworkAccessManager::setRequestPreprocessor
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...
Definition: qgsnetworkaccessmanager.cpp:814
SIP_DEPRECATED
#define SIP_DEPRECATED
Definition: qgis_sip.h:106
QgsSslErrorHandler
SSL error handler, used for responding to SSL errors encountered during network requests.
Definition: qgsnetworkaccessmanager.h:173
QgsNetworkRequestParameters
Encapsulates parameters and properties of a network request.
Definition: qgsnetworkaccessmanager.h:55
QgsNetworkRequestParameters::AttributeInitiatorRequestId
@ AttributeInitiatorRequestId
Internal ID used by originator object to identify requests.
Definition: qgsnetworkaccessmanager.h:63
QgsNetworkAccessManager::removeReplyPreprocessor
static bool removeReplyPreprocessor(const QString &id)
Removes the custom reply pre-processor function with matching id.
Definition: qgsnetworkaccessmanager.cpp:838
QgsFeedback
Base class for feedback objects to be used for cancellation of something running in a worker thread.
Definition: qgsfeedback.h:44
QgsNetworkAccessManager::removeRequestPreprocessor
static bool removeRequestPreprocessor(const QString &id)
Removes the custom request pre-processor function with matching id.
Definition: qgsnetworkaccessmanager.cpp:821
QgsNetworkAccessManager::setCacheDisabled
void setCacheDisabled(bool disabled)
Sets whether all network caching should be disabled.
Definition: qgsnetworkaccessmanager.h:451
qgis_sip.h
SIP_TRANSFER
#define SIP_TRANSFER
Definition: qgis_sip.h:36
QgsNetworkRequestParameters::initiatorRequestId
QVariant initiatorRequestId() const
Returns the internal ID used by the object which initiated this request to identify individual reques...
Definition: qgsnetworkaccessmanager.h:128
qgssettingsentryimpl.h
QgsNetworkAccessManager
network access manager for QGIS
Definition: qgsnetworkaccessmanager.h:269
sFilePrefixLength
constexpr int sFilePrefixLength
Definition: qgsnetworkaccessmanager.h:43
qgsnetworkreply.h
QgsNetworkReplyContent
Encapsulates a network reply within a container which is inexpensive to copy and safe to pass between...
Definition: qgsnetworkreply.h:28
QgsNetworkRequestParameters::originatingThreadId
QString originatingThreadId() const
Returns a string identifying the thread which the request originated from.
Definition: qgsnetworkaccessmanager.h:96
QgsNetworkRequestParameters::operation
QNetworkAccessManager::Operation operation() const
Returns the request operation, e.g.
Definition: qgsnetworkaccessmanager.h:83
QgsNetworkAccessManager::cacheDisabled
bool cacheDisabled() const
Returns true if all network caching is disabled.
Definition: qgsnetworkaccessmanager.h:439
QgsNetworkAccessManager::useSystemProxy
bool useSystemProxy() const
Returns whether the system proxy should be used.
Definition: qgsnetworkaccessmanager.h:457