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 <dcopclient.h>
00025 #include <kapplication.h>
00026 #include <klocale.h>
00027 #include <knotifyclient.h>
00028 #include <kprotocolmanager.h>
00029
00030 #include "proxyscout.moc"
00031 #include "discovery.h"
00032 #include "script.h"
00033
00034 namespace KPAC
00035 {
00036 ProxyScout::QueuedRequest::QueuedRequest( const KURL& u )
00037 : transaction( kapp->dcopClient()->beginTransaction() ),
00038 url( u )
00039 {
00040 }
00041
00042 ProxyScout::ProxyScout( const QCString& name )
00043 : KDEDModule( name ),
00044 m_instance( new KInstance( "proxyscout" ) ),
00045 m_downloader( 0 ),
00046 m_script( 0 ),
00047 m_suspendTime( 0 )
00048 {
00049 }
00050
00051 ProxyScout::~ProxyScout()
00052 {
00053 delete m_script;
00054 delete m_instance;
00055 }
00056
00057 QString ProxyScout::proxyForURL( const KURL& url )
00058 {
00059 if ( m_suspendTime )
00060 {
00061 if ( std::time( 0 ) - m_suspendTime < 300 ) return "DIRECT";
00062 m_suspendTime = 0;
00063 }
00064
00065
00066 if ( m_downloader && url.equals( m_downloader->scriptURL(), true ) ) return "DIRECT";
00067
00068 if ( m_script ) return handleRequest( url );
00069
00070 if ( m_downloader || startDownload() )
00071 {
00072 m_requestQueue.append( url );
00073 return QString::null;
00074 }
00075 else return "DIRECT";
00076 }
00077
00078 ASYNC ProxyScout::blackListProxy( const QString& proxy )
00079 {
00080 m_blackList[ proxy ] = std::time( 0 );
00081 }
00082
00083 ASYNC ProxyScout::reset()
00084 {
00085 delete m_script;
00086 m_script = 0;
00087 delete m_downloader;
00088 m_downloader = 0;
00089 m_blackList.clear();
00090 m_suspendTime = 0;
00091 KProtocolManager::reparseConfiguration();
00092 }
00093
00094 bool ProxyScout::startDownload()
00095 {
00096 switch ( KProtocolManager::proxyType() )
00097 {
00098 case KProtocolManager::WPADProxy:
00099 m_downloader = new Discovery( this );
00100 break;
00101 case KProtocolManager::PACProxy:
00102 m_downloader = new Downloader( this );
00103 m_downloader->download( KURL( KProtocolManager::proxyConfigScript() ) );
00104 break;
00105 default:
00106 return false;
00107 }
00108 connect( m_downloader, SIGNAL( result( bool ) ),
00109 SLOT( downloadResult( bool ) ) );
00110 return true;
00111 }
00112
00113 void ProxyScout::downloadResult( bool success )
00114 {
00115 KNotifyClient::Instance notifyInstance( m_instance );
00116 if ( success )
00117 try
00118 {
00119 m_script = new Script( m_downloader->script() );
00120 }
00121 catch ( const Script::Error& e )
00122 {
00123 KNotifyClient::event( "script-error", i18n(
00124 "The proxy configuration script is invalid:\n%1" )
00125 .arg( e.message() ) );
00126 success = false;
00127 }
00128 else KNotifyClient::event( "download-error", m_downloader->error() );
00129
00130 for ( RequestQueue::ConstIterator it = m_requestQueue.begin();
00131 it != m_requestQueue.end(); ++it )
00132 {
00133 QCString type = "QString";
00134 QByteArray data;
00135 QDataStream ds( data, IO_WriteOnly );
00136 if ( success ) ds << handleRequest( ( *it ).url );
00137 else ds << QString( "DIRECT" );
00138 kapp->dcopClient()->endTransaction( ( *it ).transaction, type, data );
00139 }
00140 m_requestQueue.clear();
00141 m_downloader->deleteLater();
00142 m_downloader = 0;
00143
00144 if ( !success ) m_suspendTime = std::time( 0 );
00145 }
00146
00147 QString ProxyScout::handleRequest( const KURL& url )
00148 {
00149 try
00150 {
00151 QString result = m_script->evaluate( url );
00152 QStringList proxies = QStringList::split( ';', result );
00153 for ( QStringList::ConstIterator it = proxies.begin();
00154 it != proxies.end(); ++it )
00155 {
00156 QString proxy = ( *it ).stripWhiteSpace();
00157 if ( proxy.left( 5 ) == "PROXY" )
00158 {
00159 KURL proxyURL( proxy = proxy.mid( 5 ).stripWhiteSpace() );
00160
00161
00162
00163
00164 int len = proxyURL.protocol().length();
00165 if ( !proxyURL.isValid() || proxy.find( ":/", len ) != len )
00166 proxy.prepend("http://");
00167 BlackList::Iterator it = m_blackList.find( proxy );
00168 if ( it == m_blackList.end() ) return proxy;
00169 else if ( std::time( 0 ) - *it > 1800 )
00170 {
00171
00172 m_blackList.remove( it );
00173 return proxy;
00174 }
00175 }
00176 else return "DIRECT";
00177 }
00178
00179 }
00180 catch ( const Script::Error& e )
00181 {
00182 KNotifyClient::Instance notifyInstance( m_instance );
00183 KNotifyClient::event( "evaluation-error", i18n(
00184 "The proxy configuration script returned an error:\n%1" )
00185 .arg( e.message() ) );
00186 }
00187 return "DIRECT";
00188 }
00189
00190 extern "C" KDE_EXPORT KDEDModule* create_proxyscout( const QCString& name )
00191 {
00192 return new ProxyScout( name );
00193 }
00194 }
00195
00196