QGIS API Documentation  3.21.0-Master (56b4176581)
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 <memory>
33 
34 #include "qgis_core.h"
35 #include "qgis_sip.h"
36 #include "qgssettingsentry.h"
37 
38 class QgsFeedback;
39 
40 #ifndef SIP_RUN
41 #include "qgsconfig.h"
42 constexpr int sFilePrefixLength = CMAKE_SOURCE_DIR[sizeof( CMAKE_SOURCE_DIR ) - 1] == '/' ? sizeof( CMAKE_SOURCE_DIR ) + 1 : sizeof( CMAKE_SOURCE_DIR );
43 
44 #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__ + ")") );
45 #define QgsSetRequestInitiatorId(request, str) request.setAttribute( static_cast< QNetworkRequest::Attribute >( QgsNetworkRequestParameters::AttributeInitiatorRequestId ), QString(QString( __FILE__ ).mid( sFilePrefixLength ) + ':' + QString::number( __LINE__ ) + " (" + __FUNCTION__ + "): " + str) );
46 #endif
47 
54 class CORE_EXPORT QgsNetworkRequestParameters
55 {
56  public:
57 
60  {
61  AttributeInitiatorClass = QNetworkRequest::User + 3000,
63  };
64 
69 
74  QgsNetworkRequestParameters( QNetworkAccessManager::Operation operation,
75  const QNetworkRequest &request,
76  int requestId,
77  const QByteArray &content = QByteArray() );
78 
82  QNetworkAccessManager::Operation operation() const { return mOperation; }
83 
90  QNetworkRequest request() const { return mRequest; }
91 
95  QString originatingThreadId() const { return mOriginatingThreadId; }
96 
100  int requestId() const { return mRequestId; }
101 
106  QByteArray content() const { return mContent; }
107 
116  QString initiatorClassName() const { return mInitiatorClass; }
117 
127  QVariant initiatorRequestId() const { return mInitiatorRequestId; }
128 
129  private:
130 
131  QNetworkAccessManager::Operation mOperation;
132  QNetworkRequest mRequest;
133  QString mOriginatingThreadId;
134  int mRequestId = 0;
135  QByteArray mContent;
136  QString mInitiatorClass;
137  QVariant mInitiatorRequestId;
138 };
139 
141 
142 #ifndef SIP_RUN
143 
172 class CORE_EXPORT QgsSslErrorHandler
173 {
174 
175  public:
176 
177  virtual ~QgsSslErrorHandler() = default;
178 
189  virtual void handleSslErrors( QNetworkReply *reply, const QList<QSslError> &errors );
190 
191 };
192 
217 {
218 
219  public:
220 
221  virtual ~QgsNetworkAuthenticationHandler() = default;
222 
231  virtual void handleAuthRequest( QNetworkReply *reply, QAuthenticator *auth );
232 
238  virtual void handleAuthRequestOpenBrowser( const QUrl &url );
239 
245  virtual void handleAuthRequestCloseBrowser();
246 
247 };
248 #endif
249 
250 
268 class CORE_EXPORT QgsNetworkAccessManager : public QNetworkAccessManager
269 {
270  Q_OBJECT
271 
272  public:
273 
292  static QgsNetworkAccessManager *instance( Qt::ConnectionType connectionType = Qt::BlockingQueuedConnection );
293 
294  QgsNetworkAccessManager( QObject *parent = nullptr );
295 
296 #ifndef SIP_RUN
297 
314  void setSslErrorHandler( std::unique_ptr< QgsSslErrorHandler > handler );
315 
332  void setAuthHandler( std::unique_ptr< QgsNetworkAuthenticationHandler > handler );
333 #endif
334 
343  void insertProxyFactory( QNetworkProxyFactory *factory SIP_TRANSFER );
344 
351  void removeProxyFactory( QNetworkProxyFactory *factory SIP_TRANSFERBACK );
352 
359  const QList<QNetworkProxyFactory *> proxyFactories() const;
360 
369  const QNetworkProxy &fallbackProxy() const;
370 
380  QStringList excludeList() const;
381 
391  QStringList noProxyList() const;
392 
404  void setFallbackProxyAndExcludes( const QNetworkProxy &proxy, const QStringList &excludes, const QStringList &noProxyURLs );
405 
411  static QString cacheLoadControlName( QNetworkRequest::CacheLoadControl control );
412 
418  static QNetworkRequest::CacheLoadControl cacheLoadControlFromName( const QString &name );
419 
427  void setupDefaultProxyAndCache( Qt::ConnectionType connectionType = Qt::BlockingQueuedConnection );
428 
429 #ifndef SIP_RUN
430 
438  bool cacheDisabled() const { return mCacheDisabled; }
439 
450  void setCacheDisabled( bool disabled ) { mCacheDisabled = disabled; }
451 #endif
452 
456  bool useSystemProxy() const { return mUseSystemProxy; }
457 
464  static int timeout();
465 
473  static void setTimeout( int time );
474 
495  static QgsNetworkReplyContent blockingGet( QNetworkRequest &request, const QString &authCfg = QString(), bool forceRefresh = false, QgsFeedback *feedback = nullptr );
496 
517  static QgsNetworkReplyContent blockingPost( QNetworkRequest &request, const QByteArray &data, const QString &authCfg = QString(), bool forceRefresh = false, QgsFeedback *feedback = nullptr );
518 
530 #ifndef SIP_RUN
531  static QString setRequestPreprocessor( const std::function< void( QNetworkRequest *request )> &processor );
532 #else
533  static QString setRequestPreprocessor( SIP_PYCALLABLE / AllowNone / );
534  % MethodCode
535  PyObject *s = 0;
536  Py_BEGIN_ALLOW_THREADS
537  Py_XINCREF( a0 );
538  QString id = QgsNetworkAccessManager::setRequestPreprocessor( [a0]( QNetworkRequest *arg )->QString
539  {
540  QString res;
541  SIP_BLOCK_THREADS
542  PyObject *s = sipCallMethod( NULL, a0, "D", arg, sipType_QNetworkRequest, NULL );
543  int state;
544  int sipIsError = 0;
545  QString *t1 = reinterpret_cast<QString *>( sipConvertToType( s, sipType_QString, 0, SIP_NOT_NONE, &state, &sipIsError ) );
546  if ( sipIsError == 0 )
547  {
548  res = QString( *t1 );
549  }
550  sipReleaseType( t1, sipType_QString, state );
551  SIP_UNBLOCK_THREADS
552  return res;
553  } );
554 
555  s = sipConvertFromNewType( new QString( id ), sipType_QString, 0 );
556  Py_END_ALLOW_THREADS
557  return s;
558  % End
559 #endif
560 
571 #ifndef SIP_RUN
572  static bool removeRequestPreprocessor( const QString &id );
573 #else
574  static void removeRequestPreprocessor( const QString &id );
575  % MethodCode
577  {
578  PyErr_SetString( PyExc_KeyError, QStringLiteral( "No processor with id %1 exists." ).arg( *a0 ).toUtf8().constData() );
579  sipIsErr = 1;
580  }
581  % End
582 #endif
583 
590  void requestAuthOpenBrowser( const QUrl &url ) const;
591 
598  void requestAuthCloseBrowser() const;
599 
606  void abortAuthBrowser();
607 
608 
609 #ifndef SIP_RUN
611  static const inline QgsSettingsEntryInteger settingsNetworkTimeout = QgsSettingsEntryInteger( QStringLiteral( "/qgis/networkAndProxy/networkTimeout" ), QgsSettings::NoSection, 60000, QObject::tr( "Network timeout" ) );
612 #endif
613 
619  void preprocessRequest( QNetworkRequest *req ) const;
620 
621  signals:
622 
626  Q_DECL_DEPRECATED void requestAboutToBeCreated( QNetworkAccessManager::Operation, const QNetworkRequest &, QIODevice * ) SIP_DEPRECATED;
627 
640 
656 
669 
684  void downloadProgress( int requestId, qint64 bytesReceived, qint64 bytesTotal );
685 
701  void requestRequiresAuth( int requestId, const QString &realm );
702 
718  void requestAuthDetailsAdded( int requestId, const QString &realm, const QString &user, const QString &password );
719 
720 #ifndef QT_NO_SSL
721 
736  void requestEncounteredSslErrors( int requestId, const QList<QSslError> &errors );
737 
738 #ifndef SIP_RUN
740  // these signals are for internal use only - it's not safe to connect by external code
741  void sslErrorsOccurred( QNetworkReply *, const QList<QSslError> &errors );
742  void sslErrorsHandled( QNetworkReply *reply );
744 #endif
745 
746 #endif
747 
751  Q_DECL_DEPRECATED void requestCreated( QNetworkReply * ) SIP_DEPRECATED;
752 
753  void requestTimedOut( QNetworkReply * );
754 
755 #ifndef SIP_RUN
757  // these signals are for internal use only - it's not safe to connect by external code
758  void authRequestOccurred( QNetworkReply *, QAuthenticator *auth );
759  void authRequestHandled( QNetworkReply *reply );
761 #endif
762 
769 
775  void cookiesChanged( const QList<QNetworkCookie> &cookies );
776 
777  private slots:
778  void abortRequest();
779 
780  void onReplyFinished( QNetworkReply *reply );
781 
782  void onReplyDownloadProgress( qint64 bytesReceived, qint64 bytesTotal );
783 #ifndef QT_NO_SSL
784  void onReplySslErrors( const QList<QSslError> &errors );
785 
786  void handleSslErrors( QNetworkReply *reply, const QList<QSslError> &errors );
787 #endif
788 
789  void onAuthRequired( QNetworkReply *reply, QAuthenticator *auth );
790  void handleAuthRequest( QNetworkReply *reply, QAuthenticator *auth );
791 
792  void syncCookies( const QList<QNetworkCookie> &cookies );
793 
794  protected:
795  QNetworkReply *createRequest( QNetworkAccessManager::Operation op, const QNetworkRequest &req, QIODevice *outgoingData = nullptr ) override;
796 
797  private:
798 #ifndef QT_NO_SSL
799  void unlockAfterSslErrorHandled();
800  void afterSslErrorHandled( QNetworkReply *reply );
801 #endif
802 
803  void unlockAfterAuthRequestHandled();
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  // only in use by worker threads, unused in main thread
828  QMutex mAuthRequestHandlerMutex;
829  // only in use by worker threads, unused in main thread
830  QWaitCondition mAuthRequestWaitCondition;
831 };
832 
833 #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...
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