KIO
proxyscout.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <cstdlib>
00022 #include <ctime>
00023
00024 #include <klocale.h>
00025 #include <knotification.h>
00026 #include <kprotocolmanager.h>
00027 #include <kpluginfactory.h>
00028 #include <kpluginloader.h>
00029 #include <QtDBus/QtDBus>
00030
00031 #include "proxyscout.moc"
00032 #include "discovery.h"
00033 #include "script.h"
00034
00035 K_PLUGIN_FACTORY(ProxyScoutFactory,
00036 registerPlugin<KPAC::ProxyScout>();
00037 )
00038 K_EXPORT_PLUGIN(ProxyScoutFactory("KProxyScoutd"))
00039
00040
00041 namespace KPAC
00042 {
00043 ProxyScout::QueuedRequest::QueuedRequest( const QDBusMessage &reply, const KUrl& u )
00044 : transaction( reply ), url( u )
00045 {
00046 }
00047
00048 ProxyScout::ProxyScout(QObject* parent, const QList<QVariant>&)
00049 : KDEDModule(parent),
00050 m_componentData("proxyscout"),
00051 m_downloader( 0 ),
00052 m_script( 0 ),
00053 m_suspendTime( 0 )
00054 {
00055 }
00056
00057 ProxyScout::~ProxyScout()
00058 {
00059 delete m_script;
00060 }
00061
00062 QString ProxyScout::proxyForUrl( const QString& checkUrl, const QDBusMessage &msg )
00063 {
00064 KUrl url( checkUrl );
00065
00066 if ( m_suspendTime )
00067 {
00068 if ( std::time( 0 ) - m_suspendTime < 300 ) return "DIRECT";
00069 m_suspendTime = 0;
00070 }
00071
00072
00073 if ( m_downloader && url.equals( m_downloader->scriptUrl(), KUrl::CompareWithoutTrailingSlash ) ) return "DIRECT";
00074
00075 if ( m_script ) return handleRequest( url );
00076
00077 if ( m_downloader || startDownload() )
00078 {
00079 msg.setDelayedReply(true);
00080 m_requestQueue.append( QueuedRequest( msg, url ) );
00081 return QString();
00082 }
00083 else return "DIRECT";
00084 }
00085
00086 void ProxyScout::blackListProxy( const QString& proxy )
00087 {
00088 m_blackList[ proxy ] = std::time( 0 );
00089 }
00090
00091 void ProxyScout::reset()
00092 {
00093 delete m_script;
00094 m_script = 0;
00095 delete m_downloader;
00096 m_downloader = 0;
00097 m_blackList.clear();
00098 m_suspendTime = 0;
00099 KProtocolManager::reparseConfiguration();
00100 }
00101
00102 bool ProxyScout::startDownload()
00103 {
00104 switch ( KProtocolManager::proxyType() )
00105 {
00106 case KProtocolManager::WPADProxy:
00107 m_downloader = new Discovery( this );
00108 break;
00109 case KProtocolManager::PACProxy:
00110 m_downloader = new Downloader( this );
00111 m_downloader->download( KUrl( KProtocolManager::proxyConfigScript() ) );
00112 break;
00113 default:
00114 return false;
00115 }
00116 connect( m_downloader, SIGNAL( result( bool ) ),
00117 SLOT( downloadResult( bool ) ) );
00118 return true;
00119 }
00120
00121 void ProxyScout::downloadResult( bool success )
00122 {
00123 if ( success )
00124 try
00125 {
00126 m_script = new Script( m_downloader->script() );
00127 }
00128 catch ( const Script::Error& e )
00129 {
00130 KNotification *notify= new KNotification ( "script-error" );
00131 notify->setText( i18n("The proxy configuration script is invalid:\n%1" , e.message() ) );
00132 notify->setComponentData(m_componentData);
00133 notify->sendEvent();
00134 success = false;
00135 }
00136 else
00137 {
00138 KNotification *notify = new KNotification ("download-error");
00139 notify->setText( m_downloader->error() );
00140 notify->setComponentData(m_componentData);
00141 notify->sendEvent();
00142 }
00143
00144 for ( RequestQueue::Iterator it = m_requestQueue.begin();
00145 it != m_requestQueue.end(); ++it )
00146 {
00147 if ( success )
00148 QDBusConnection::sessionBus().send( ( *it ).transaction.createReply( handleRequest( ( *it ).url ) ) );
00149 else
00150 QDBusConnection::sessionBus().send( ( *it ).transaction.createReply( QString( "DIRECT" ) ) );
00151 }
00152 m_requestQueue.clear();
00153 m_downloader->deleteLater();
00154 m_downloader = 0;
00155
00156 if ( !success ) m_suspendTime = std::time( 0 );
00157 }
00158
00159 QString ProxyScout::handleRequest( const KUrl& url )
00160 {
00161 try
00162 {
00163 QString result = m_script->evaluate( url );
00164 const QStringList proxies = result.split( ';', QString::SkipEmptyParts );
00165 for ( QStringList::ConstIterator it = proxies.begin();
00166 it != proxies.end(); ++it )
00167 {
00168 QString proxy = ( *it ).trimmed();
00169 if ( proxy.startsWith( QLatin1String( "PROXY" ) ) )
00170 {
00171 KUrl proxyURL( proxy = proxy.mid( 5 ).trimmed() );
00172
00173
00174
00175
00176 int len = proxyURL.protocol().length();
00177 if ( !proxyURL.isValid() || proxy.indexOf( ":/", len ) != len )
00178 proxy.prepend("http://");
00179 if ( !m_blackList.contains( proxy ) )
00180 return proxy;
00181 if ( std::time( 0 ) - m_blackList[ proxy ] > 1800 )
00182 {
00183
00184 m_blackList.remove( proxy );
00185 return proxy;
00186 }
00187 }
00188 else return "DIRECT";
00189 }
00190
00191 }
00192 catch ( const Script::Error& e )
00193 {
00194 KNotification *n=new KNotification( "evaluation-error" );
00195 n->setText( i18n( "The proxy configuration script returned an error:\n%1" , e.message() ) );
00196 n->setComponentData(m_componentData);
00197 n->sendEvent();
00198 }
00199 return "DIRECT";
00200 }
00201 }
00202
00203