# kio Library API Documentation

Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

# proxyscout.cpp

    00001 /*
    00002    Copyright (c) 2003 Malte Starostik <malte@kde.org>
    00003
    00004    This library is free software; you can redistribute it and/or
    00005    modify it under the terms of the GNU Library General Public
    00006    License as published by the Free Software Foundation; either
    00007    version 2 of the License, or (at your option) any later version.
    00008
    00009    This library is distributed in the hope that it will be useful,
    00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
    00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00012    Library General Public License for more details.
    00013
    00014    You should have received a copy of the GNU Library General Public License
    00015    along with this library; see the file COPYING.LIB.  If not, write to
    00016    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    00017    Boston, MA 02111-1307, USA.
    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         // Never use a proxy for the script itself
    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         // Suppress further attempts for 5 minutes
    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                     // If the URL is invalid or the URL is valid but in opaque
    00161                     // format which indicates a port number being present in
    00162                     // this particular case, simply calling setProtocol() on
    00163                     // it trashes the whole URL.
    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 ) // 30 minutes
    00170                     {
    00171                         // black listing expired
    00172                         m_blackList.remove( it );
    00173                         return proxy;
    00174                     }
    00175                 }
    00176                 else return "DIRECT";
    00177             }
    00178             // FIXME: blacklist
    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 // vim: ts=4 sw=4 et

This file is part of the documentation for kio Library Version 3.4.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Jun 11 20:24:06 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003