QGIS API Documentation 3.99.0-Master (26c88405ac0)
Loading...
Searching...
No Matches
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 <memory>
22
23#include "qgis.h"
24#include "qgis_core.h"
25#include "qgis_sip.h"
26#include "qgsnetworkreply.h"
27
28#include <QList>
29#include <QMutex>
30#include <QNetworkAccessManager>
31#include <QNetworkCookie>
32#include <QNetworkCookieJar>
33#include <QNetworkProxy>
34#include <QNetworkRequest>
35#include <QSemaphore>
36#include <QStringList>
37#include <QWaitCondition>
38
39class QgsFeedback;
41
49{
50 public:
51
54 {
55 AttributeInitiatorClass = QNetworkRequest::User + 3000,
57 };
58
60
65 QgsNetworkRequestParameters( QNetworkAccessManager::Operation operation,
66 const QNetworkRequest &request,
67 int requestId,
68 const QByteArray &content = QByteArray() );
69
73 QNetworkAccessManager::Operation operation() const { return mOperation; }
74
81 QNetworkRequest request() const { return mRequest; }
82
86 QString originatingThreadId() const { return mOriginatingThreadId; }
87
91 int requestId() const { return mRequestId; }
92
97 QByteArray content() const { return mContent; }
98
107 QString initiatorClassName() const { return mInitiatorClass; }
108
118 QVariant initiatorRequestId() const { return mInitiatorRequestId; }
119
120 private:
121
122 QNetworkAccessManager::Operation mOperation = QNetworkAccessManager::Operation::UnknownOperation;
123 QNetworkRequest mRequest;
124 QString mOriginatingThreadId;
125 int mRequestId = 0;
126 QByteArray mContent;
127 QString mInitiatorClass;
128 QVariant mInitiatorRequestId;
129};
130
132
133#ifndef SIP_RUN
134
163class CORE_EXPORT QgsSslErrorHandler
164{
165
166 public:
167
168 virtual ~QgsSslErrorHandler() = default;
169
180 virtual void handleSslErrors( QNetworkReply *reply, const QList<QSslError> &errors );
181
182};
183
208{
209
210 public:
211
213
222 virtual void handleAuthRequest( QNetworkReply *reply, QAuthenticator *auth );
223
229 virtual void handleAuthRequestOpenBrowser( const QUrl &url );
230
236 virtual void handleAuthRequestCloseBrowser();
237
238};
239#endif
240
241
257class CORE_EXPORT QgsNetworkAccessManager : public QNetworkAccessManager
258{
259 Q_OBJECT
260
261 public:
262
281 static QgsNetworkAccessManager *instance( Qt::ConnectionType connectionType = Qt::BlockingQueuedConnection );
282
283 QgsNetworkAccessManager( QObject *parent = nullptr );
284
285#ifndef SIP_RUN
286
303 void setSslErrorHandler( std::unique_ptr< QgsSslErrorHandler > handler );
304
321 void setAuthHandler( std::unique_ptr< QgsNetworkAuthenticationHandler > handler );
322#endif
323
332 void insertProxyFactory( QNetworkProxyFactory *factory SIP_TRANSFER );
333
340 void removeProxyFactory( QNetworkProxyFactory *factory SIP_TRANSFERBACK );
341
348 const QList<QNetworkProxyFactory *> proxyFactories() const;
349
358 const QNetworkProxy &fallbackProxy() const;
359
369 QStringList excludeList() const;
370
380 QStringList noProxyList() const;
381
393 void setFallbackProxyAndExcludes( const QNetworkProxy &proxy, const QStringList &excludes, const QStringList &noProxyURLs );
394
400 static QString cacheLoadControlName( QNetworkRequest::CacheLoadControl control );
401
407 static QNetworkRequest::CacheLoadControl cacheLoadControlFromName( const QString &name );
408
416 void setupDefaultProxyAndCache( Qt::ConnectionType connectionType = Qt::BlockingQueuedConnection );
417
418#ifndef SIP_RUN
419
427 bool cacheDisabled() const { return mCacheDisabled; }
428
439 void setCacheDisabled( bool disabled ) { mCacheDisabled = disabled; }
440#endif
441
445 bool useSystemProxy() const { return mUseSystemProxy; }
446
453 static int timeout();
454
462 static void setTimeout( int time );
463
486 static QgsNetworkReplyContent blockingGet( QNetworkRequest &request, const QString &authCfg = QString(), bool forceRefresh = false, QgsFeedback *feedback = nullptr, Qgis::NetworkRequestFlags flags = Qgis::NetworkRequestFlags() );
487
510 static QgsNetworkReplyContent blockingPost( QNetworkRequest &request, const QByteArray &data, const QString &authCfg = QString(), bool forceRefresh = false, QgsFeedback *feedback = nullptr, Qgis::NetworkRequestFlags flags = Qgis::NetworkRequestFlags() );
511
523#ifndef SIP_RUN
524 static QString setRequestPreprocessor( const std::function< void( QNetworkRequest *request )> &processor );
525#else
526 static QString setRequestPreprocessor( SIP_PYCALLABLE / AllowNone / );
527 % MethodCode
528 PyObject *s = 0;
529 QString id;
530 Py_XINCREF( a0 );
531 Py_BEGIN_ALLOW_THREADS
532 id = QgsNetworkAccessManager::setRequestPreprocessor( [a0]( QNetworkRequest *arg )->QString
533 {
534 QString res;
535 SIP_BLOCK_THREADS
536 PyObject *s = sipCallMethod( NULL, a0, "D", arg, sipType_QNetworkRequest, NULL );
537 int state;
538 int sipIsError = 0;
539 QString *t1 = reinterpret_cast<QString *>( sipConvertToType( s, sipType_QString, 0, SIP_NOT_NONE, &state, &sipIsError ) );
540 if ( sipIsError == 0 )
541 {
542 res = QString( *t1 );
543 }
544 sipReleaseType( t1, sipType_QString, state );
545 SIP_UNBLOCK_THREADS
546 return res;
547 } );
548 Py_END_ALLOW_THREADS
549
550 s = sipConvertFromNewType( new QString( id ), sipType_QString, 0 );
551 return s;
552 % End
553#endif
554
565#ifndef SIP_RUN
566 static bool removeRequestPreprocessor( const QString &id );
567#else
568 static void removeRequestPreprocessor( const QString &id );
569 % MethodCode
571 {
572 PyErr_SetString( PyExc_KeyError, QStringLiteral( "No processor with id %1 exists." ).arg( *a0 ).toUtf8().constData() );
573 sipIsErr = 1;
574 }
575 % End
576#endif
577
593#ifndef SIP_RUN
594 static QString setAdvancedRequestPreprocessor( const std::function< void( QNetworkRequest *, int &op, QByteArray *data )> &processor );
595#else
596 static QString setAdvancedRequestPreprocessor( SIP_PYCALLABLE / AllowNone / );
597 % MethodCode
598 PyObject *s = 0;
599 QString id;
600 Py_XINCREF( a0 );
601 Py_BEGIN_ALLOW_THREADS
602 id = QgsNetworkAccessManager::setAdvancedRequestPreprocessor( [a0]( QNetworkRequest *reqArg, int &op, QByteArray *data )
603 {
604 SIP_BLOCK_THREADS
605
606 PyObject *requestObj = sipConvertFromType( reqArg, sipType_QNetworkRequest, NULL );
607 PyObject *postDataObj = sipConvertFromType( new QByteArray( *data ), sipType_QByteArray, Py_None );
608
609 PyObject *result = sipCallMethod( NULL, a0, "RiR", requestObj, op, postDataObj );
610
611 Py_XDECREF( requestObj );
612 Py_XDECREF( postDataObj );
613
614 if ( result && PyTuple_Check( result ) && PyTuple_Size( result ) == 2 )
615 {
616 // Extract modified operation
617 PyObject *opObj = PyTuple_GetItem( result, 0 );
618 if ( opObj && PyLong_Check( opObj ) )
619 {
620 op = static_cast<int>( PyLong_AsLong( opObj ) );
621 }
622 PyObject *dataObj = PyTuple_GetItem( result, 1 );
623 if ( dataObj && dataObj != Py_None )
624 {
625 int dataState;
626 int sipIsErr = 0;
627 QByteArray *modifiedData = reinterpret_cast<QByteArray *>( sipConvertToType( dataObj, sipType_QByteArray, 0, SIP_NOT_NONE, &dataState, &sipIsErr ) );
628 if ( sipIsErr == 0 )
629 {
630 data->clear();
631 data->append( *modifiedData );
632 sipReleaseType( modifiedData, sipType_QByteArray, dataState );
633 }
634 }
635 }
636
637 Py_XDECREF( result );
638 SIP_UNBLOCK_THREADS
639 } );
640 Py_END_ALLOW_THREADS
641
642 s = sipConvertFromNewType( new QString( id ), sipType_QString, 0 );
643 return s;
644 % End
645#endif
646
657#ifndef SIP_RUN
658 static bool removeAdvancedRequestPreprocessor( const QString &id );
659#else
660 static void removeAdvancedRequestPreprocessor( const QString &id );
661 % MethodCode
663 {
664 PyErr_SetString( PyExc_KeyError, QStringLiteral( "No processor with id %1 exists." ).arg( *a0 ).toUtf8().constData() );
665 sipIsErr = 1;
666 }
667 % End
668#endif
669
670
682#ifndef SIP_RUN
683 static QString setReplyPreprocessor( const std::function<void ( const QNetworkRequest &, QNetworkReply * )> &processor );
684#else
685 static QString setReplyPreprocessor( SIP_PYCALLABLE / AllowNone / );
686 % MethodCode
687 PyObject *s = 0;
688 QString id;
689 Py_XINCREF( a0 );
690 Py_BEGIN_ALLOW_THREADS
691 id = QgsNetworkAccessManager::setReplyPreprocessor( [a0]( const QNetworkRequest &request, QNetworkReply *reply )
692 {
693 SIP_BLOCK_THREADS
694 Py_XDECREF( sipCallMethod( NULL, a0, "ND", new QNetworkRequest( request ), sipType_QNetworkRequest, NULL, reply, sipType_QNetworkReply, NULL ) );
695 SIP_UNBLOCK_THREADS
696 } );
697
698 Py_END_ALLOW_THREADS
699 s = sipConvertFromNewType( new QString( id ), sipType_QString, 0 );
700 return s;
701 % End
702#endif
703
714#ifndef SIP_RUN
715 static bool removeReplyPreprocessor( const QString &id );
716#else
717 static void removeReplyPreprocessor( const QString &id );
718 % MethodCode
720 {
721 PyErr_SetString( PyExc_KeyError, QStringLiteral( "No processor with id %1 exists." ).arg( *a0 ).toUtf8().constData() );
722 sipIsErr = 1;
723 }
724 % End
725#endif
726
733 void requestAuthOpenBrowser( const QUrl &url ) const;
734
741 void requestAuthCloseBrowser() const;
742
749 void abortAuthBrowser();
750
751
752#ifndef SIP_RUN
755#endif
756
762 void preprocessRequest( QNetworkRequest *req ) const;
763
764 signals:
765
769 Q_DECL_DEPRECATED void requestAboutToBeCreated( QNetworkAccessManager::Operation operation, const QNetworkRequest &request, QIODevice *device ) SIP_DEPRECATED;
770
784
798
814
827
842 void downloadProgress( int requestId, qint64 bytesReceived, qint64 bytesTotal );
843
859 void requestRequiresAuth( int requestId, const QString &realm );
860
876 void requestAuthDetailsAdded( int requestId, const QString &realm, const QString &user, const QString &password );
877
878#ifndef QT_NO_SSL
879
894 void requestEncounteredSslErrors( int requestId, const QList<QSslError> &errors );
895
896#ifndef SIP_RUN
898 // these signals are for internal use only - it's not safe to connect by external code
899 void sslErrorsOccurred( QNetworkReply *, const QList<QSslError> &errors );
900 void sslErrorsHandled( QNetworkReply *reply );
902#endif
903
904#endif
905
909 Q_DECL_DEPRECATED void requestCreated( QNetworkReply *reply ) SIP_DEPRECATED;
910
914 void requestTimedOut( QNetworkReply *reply );
915
916#ifndef SIP_RUN
918 // these signals are for internal use only - it's not safe to connect by external code
919 void authRequestOccurred( QNetworkReply *, QAuthenticator *auth );
920 void authRequestHandled( QNetworkReply *reply );
922#endif
923
930
935
936 void cookiesChanged( const QList<QNetworkCookie> &cookies );
937
938 private slots:
939 void abortRequest();
940
941 void onReplyFinished( QNetworkReply *reply );
942
943 void onReplyDownloadProgress( qint64 bytesReceived, qint64 bytesTotal );
944#ifndef QT_NO_SSL
945 void onReplySslErrors( const QList<QSslError> &errors );
946
947 void handleSslErrors( QNetworkReply *reply, const QList<QSslError> &errors );
948#endif
949
950 void onAuthRequired( QNetworkReply *reply, QAuthenticator *auth );
951 void handleAuthRequest( QNetworkReply *reply, QAuthenticator *auth );
952
953 void syncCookies( const QList<QNetworkCookie> &cookies );
954
955 protected:
956 QNetworkReply *createRequest( QNetworkAccessManager::Operation op, const QNetworkRequest &req, QIODevice *outgoingData = nullptr ) override;
957
958 private:
959#ifndef QT_NO_SSL
960 void afterSslErrorHandled( QNetworkReply *reply );
961#endif
962
963 void afterAuthRequestHandled( QNetworkReply *reply );
964
965 void pauseTimeout( QNetworkReply *reply );
966 void restartTimeout( QNetworkReply *reply );
967 static int getRequestId( QNetworkReply *reply );
968
969 QList<QNetworkProxyFactory *> mProxyFactories;
970 QNetworkProxy mFallbackProxy;
971 QStringList mExcludedURLs;
972 QStringList mNoProxyURLs;
973 bool mUseSystemProxy = false;
974 bool mInitialized = false;
975 bool mCacheDisabled = false;
976 static QgsNetworkAccessManager *sMainNAM;
977 // ssl error handler, will be set for main thread ONLY
978 std::unique_ptr< QgsSslErrorHandler > mSslErrorHandler;
979 // Used by worker threads to wait for ssl error handler run in main thread
980 QSemaphore mSslErrorHandlerSemaphore;
981
982 // auth request handler, will be set for main thread ONLY
983 std::unique_ptr< QgsNetworkAuthenticationHandler > mAuthHandler;
984 // Used by worker threads to wait for authentication handler run in main thread
985 QSemaphore mAuthRequestHandlerSemaphore;
986
988};
989
990#endif // QGSNETWORKACCESSMANAGER_H
QFlags< NetworkRequestFlag > NetworkRequestFlags
Flags controlling behavior of network requests.
Definition qgis.h:181
Base class for feedback objects to be used for cancellation of something running in a worker thread.
Definition qgsfeedback.h:44
QNetworkAccessManager with additional QGIS specific logic.
QStringList noProxyList() const
Returns the no proxy list.
void finished(QgsNetworkReplyContent reply)
Emitted whenever a pending network reply is finished.
static const QgsSettingsEntryInteger * settingsNetworkTimeout
Settings entry network timeout.
void cookiesChanged(const QList< QNetworkCookie > &cookies)
Emitted when the cookies changed.
void insertProxyFactory(QNetworkProxyFactory *factory)
Inserts a factory into the proxy factories list.
void setSslErrorHandler(std::unique_ptr< QgsSslErrorHandler > handler)
Sets the application SSL error handler, which is used to respond to SSL errors encountered during net...
Q_DECL_DEPRECATED void requestAboutToBeCreated(QNetworkAccessManager::Operation operation, const QNetworkRequest &request, QIODevice *device)
void setCacheDisabled(bool disabled)
Sets whether all network caching should be disabled.
const QList< QNetworkProxyFactory * > proxyFactories() const
Returns a list of proxy factories used by the manager.
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.
static QString cacheLoadControlName(QNetworkRequest::CacheLoadControl control)
Returns the name for QNetworkRequest::CacheLoadControl.
void requestAboutToBeCreated(QgsNetworkRequestParameters request)
Emitted when a network request is about to be created.
void requestCreated(const QgsNetworkRequestParameters &request)
Emitted when a network request has been 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.
void requestTimedOut(QNetworkReply *reply)
Emitted when a request times out.
static QNetworkRequest::CacheLoadControl cacheLoadControlFromName(const QString &name)
Returns QNetworkRequest::CacheLoadControl from a name.
bool cacheDisabled() const
Returns true if all network caching is disabled.
static bool removeAdvancedRequestPreprocessor(const QString &id)
Removes an advanced request pre-processor function with matching id.
QgsNetworkAccessManager(QObject *parent=nullptr)
void requestRequiresAuth(int requestId, const QString &realm)
Emitted when a network request prompts an authentication request.
void preprocessRequest(QNetworkRequest *req) const
Preprocesses request.
void setAuthHandler(std::unique_ptr< QgsNetworkAuthenticationHandler > handler)
Sets the application network authentication handler, which is used to respond to network authenticati...
static QString setAdvancedRequestPreprocessor(const std::function< void(QNetworkRequest *, int &op, QByteArray *data)> &processor)
Sets an advanced request pre-processor function, which allows manipulation of a network request befor...
const QNetworkProxy & fallbackProxy() const
Returns the fallback proxy used by the manager.
void setupDefaultProxyAndCache(Qt::ConnectionType connectionType=Qt::BlockingQueuedConnection)
Setup the QgsNetworkAccessManager (NAM) according to the user's settings.
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...
void setFallbackProxyAndExcludes(const QNetworkProxy &proxy, const QStringList &excludes, const QStringList &noProxyURLs)
Sets the fallback proxy and URLs which shouldn't use it.
static bool removeReplyPreprocessor(const QString &id)
Removes the custom reply pre-processor function with matching id.
Q_DECL_DEPRECATED void requestCreated(QNetworkReply *reply)
QStringList excludeList() const
Returns the proxy exclude list.
static QgsNetworkAccessManager * instance(Qt::ConnectionType connectionType=Qt::BlockingQueuedConnection)
Returns a pointer to the active QgsNetworkAccessManager for the current thread.
void removeProxyFactory(QNetworkProxyFactory *factory)
Removes a factory from the proxy factories list.
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.
QNetworkReply * createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest &req, QIODevice *outgoingData=nullptr) override
Network authentication handler, used for responding to network authentication requests during network...
virtual ~QgsNetworkAuthenticationHandler()=default
virtual void handleAuthRequest(QNetworkReply *reply, QAuthenticator *auth)
Called whenever network authentication requests are encountered during a network reply.
virtual void handleAuthRequestCloseBrowser()
Called to terminate a network authentication through external browser.
virtual void handleAuthRequestOpenBrowser(const QUrl &url)
Called to initiate a network authentication through external browser url.
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.
@ AttributeInitiatorClass
Class name of original object which created the request.
@ AttributeInitiatorRequestId
Internal ID used by originator object to identify requests.
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
virtual void handleSslErrors(QNetworkReply *reply, const QList< QSslError > &errors)
Called whenever SSL errors are encountered during a network reply.
#define SIP_DEPRECATED
Definition qgis_sip.h:114
#define SIP_TRANSFER
Definition qgis_sip.h:36
#define SIP_TRANSFERBACK
Definition qgis_sip.h:48