Quantum GIS API Documentation  master-693a1fe
src/core/qgsnetworkaccessmanager.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002                        qgsnetworkaccessmanager.cpp
00003   This class implements a QNetworkManager with the ability to chain in
00004   own proxy factories.
00005 
00006                               -------------------
00007           begin                : 2010-05-08
00008           copyright            : (C) 2010 by Juergen E. Fischer
00009           email                : jef at norbit dot de
00010 
00011 ***************************************************************************/
00012 
00013 /***************************************************************************
00014  *                                                                         *
00015  *   This program is free software; you can redistribute it and/or modify  *
00016  *   it under the terms of the GNU General Public License as published by  *
00017  *   the Free Software Foundation; either version 2 of the License, or     *
00018  *   (at your option) any later version.                                   *
00019  *                                                                         *
00020  ***************************************************************************/
00021 
00022 #include <qgsnetworkaccessmanager.h>
00023 #include <qgsmessagelog.h>
00024 #include <qgslogger.h>
00025 
00026 #include <QUrl>
00027 #include <QSettings>
00028 #include <QTimer>
00029 #include <QNetworkReply>
00030 
00031 #if QT_VERSION >= 0x40500
00032 class QgsNetworkProxyFactory : public QNetworkProxyFactory
00033 {
00034   public:
00035     QgsNetworkProxyFactory() {}
00036     virtual ~QgsNetworkProxyFactory() {}
00037 
00038     virtual QList<QNetworkProxy> queryProxy( const QNetworkProxyQuery & query = QNetworkProxyQuery() )
00039     {
00040       QgsNetworkAccessManager *nam = QgsNetworkAccessManager::instance();
00041 
00042       // iterate proxies factories and take first non empty list
00043       foreach ( QNetworkProxyFactory *f, nam->proxyFactories() )
00044       {
00045         QList<QNetworkProxy> proxies = f->queryProxy( query );
00046         if ( proxies.size() > 0 )
00047           return proxies;
00048       }
00049 
00050       // no proxies from the proxy factor list check for excludes
00051       if ( query.queryType() != QNetworkProxyQuery::UrlRequest )
00052         return QList<QNetworkProxy>() << nam->fallbackProxy();
00053 
00054       QString url = query.url().toString();
00055 
00056       foreach ( QString exclude, nam->excludeList() )
00057       {
00058         if ( url.startsWith( exclude ) )
00059         {
00060           QgsDebugMsg( QString( "using default proxy for %1 [exclude %2]" ).arg( url ).arg( exclude ) );
00061           return QList<QNetworkProxy>() << QNetworkProxy();
00062         }
00063       }
00064 
00065       QgsDebugMsg( QString( "using user proxy for %1" ).arg( url ) );
00066       return QList<QNetworkProxy>() << nam->fallbackProxy();
00067     }
00068 };
00069 #endif
00070 
00071 QgsNetworkAccessManager *QgsNetworkAccessManager::smNAM = 0;
00072 
00073 QgsNetworkAccessManager *QgsNetworkAccessManager::instance()
00074 {
00075   if ( smNAM )
00076     return smNAM;
00077 
00078   smNAM = new QgsNetworkAccessManager();
00079 
00080   return smNAM;
00081 }
00082 
00083 QgsNetworkAccessManager::QgsNetworkAccessManager( QObject *parent )
00084     : QNetworkAccessManager( parent )
00085 {
00086 #if QT_VERSION >= 0x40500
00087   setProxyFactory( new QgsNetworkProxyFactory() );
00088 #endif
00089 }
00090 
00091 QgsNetworkAccessManager::~QgsNetworkAccessManager()
00092 {
00093 }
00094 
00095 #if QT_VERSION >= 0x40500
00096 void QgsNetworkAccessManager::insertProxyFactory( QNetworkProxyFactory *factory )
00097 {
00098   mProxyFactories.insert( 0, factory );
00099 }
00100 
00101 void QgsNetworkAccessManager::removeProxyFactory( QNetworkProxyFactory *factory )
00102 {
00103   mProxyFactories.removeAll( factory );
00104 }
00105 
00106 const QList<QNetworkProxyFactory *> QgsNetworkAccessManager::proxyFactories() const
00107 {
00108   return mProxyFactories;
00109 }
00110 #endif
00111 
00112 const QStringList &QgsNetworkAccessManager::excludeList() const
00113 {
00114   return mExcludedURLs;
00115 }
00116 
00117 const QNetworkProxy &QgsNetworkAccessManager::fallbackProxy() const
00118 {
00119   return mFallbackProxy;
00120 }
00121 
00122 void QgsNetworkAccessManager::setFallbackProxyAndExcludes( const QNetworkProxy &proxy, const QStringList &excludes )
00123 {
00124   mFallbackProxy = proxy;
00125   mExcludedURLs = excludes;
00126 }
00127 
00128 QNetworkReply *QgsNetworkAccessManager::createRequest( QNetworkAccessManager::Operation op, const QNetworkRequest &req, QIODevice *outgoingData )
00129 {
00130   emit requestAboutToBeCreated( op, req, outgoingData );
00131   QNetworkReply *reply = QNetworkAccessManager::createRequest( op, req, outgoingData );
00132   emit requestCreated( reply );
00133 
00134   // abort request, when network timeout happens
00135   QTimer *timer = new QTimer( reply );
00136   connect( timer, SIGNAL( timeout() ), this, SLOT( abortRequest() ) );
00137 
00138   QSettings s;
00139   timer->start( s.value( "/qgis/networkAndProxy/networkTimeout", "20000" ).toInt() );
00140 
00141   return reply;
00142 }
00143 
00144 void QgsNetworkAccessManager::abortRequest()
00145 {
00146   QTimer *timer = qobject_cast<QTimer *>( sender() );
00147   Q_ASSERT( timer );
00148 
00149   QNetworkReply *reply = qobject_cast<QNetworkReply *>( timer->parent() );
00150   Q_ASSERT( reply );
00151 
00152   QgsMessageLog::logMessage( tr( "Network request %1 timed out" ).arg( reply->url().toString() ), tr( "Network" ) );
00153 
00154   reply->abort();
00155 }
00156 
00157 QString QgsNetworkAccessManager::cacheLoadControlName( QNetworkRequest::CacheLoadControl theControl )
00158 {
00159   switch ( theControl )
00160   {
00161     case QNetworkRequest::AlwaysNetwork:
00162       return "AlwaysNetwork";
00163       break;
00164     case QNetworkRequest::PreferNetwork:
00165       return "PreferNetwork";
00166       break;
00167     case QNetworkRequest::PreferCache:
00168       return "PreferCache";
00169       break;
00170     case QNetworkRequest::AlwaysCache:
00171       return "AlwaysCache";
00172       break;
00173     default:
00174       break;
00175   }
00176   return "PreferNetwork";
00177 }
00178 
00179 QNetworkRequest::CacheLoadControl QgsNetworkAccessManager::cacheLoadControlFromName( const QString &theName )
00180 {
00181   if ( theName == "AlwaysNetwork" )
00182   {
00183     return QNetworkRequest::AlwaysNetwork;
00184   }
00185   else if ( theName == "PreferNetwork" )
00186   {
00187     return QNetworkRequest::PreferNetwork;
00188   }
00189   else if ( theName == "PreferCache" )
00190   {
00191     return QNetworkRequest::PreferCache;
00192   }
00193   else if ( theName == "AlwaysCache" )
00194   {
00195     return QNetworkRequest::AlwaysCache;
00196   }
00197   return QNetworkRequest::PreferNetwork;
00198 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines