37#include <QAuthenticator>
39#include <QNetworkReply>
40#include <QRecursiveMutex>
41#include <QStandardPaths>
43#include <QThreadStorage>
48#include "moc_qgsnetworkaccessmanager.cpp"
50using namespace Qt::StringLiterals;
66#include <QSslConfiguration>
74static std::vector< std::pair< QString, std::function< void( QNetworkRequest * ) > > > sCustomPreprocessors;
75static std::vector< std::pair< QString, std::function< void( QNetworkRequest *,
int &op, QByteArray *data ) > > > sCustomAdvancedPreprocessors;
76static std::vector< std::pair< QString, std::function< void(
const QNetworkRequest &, QNetworkReply * ) > > > sCustomReplyPreprocessors;
79class QgsNetworkProxyFactory :
public QNetworkProxyFactory
82 QgsNetworkProxyFactory() =
default;
84 QList<QNetworkProxy> queryProxy(
const QNetworkProxyQuery &query = QNetworkProxyQuery() )
override
90 for ( QNetworkProxyFactory *f : constProxyFactories )
92 QList<QNetworkProxy> systemproxies = QNetworkProxyFactory::systemProxyForQuery( query );
93 if ( !systemproxies.isEmpty() )
96 QList<QNetworkProxy> proxies = f->queryProxy( query );
97 if ( !proxies.isEmpty() )
102 if ( query.queryType() != QNetworkProxyQuery::UrlRequest )
105 const QString url = query.url().toString();
108 for (
const QString &noProxy : constNoProxyList )
110 if ( !noProxy.trimmed().isEmpty() && url.startsWith( noProxy ) )
112 QgsDebugMsgLevel( u
"don't using any proxy for %1 [exclude %2]"_s.arg( url, noProxy ), 4 );
113 return QList<QNetworkProxy>() << QNetworkProxy( QNetworkProxy::NoProxy );
118 for (
const QString &exclude : constExcludeList )
120 if ( !exclude.trimmed().isEmpty() && url.startsWith( exclude ) )
122 QgsDebugMsgLevel( u
"using default proxy for %1 [exclude %2]"_s.arg( url, exclude ), 4 );
123 return QList<QNetworkProxy>() << QNetworkProxy( QNetworkProxy::DefaultProxy );
129 QgsDebugMsgLevel( u
"requesting system proxy for query %1"_s.arg( url ), 4 );
130 QList<QNetworkProxy> proxies = QNetworkProxyFactory::systemProxyForQuery( query );
131 if ( !proxies.isEmpty() )
133 QgsDebugMsgLevel( u
"using system proxy %1:%2 for query"_s.arg( proxies.first().hostName() ).arg( proxies.first().port() ), 4 );
145class QgsNetworkCookieJar :
public QNetworkCookieJar
150 QgsNetworkCookieJar( QgsNetworkAccessManager *parent )
151 : QNetworkCookieJar( parent )
155 bool deleteCookie(
const QNetworkCookie &cookie )
override
157 const QMutexLocker locker( &mMutex );
158 if ( QNetworkCookieJar::deleteCookie( cookie ) )
160 emit mNam->cookiesChanged( allCookies() );
165 bool insertCookie(
const QNetworkCookie &cookie )
override
167 const QMutexLocker locker( &mMutex );
168 if ( QNetworkCookieJar::insertCookie( cookie ) )
170 emit mNam->cookiesChanged( allCookies() );
175 bool setCookiesFromUrl(
const QList<QNetworkCookie> &cookieList,
const QUrl &url )
override
177 const QMutexLocker locker( &mMutex );
178 return QNetworkCookieJar::setCookiesFromUrl( cookieList, url );
180 bool updateCookie(
const QNetworkCookie &cookie )
override
182 const QMutexLocker locker( &mMutex );
183 if ( QNetworkCookieJar::updateCookie( cookie ) )
185 emit mNam->cookiesChanged( allCookies() );
192 QList<QNetworkCookie> allCookies()
const
194 const QMutexLocker locker( &mMutex );
195 return QNetworkCookieJar::allCookies();
197 void setAllCookies(
const QList<QNetworkCookie> &cookieList )
199 const QMutexLocker locker( &mMutex );
200 QNetworkCookieJar::setAllCookies( cookieList );
203 QgsNetworkAccessManager *mNam =
nullptr;
204 mutable QRecursiveMutex mMutex;
214 static QThreadStorage<QgsNetworkAccessManager> sInstances;
217 if ( nam->thread() == qApp->thread() )
220 if ( !nam->mInitialized )
222 QgsDebugMsgLevel( u
"Initializing new network access manager for %1thread: %2"_s.arg( QThread::currentThread() == qApp->thread() ? u
"MAIN "_s : QString() ).arg(
reinterpret_cast< qint64
>( QThread::currentThread() ), 0, 16 ), 2 );
228 QgsDebugMsgLevel( u
"Network access manager retrieved for %1thread: %2"_s.arg( QThread::currentThread() == qApp->thread() ? u
"MAIN "_s : QString() ).arg(
reinterpret_cast< qint64
>( QThread::currentThread() ), 0, 16 ), 4 );
235 : QNetworkAccessManager( parent )
236 , mSslErrorHandlerSemaphore( 1 )
237 , mAuthRequestHandlerSemaphore( 1 )
239 setRedirectPolicy( QNetworkRequest::NoLessSafeRedirectPolicy );
240 setProxyFactory(
new QgsNetworkProxyFactory() );
241 setCookieJar(
new QgsNetworkCookieJar(
this ) );
242 enableStrictTransportSecurityStore(
true );
243 setStrictTransportSecurityEnabled(
true );
248 Q_ASSERT( sMainNAM ==
this );
249 mSslErrorHandler = std::move( handler );
254 Q_ASSERT( sMainNAM ==
this );
255 mAuthHandler = std::move( handler );
260 mProxyFactories.insert( 0, factory );
265 mProxyFactories.removeAll( factory );
270 return mProxyFactories;
275 return mExcludedURLs;
285 return mFallbackProxy;
291 u
"proxy settings: (type:%1 host: %2:%3, user:%4, password:%5"_s
293 proxy.type() == QNetworkProxy::DefaultProxy ? u
"DefaultProxy"_s
294 : proxy.type() == QNetworkProxy::Socks5Proxy ? u
"Socks5Proxy"_s
295 : proxy.type() == QNetworkProxy::NoProxy ? u
"NoProxy"_s
296 : proxy.type() == QNetworkProxy::HttpProxy ? u
"HttpProxy"_s
297 : proxy.type() == QNetworkProxy::HttpCachingProxy ? u
"HttpCachingProxy"_s
298 : proxy.type() == QNetworkProxy::FtpCachingProxy ? u
"FtpCachingProxy"_s
303 .arg( proxy.user(), proxy.password().isEmpty() ? u
"not set"_s : u
"set"_s ),
307 mFallbackProxy = proxy;
308 mExcludedURLs = excludes;
312 mExcludedURLs.begin(),
314 [](
const QString &url ) { return url.trimmed().isEmpty(); }
319 mNoProxyURLs = noProxyURLs;
322 mNoProxyURLs.begin(),
324 [](
const QString &url ) { return url.trimmed().isEmpty(); }
332 QgsDebugMsgLevel( u
"Creating new network request on thread: %1 for %2"_s.arg(
reinterpret_cast< qint64
>( QThread::currentThread() ), 0, 16 ).arg( req.url().toString() ), 3 );
335 QNetworkRequest modifiedRequest( req );
338 const QVariant userAgentCustomSuffix = modifiedRequest.attribute( attrSuffix );
341 if ( !userAgent.isEmpty() )
343 userAgent += u
"QGIS/%1/%2"_s.arg(
Qgis::versionInt() ).arg( QSysInfo::prettyProductName() );
345 if ( !userAgentCustomSuffix.toString().isEmpty() )
347 userAgent.append(
' ' + userAgentCustomSuffix.toString() );
350 modifiedRequest.setRawHeader(
"User-Agent", userAgent.toLatin1() );
353 const bool ishttps = modifiedRequest.url().scheme().compare(
"https"_L1, Qt::CaseInsensitive ) == 0;
357 QSslConfiguration sslconfig( modifiedRequest.sslConfiguration() );
359 sslconfig.setCaCertificates( QgsAuthCertUtils::casMerge(
QgsApplication::authManager()->trustedCaCertsCache(), sslconfig.caCertificates() ) );
361 const QString hostport( u
"%1:%2"_s.arg( modifiedRequest.url().host().trimmed() ).arg( modifiedRequest.url().port() != -1 ? modifiedRequest.url().port() : 443 ) );
363 if ( !servconfig.
isNull() )
365 QgsDebugMsgLevel( u
"Adding SSL custom config to request for %1"_s.arg( hostport ), 2 );
371 modifiedRequest.setSslConfiguration( sslconfig );
375 if ( modifiedRequest.url().port() != -1 )
377 QUrl requestUrl = modifiedRequest.url();
378 const QString scheme = requestUrl.scheme();
379 const bool isDefaultPort = ( scheme ==
"http"_L1 && requestUrl.port() == 80 ) || ( scheme ==
"https"_L1 && requestUrl.port() == 443 );
382 QgsDebugMsgLevel( u
"Removing explicit default port %2 from url %1"_s.arg( requestUrl.port() ).arg( requestUrl.toString() ), 2 );
383 requestUrl.setPort( -1 );
384 modifiedRequest.setUrl( requestUrl );
388 if ( sMainNAM->mCacheDisabled )
391 modifiedRequest.setAttribute( QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::AlwaysNetwork );
392 modifiedRequest.setAttribute( QNetworkRequest::CacheSaveControlAttribute,
false );
395 for (
const auto &preprocessor : sCustomPreprocessors )
397 preprocessor.second( &modifiedRequest );
400 static QAtomicInt sRequestId = 0;
401 const int requestId = ++sRequestId;
403 if ( QBuffer *buffer = qobject_cast<QBuffer *>( outgoingData ) )
405 content = buffer->buffer();
408 for (
const auto &preprocessor : sCustomAdvancedPreprocessors )
410 int intOp =
static_cast< int >( op );
411 preprocessor.second( &modifiedRequest, intOp, &content );
412 op =
static_cast< QNetworkAccessManager::Operation
>( intOp );
415 bool needsCachePendingRequestCleanup =
false;
418 if ( modifiedRequest.attribute( QNetworkRequest::CacheLoadControlAttribute ) != QNetworkRequest::AlwaysNetwork )
422 if ( diskCache->hasInvalidMatchForRequest( modifiedRequest ) )
424 if ( modifiedRequest.attribute( QNetworkRequest::CacheSaveControlAttribute ).toBool() )
427 diskCache->remove( modifiedRequest.url() );
432 modifiedRequest.setAttribute( QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::AlwaysNetwork );
433 modifiedRequest.setAttribute( QNetworkRequest::CacheSaveControlAttribute,
false );
438 if ( modifiedRequest.attribute( QNetworkRequest::CacheSaveControlAttribute,
true ).toBool() )
440 if ( diskCache->hasPendingRequestForUrl( modifiedRequest.url() ) )
443 modifiedRequest.setAttribute( QNetworkRequest::CacheSaveControlAttribute,
false );
447 QVariantMap currentHeaders;
448 const QList<QByteArray> rawHeaderList = modifiedRequest.rawHeaderList();
449 for (
const QByteArray &header : rawHeaderList )
451 currentHeaders.insert( QString::fromUtf8( header ).toLower(), modifiedRequest.rawHeader( header ) );
453 diskCache->insertPendingRequestHeaders( modifiedRequest.url(), currentHeaders );
454 needsCachePendingRequestCleanup =
true;
463 QNetworkReply *reply = QNetworkAccessManager::createRequest( op, modifiedRequest, outgoingData );
464 reply->setProperty(
"requestId", requestId );
471 connect( reply, &QNetworkReply::downloadProgress,
this, &QgsNetworkAccessManager::onReplyDownloadProgress );
473 connect( reply, &QNetworkReply::sslErrors,
this, &QgsNetworkAccessManager::onReplySslErrors );
476 for (
const auto &replyPreprocessor : sCustomReplyPreprocessors )
478 replyPreprocessor.second( modifiedRequest, reply );
481 if ( needsCachePendingRequestCleanup )
485 const QUrl url = modifiedRequest.url();
486 connect( reply, &QNetworkReply::finished, diskCache, [url, diskCache] { diskCache->removePendingRequestForUrl( url ); } );
495 QTimer *timer =
new QTimer( reply );
496 timer->setObjectName( u
"timeoutTimer"_s );
497 connect( timer, &QTimer::timeout,
this, &QgsNetworkAccessManager::abortRequest );
498 timer->setSingleShot(
true );
501 connect( reply, &QNetworkReply::downloadProgress, timer, [timer] { timer->start(); } );
502 connect( reply, &QNetworkReply::uploadProgress, timer, [timer] { timer->start(); } );
503 connect( reply, &QNetworkReply::finished, timer, &QTimer::stop );
505 QgsDebugMsgLevel( u
"Created [reply:%1]"_s.arg(
reinterpret_cast< qint64
>( reply ), 0, 16 ), 3 );
510void QgsNetworkAccessManager::abortRequest()
512 QTimer *timer = qobject_cast<QTimer *>( sender() );
515 QNetworkReply *reply = qobject_cast<QNetworkReply *>( timer->parent() );
519 QgsDebugMsgLevel( u
"Abort [reply:%1] %2"_s.arg(
reinterpret_cast< qint64
>( reply ), 0, 16 ).arg( reply->url().toString() ), 3 );
526void QgsNetworkAccessManager::onReplyFinished( QNetworkReply *reply )
528 emit
finished( QgsNetworkReplyContent( reply ) );
531void QgsNetworkAccessManager::onReplyDownloadProgress( qint64 bytesReceived, qint64 bytesTotal )
533 if ( QNetworkReply *reply = qobject_cast< QNetworkReply *>( sender() ) )
539int QgsNetworkAccessManager::getRequestId( QNetworkReply *reply )
541 return reply->property(
"requestId" ).toInt();
544void QgsNetworkAccessManager::pauseTimeout( QNetworkReply *reply )
546 Q_ASSERT( reply->manager() ==
this );
548 QTimer *timer = reply->findChild<QTimer *>( u
"timeoutTimer"_s );
549 if ( timer && timer->isActive() )
555void QgsNetworkAccessManager::restartTimeout( QNetworkReply *reply )
557 Q_ASSERT( reply->manager() ==
this );
559 QTimer *timer = reply->findChild<QTimer *>( u
"timeoutTimer"_s );
562 Q_ASSERT( !timer->isActive() );
564 timer->setSingleShot(
true );
569void QgsNetworkAccessManager::afterAuthRequestHandled( QNetworkReply *reply )
571 if ( reply->manager() ==
this )
573 restartTimeout( reply );
574 emit authRequestHandled( reply );
579void QgsNetworkAccessManager::onReplySslErrors(
const QList<QSslError> &errors )
581 QNetworkReply *reply = qobject_cast< QNetworkReply *>( sender() );
583 Q_ASSERT( reply->manager() ==
this );
585 QgsDebugMsgLevel( u
"Stopping network reply timeout whilst SSL error is handled"_s, 2 );
586 pauseTimeout( reply );
591 mSslErrorHandlerSemaphore.acquire();
595 emit sslErrorsOccurred( reply, errors );
596 if (
this != sMainNAM )
600 mSslErrorHandlerSemaphore.acquire();
601 mSslErrorHandlerSemaphore.release();
602 afterSslErrorHandled( reply );
606void QgsNetworkAccessManager::afterSslErrorHandled( QNetworkReply *reply )
608 if ( reply->manager() ==
this )
610 restartTimeout( reply );
611 emit sslErrorsHandled( reply );
615void QgsNetworkAccessManager::handleSslErrors( QNetworkReply *reply,
const QList<QSslError> &errors )
617 mSslErrorHandler->handleSslErrors( reply, errors );
618 afterSslErrorHandled( reply );
619 qobject_cast<QgsNetworkAccessManager *>( reply->manager() )->mSslErrorHandlerSemaphore.release();
624void QgsNetworkAccessManager::onAuthRequired( QNetworkReply *reply, QAuthenticator *auth )
627 Q_ASSERT( reply->manager() ==
this );
629 QgsDebugMsgLevel( u
"Stopping network reply timeout whilst auth request is handled"_s, 2 );
630 pauseTimeout( reply );
635 mAuthRequestHandlerSemaphore.acquire();
639 emit authRequestOccurred( reply, auth );
641 if (
this != sMainNAM )
645 mAuthRequestHandlerSemaphore.acquire();
646 mAuthRequestHandlerSemaphore.release();
647 afterAuthRequestHandled( reply );
653 if (
this != sMainNAM )
655 sMainNAM->requestAuthOpenBrowser( url );
659 mAuthHandler->handleAuthRequestOpenBrowser( url );
664 if (
this != sMainNAM )
666 sMainNAM->requestAuthCloseBrowser();
670 mAuthHandler->handleAuthRequestCloseBrowser();
675 if (
this != sMainNAM )
682void QgsNetworkAccessManager::handleAuthRequest( QNetworkReply *reply, QAuthenticator *auth )
684 mAuthHandler->handleAuthRequest( reply, auth );
688 afterAuthRequestHandled( reply );
689 qobject_cast<QgsNetworkAccessManager *>( reply->manager() )->mAuthRequestHandlerSemaphore.release();
696 case QNetworkRequest::AlwaysNetwork:
697 return u
"AlwaysNetwork"_s;
698 case QNetworkRequest::PreferNetwork:
699 return u
"PreferNetwork"_s;
700 case QNetworkRequest::PreferCache:
701 return u
"PreferCache"_s;
702 case QNetworkRequest::AlwaysCache:
703 return u
"AlwaysCache"_s;
705 return u
"PreferNetwork"_s;
710 if ( name ==
"AlwaysNetwork"_L1 )
712 return QNetworkRequest::AlwaysNetwork;
714 else if ( name ==
"PreferNetwork"_L1 )
716 return QNetworkRequest::PreferNetwork;
718 else if ( name ==
"PreferCache"_L1 )
720 return QNetworkRequest::PreferCache;
722 else if ( name ==
"AlwaysCache"_L1 )
724 return QNetworkRequest::AlwaysCache;
726 return QNetworkRequest::PreferNetwork;
732 mUseSystemProxy =
false;
734 Q_ASSERT( sMainNAM );
736 if ( sMainNAM !=
this )
738 connect(
this, &QNetworkAccessManager::proxyAuthenticationRequired, sMainNAM, &QNetworkAccessManager::proxyAuthenticationRequired, connectionType );
753 connect(
this, &QNetworkAccessManager::sslErrors, sMainNAM, &QNetworkAccessManager::sslErrors, connectionType );
765 if ( !mSslErrorHandler )
769 setAuthHandler( std::make_unique< QgsNetworkAuthenticationHandler>() );
772 connect(
this, &QgsNetworkAccessManager::sslErrorsOccurred, sMainNAM, &QgsNetworkAccessManager::handleSslErrors );
774 connect(
this, &QNetworkAccessManager::authenticationRequired,
this, &QgsNetworkAccessManager::onAuthRequired );
775 connect(
this, &QgsNetworkAccessManager::authRequestOccurred, sMainNAM, &QgsNetworkAccessManager::handleAuthRequest );
777 connect(
this, &QNetworkAccessManager::finished,
this, &QgsNetworkAccessManager::onReplyFinished );
781 QStringList excludes;
782 QStringList noProxyURLs;
802 if ( proxyTypeString ==
"DefaultProxy"_L1 )
804 mUseSystemProxy =
true;
805 QNetworkProxyFactory::setUseSystemConfiguration(
true );
806 QList<QNetworkProxy> proxies = QNetworkProxyFactory::systemProxyForQuery();
807 if ( !proxies.isEmpty() )
809 proxy = proxies.first();
815 QNetworkProxy::ProxyType proxyType = QNetworkProxy::DefaultProxy;
816 if ( proxyTypeString ==
"Socks5Proxy"_L1 )
818 proxyType = QNetworkProxy::Socks5Proxy;
820 else if ( proxyTypeString ==
"HttpProxy"_L1 )
822 proxyType = QNetworkProxy::HttpProxy;
824 else if ( proxyTypeString ==
"HttpCachingProxy"_L1 )
826 proxyType = QNetworkProxy::HttpCachingProxy;
828 else if ( proxyTypeString ==
"FtpCachingProxy"_L1 )
830 proxyType = QNetworkProxy::FtpCachingProxy;
832 QgsDebugMsgLevel( u
"setting proxy %1 %2:%3 %4/%5"_s.arg( proxyType ).arg( proxyHost ).arg( proxyPort ).arg( proxyUser, proxyPassword ), 2 );
833 proxy = QNetworkProxy( proxyType, proxyHost, proxyPort, proxyUser, proxyPassword );
837 if ( !authcfg.isEmpty() )
840 QgsDebugMsgLevel( u
"setting proxy from stored authentication configuration %1"_s.arg( authcfg ), 2 );
843 authManager->updateNetworkProxy( proxy, authcfg );
845 QgsDebugError( u
"Auth manager is not available - cannot update network proxy for authcfg: %1"_s.arg( authcfg ) );
857 if ( cacheDirectory.isEmpty() )
858 cacheDirectory = QStandardPaths::writableLocation( QStandardPaths::CacheLocation );
866 if ( cache() != newcache )
867 setCache( newcache );
869 if (
this != sMainNAM )
871 static_cast<QgsNetworkCookieJar *
>( cookieJar() )->setAllCookies(
static_cast<QgsNetworkCookieJar *
>( sMainNAM->cookieJar() )->allCookies() );
875void QgsNetworkAccessManager::syncCookies(
const QList<QNetworkCookie> &cookies )
877 if ( sender() !=
this )
879 static_cast<QgsNetworkCookieJar *
>( cookieJar() )->setAllCookies( cookies );
880 if (
this == sMainNAM )
901 br.
get( request, forceRefresh, feedback );
911 ( void ) br.
post( request, data, forceRefresh, feedback );
917 QString
id = QUuid::createUuid().toString();
918 sCustomPreprocessors.emplace_back( std::make_pair(
id, processor ) );
924 const size_t prevCount = sCustomPreprocessors.size();
925 sCustomPreprocessors.erase(
926 std::remove_if( sCustomPreprocessors.begin(), sCustomPreprocessors.end(), [
id]( std::pair< QString, std::function<
void( QNetworkRequest * ) > > &a ) { return a.first == id; } ),
927 sCustomPreprocessors.end()
929 return prevCount != sCustomPreprocessors.size();
934 const size_t prevCount = sCustomAdvancedPreprocessors.size();
935 sCustomAdvancedPreprocessors.erase(
937 sCustomAdvancedPreprocessors.begin(),
938 sCustomAdvancedPreprocessors.end(),
939 [
id]( std::pair< QString, std::function<
void( QNetworkRequest *,
int &, QByteArray * ) > > &a ) { return a.first == id; }
941 sCustomAdvancedPreprocessors.end()
943 return prevCount != sCustomAdvancedPreprocessors.size();
948 QString
id = QUuid::createUuid().toString();
949 sCustomAdvancedPreprocessors.emplace_back( std::make_pair(
id, processor ) );
955 QString
id = QUuid::createUuid().toString();
956 sCustomReplyPreprocessors.emplace_back( std::make_pair(
id, processor ) );
962 const size_t prevCount = sCustomReplyPreprocessors.size();
963 sCustomReplyPreprocessors.erase(
965 sCustomReplyPreprocessors.begin(), sCustomReplyPreprocessors.end(), [
id]( std::pair< QString, std::function<
void(
const QNetworkRequest &, QNetworkReply * ) > > &a ) { return a.first == id; }
967 sCustomReplyPreprocessors.end()
969 return prevCount != sCustomReplyPreprocessors.size();
974 for (
const auto &preprocessor : sCustomPreprocessors )
976 preprocessor.second( req );
988 , mOriginatingThreadId( u
"0x%2"_s.arg( reinterpret_cast<quintptr>( QThread::currentThread() ), 2 * QT_POINTER_SIZE, 16,
'0'_L1 ) )
1003 QgsDebugError( u
"SSL errors occurred accessing URL:\n%1"_s.arg( reply->request().url().toString() ) );
1013 QgsDebugError( u
"Network reply required authentication, but no handler was in place to provide this authentication request while accessing the URL:\n%1"_s.arg( reply->request().url().toString() ) );
1019 QgsDebugError( u
"Network authentication required external browser to open URL %1, but no handler was in place"_s.arg( url.toString() ) );
1024 QgsDebugError( u
"Network authentication required external browser closed, but no handler was in place"_s );
1028#include "qgsnetworkaccessmanager.moc"
QFlags< NetworkRequestFlag > NetworkRequestFlags
Flags controlling behavior of network requests.
static int versionInt()
Version number used for comparing versions using the "Check QGIS Version" function.
static QgsAuthManager * authManager()
Returns the application's authentication manager instance.
Configuration container for SSL server connection exceptions or overrides.
QSsl::SslProtocol sslProtocol() const
SSL server protocol to use in connections.
int sslPeerVerifyDepth() const
Number or SSL client's peer to verify in connections.
bool isNull() const
Whether configuration is null (missing components).
QSslSocket::PeerVerifyMode sslPeerVerifyMode() const
SSL client's peer verify mode to use in connections.
Singleton which offers an interface to manage the authentication configuration database and to utiliz...
const QgsAuthConfigSslServer sslCertCustomConfigByHost(const QString &hostport)
sslCertCustomConfigByHost get an SSL certificate custom config by hostport (host:port)
A thread safe class for performing blocking (sync) network requests, with full support for QGIS proxy...
ErrorCode post(QNetworkRequest &request, QIODevice *data, bool forceRefresh=false, QgsFeedback *feedback=nullptr)
Performs a "post" operation on the specified request, using the given data.
void setAuthCfg(const QString &authCfg)
Sets the authentication config id which should be used during the request.
ErrorCode get(QNetworkRequest &request, bool forceRefresh=false, QgsFeedback *feedback=nullptr, RequestFlags requestFlags=QgsBlockingNetworkRequest::RequestFlags())
Performs a "get" operation on the specified request.
QgsNetworkReplyContent reply() const
Returns the content of the network reply, after a get(), post(), head() or put() request has been mad...
Base class for feedback objects to be used for cancellation of something running in a worker thread.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true, const char *file=__builtin_FILE(), const char *function=__builtin_FUNCTION(), int line=__builtin_LINE(), Qgis::StringFormat format=Qgis::StringFormat::PlainText)
Adds a message to the log instance (and creates it if necessary).
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 abortAuthBrowser()
Abort any outstanding external browser login request.
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 requestAuthOpenBrowser(const QUrl &url) const
Forwards an external browser login url opening request to the authentication handler.
void requestAuthCloseBrowser() const
Forwards an external browser login closure request to the authentication handler.
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 requestCreated(const QgsNetworkRequestParameters &request)
Emitted when a network request has been created.
static QgsNetworkReplyContent blockingGet(QNetworkRequest &request, const QString &authCfg=QString(), bool forceRefresh=false, QgsFeedback *feedback=nullptr, Qgis::NetworkRequestFlags flags=Qgis::NetworkRequestFlags())
Posts a GET request to obtain the contents of the target request and returns a new QgsNetworkReplyCon...
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.
static const QgsSettingsEntryString * settingsProxyPort
Settings entry for proxy port.
static QNetworkRequest::CacheLoadControl cacheLoadControlFromName(const QString &name)
Returns QNetworkRequest::CacheLoadControl from a name.
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 void setTimeout(int time)
Sets the maximum timeout time for network requests, in milliseconds.
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 QgsNetworkReplyContent blockingPost(QNetworkRequest &request, const QByteArray &data, const QString &authCfg=QString(), bool forceRefresh=false, QgsFeedback *feedback=nullptr, Qgis::NetworkRequestFlags flags=Qgis::NetworkRequestFlags())
Posts a POST request to obtain the contents of the target request, using the given data,...
static const QgsSettingsEntryBool * settingsProxyEnabled
Settings entry for whether proxy is enabled.
static int timeout()
Returns the network timeout length, in milliseconds.
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.
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
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.
Wrapper implementation of QNetworkDiskCache with all methods guarded by a mutex solely for internal u...
void setCacheDirectory(const QString &cacheDir)
qint64 maximumCacheSize() const
void setMaximumCacheSize(qint64 size)
QString cacheDirectory() const
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.
@ AttributeUserAgentSuffix
Custom string to append to the default User-Agent header.
@ AttributeInitiatorClass
Class name of original object which created the request.
@ AttributeInitiatorRequestId
Internal ID used by originator object to identify requests.
QgsNetworkRequestParameters()=default
QNetworkAccessManager::Operation operation() const
Returns the request operation, e.g.
QNetworkRequest request() const
Returns the network request.
QByteArray content() const
Returns the request's content.
A boolean settings entry.
An integer settings entry.
A string list settings entry.
static const QgsSettingsEntryInteger64 * settingsNetworkCacheSize
Settings entry network cache directory.
static const QgsSettingsEntryString * settingsNetworkCacheDirectory
Settings entry network cache directory.
static QgsSettingsTreeNode * sTreeProxy
static QgsSettingsTreeNode * sTreeNetwork
virtual void handleSslErrors(QNetworkReply *reply, const QList< QSslError > &errors)
Called whenever SSL errors are encountered during a network reply.
#define Q_NOWARN_DEPRECATED_POP
#define Q_NOWARN_DEPRECATED_PUSH
#define QgsDebugMsgLevel(str, level)
#define QgsDebugError(str)