QGIS API Documentation 3.99.0-Master (d270888f95f)
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 <QString>
37#include <QStringList>
38#include <QWaitCondition>
39
40using namespace Qt::StringLiterals;
41
42class QgsFeedback;
44
52{
53 public:
54
57 {
58 AttributeInitiatorClass = QNetworkRequest::User + 3000,
60 };
61
63
68 QgsNetworkRequestParameters( QNetworkAccessManager::Operation operation,
69 const QNetworkRequest &request,
70 int requestId,
71 const QByteArray &content = QByteArray() );
72
76 QNetworkAccessManager::Operation operation() const { return mOperation; }
77
84 QNetworkRequest request() const { return mRequest; }
85
89 QString originatingThreadId() const { return mOriginatingThreadId; }
90
94 int requestId() const { return mRequestId; }
95
100 QByteArray content() const { return mContent; }
101
110 QString initiatorClassName() const { return mInitiatorClass; }
111
121 QVariant initiatorRequestId() const { return mInitiatorRequestId; }
122
123 private:
124
125 QNetworkAccessManager::Operation mOperation = QNetworkAccessManager::Operation::UnknownOperation;
126 QNetworkRequest mRequest;
127 QString mOriginatingThreadId;
128 int mRequestId = 0;
129 QByteArray mContent;
130 QString mInitiatorClass;
131 QVariant mInitiatorRequestId;
132};
133
135
136#ifndef SIP_RUN
137
166class CORE_EXPORT QgsSslErrorHandler
167{
168
169 public:
170
171 virtual ~QgsSslErrorHandler() = default;
172
183 virtual void handleSslErrors( QNetworkReply *reply, const QList<QSslError> &errors );
184
185};
186
211{
212
213 public:
214
216
225 virtual void handleAuthRequest( QNetworkReply *reply, QAuthenticator *auth );
226
232 virtual void handleAuthRequestOpenBrowser( const QUrl &url );
233
239 virtual void handleAuthRequestCloseBrowser();
240
241};
242#endif
243
244
260class CORE_EXPORT QgsNetworkAccessManager : public QNetworkAccessManager
261{
262 Q_OBJECT
263
264 public:
265
284 static QgsNetworkAccessManager *instance( Qt::ConnectionType connectionType = Qt::BlockingQueuedConnection );
285
286 QgsNetworkAccessManager( QObject *parent = nullptr );
287
288#ifndef SIP_RUN
289
306 void setSslErrorHandler( std::unique_ptr< QgsSslErrorHandler > handler );
307
324 void setAuthHandler( std::unique_ptr< QgsNetworkAuthenticationHandler > handler );
325#endif
326
335 void insertProxyFactory( QNetworkProxyFactory *factory SIP_TRANSFER );
336
343 void removeProxyFactory( QNetworkProxyFactory *factory SIP_TRANSFERBACK );
344
351 const QList<QNetworkProxyFactory *> proxyFactories() const;
352
361 const QNetworkProxy &fallbackProxy() const;
362
372 QStringList excludeList() const;
373
383 QStringList noProxyList() const;
384
396 void setFallbackProxyAndExcludes( const QNetworkProxy &proxy, const QStringList &excludes, const QStringList &noProxyURLs );
397
403 static QString cacheLoadControlName( QNetworkRequest::CacheLoadControl control );
404
410 static QNetworkRequest::CacheLoadControl cacheLoadControlFromName( const QString &name );
411
419 void setupDefaultProxyAndCache( Qt::ConnectionType connectionType = Qt::BlockingQueuedConnection );
420
421#ifndef SIP_RUN
422
430 bool cacheDisabled() const { return mCacheDisabled; }
431
442 void setCacheDisabled( bool disabled ) { mCacheDisabled = disabled; }
443#endif
444
448 bool useSystemProxy() const { return mUseSystemProxy; }
449
456 static int timeout();
457
465 static void setTimeout( int time );
466
489 static QgsNetworkReplyContent blockingGet( QNetworkRequest &request, const QString &authCfg = QString(), bool forceRefresh = false, QgsFeedback *feedback = nullptr, Qgis::NetworkRequestFlags flags = Qgis::NetworkRequestFlags() );
490
513 static QgsNetworkReplyContent blockingPost( QNetworkRequest &request, const QByteArray &data, const QString &authCfg = QString(), bool forceRefresh = false, QgsFeedback *feedback = nullptr, Qgis::NetworkRequestFlags flags = Qgis::NetworkRequestFlags() );
514
526#ifndef SIP_RUN
527 static QString setRequestPreprocessor( const std::function< void( QNetworkRequest *request )> &processor );
528#else
529 static QString setRequestPreprocessor( SIP_PYCALLABLE / AllowNone / );
530 % MethodCode
531 PyObject *s = 0;
532 QString id;
533 Py_XINCREF( a0 );
534 Py_BEGIN_ALLOW_THREADS
535 id = QgsNetworkAccessManager::setRequestPreprocessor( [a0]( QNetworkRequest *arg )->QString
536 {
537 QString res;
538 SIP_BLOCK_THREADS
539 PyObject *s = sipCallMethod( NULL, a0, "D", arg, sipType_QNetworkRequest, NULL );
540 int state;
541 int sipIsError = 0;
542 QString *t1 = reinterpret_cast<QString *>( sipConvertToType( s, sipType_QString, 0, SIP_NOT_NONE, &state, &sipIsError ) );
543 if ( sipIsError == 0 )
544 {
545 res = QString( *t1 );
546 }
547 sipReleaseType( t1, sipType_QString, state );
548 SIP_UNBLOCK_THREADS
549 return res;
550 } );
551 Py_END_ALLOW_THREADS
552
553 s = sipConvertFromNewType( new QString( id ), sipType_QString, 0 );
554 return s;
555 % End
556#endif
557
568#ifndef SIP_RUN
569 static bool removeRequestPreprocessor( const QString &id );
570#else
571 static void removeRequestPreprocessor( const QString &id );
572 % MethodCode
574 {
575 PyErr_SetString( PyExc_KeyError, u"No processor with id %1 exists."_s.arg( *a0 ).toUtf8().constData() );
576 sipIsErr = 1;
577 }
578 % End
579#endif
580
596#ifndef SIP_RUN
597 static QString setAdvancedRequestPreprocessor( const std::function< void( QNetworkRequest *, int &op, QByteArray *data )> &processor );
598#else
599 static QString setAdvancedRequestPreprocessor( SIP_PYCALLABLE / AllowNone / );
600 % MethodCode
601 PyObject *s = 0;
602 QString id;
603 Py_XINCREF( a0 );
604 Py_BEGIN_ALLOW_THREADS
605 id = QgsNetworkAccessManager::setAdvancedRequestPreprocessor( [a0]( QNetworkRequest *reqArg, int &op, QByteArray *data )
606 {
607 SIP_BLOCK_THREADS
608
609 PyObject *requestObj = sipConvertFromType( reqArg, sipType_QNetworkRequest, NULL );
610 PyObject *postDataObj = sipConvertFromType( new QByteArray( *data ), sipType_QByteArray, Py_None );
611
612 PyObject *result = sipCallMethod( NULL, a0, "RiR", requestObj, op, postDataObj );
613
614 Py_XDECREF( requestObj );
615 Py_XDECREF( postDataObj );
616
617 if ( result && PyTuple_Check( result ) && PyTuple_Size( result ) == 2 )
618 {
619 // Extract modified operation
620 PyObject *opObj = PyTuple_GetItem( result, 0 );
621 if ( opObj && PyLong_Check( opObj ) )
622 {
623 op = static_cast<int>( PyLong_AsLong( opObj ) );
624 }
625 PyObject *dataObj = PyTuple_GetItem( result, 1 );
626 if ( dataObj && dataObj != Py_None )
627 {
628 int dataState;
629 int sipIsErr = 0;
630 QByteArray *modifiedData = reinterpret_cast<QByteArray *>( sipConvertToType( dataObj, sipType_QByteArray, 0, SIP_NOT_NONE, &dataState, &sipIsErr ) );
631 if ( sipIsErr == 0 )
632 {
633 data->clear();
634 data->append( *modifiedData );
635 sipReleaseType( modifiedData, sipType_QByteArray, dataState );
636 }
637 }
638 }
639
640 Py_XDECREF( result );
641 SIP_UNBLOCK_THREADS
642 } );
643 Py_END_ALLOW_THREADS
644
645 s = sipConvertFromNewType( new QString( id ), sipType_QString, 0 );
646 return s;
647 % End
648#endif
649
660#ifndef SIP_RUN
661 static bool removeAdvancedRequestPreprocessor( const QString &id );
662#else
663 static void removeAdvancedRequestPreprocessor( const QString &id );
664 % MethodCode
666 {
667 PyErr_SetString( PyExc_KeyError, u"No processor with id %1 exists."_s.arg( *a0 ).toUtf8().constData() );
668 sipIsErr = 1;
669 }
670 % End
671#endif
672
673
685#ifndef SIP_RUN
686 static QString setReplyPreprocessor( const std::function<void ( const QNetworkRequest &, QNetworkReply * )> &processor );
687#else
688 static QString setReplyPreprocessor( SIP_PYCALLABLE / AllowNone / );
689 % MethodCode
690 PyObject *s = 0;
691 QString id;
692 Py_XINCREF( a0 );
693 Py_BEGIN_ALLOW_THREADS
694 id = QgsNetworkAccessManager::setReplyPreprocessor( [a0]( const QNetworkRequest &request, QNetworkReply *reply )
695 {
696 SIP_BLOCK_THREADS
697 Py_XDECREF( sipCallMethod( NULL, a0, "ND", new QNetworkRequest( request ), sipType_QNetworkRequest, NULL, reply, sipType_QNetworkReply, NULL ) );
698 SIP_UNBLOCK_THREADS
699 } );
700
701 Py_END_ALLOW_THREADS
702 s = sipConvertFromNewType( new QString( id ), sipType_QString, 0 );
703 return s;
704 % End
705#endif
706
717#ifndef SIP_RUN
718 static bool removeReplyPreprocessor( const QString &id );
719#else
720 static void removeReplyPreprocessor( const QString &id );
721 % MethodCode
723 {
724 PyErr_SetString( PyExc_KeyError, u"No processor with id %1 exists."_s.arg( *a0 ).toUtf8().constData() );
725 sipIsErr = 1;
726 }
727 % End
728#endif
729
736 void requestAuthOpenBrowser( const QUrl &url ) const;
737
744 void requestAuthCloseBrowser() const;
745
752 void abortAuthBrowser();
753
754
755#ifndef SIP_RUN
758#endif
759
765 void preprocessRequest( QNetworkRequest *req ) const;
766
767 signals:
768
772 Q_DECL_DEPRECATED void requestAboutToBeCreated( QNetworkAccessManager::Operation operation, const QNetworkRequest &request, QIODevice *device ) SIP_DEPRECATED;
773
787
801
817
830
845 void downloadProgress( int requestId, qint64 bytesReceived, qint64 bytesTotal );
846
862 void requestRequiresAuth( int requestId, const QString &realm );
863
879 void requestAuthDetailsAdded( int requestId, const QString &realm, const QString &user, const QString &password );
880
881#ifndef QT_NO_SSL
882
897 void requestEncounteredSslErrors( int requestId, const QList<QSslError> &errors );
898
899#ifndef SIP_RUN
901 // these signals are for internal use only - it's not safe to connect by external code
902 void sslErrorsOccurred( QNetworkReply *, const QList<QSslError> &errors );
903 void sslErrorsHandled( QNetworkReply *reply );
905#endif
906
907#endif
908
912 Q_DECL_DEPRECATED void requestCreated( QNetworkReply *reply ) SIP_DEPRECATED;
913
917 void requestTimedOut( QNetworkReply *reply );
918
919#ifndef SIP_RUN
921 // these signals are for internal use only - it's not safe to connect by external code
922 void authRequestOccurred( QNetworkReply *, QAuthenticator *auth );
923 void authRequestHandled( QNetworkReply *reply );
925#endif
926
933
938
939 void cookiesChanged( const QList<QNetworkCookie> &cookies );
940
941 private slots:
942 void abortRequest();
943
944 void onReplyFinished( QNetworkReply *reply );
945
946 void onReplyDownloadProgress( qint64 bytesReceived, qint64 bytesTotal );
947#ifndef QT_NO_SSL
948 void onReplySslErrors( const QList<QSslError> &errors );
949
950 void handleSslErrors( QNetworkReply *reply, const QList<QSslError> &errors );
951#endif
952
953 void onAuthRequired( QNetworkReply *reply, QAuthenticator *auth );
954 void handleAuthRequest( QNetworkReply *reply, QAuthenticator *auth );
955
956 void syncCookies( const QList<QNetworkCookie> &cookies );
957
958 protected:
959 QNetworkReply *createRequest( QNetworkAccessManager::Operation op, const QNetworkRequest &req, QIODevice *outgoingData = nullptr ) override;
960
961 private:
962#ifndef QT_NO_SSL
963 void afterSslErrorHandled( QNetworkReply *reply );
964#endif
965
966 void afterAuthRequestHandled( QNetworkReply *reply );
967
968 void pauseTimeout( QNetworkReply *reply );
969 void restartTimeout( QNetworkReply *reply );
970 static int getRequestId( QNetworkReply *reply );
971
972 QList<QNetworkProxyFactory *> mProxyFactories;
973 QNetworkProxy mFallbackProxy;
974 QStringList mExcludedURLs;
975 QStringList mNoProxyURLs;
976 bool mUseSystemProxy = false;
977 bool mInitialized = false;
978 bool mCacheDisabled = false;
979 static QgsNetworkAccessManager *sMainNAM;
980 // ssl error handler, will be set for main thread ONLY
981 std::unique_ptr< QgsSslErrorHandler > mSslErrorHandler;
982 // Used by worker threads to wait for ssl error handler run in main thread
983 QSemaphore mSslErrorHandlerSemaphore;
984
985 // auth request handler, will be set for main thread ONLY
986 std::unique_ptr< QgsNetworkAuthenticationHandler > mAuthHandler;
987 // Used by worker threads to wait for authentication handler run in main thread
988 QSemaphore mAuthRequestHandlerSemaphore;
989
991};
992
993#endif // QGSNETWORKACCESSMANAGER_H
QFlags< NetworkRequestFlag > NetworkRequestFlags
Flags controlling behavior of network requests.
Definition qgis.h:184
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