34 #include <QNetworkReply>    35 #include <QThreadStorage>    36 #include <QAuthenticator>    39 #include <QSslConfiguration>    48 class QgsNetworkProxyFactory : 
public QNetworkProxyFactory
    51     QgsNetworkProxyFactory() = 
default;
    53     QList<QNetworkProxy> queryProxy( 
const QNetworkProxyQuery &query = QNetworkProxyQuery() )
 override    60         QList<QNetworkProxy> systemproxies = f->systemProxyForQuery( query );
    61         if ( !systemproxies.isEmpty() )
    64         QList<QNetworkProxy> proxies = f->queryProxy( query );
    65         if ( !proxies.isEmpty() )
    70       if ( query.queryType() != QNetworkProxyQuery::UrlRequest )
    73       QString url = query.url().toString();
    75       Q_FOREACH ( 
const QString &exclude, nam->
excludeList() )
    77         if ( url.startsWith( exclude ) )
    79           QgsDebugMsgLevel( QString( 
"using default proxy for %1 [exclude %2]" ).arg( url, exclude ), 4 );
    80           return QList<QNetworkProxy>() << QNetworkProxy();
    86         QgsDebugMsgLevel( QString( 
"requesting system proxy for query %1" ).arg( url ), 4 );
    87         QList<QNetworkProxy> proxies = QNetworkProxyFactory::systemProxyForQuery( query );
    88         if ( !proxies.isEmpty() )
    91                             .arg( proxies.first().hostName() ).arg( proxies.first().port() ), 4 );
   107   static QThreadStorage<QgsNetworkAccessManager> sInstances;
   110   if ( nam->thread() == qApp->thread() )
   113   if ( !nam->mInitialized )
   120   : QNetworkAccessManager( parent )
   122   setProxyFactory( 
new QgsNetworkProxyFactory() );
   127   mProxyFactories.insert( 0, factory );
   132   mProxyFactories.removeAll( factory );
   137   return mProxyFactories;
   142   return mExcludedURLs;
   147   return mFallbackProxy;
   152   QgsDebugMsg( QString( 
"proxy settings: (type:%1 host: %2:%3, user:%4, password:%5" )
   153                .arg( proxy.type() == QNetworkProxy::DefaultProxy ? 
"DefaultProxy" :
   154                      proxy.type() == QNetworkProxy::Socks5Proxy ? 
"Socks5Proxy" :
   155                      proxy.type() == QNetworkProxy::NoProxy ? 
"NoProxy" :
   156                      proxy.type() == QNetworkProxy::HttpProxy ? 
"HttpProxy" :
   157                      proxy.type() == QNetworkProxy::HttpCachingProxy ? 
"HttpCachingProxy" :
   158                      proxy.type() == QNetworkProxy::FtpCachingProxy ? 
"FtpCachingProxy" :
   163                      proxy.password().isEmpty() ? 
"not set" : 
"set" ) );
   165   mFallbackProxy = proxy;
   166   mExcludedURLs = excludes;
   173   QNetworkRequest *pReq( const_cast< QNetworkRequest * >( &req ) ); 
   175   QString userAgent = s.
value( QStringLiteral( 
"/qgis/networkAndProxy/userAgent" ), 
"Mozilla/5.0" ).toString();
   176   if ( !userAgent.isEmpty() )
   179   pReq->setRawHeader( 
"User-Agent", userAgent.toUtf8() );
   182   bool ishttps = pReq->url().scheme().toLower() == QLatin1String( 
"https" );
   186     QSslConfiguration sslconfig( pReq->sslConfiguration() );
   190     QString hostport( QStringLiteral( 
"%1:%2" )
   191                       .arg( pReq->url().host().trimmed() )
   192                       .arg( pReq->url().port() != -1 ? pReq->url().port() : 443 ) );
   194     if ( !servconfig.
isNull() )
   196       QgsDebugMsg( QString( 
"Adding SSL custom config to request for %1" ).arg( hostport ) );
   202     pReq->setSslConfiguration( sslconfig );
   207   QNetworkReply *reply = QNetworkAccessManager::createRequest( op, req, outgoingData );
   214   QTimer *timer = 
