QGIS API Documentation 4.1.0-Master (60fea48833c)
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:
56 {
57 AttributeInitiatorClass = QNetworkRequest::User + 3000,
59 };
60
62
67 QgsNetworkRequestParameters( QNetworkAccessManager::Operation operation, const QNetworkRequest &request, int requestId, const QByteArray &content = QByteArray() );
68
72 QNetworkAccessManager::Operation operation() const { return mOperation; }
73
80 QNetworkRequest request() const { return mRequest; }
81
85 QString originatingThreadId() const { return mOriginatingThreadId; }
86
90 int requestId() const { return mRequestId; }
91
96 QByteArray content() const { return mContent; }
97
106 QString initiatorClassName() const { return mInitiatorClass; }
107
117 QVariant initiatorRequestId() const { return mInitiatorRequestId; }
118
119 private:
120 QNetworkAccessManager::Operation mOperation = QNetworkAccessManager::Operation::UnknownOperation;
121 QNetworkRequest mRequest;
122 QString mOriginatingThreadId;
123 int mRequestId = 0;
124 QByteArray mContent;
125 QString mInitiatorClass;
126 QVariant mInitiatorRequestId;
127};
128
130
131#ifndef SIP_RUN
132
161class CORE_EXPORT QgsSslErrorHandler
162{
163 public:
164 virtual ~QgsSslErrorHandler() = default;
165
176 virtual void handleSslErrors( QNetworkReply *reply, const QList<QSslError> &errors );
177};
178
203{
204 public:
206
215 virtual void handleAuthRequest( QNetworkReply *reply, QAuthenticator *auth );
216
222 virtual void handleAuthRequestOpenBrowser( const QUrl &url );
223
229 virtual void handleAuthRequestCloseBrowser();
230};
231#endif
232
233
249class CORE_EXPORT QgsNetworkAccessManager : public QNetworkAccessManager
250{
251 Q_OBJECT
252
253 public:
272 static QgsNetworkAccessManager *instance( Qt::ConnectionType connectionType = Qt::BlockingQueuedConnection );
273
274 QgsNetworkAccessManager( QObject *parent = nullptr );
275
276#ifndef SIP_RUN
277
294 void setSslErrorHandler( std::unique_ptr< QgsSslErrorHandler > handler );
295
312 void setAuthHandler( std::unique_ptr< QgsNetworkAuthenticationHandler > handler );
313#endif
314
323 void insertProxyFactory( QNetworkProxyFactory *factory SIP_TRANSFER );
324
331 void removeProxyFactory( QNetworkProxyFactory *factory SIP_TRANSFERBACK );
332
339 const QList<QNetworkProxyFactory *> proxyFactories() const;
340
349 const QNetworkProxy &fallbackProxy() const;
350
360 QStringList excludeList() const;
361
371 QStringList noProxyList() const;
372
384 void setFallbackProxyAndExcludes( const QNetworkProxy &proxy, const QStringList &excludes, const QStringList &noProxyURLs );
385
391 static QString cacheLoadControlName( QNetworkRequest::CacheLoadControl control );
392
398 static QNetworkRequest::CacheLoadControl cacheLoadControlFromName( const QString &name );
399
407 void setupDefaultProxyAndCache( Qt::ConnectionType connectionType = Qt::BlockingQueuedConnection );
408
409#ifndef SIP_RUN
410
418 bool cacheDisabled() const { return mCacheDisabled; }
419
430 void setCacheDisabled( bool disabled ) { mCacheDisabled = disabled; }
431#endif
432
436 bool useSystemProxy() const { return mUseSystemProxy; }
437
444 static int timeout();
445
453 static void setTimeout( int time );
454
477 static QgsNetworkReplyContent blockingGet(
478 QNetworkRequest &request, const QString &authCfg = QString(), bool forceRefresh = false, QgsFeedback *feedback = nullptr, Qgis::NetworkRequestFlags flags = Qgis::NetworkRequestFlags()
479 );
480
503 static QgsNetworkReplyContent blockingPost(
504 QNetworkRequest &request,
505 const QByteArray &data,
506 const QString &authCfg = QString(),
507 bool forceRefresh = false,
508 QgsFeedback *feedback = nullptr,
510 );
511
523#ifndef SIP_RUN
524 static QString setRequestPreprocessor( const std::function< void( QNetworkRequest *request )> &processor );
525#else
526 // clang-format off
527 static QString setRequestPreprocessor( SIP_PYCALLABLE / AllowNone / );
528 % MethodCode
529 PyObject *s = 0;
530 QString id;
531 Py_XINCREF( a0 );
532 Py_BEGIN_ALLOW_THREADS
533 id = QgsNetworkAccessManager::setRequestPreprocessor( [a0]( QNetworkRequest *arg )->QString
534 {
535 QString res;
536 SIP_BLOCK_THREADS
537 PyObject *s = sipCallMethod( NULL, a0, "D", arg, sipType_QNetworkRequest, NULL );
538 int state;
539 int sipIsError = 0;
540 QString *t1 = reinterpret_cast<QString *>( sipConvertToType( s, sipType_QString, 0, SIP_NOT_NONE, &state, &sipIsError ) );
541 if ( sipIsError == 0 )
542 {
543 res = QString( *t1 );
544 }
545 sipReleaseType( t1, sipType_QString, state );
546 SIP_UNBLOCK_THREADS
547 return res;
548 } );
549 Py_END_ALLOW_THREADS
550
551 s = sipConvertFromNewType( new QString( id ), sipType_QString, 0 );
552 return s;
553 % End
554// clang-format on
555#endif
556
567#ifndef SIP_RUN
568 static bool removeRequestPreprocessor( const QString &id );
569#else
570 // clang-format off
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// clang-format on
580#endif
581
597#ifndef SIP_RUN
598 static QString setAdvancedRequestPreprocessor( const std::function< void( QNetworkRequest *, int &op, QByteArray *data )> &processor );
599#else
600 // clang-format off
601 static QString setAdvancedRequestPreprocessor( SIP_PYCALLABLE / AllowNone / );
602 % MethodCode
603 PyObject *s = 0;
604 QString id;
605 Py_XINCREF( a0 );
606 Py_BEGIN_ALLOW_THREADS
607 id = QgsNetworkAccessManager::setAdvancedRequestPreprocessor( [a0]( QNetworkRequest *reqArg, int &op, QByteArray *data )
608 {
609 SIP_BLOCK_THREADS
610
611 PyObject *requestObj = sipConvertFromType( reqArg, sipType_QNetworkRequest, NULL );
612 PyObject *postDataObj = sipConvertFromType( new QByteArray( *data ), sipType_QByteArray, Py_None );
613
614 PyObject *result = sipCallMethod( NULL, a0, "RiR", requestObj, op, postDataObj );
615
616 Py_XDECREF( requestObj );
617 Py_XDECREF( postDataObj );
618
619 if ( result && PyTuple_Check( result ) && PyTuple_Size( result ) == 2 )
620 {
621 // Extract modified operation
622 PyObject *opObj = PyTuple_GetItem( result, 0 );
623 if ( opObj && PyLong_Check( opObj ) )
624 {
625 op = static_cast<int>( PyLong_AsLong( opObj ) );
626 }
627 PyObject *dataObj = PyTuple_GetItem( result, 1 );
628 if ( dataObj && dataObj != Py_None )
629 {
630 int dataState;
631 int sipIsErr = 0;
632 QByteArray *modifiedData = reinterpret_cast<QByteArray *>( sipConvertToType( dataObj, sipType_QByteArray, 0, SIP_NOT_NONE, &dataState, &sipIsErr ) );
633 if ( sipIsErr == 0 )
634 {
635 data->clear();
636 data->append( *modifiedData );
637 sipReleaseType( modifiedData, sipType_QByteArray, dataState );
638 }
639 }
640 }
641
642 Py_XDECREF( result );
643 SIP_UNBLOCK_THREADS
644 } );
645 Py_END_ALLOW_THREADS
646
647 s = sipConvertFromNewType( new QString( id ), sipType_QString, 0 );
648 return s;
649 % End
650// clang-format on
651#endif
652
663#ifndef SIP_RUN
664 static bool removeAdvancedRequestPreprocessor( const QString &id );
665#else
666 // clang-format off
667 static void removeAdvancedRequestPreprocessor( const QString &id );
668 % MethodCode
670 {
671 PyErr_SetString( PyExc_KeyError, u"No processor with id %1 exists."_s.arg( *a0 ).toUtf8().constData() );
672 sipIsErr = 1;
673 }
674 % End
675// clang-format on
676#endif
677
678
690#ifndef SIP_RUN
691 static QString setReplyPreprocessor( const std::function<void( const QNetworkRequest &, QNetworkReply * )> &processor );
692#else
693 // clang-format off
694 static QString setReplyPreprocessor( SIP_PYCALLABLE / AllowNone / );
695 % MethodCode
696 PyObject *s = 0;
697 QString id;
698 Py_XINCREF( a0 );
699 Py_BEGIN_ALLOW_THREADS
700 id = QgsNetworkAccessManager::setReplyPreprocessor( [a0]( const QNetworkRequest &request, QNetworkReply *reply )
701 {
702 SIP_BLOCK_THREADS
703 Py_XDECREF( sipCallMethod( NULL, a0, "ND", new QNetworkRequest( request ), sipType_QNetworkRequest, NULL, reply, sipType_QNetworkReply, NULL ) );
704 SIP_UNBLOCK_THREADS
705 } );
706
707 Py_END_ALLOW_THREADS
708 s = sipConvertFromNewType( new QString( id ), sipType_QString, 0 );
709 return s;
710 % End
711// clang-format on
712#endif
713
724#ifndef SIP_RUN
725 static bool removeReplyPreprocessor( const QString &id );
726#else
727 // clang-format off
728 static void removeReplyPreprocessor( const QString &id );
729 % MethodCode
731 {
732 PyErr_SetString( PyExc_KeyError, u"No processor with id %1 exists."_s.arg( *a0 ).toUtf8().constData() );
733 sipIsErr = 1;
734 }
735 % End
736// clang-format on
737#endif
738
745 void requestAuthOpenBrowser( const QUrl &url ) const;
746
753 void requestAuthCloseBrowser() const;
754
761 void abortAuthBrowser();
762
763
764#ifndef SIP_RUN
767#endif
768
774 void preprocessRequest( QNetworkRequest *req ) const;
775
776 signals:
777
781 Q_DECL_DEPRECATED void requestAboutToBeCreated( QNetworkAccessManager::Operation operation, const QNetworkRequest &request, QIODevice *device ) SIP_DEPRECATED;
782
796
810
826
839
854 void downloadProgress( int requestId, qint64 bytesReceived, qint64 bytesTotal );
855
871 void requestRequiresAuth( int requestId, const QString &realm );
872
888 void requestAuthDetailsAdded( int requestId, const QString &realm, const QString &user, const QString &password );
889
890#ifndef QT_NO_SSL
891
906 void requestEncounteredSslErrors( int requestId, const QList<QSslError> &errors );
907
908#ifndef SIP_RUN
910 // these signals are for internal use only - it's not safe to connect by external code
911 void sslErrorsOccurred( QNetworkReply *, const QList<QSslError> &errors );
912 void sslErrorsHandled( QNetworkReply *reply );
914#endif
915
916#endif
917
921 Q_DECL_DEPRECATED void requestCreated( QNetworkReply *reply ) SIP_DEPRECATED;
922
926 void requestTimedOut( QNetworkReply *reply );
927
928#ifndef SIP_RUN
930 // these signals are for internal use only - it's not safe to connect by external code
931 void authRequestOccurred( QNetworkReply *, QAuthenticator *auth );
932 void authRequestHandled( QNetworkReply *reply );
934#endif
935
942
947
948 void cookiesChanged( const QList<QNetworkCookie> &cookies );
949
950 private slots:
951 void abortRequest();
952
953 void onReplyFinished( QNetworkReply *reply );
954
955 void onReplyDownloadProgress( qint64 bytesReceived, qint64 bytesTotal );
956#ifndef QT_NO_SSL
957 void onReplySslErrors( const QList<QSslError> &errors );
958
959 void handleSslErrors( QNetworkReply *reply, const QList<QSslError> &errors );
960#endif
961
962 void onAuthRequired( QNetworkReply *reply, QAuthenticator *auth );
963 void handleAuthRequest( QNetworkReply *reply, QAuthenticator *auth );
964
965 void syncCookies( const QList<QNetworkCookie> &cookies );
966
967 protected:
968 QNetworkReply *createRequest( QNetworkAccessManager::Operation op, const QNetworkRequest &req, QIODevice *outgoingData = nullptr ) override;
969
970 private:
971#ifndef QT_NO_SSL
972 void afterSslErrorHandled( QNetworkReply *reply );
973#endif
974
975 void afterAuthRequestHandled( QNetworkReply *reply );
976
977 void pauseTimeout( QNetworkReply *reply );
978 void restartTimeout( QNetworkReply *reply );
979 static int getRequestId( QNetworkReply *reply );
980
981 QList<QNetworkProxyFactory *> mProxyFactories;
982 QNetworkProxy mFallbackProxy;
983 QStringList mExcludedURLs;
984 QStringList mNoProxyURLs;
985 bool mUseSystemProxy = false;
986 bool mInitialized = false;
987 bool mCacheDisabled = false;
988 static QgsNetworkAccessManager *sMainNAM;
989 // ssl error handler, will be set for main thread ONLY
990 std::unique_ptr< QgsSslErrorHandler > mSslErrorHandler;
991 // Used by worker threads to wait for ssl error handler run in main thread
992 QSemaphore mSslErrorHandlerSemaphore;
993
994 // auth request handler, will be set for main thread ONLY
995 std::unique_ptr< QgsNetworkAuthenticationHandler > mAuthHandler;
996 // Used by worker threads to wait for authentication handler run in main thread
997 QSemaphore mAuthRequestHandlerSemaphore;
998
1000};
1001
1002#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.
@ 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