QGIS API Documentation  3.23.0-Master (7c4a6de034)
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 "qgssettingsentry.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 
591  void requestAuthOpenBrowser( const QUrl &url ) const;
592 
599  void requestAuthCloseBrowser() const;
600 
607  void abortAuthBrowser();
608 
609 
610 #ifndef SIP_RUN
612  static const inline QgsSettingsEntryInteger settingsNetworkTimeout = QgsSettingsEntryInteger( QStringLiteral( "/qgis/networkAndProxy/networkTimeout" ), QgsSettings::NoSection, 60000, QObject::tr( "Network timeout" ) );
613 #endif
614 
620  void preprocessRequest( QNetworkRequest *req ) const;
621 
622  signals:
623 
627  Q_DECL_DEPRECATED void requestAboutToBeCreated( QNetworkAccessManager::Operation, const QNetworkRequest &, QIODevice * ) SIP_DEPRECATED;
628 
641 
657 
670 
685  void downloadProgress( int requestId, qint64 bytesReceived, qint64 bytesTotal );
686 
702  void requestRequiresAuth( int requestId, const QString &realm );
703 
719  void requestAuthDetailsAdded( int requestId, const QString &realm, const QString &user, const QString &password );
720 
721 #ifndef QT_NO_SSL
722 
737  void requestEncounteredSslErrors( int requestId, const QList<QSslError> &errors );
738 
739 #ifndef SIP_RUN
741  // these signals are for internal use only - it's not safe to connect by external code
742  void sslErrorsOccurred( QNetworkReply *, const QList<QSslError> &errors );
743  void sslErrorsHandled( QNetworkReply *reply );
745 #endif
746 
747 #endif
748 
752  Q_DECL_DEPRECATED void requestCreated( QNetworkReply * ) SIP_DEPRECATED;
753 
754  void requestTimedOut( QNetworkReply * );
755 
756 #ifndef SIP_RUN
758  // these signals are for internal use only - it's not safe to connect by external code
759  void authRequestOccurred( QNetworkReply *, QAuthenticator *auth );
760  void authRequestHandled( QNetworkReply *reply );
762 #endif
763 
770 
776  void cookiesChanged( const QList<QNetworkCookie> &cookies );
777 
778  private slots:
779  void abortRequest();
780 
781  void onReplyFinished( QNetworkReply *reply );
782 
783  void onReplyDownloadProgress( qint64 bytesReceived, qint64 bytesTotal );
784 #ifndef QT_NO_SSL
785  void onReplySslErrors( const QList<QSslError> &errors );
786 
787  void handleSslErrors( QNetworkReply *reply, const QList<QSslError> &errors );
788 #endif
789 
790  void onAuthRequired( QNetworkReply *reply, QAuthenticator *auth );
791  void handleAuthRequest( QNetworkReply *reply, QAuthenticator *auth );
792 
793  void syncCookies( const QList<QNetworkCookie> &cookies );
794 
795  protected:
796  QNetworkReply *createRequest( QNetworkAccessManager::Operation op, const QNetworkRequest &req, QIODevice *outgoingData = nullptr ) override;
797 
798  private:
799 #ifndef QT_NO_SSL
800  void unlockAfterSslErrorHandled();
801  void afterSslErrorHandled( QNetworkReply *reply );
802 #endif
803 
804  void afterAuthRequestHandled( QNetworkReply *reply );
805 
806  void pauseTimeout( QNetworkReply *reply );
807  void restartTimeout( QNetworkReply *reply );
808  static int getRequestId( QNetworkReply *reply );
809 
810  QList<QNetworkProxyFactory *> mProxyFactories;
811  QNetworkProxy mFallbackProxy;
812  QStringList mExcludedURLs;
813  QStringList mNoProxyURLs;
814  bool mUseSystemProxy = false;
815  bool mInitialized = false;
816  bool mCacheDisabled = false;
817  static QgsNetworkAccessManager *sMainNAM;
818  // ssl error handler, will be set for main thread ONLY
819  std::unique_ptr< QgsSslErrorHandler > mSslErrorHandler;
820  // only in use by worker threads, unused in main thread
821  QMutex mSslErrorHandlerMutex;
822  // only in use by worker threads, unused in main thread
823  QWaitCondition mSslErrorWaitCondition;
824 
825  // auth request handler, will be set for main thread ONLY
826  std::unique_ptr< QgsNetworkAuthenticationHandler > mAuthHandler;
827  // Used by worker threads to wait for authentication handler run in main thread
828  QSemaphore mAuthRequestHandlerSemaphore;
829 };
830 
831 #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 bool removeRequestPreprocessor(const QString &id)
Removes the custom 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 *)
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.
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