QGIS API Documentation  3.27.0-Master (bef583a8ef)
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 
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
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 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
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