new QTimer( reply );
   215   timer->setObjectName( QStringLiteral( 
"timeoutTimer" ) );
   216   connect( timer, &QTimer::timeout, 
this, &QgsNetworkAccessManager::abortRequest );
   217   timer->setSingleShot( 
true );
   218   timer->start( s.
value( QStringLiteral( 
"/qgis/networkAndProxy/networkTimeout" ), 
"60000" ).toInt() );
   220   connect( reply, &QNetworkReply::downloadProgress, timer, [timer] { timer->start(); } );
   221   connect( reply, &QNetworkReply::uploadProgress, timer, [timer] { timer->start(); } );
   222   connect( reply, &QNetworkReply::finished, timer, &QTimer::stop );
   223   QgsDebugMsgLevel( QString( 
"Created [reply:%1]" ).arg( ( qint64 ) reply, 0, 16 ), 3 );
   228 void QgsNetworkAccessManager::abortRequest()
   230   QTimer *timer = qobject_cast<QTimer *>( sender() );
   233   QNetworkReply *reply = qobject_cast<QNetworkReply *>( timer->parent() );
   237   QgsDebugMsgLevel( QString( 
"Abort [reply:%1] %2" ).arg( ( qint64 ) reply, 0, 16 ).arg( reply->url().toString() ), 3 );
   249     case QNetworkRequest::AlwaysNetwork:
   250       return QStringLiteral( 
"AlwaysNetwork" );
   251     case QNetworkRequest::PreferNetwork:
   252       return QStringLiteral( 
"PreferNetwork" );
   253     case QNetworkRequest::PreferCache:
   254       return QStringLiteral( 
"PreferCache" );
   255     case QNetworkRequest::AlwaysCache:
   256       return QStringLiteral( 
"AlwaysCache" );
   260   return QStringLiteral( 
"PreferNetwork" );
   265   if ( name == QLatin1String( 
"AlwaysNetwork" ) )
   267     return QNetworkRequest::AlwaysNetwork;
   269   else if ( name == QLatin1String( 
"PreferNetwork" ) )
   271     return QNetworkRequest::PreferNetwork;
   273   else if ( name == QLatin1String( 
"PreferCache" ) )
   275     return QNetworkRequest::PreferCache;
   277   else if ( name == QLatin1String( 
"AlwaysCache" ) )
   279     return QNetworkRequest::AlwaysCache;
   281   return QNetworkRequest::PreferNetwork;
   287   mUseSystemProxy = 
false;
   289   Q_ASSERT( sMainNAM );
   291   if ( sMainNAM != 
this )
   293     connect( 
this, &QNetworkAccessManager::authenticationRequired,
   294              sMainNAM, &QNetworkAccessManager::authenticationRequired,
   295              Qt::BlockingQueuedConnection );
   297     connect( 
this, &QNetworkAccessManager::proxyAuthenticationRequired,
   298              sMainNAM, &QNetworkAccessManager::proxyAuthenticationRequired,
   299              Qt::BlockingQueuedConnection );
   305     connect( 
this, &QNetworkAccessManager::sslErrors,
   306              sMainNAM, &QNetworkAccessManager::sslErrors,
   307              Qt::BlockingQueuedConnection );
   314   QStringList excludes;
   316   bool proxyEnabled = settings.
value( QStringLiteral( 
"proxy/proxyEnabled" ), 
false ).toBool();
   319     excludes = settings.
value( QStringLiteral( 
"proxy/proxyExcludedUrls" ), 
"" ).toString().split( 
'|', QString::SkipEmptyParts );
   322     QString proxyHost = settings.
value( QStringLiteral( 
"proxy/proxyHost" ), 
"" ).toString();
   323     int proxyPort = settings.
value( QStringLiteral( 
"proxy/proxyPort" ), 
"" ).toString().toInt();
   325     QString proxyUser = settings.
value( QStringLiteral( 
"proxy/proxyUser" ), 
"" ).toString();
   326     QString proxyPassword = settings.
value( QStringLiteral( 
"proxy/proxyPassword" ), 
"" ).toString();
   328     QString proxyTypeString = settings.
value( QStringLiteral( 
"proxy/proxyType" ), 
"" ).toString();
   330     if ( proxyTypeString == QLatin1String( 
"DefaultProxy" ) )
   332       mUseSystemProxy = 
