• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

KIO

proxyscout.cpp

Go to the documentation of this file.
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., 51 Franklin Street, Fifth Floor,
00017    Boston, MA 02110-1301, USA.
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         // Never use a proxy for the script itself
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();   // return value will be ignored
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         // Suppress further attempts for 5 minutes
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                     // If the URL is invalid or the URL is valid but in opaque
00173                     // format which indicates a port number being present in
00174                     // this particular case, simply calling setProtocol() on
00175                     // it trashes the whole URL.
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 ) // 30 minutes
00182                     {
00183                         // black listing expired
00184                         m_blackList.remove( proxy );
00185                         return proxy;
00186                     }
00187                 }
00188                 else return "DIRECT";
00189             }
00190             // FIXME: blacklist
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 // vim: ts=4 sw=4 et

KIO

Skip menu "KIO"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.5.7
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal