QGIS API Documentation 4.1.0-Master (467af3bbe65)
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;
47
55{
56 public:
65
67
72 QgsNetworkRequestParameters( QNetworkAccessManager::Operation operation, const QNetworkRequest &request, int requestId, const QByteArray &content = QByteArray() );
73
77 QNetworkAccessManager::Operation operation() const { return mOperation; }
78
85 QNetworkRequest request() const { return mRequest; }
86
90 QString originatingThreadId() const { return mOriginatingThreadId; }
91
95 int requestId() const { return mRequestId; }
96
101 QByteArray content() const { return mContent; }
102
111 QString initiatorClassName() const { return mInitiatorClass; }
112
122 QVariant initiatorRequestId() const { return mInitiatorRequestId; }
123
124 private:
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 public:
169 virtual ~QgsSslErrorHandler() = default;
170
181 virtual void handleSslErrors( QNetworkReply *reply, const QList<QSslError> &errors );
182};
183
208{
209 public:
211
220 virtual void handleAuthRequest( QNetworkReply *reply, QAuthenticator *auth );
221
227 virtual void handleAuthRequestOpenBrowser( const QUrl &url );
228
234 virtual void handleAuthRequestCloseBrowser();
235};
236#endif
237
238
254class CORE_EXPORT QgsNetworkAccessManager : public QNetworkAccessManager
255{
256 Q_OBJECT
257
258 public:
277 static QgsNetworkAccessManager *instance( Qt::ConnectionType connectionType = Qt::BlockingQueuedConnection );
278
279 QgsNetworkAccessManager( QObject *parent = nullptr );
280
281#ifndef SIP_RUN
282
299 void setSslErrorHandler( std::unique_ptr< QgsSslErrorHandler > handler );
300
317 void setAuthHandler( std::unique_ptr< QgsNetworkAuthenticationHandler > handler );
318#endif
319
328 void insertProxyFactory( QNetworkProxyFactory *factory SIP_TRANSFER );
329
336 void removeProxyFactory( QNetworkProxyFactory *factory SIP_TRANSFERBACK );
337
344 const QList<QNetworkProxyFactory *> proxyFactories() const;
345
354 const QNetworkProxy &fallbackProxy() const;
355
365 QStringList excludeList() const;
366
376 QStringList noProxyList() const;
377
389 void setFallbackProxyAndExcludes( const QNetworkProxy &proxy, const QStringList &excludes, const QStringList &noProxyURLs );
390
396 static QString cacheLoadControlName( QNetworkRequest::CacheLoadControl control );
397
403 static QNetworkRequest::CacheLoadControl cacheLoadControlFromName( const QString &name );
404
412 void setupDefaultProxyAndCache( Qt::ConnectionType connectionType = Qt::BlockingQueuedConnection );
413
414#ifndef SIP_RUN
415
423 bool cacheDisabled() const { return mCacheDisabled; }
424
435 void setCacheDisabled( bool disabled ) { mCacheDisabled = disabled; }
436#endif
437
441 bool useSystemProxy() const { return mUseSystemProxy; }
442
449 static int timeout();
450
458 static void setTimeout( int time );
459
482 static QgsNetworkReplyContent blockingGet(
483 QNetworkRequest &request, const QString &authCfg = QString(), bool forceRefresh = false, QgsFeedback *feedback = nullptr, Qgis::NetworkRequestFlags flags = Qgis::NetworkRequestFlags()
484 );
485
508 static QgsNetworkReplyContent blockingPost(
509 QNetworkRequest &request,
510 const QByteArray &data,
511 const QString &authCfg = QString(),
512 bool forceRefresh = false,
513 QgsFeedback *feedback = nullptr,
515 );
516
528#ifndef SIP_RUN
529 static QString setRequestPreprocessor( const std::function< void( QNetworkRequest *request )> &processor );
530#else
531 // clang-format off
532 static QString setRequestPreprocessor( SIP_PYCALLABLE / AllowNone / );
533 % MethodCode
534 PyObject *s = 0;
535 QString id;
536 Py_XINCREF( a0 );
537 Py_BEGIN_ALLOW_THREADS
538 id = QgsNetworkAccessManager::setRequestPreprocessor( [a0]( QNetworkRequest *arg )->QString
539 {
540 QString res;
541 SIP_BLOCK_THREADS
542 PyObject *s = sipCallMethod( NULL, a0, "D", arg, sipType_QNetworkRequest, NULL );
543 int state;
544 int sipIsError = 0;
545 QString *t1 = reinterpret_cast<QString *>( sipConvertToType( s, sipType_QString, 0, SIP_NOT_NONE, &state, &sipIsError ) );
546 if ( sipIsError == 0 )
547 {
548 res = QString( *t1 );
549 }
550 sipReleaseType( t1, sipType_QString, state );
551 SIP_UNBLOCK_THREADS
552 return res;
553 } );
554 Py_END_ALLOW_THREADS
555
556 s = sipConvertFromNewType( new QString( id ), sipType_QString, 0 );
557 return s;
558 % End
559// clang-format on
560#endif
561
572#ifndef SIP_RUN
573 static bool removeRequestPreprocessor( const QString &id );
574#else
575 // clang-format off
576 static void removeRequestPreprocessor( const QString &id );
577 % MethodCode
579 {
580 PyErr_SetString( PyExc_KeyError, u"No processor with id %1 exists."_s.arg( *a0 ).toUtf8().constData() );
581 sipIsErr = 1;
582 }
583 % End
584// clang-format on
585#endif
586
602#ifndef SIP_RUN
603 static QString setAdvancedRequestPreprocessor( const std::function< void( QNetworkRequest *, int &op, QByteArray *data )> &processor );
604#else
605 // clang-format off
606 static QString setAdvancedRequestPreprocessor( SIP_PYCALLABLE / AllowNone / );
607 % MethodCode
608 PyObject *s = 0;
609 QString id;
610 Py_XINCREF( a0 );
611 Py_BEGIN_ALLOW_THREADS
612 id = QgsNetworkAccessManager::setAdvancedRequestPreprocessor( [a0]( QNetworkRequest *reqArg, int &op, QByteArray *data )
613 {
614 SIP_BLOCK_THREADS
615
616 PyObject *requestObj = sipConvertFromType( reqArg, sipType_QNetworkRequest, NULL );
617 PyObject *postDataObj = sipConvertFromType( new QByteArray( *data ), sipType_QByteArray, Py_None );
618
619 PyObject *result = sipCallMethod( NULL, a0, "RiR", requestObj, op, postDataObj );
620
621 Py_XDECREF( requestObj );
622 Py_XDECREF( postDataObj );
623
624 if ( result && PyTuple_Check( result ) && PyTuple_Size( result ) == 2 )
625 {
626 // Extract modified operation
627 PyObject *opObj = PyTuple_GetItem( result, 0 );
628 if ( opObj && PyLong_Check( opObj ) )
629 {
630 op = static_cast<int>( PyLong_AsLong( opObj ) );
631 }
632 PyObject *dataObj = PyTuple_GetItem( result, 1 );
633 if ( dataObj && dataObj != Py_None )
634 {
635 int dataState;
636 int sipIsErr = 0;
637 QByteArray *modifiedData = reinterpret_cast<QByteArray *>( sipConvertToType( dataObj, sipType_QByteArray, 0, SIP_NOT_NONE, &dataState, &sipIsErr ) );
638 if ( sipIsErr == 0 )
639 {
640 data->clear();
641 data->append( *modifiedData );
642 sipReleaseType( modifiedData, sipType_QByteArray, dataState );
643 }
644 }
645 }
646
647 Py_XDECREF( result );
648 SIP_UNBLOCK_THREADS
649 } );
650 Py_END_ALLOW_THREADS
651
652 s = sipConvertFromNewType( new QString( id ), sipType_QString, 0 );
653 return s;
654 % End
655// clang-format on
656#endif
657
668#ifndef SIP_RUN
669 static bool removeAdvancedRequestPreprocessor( const QString &id );
670#else
671 // clang-format off
672 static void removeAdvancedRequestPreprocessor( const QString &id );
673 % MethodCode
675 {
676 PyErr_SetString( PyExc_KeyError, u"No processor with id %1 exists."_s.arg( *a0 ).toUtf8().constData() );
677 sipIsErr = 1;
678 }
679 % End
680// clang-format on
681#endif
682
683
695#ifndef SIP_RUN
696 static QString setReplyPreprocessor( const std::function<void( const QNetworkRequest &, QNetworkReply * )> &processor );
697#else
698 // clang-format off
699 static QString setReplyPreprocessor( SIP_PYCALLABLE / AllowNone / );
700 % MethodCode
701 PyObject *s = 0;
702 QString id;
703 Py_XINCREF( a0 );
704 Py_BEGIN_ALLOW_THREADS
705 id = QgsNetworkAccessManager::setReplyPreprocessor( [a0]( const QNetworkRequest &request, QNetworkReply *reply )
706 {
707 SIP_BLOCK_THREADS
708 Py_XDECREF( sipCallMethod( NULL, a0, "ND", new QNetworkRequest( request ), sipType_QNetworkRequest, NULL, reply, sipType_QNetworkReply, NULL ) );
709 SIP_UNBLOCK_THREADS
710 } );
711
712 Py_END_ALLOW_THREADS
713 s = sipConvertFromNewType( new QString( id ), sipType_QString, 0 );
714 return s;
715 % End
716// clang-format on
717#endif
718
729#ifndef SIP_RUN
730 static bool removeReplyPreprocessor( const QString &id );
731#else
732 // clang-format off
733 static void removeReplyPreprocessor( const QString &id );
734 % MethodCode
736 {
737 PyErr_SetString( PyExc_KeyError, u"No processor with id %1 exists."_s.arg( *a0 ).toUtf8().constData() );
738 sipIsErr = 1;
739 }
740 % End
741// clang-format on
742#endif
743
750 void requestAuthOpenBrowser( const QUrl &url ) const;
751
758 void requestAuthCloseBrowser() const;
759
766 void abortAuthBrowser();
767
768
769#ifndef SIP_RUN
792#endif
793
799 void preprocessRequest( QNetworkRequest *req ) const;
800
801 signals:
802
806 Q_DECL_DEPRECATED void requestAboutToBeCreated( QNetworkAccessManager::Operation operation, const QNetworkRequest &request, QIODevice *device ) SIP_DEPRECATED;
807
821
835
851
864
879 void downloadProgress( int requestId, qint64 bytesReceived, qint64 bytesTotal );
880
896 void requestRequiresAuth( int requestId, const QString &realm );
897
913 void requestAuthDetailsAdded( int requestId, const QString &realm, const QString &user, const QString &password );
914
915#ifndef QT_NO_SSL
916
931 void requestEncounteredSslErrors( int requestId, const QList<QSslError> &errors );
932
933#ifndef SIP_RUN
935 // these signals are for internal use only - it's not safe to connect by external code
936 void sslErrorsOccurred( QNetworkReply *, const QList<QSslError> &errors );
937 void sslErrorsHandled( QNetworkReply *reply );
939#endif
940
941#endif
942
946 Q_DECL_DEPRECATED void requestCreated( QNetworkReply *reply ) SIP_DEPRECATED;
947
951 void requestTimedOut( QNetworkReply *reply );
952
953#ifndef SIP_RUN
955 // these signals are for internal use only - it's not safe to connect by external code
956 void authRequestOccurred( QNetworkReply *, QAuthenticator *auth );
957 void authRequestHandled( QNetworkReply *reply );
959#endif
960
967
972
973 void cookiesChanged( const QList<QNetworkCookie> &cookies );
974
975 private slots:
976 void abortRequest();
977
978 void onReplyFinished( QNetworkReply *reply );
979
980 void onReplyDownloadProgress( qint64 bytesReceived, qint64 bytesTotal );
981#ifndef QT_NO_SSL
982 void onReplySslErrors( const QList<QSslError> &errors );
983
984 void handleSslErrors( QNetworkReply *reply, const QList<QSslError> &errors );
985#endif
986
987 void onAuthRequired( QNetworkReply *reply, QAuthenticator *auth );
988 void handleAuthRequest( QNetworkReply *reply, QAuthenticator *auth );
989
990 void syncCookies( const QList<QNetworkCookie> &cookies );
991
992 protected:
993 QNetworkReply *createRequest( QNetworkAccessManager::Operation op, const QNetworkRequest &req, QIODevice *outgoingData = nullptr ) override;
994
995 private:
996#ifndef QT_NO_SSL
997 void afterSslErrorHandled( QNetworkReply *reply );
998#endif
999
1000 void afterAuthRequestHandled( QNetworkReply *reply );
1001
1002 void pauseTimeout( QNetworkReply *reply );
1003 void restartTimeout( QNetworkReply *reply );
1004 static int getRequestId( QNetworkReply *reply );
1005
1006 QList<QNetworkProxyFactory *> mProxyFactories;
1007 QNetworkProxy mFallbackProxy;
1008 QStringList mExcludedURLs;
1009 QStringList mNoProxyURLs;
1010 bool mUseSystemProxy = false;
1011 bool mInitialized = false;
1012 bool mCacheDisabled = false;
1013 static QgsNetworkAccessManager *sMainNAM;
1014 // ssl error handler, will be set for main thread ONLY
1015 std::unique_ptr< QgsSslErrorHandler > mSslErrorHandler;
1016 // Used by worker threads to wait for ssl error handler run in main thread
1017 QSemaphore mSslErrorHandlerSemaphore;
1018
1019 // auth request handler, will be set for main thread ONLY
1020 std::unique_ptr< QgsNetworkAuthenticationHandler > mAuthHandler;
1021 // Used by worker threads to wait for authentication handler run in main thread
1022 QSemaphore mAuthRequestHandlerSemaphore;
1023
1025};
1026
1027#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 QgsSettingsEntryString * settingsProxyAuthCfg
Settings entry for proxy authentication configuration.
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 const QgsSettingsEntryString * settingsProxyUser
Settings entry for proxy user.
static QString cacheLoadControlName(QNetworkRequest::CacheLoadControl control)
Returns the name for QNetworkRequest::CacheLoadControl.
static const QgsSettingsEntryString * settingsProxyHost
Settings entry for proxy host.
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 const QgsSettingsEntryString * settingsProxyPort
Settings entry for proxy port.
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 const QgsSettingsEntryString * settingsProxyExcludedUrls
Settings entry for proxy excluded URLs (legacy, falls back to system proxy for these).
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.
static const QgsSettingsEntryString * settingsUserAgent
Settings entry for user agent string.
static const QgsSettingsEntryBool * settingsProxyEnabled
Settings entry for whether proxy is enabled.
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 const QgsSettingsEntryString * settingsProxyPassword
Settings entry for proxy password.
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 const QgsSettingsEntryStringList * settingsNoProxyUrls
Settings entry for no-proxy URLs.
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.
static const QgsSettingsEntryString * settingsProxyType
Settings entry for proxy type.
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.
@ AttributeUserAgentSuffix
Custom string to append to the default User-Agent header.
@ 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...
A boolean settings entry.
An integer settings entry.
A string list settings entry.
A string 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