true;
   333       QNetworkProxyFactory::setUseSystemConfiguration( 
true );
   334       QList<QNetworkProxy> proxies = QNetworkProxyFactory::systemProxyForQuery();
   335       if ( !proxies.isEmpty() )
   337         proxy = proxies.first();
   343       QNetworkProxy::ProxyType proxyType = QNetworkProxy::DefaultProxy;
   344       if ( proxyTypeString == QLatin1String( 
"Socks5Proxy" ) )
   346         proxyType = QNetworkProxy::Socks5Proxy;
   348       else if ( proxyTypeString == QLatin1String( 
"HttpProxy" ) )
   350         proxyType = QNetworkProxy::HttpProxy;
   352       else if ( proxyTypeString == QLatin1String( 
"HttpCachingProxy" ) )
   354         proxyType = QNetworkProxy::HttpCachingProxy;
   356       else if ( proxyTypeString == QLatin1String( 
"FtpCachingProxy" ) )
   358         proxyType = QNetworkProxy::FtpCachingProxy;
   360       QgsDebugMsg( QStringLiteral( 
"setting proxy %1 %2:%3 %4/%5" )
   362                    .arg( proxyHost ).arg( proxyPort )
   363                    .arg( proxyUser, proxyPassword )
   365       proxy = QNetworkProxy( proxyType, proxyHost, proxyPort, proxyUser, proxyPassword );
   368     QString authcfg = settings.
value( QStringLiteral( 
"proxy/authcfg" ), 
"" ).toString();
   369     if ( !authcfg.isEmpty( ) )
   371       QgsDebugMsg( QStringLiteral( 
"setting proxy from stored authentication configuration %1" ).arg( authcfg ) );
   384   QString cacheDirectory = settings.
value( QStringLiteral( 
"cache/directory" ) ).toString();
   385   if ( cacheDirectory.isEmpty() )
   387   qint64 cacheSize = settings.
value( QStringLiteral( 
"cache/size" ), 50 * 1024 * 1024 ).toULongLong();
   393   if ( cache() != newcache )
   394     setCache( newcache );
 bool isNull() const
Whether configuration is null (missing components) 
 
void requestCreated(QNetworkReply *)
 
static QList< QSslCertificate > casMerge(const QList< QSslCertificate > &bundle1, const QList< QSslCertificate > &bundle2)
casMerge merges two certificate bundles in a single one removing duplicates, the certificates from th...
 
static const QString QGIS_VERSION
Version string. 
 
static QString cacheLoadControlName(QNetworkRequest::CacheLoadControl control)
Get name for QNetworkRequest::CacheLoadControl. 
 
int sslPeerVerifyDepth() const
Number or SSL client's peer to verify in connections. 
 
static QString qgisSettingsDirPath()
Returns the path to the settings directory in user's home dir. 
 
This class is a composition of two QSettings instances: 
 
bool updateNetworkProxy(QNetworkProxy &proxy, const QString &authcfg, const QString &dataprovider=QString())
Provider call to update a QNetworkProxy with an authentication config. 
 
void setCacheDirectory(const QString &cacheDir)
 
Configuration container for SSL server connection exceptions or overrides. 
 
void setupDefaultProxyAndCache()
Setup the NAM according to the user's settings. 
 
QStringList excludeList() const
retrieve exclude list (urls shouldn't use the fallback proxy) 
 
QSsl::SslProtocol sslProtocol() const
SSL server protocol to use in connections. 
 
QNetworkReply * createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest &req, QIODevice *outgoingData=nullptr) override
 
static QNetworkRequest::CacheLoadControl cacheLoadControlFromName(const QString &name)
Get QNetworkRequest::CacheLoadControl from name. 
 
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::Warning)
add a message to the instance (and create it if necessary) 
 
QgsNetworkAccessManager(QObject *parent=nullptr)
 
QSslSocket::PeerVerifyMode sslPeerVerifyMode() const
SSL client's peer verify mode to use in connections. 
 
#define QgsDebugMsgLevel(str, level)
 
void requestTimedOut(QNetworkReply *)
 
QString cacheDirectory() const
 
void removeProxyFactory(QNetworkProxyFactory *factory)
remove a factory from the proxy factories list 
 
const QgsAuthConfigSslServer sslCertCustomConfigByHost(const QString &hostport)
sslCertCustomConfigByHost get an SSL certificate custom config by hostport (host:port) ...
 
void insertProxyFactory(QNetworkProxyFactory *factory)
insert a factory into the proxy factories list 
 
static QgsAuthManager * authManager()
Returns the application's authentication manager instance. 
 
static QgsNetworkAccessManager * instance()
returns a pointer to the single instance 
 
qint64 maximumCacheSize() const
 
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), const Section section=NoSection) const
Returns the value for setting key. 
 
const QNetworkProxy & fallbackProxy() const
retrieve fall back proxy (for urls that no factory returned proxies for) 
 
bool useSystemProxy() const
return whether the system proxy should be used 
 
void requestAboutToBeCreated(QNetworkAccessManager::Operation, const QNetworkRequest &, QIODevice *)
 
network access manager for QGIS 
 
void setFallbackProxyAndExcludes(const QNetworkProxy &proxy, const QStringList &excludes)
set fallback proxy and URL that shouldn't use it. 
 
void setMaximumCacheSize(qint64 size)
 
Wrapper implementation of QNetworkDiskCache with all methods guarded by a mutex soly for internal use...
 
const QList< QNetworkProxyFactory * > proxyFactories() const
retrieve proxy factory list