QGIS API Documentation 4.1.0-Master (5bf3c20f3c9)
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:
61
63
68 QgsNetworkRequestParameters( QNetworkAccessManager::Operation operation, const QNetworkRequest &request, int requestId, 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 QNetworkAccessManager::Operation mOperation = QNetworkAccessManager::Operation::UnknownOperation;
122 QNetworkRequest mRequest;
123 QString mOriginatingThreadId;
124 int mRequestId = 0;
125 QByteArray mContent;
126 QString mInitiatorClass;
127 QVariant mInitiatorRequestId;
128};
129
131
132#ifndef SIP_RUN
133
162class CORE_EXPORT QgsSslErrorHandler
163{
164 public:
165 virtual ~QgsSslErrorHandler() = default;
166
177 virtual void handleSslErrors( QNetworkReply *reply, const QList<QSslError> &errors );
178};
179
204{
205 public:
207
216 virtual void handleAuthRequest( QNetworkReply *reply, QAuthenticator *auth );
217
223 virtual void handleAuthRequestOpenBrowser( const QUrl &url );
224
230 virtual void handleAuthRequestCloseBrowser();
231};
232#endif
233
234
250class CORE_EXPORT QgsNetworkAccessManager : public QNetworkAccessManager
251{
252 Q_OBJECT
253
254 public:
273 static QgsNetworkAccessManager *instance( Qt::ConnectionType connectionType = Qt::BlockingQueuedConnection );
274
275 QgsNetworkAccessManager( QObject *parent = nullptr );
276
277#ifndef SIP_RUN
278
295 void setSslErrorHandler( std::unique_ptr< QgsSslErrorHandler > handler );
296
313 void setAuthHandler( std::unique_ptr< QgsNetworkAuthenticationHandler > handler );
314#endif
315
324 void insertProxyFactory( QNetworkProxyFactory *factory SIP_TRANSFER );
325
332 void removeProxyFactory( QNetworkProxyFactory *factory SIP_TRANSFERBACK );
333
340 const QList<QNetworkProxyFactory *> proxyFactories() const;
341
350 const QNetworkProxy &fallbackProxy() const;
351
361 QStringList excludeList() const;
362
372 QStringList noProxyList() const;
373
385 void setFallbackProxyAndExcludes( const QNetworkProxy &proxy, const QStringList &excludes, const QStringList &noProxyURLs );
386
392 static QString cacheLoadControlName( QNetworkRequest::CacheLoadControl control );
393
399 static QNetworkRequest::CacheLoadControl cacheLoadControlFromName( const QString &name );
400
408 void setupDefaultProxyAndCache( Qt::ConnectionType connectionType = Qt::BlockingQueuedConnection );
409
410#ifndef SIP_RUN
411
419 bool cacheDisabled() const { return mCacheDisabled; }
420
431 void setCacheDisabled( bool disabled ) { mCacheDisabled = disabled; }
432#endif
433
437 bool useSystemProxy() const { return mUseSystemProxy; }
438
445 static int timeout();
446
454 static void setTimeout( int time );
455
478 static QgsNetworkReplyContent blockingGet(
479 QNetworkRequest &request, const QString &authCfg = QString(), bool forceRefresh = false, QgsFeedback *feedback = nullptr, Qgis::NetworkRequestFlags flags = Qgis::NetworkRequestFlags()
480 );
481
504 static QgsNetworkReplyContent blockingPost(
505 QNetworkRequest &request,
506 const QByteArray &data,
507 const QString &authCfg = QString(),
508 bool forceRefresh = false,
509 QgsFeedback *feedback = nullptr,
511 );
512
524#ifndef SIP_RUN
525 static QString setRequestPreprocessor( const std::function< void( QNetworkRequest *request )> &processor );
526#else
527 // clang-format off
528 static QString setRequestPreprocessor( SIP_PYCALLABLE / AllowNone / );
529 % MethodCode
530 PyObject *s = 0;
531 QString id;
532 Py_XINCREF( a0 );
533 Py_BEGIN_ALLOW_THREADS
534 id = QgsNetworkAccessManager::setRequestPreprocessor( [a0]( QNetworkRequest *arg )->QString
535 {
536 QString res;
537 SIP_BLOCK_THREADS
538 PyObject *s = sipCallMethod( NULL, a0, "D", arg, sipType_QNetworkRequest, NULL );
539 int state;
540 int sipIsError = 0;
541 QString *t1 = reinterpret_cast<QString *>( sipConvertToType( s, sipType_QString, 0, SIP_NOT_NONE, &state, &sipIsError ) );
542 if ( sipIsError == 0 )
543 {
544 res = QString( *t1 );
545 }
546 sipReleaseType( t1, sipType_QString, state );
547 SIP_UNBLOCK_THREADS
548 return res;
549 } );
550 Py_END_ALLOW_THREADS
551
552 s = sipConvertFromNewType( new QString( id ), sipType_QString, 0 );
553 return s;
554 % End
555// clang-format on
556#endif
557
568#ifndef SIP_RUN
569 static bool removeRequestPreprocessor( const QString &id );
570#else
571 // clang-format off
572 static void removeRequestPreprocessor( const QString &id );
573 % MethodCode
575 {
576 PyErr_SetString( PyExc_KeyError, u"No processor with id %1 exists."_s.arg( *a0 ).toUtf8().constData() );
577 sipIsErr = 1;
578 }
579 % End
580// clang-format on
581#endif
582
598#ifndef SIP_RUN
599 static QString setAdvancedRequestPreprocessor( const std::function< void( QNetworkRequest *, int &op, QByteArray *data )> &processor );
600#else
601 // clang-format off
602 static QString setAdvancedRequestPreprocessor( SIP_PYCALLABLE / AllowNone / );
603 % MethodCode
604 PyObject *s = 0;
605 QString id;
606 Py_XINCREF( a0 );
607 Py_BEGIN_ALLOW_THREADS
608 id = QgsNetworkAccessManager::setAdvancedRequestPreprocessor( [a0]( QNetworkRequest *reqArg, int &op, QByteArray *data )
609 {
610 SIP_BLOCK_THREADS
611
612 PyObject *requestObj = sipConvertFromType( reqArg, sipType_QNetworkRequest, NULL );
613 PyObject *postDataObj = sipConvertFromType( new QByteArray( *data ), sipType_QByteArray, Py_None );
614
615 PyObject *result = sipCallMethod( NULL, a0, "RiR", requestObj, op, postDataObj );
616
617 Py_XDECREF( requestObj );
618 Py_XDECREF( postDataObj );
619
620 if ( result && PyTuple_Check( result ) && PyTuple_Size( result ) == 2 )
621 {
622 // Extract modified operation
623 PyObject *opObj = PyTuple_GetItem( result, 0 );
624 if ( opObj && PyLong_Check( opObj ) )
625 {
626 op = static_cast<int>( PyLong_AsLong( opObj ) );
627 }
628 PyObject *dataObj = PyTuple_GetItem( result, 1 );
629 if ( dataObj && dataObj != Py_None )
630 {
631 int dataState;
632 int sipIsErr = 0;
633 QByteArray *modifiedData = reinterpret_cast<QByteArray *>( sipConvertToType( dataObj, sipType_QByteArray, 0, SIP_NOT_NONE, &dataState, &sipIsErr ) );
634 if ( sipIsErr == 0 )
635 {
636 data->clear();
637 data->append( *modifiedData );
638 sipReleaseType( modifiedData, sipType_QByteArray, dataState );
639 }
640 }
641 }
642
643 Py_XDECREF( result );
644 SIP_UNBLOCK_THREADS
645 } );
646 Py_END_ALLOW_THREADS
647
648 s = sipConvertFromNewType( new QString( id ), sipType_QString, 0 );
649 return s;
650 % End
651// clang-format on
652#endif
653
664#ifndef SIP_RUN
665 static bool removeAdvancedRequestPreprocessor( const QString &id );
666#else
667 // clang-format off
668 static void removeAdvancedRequestPreprocessor( const QString &id );
669 % MethodCode
671 {
672 PyErr_SetString( PyExc_KeyError, u"No processor with id %1 exists."_s.arg( *a0 ).toUtf8().constData() );
673 sipIsErr = 1;
674 }
675 % End
676// clang-format on
677#endif
678
679
691#ifndef SIP_RUN
692 static QString setReplyPreprocessor( const std::function<void( const QNetworkRequest &, QNetworkReply * )> &processor );
693#else
694 // clang-format off
695 static QString setReplyPreprocessor( SIP_PYCALLABLE / AllowNone / );
696 % MethodCode
697 PyObject *s = 0;
698 QString id;
699 Py_XINCREF( a0 );
700 Py_BEGIN_ALLOW_THREADS
701 id = QgsNetworkAccessManager::setReplyPreprocessor( [a0]( const QNetworkRequest &request, QNetworkReply *reply )
702 {
703 SIP_BLOCK_THREADS
704 Py_XDECREF( sipCallMethod( NULL, a0, "ND", new QNetworkRequest( request ), sipType_QNetworkRequest, NULL, reply, sipType_QNetworkReply, NULL ) );
705 SIP_UNBLOCK_THREADS
706 } );
707
708 Py_END_ALLOW_THREADS
709 s = sipConvertFromNewType( new QString( id ), sipType_QString, 0 );
710 return s;
711 % End
712// clang-format on
713#endif
714
725#ifndef SIP_RUN
726 static bool removeReplyPreprocessor( const QString &id );
727#else
728 // clang-format off
729 static void removeReplyPreprocessor( const QString &id );
730 % MethodCode
732 {
733 PyErr_SetString( PyExc_KeyError, u"No processor with id %1 exists."_s.arg( *a0 ).toUtf8().constData() );
734 sipIsErr = 1;
735 }
736 % End
737// clang-format on
738#endif
739
746 void requestAuthOpenBrowser( const QUrl &url ) const;
747
754 void requestAuthCloseBrowser() const;
755
762 void abortAuthBrowser();
763
764
765#ifndef SIP_RUN
768#endif
769
775 void preprocessRequest( QNetworkRequest *req ) const;
776
777 signals:
778
782 Q_DECL_DEPRECATED void requestAboutToBeCreated( QNetworkAccessManager::Operation operation, const QNetworkRequest &request, QIODevice *device ) SIP_DEPRECATED;
783
797
811
827
840
855 void downloadProgress( int requestId, qint64 bytesReceived, qint64 bytesTotal );
856
872 void requestRequiresAuth( int requestId, const QString &realm );
873
889 void requestAuthDetailsAdded( int requestId, const QString &realm, const QString &user, const QString &password );
890
891#ifndef QT_NO_SSL
892
907 void requestEncounteredSslErrors( int requestId, const QList<QSslError> &errors );
908
909#ifndef SIP_RUN
911 // these signals are for internal use only - it's not safe to connect by external code
912 void sslErrorsOccurred( QNetworkReply *, const QList<QSslError> &errors );
913 void sslErrorsHandled( QNetworkReply *reply );
915#endif
916
917#endif
918
922 Q_DECL_DEPRECATED void requestCreated( QNetworkReply *reply ) SIP_DEPRECATED;
923
927 void requestTimedOut( QNetworkReply *reply );
928
929#ifndef SIP_RUN
931 // these signals are for internal use only - it's not safe to connect by external code
932 void authRequestOccurred( QNetworkReply *, QAuthenticator *auth );
933 void authRequestHandled( QNetworkReply *reply );
935#endif
936
943
948
949 void cookiesChanged( const QList<QNetworkCookie> &cookies );
950
951 private slots:
952 void abortRequest();
953
954 void onReplyFinished( QNetworkReply *reply );
955
956 void onReplyDownloadProgress( qint64 bytesReceived, qint64 bytesTotal );
957#ifndef QT_NO_SSL
958 void onReplySslErrors( const QList<QSslError> &errors );
959
960 void handleSslErrors( QNetworkReply *reply, const QList<QSslError> &errors );
961#endif
962
963 void onAuthRequired( QNetworkReply *reply, QAuthenticator *auth );
964 void handleAuthRequest( QNetworkReply *reply, QAuthenticator *auth );
965
966 void syncCookies( const QList<QNetworkCookie> &cookies );
967
968 protected:
969 QNetworkReply *createRequest( QNetworkAccessManager::Operation op, const QNetworkRequest &req, QIODevice *outgoingData = nullptr ) override;
970
971 private:
972#ifndef QT_NO_SSL
973 void afterSslErrorHandled( QNetworkReply *reply );
974#endif
975
976 void afterAuthRequestHandled( QNetworkReply *reply );
977
978 void pauseTimeout( QNetworkReply *reply );
979 void restartTimeout( QNetworkReply *reply );
980 static int getRequestId( QNetworkReply *reply );
981
982 QList<QNetworkProxyFactory *> mProxyFactories;
983 QNetworkProxy mFallbackProxy;
984 QStringList mExcludedURLs;
985 QStringList mNoProxyURLs;
986 bool mUseSystemProxy = false;
987 bool mInitialized = false;
988 bool mCacheDisabled = false;
989 static QgsNetworkAccessManager *sMainNAM;
990 // ssl error handler, will be set for main thread ONLY
991 std::unique_ptr< QgsSslErrorHandler > mSslErrorHandler;
992 // Used by worker threads to wait for ssl error handler run in main thread
993 QSemaphore mSslErrorHandlerSemaphore;
994
995 // auth request handler, will be set for main thread ONLY
996 std::unique_ptr< QgsNetworkAuthenticationHandler > mAuthHandler;
997 // Used by worker threads to wait for authentication handler run in main thread
998 QSemaphore mAuthRequestHandlerSemaphore;
999
1001};
1002
1003#endif // QGSNETWORKACCESSMANAGER_H
QFlags< NetworkRequestFlag > NetworkRequestFlags
Flags controlling behavior of network requests.
Definition qgis.h:197
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.
@ AttributeOriginalHeaders
Internal ID used to store original request headers, used when checking against previously cached resp...
@ 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:113
#define SIP_TRANSFER
Definition qgis_sip.h:35
#define SIP_TRANSFERBACK
Definition qgis_sip.h:47