QGIS API Documentation 3.43.0-Master (3ee7834ace6)
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 <QSemaphore>
33#include <memory>
34
35#include "qgis_core.h"
36#include "qgis_sip.h"
37
38class QgsFeedback;
40
48{
49 public:
50
53 {
54 AttributeInitiatorClass = QNetworkRequest::User + 3000,
56 };
57
59
64 QgsNetworkRequestParameters( QNetworkAccessManager::Operation operation,
65 const QNetworkRequest &request,
66 int requestId,
67 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
121 QNetworkAccessManager::Operation mOperation;
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
165 public:
166
167 virtual ~QgsSslErrorHandler() = default;
168
179 virtual void handleSslErrors( QNetworkReply *reply, const QList<QSslError> &errors );
180
181};
182
207{
208
209 public:
210
212
221 virtual void handleAuthRequest( QNetworkReply *reply, QAuthenticator *auth );
222
228 virtual void handleAuthRequestOpenBrowser( const QUrl &url );
229
235 virtual void handleAuthRequestCloseBrowser();
236
237};
238#endif
239
240
256class CORE_EXPORT QgsNetworkAccessManager : public QNetworkAccessManager
257{
258 Q_OBJECT
259
260 public:
261
280 static QgsNetworkAccessManager *instance( Qt::ConnectionType connectionType = Qt::BlockingQueuedConnection );
281
282 QgsNetworkAccessManager( QObject *parent = nullptr );
283
284#ifndef SIP_RUN
285
302 void setSslErrorHandler( std::unique_ptr< QgsSslErrorHandler > handler );
303
320 void setAuthHandler( std::unique_ptr< QgsNetworkAuthenticationHandler > handler );
321#endif
322
331 void insertProxyFactory( QNetworkProxyFactory *factory SIP_TRANSFER );
332
339 void removeProxyFactory( QNetworkProxyFactory *factory SIP_TRANSFERBACK );
340
347 const QList<QNetworkProxyFactory *> proxyFactories() const;
348
357 const QNetworkProxy &fallbackProxy() const;
358
368 QStringList excludeList() const;
369
379 QStringList noProxyList() const;
380
392 void setFallbackProxyAndExcludes( const QNetworkProxy &proxy, const QStringList &excludes, const QStringList &noProxyURLs );
393
399 static QString cacheLoadControlName( QNetworkRequest::CacheLoadControl control );
400
406 static QNetworkRequest::CacheLoadControl cacheLoadControlFromName( const QString &name );
407
415 void setupDefaultProxyAndCache( Qt::ConnectionType connectionType = Qt::BlockingQueuedConnection );
416
417#ifndef SIP_RUN
418
426 bool cacheDisabled() const { return mCacheDisabled; }
427
438 void setCacheDisabled( bool disabled ) { mCacheDisabled = disabled; }
439#endif
440
444 bool useSystemProxy() const { return mUseSystemProxy; }
445
452 static int timeout();
453
461 static void setTimeout( int time );
462
483 static QgsNetworkReplyContent blockingGet( QNetworkRequest &request, const QString &authCfg = QString(), bool forceRefresh = false, QgsFeedback *feedback = nullptr );
484
505 static QgsNetworkReplyContent blockingPost( QNetworkRequest &request, const QByteArray &data, const QString &authCfg = QString(), bool forceRefresh = false, QgsFeedback *feedback = nullptr );
506
518#ifndef SIP_RUN
519 static QString setRequestPreprocessor( const std::function< void( QNetworkRequest *request )> &processor );
520#else
521 static QString setRequestPreprocessor( SIP_PYCALLABLE / AllowNone / );
522 % MethodCode
523 PyObject *s = 0;
524 QString id;
525 Py_XINCREF( a0 );
526 Py_BEGIN_ALLOW_THREADS
527 id = QgsNetworkAccessManager::setRequestPreprocessor( [a0]( QNetworkRequest *arg )->QString
528 {
529 QString res;
530 SIP_BLOCK_THREADS
531 PyObject *s = sipCallMethod( NULL, a0, "D", arg, sipType_QNetworkRequest, NULL );
532 int state;
533 int sipIsError = 0;
534 QString *t1 = reinterpret_cast<QString *>( sipConvertToType( s, sipType_QString, 0, SIP_NOT_NONE, &state, &sipIsError ) );
535 if ( sipIsError == 0 )
536 {
537 res = QString( *t1 );
538 }
539 sipReleaseType( t1, sipType_QString, state );
540 SIP_UNBLOCK_THREADS
541 return res;
542 } );
543 Py_END_ALLOW_THREADS
544
545 s = sipConvertFromNewType( new QString( id ), sipType_QString, 0 );
546 return s;
547 % End
548#endif
549
560#ifndef SIP_RUN
561 static bool removeRequestPreprocessor( const QString &id );
562#else
563 static void removeRequestPreprocessor( const QString &id );
564 % MethodCode
566 {
567 PyErr_SetString( PyExc_KeyError, QStringLiteral( "No processor with id %1 exists." ).arg( *a0 ).toUtf8().constData() );
568 sipIsErr = 1;
569 }
570 % End
571#endif
572
588#ifndef SIP_RUN
589 static QString setAdvancedRequestPreprocessor( const std::function< void( QNetworkRequest *, int &op, QByteArray *data )> &processor );
590#else
591 static QString setAdvancedRequestPreprocessor( SIP_PYCALLABLE / AllowNone / );
592 % MethodCode
593 PyObject *s = 0;
594 QString id;
595 Py_XINCREF( a0 );
596 Py_BEGIN_ALLOW_THREADS
597 id = QgsNetworkAccessManager::setAdvancedRequestPreprocessor( [a0]( QNetworkRequest *reqArg, int &op, QByteArray *data )
598 {
599 SIP_BLOCK_THREADS
600
601 PyObject *requestObj = sipConvertFromType( reqArg, sipType_QNetworkRequest, NULL );
602 PyObject *postDataObj = sipConvertFromType( new QByteArray( *data ), sipType_QByteArray, Py_None );
603
604 PyObject *result = sipCallMethod( NULL, a0, "RiR", requestObj, op, postDataObj );
605
606 Py_XDECREF( requestObj );
607 Py_XDECREF( postDataObj );
608
609 if ( result && PyTuple_Check( result ) && PyTuple_Size( result ) == 2 )
610 {
611 // Extract modified operation
612 PyObject *opObj = PyTuple_GetItem( result, 0 );
613 if ( opObj && PyLong_Check( opObj ) )
614 {
615 op = static_cast<int>( PyLong_AsLong( opObj ) );
616 }
617 PyObject *dataObj = PyTuple_GetItem( result, 1 );
618 if ( dataObj && dataObj != Py_None )
619 {
620 int dataState;
621 int sipIsErr = 0;
622 QByteArray *modifiedData = reinterpret_cast<QByteArray *>( sipConvertToType( dataObj, sipType_QByteArray, 0, SIP_NOT_NONE, &dataState, &sipIsErr ) );
623 if ( sipIsErr == 0 )
624 {
625 data->clear();
626 data->append( *modifiedData );
627 sipReleaseType( modifiedData, sipType_QByteArray, dataState );
628 }
629 }
630 }
631
632 Py_XDECREF( result );
633 SIP_UNBLOCK_THREADS
634 } );
635 Py_END_ALLOW_THREADS
636
637 s = sipConvertFromNewType( new QString( id ), sipType_QString, 0 );
638 return s;
639 % End
640#endif
641
652#ifndef SIP_RUN
653 static bool removeAdvancedRequestPreprocessor( const QString &id );
654#else
655 static void removeAdvancedRequestPreprocessor( const QString &id );
656 % MethodCode
658 {
659 PyErr_SetString( PyExc_KeyError, QStringLiteral( "No processor with id %1 exists." ).arg( *a0 ).toUtf8().constData() );
660 sipIsErr = 1;
661 }
662 % End
663#endif
664
665
677#ifndef SIP_RUN
678 static QString setReplyPreprocessor( const std::function<void ( const QNetworkRequest &, QNetworkReply * )> &processor );
679#else
680 static QString setReplyPreprocessor( SIP_PYCALLABLE / AllowNone / );
681 % MethodCode
682 PyObject *s = 0;
683 QString id;
684 Py_XINCREF( a0 );
685 Py_BEGIN_ALLOW_THREADS
686 id = QgsNetworkAccessManager::setReplyPreprocessor( [a0]( const QNetworkRequest &request, QNetworkReply *reply )
687 {
688 SIP_BLOCK_THREADS
689 Py_XDECREF( sipCallMethod( NULL, a0, "ND", new QNetworkRequest( request ), sipType_QNetworkRequest, NULL, reply, sipType_QNetworkReply, NULL ) );
690 SIP_UNBLOCK_THREADS
691 } );
692
693 Py_END_ALLOW_THREADS
694 s = sipConvertFromNewType( new QString( id ), sipType_QString, 0 );
695 return s;
696 % End
697#endif
698
709#ifndef SIP_RUN
710 static bool removeReplyPreprocessor( const QString &id );
711#else
712 static void removeReplyPreprocessor( const QString &id );
713 % MethodCode
715 {
716 PyErr_SetString( PyExc_KeyError, QStringLiteral( "No processor with id %1 exists." ).arg( *a0 ).toUtf8().constData() );
717 sipIsErr = 1;
718 }
719 % End
720#endif
721
728 void requestAuthOpenBrowser( const QUrl &url ) const;
729
736 void requestAuthCloseBrowser() const;
737
744 void abortAuthBrowser();
745
746
747#ifndef SIP_RUN
750#endif
751
757 void preprocessRequest( QNetworkRequest *req ) const;
758
759 signals:
760
764 Q_DECL_DEPRECATED void requestAboutToBeCreated( QNetworkAccessManager::Operation operation, const QNetworkRequest &request, QIODevice *device ) SIP_DEPRECATED;
765
779
793
809
822
837 void downloadProgress( int requestId, qint64 bytesReceived, qint64 bytesTotal );
838
854 void requestRequiresAuth( int requestId, const QString &realm );
855
871 void requestAuthDetailsAdded( int requestId, const QString &realm, const QString &user, const QString &password );
872
873#ifndef QT_NO_SSL
874
889 void requestEncounteredSslErrors( int requestId, const QList<QSslError> &errors );
890
891#ifndef SIP_RUN
893 // these signals are for internal use only - it's not safe to connect by external code
894 void sslErrorsOccurred( QNetworkReply *, const QList<QSslError> &errors );
895 void sslErrorsHandled( QNetworkReply *reply );
897#endif
898
899#endif
900
904 Q_DECL_DEPRECATED void requestCreated( QNetworkReply *reply ) SIP_DEPRECATED;
905
909 void requestTimedOut( QNetworkReply *reply );
910
911#ifndef SIP_RUN
913 // these signals are for internal use only - it's not safe to connect by external code
914 void authRequestOccurred( QNetworkReply *, QAuthenticator *auth );
915 void authRequestHandled( QNetworkReply *reply );
917#endif
918
925
931 void cookiesChanged( const QList<QNetworkCookie> &cookies );
932
933 private slots:
934 void abortRequest();
935
936 void onReplyFinished( QNetworkReply *reply );
937
938 void onReplyDownloadProgress( qint64 bytesReceived, qint64 bytesTotal );
939#ifndef QT_NO_SSL
940 void onReplySslErrors( const QList<QSslError> &errors );
941
942 void handleSslErrors( QNetworkReply *reply, const QList<QSslError> &errors );
943#endif
944
945 void onAuthRequired( QNetworkReply *reply, QAuthenticator *auth );
946 void handleAuthRequest( QNetworkReply *reply, QAuthenticator *auth );
947
948 void syncCookies( const QList<QNetworkCookie> &cookies );
949
950 protected:
951 QNetworkReply *createRequest( QNetworkAccessManager::Operation op, const QNetworkRequest &req, QIODevice *outgoingData = nullptr ) override;
952
953 private:
954#ifndef QT_NO_SSL
955 void afterSslErrorHandled( QNetworkReply *reply );
956#endif
957
958 void afterAuthRequestHandled( QNetworkReply *reply );
959
960 void pauseTimeout( QNetworkReply *reply );
961 void restartTimeout( QNetworkReply *reply );
962 static int getRequestId( QNetworkReply *reply );
963
964 QList<QNetworkProxyFactory *> mProxyFactories;
965 QNetworkProxy mFallbackProxy;
966 QStringList mExcludedURLs;
967 QStringList mNoProxyURLs;
968 bool mUseSystemProxy = false;
969 bool mInitialized = false;
970 bool mCacheDisabled = false;
971 static QgsNetworkAccessManager *sMainNAM;
972 // ssl error handler, will be set for main thread ONLY
973 std::unique_ptr< QgsSslErrorHandler > mSslErrorHandler;
974 // Used by worker threads to wait for ssl error handler run in main thread
975 QSemaphore mSslErrorHandlerSemaphore;
976
977 // auth request handler, will be set for main thread ONLY
978 std::unique_ptr< QgsNetworkAuthenticationHandler > mAuthHandler;
979 // Used by worker threads to wait for authentication handler run in main thread
980 QSemaphore mAuthRequestHandlerSemaphore;
981
982 friend class TestQgsNetworkAccessManager;
983};
984
985#endif // QGSNETWORKACCESSMANAGER_H
Base class for feedback objects to be used for cancellation of something running in a worker thread.
Definition qgsfeedback.h:44
network access manager for QGIS
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.
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.
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 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.
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.
void requestRequiresAuth(int requestId, const QString &realm)
Emitted when a network request prompts an authentication request.
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...
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...
static bool removeReplyPreprocessor(const QString &id)
Removes the custom reply pre-processor function with matching id.
Q_DECL_DEPRECATED void requestCreated(QNetworkReply *reply)
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.
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
#define SIP_DEPRECATED
Definition qgis_sip.h:106
#define SIP_TRANSFER
Definition qgis_sip.h:36
#define SIP_TRANSFERBACK
Definition qgis_sip.h:48