# kio Library API Documentation

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

# kprotocolmanager.cpp

    00001 /* This file is part of the KDE libraries
    00002    Copyright (C) 1999 Torben Weis <weis@kde.org>
    00003    Copyright (C) 2000- Waldo Bastain <bastain@kde.org>
    00004    Copyright (C) 2000- Dawit Alemayehu <adawit@kde.org>
    00005
    00006    This library is free software; you can redistribute it and/or
    00007    modify it under the terms of the GNU Library General Public
    00008    License version 2 as published by the Free Software Foundation.
    00009
    00010    This library is distributed in the hope that it will be useful,
    00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
    00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00013    Library General Public License for more details.
    00014
    00015    You should have received a copy of the GNU Library General Public License
    00016    along with this library; see the file COPYING.LIB.  If not, write to
    00017    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    00018    Boston, MA 02111-1307, USA.
    00019 */
    00020
    00021 #include <string.h>
    00022 #include <sys/utsname.h>
    00023
    00024 #include <dcopref.h>
    00025 #include <kdebug.h>
    00026 #include <kglobal.h>
    00027 #include <klocale.h>
    00028 #include <kconfig.h>
    00029 #include <kstandarddirs.h>
    00030 #include <klibloader.h>
    00031 #include <kstringhandler.h>
    00032 #include <kstaticdeleter.h>
    00033 #include <kio/slaveconfig.h>
    00034 #include <kio/ioslave_defaults.h>
    00035 #include <kio/http_slave_defaults.h>
    00036
    00037 #include "kprotocolmanager.h"
    00038
    00039 class
    00040 KProtocolManagerPrivate
    00041 {
    00042 public:
    00043    KProtocolManagerPrivate();
    00044
    00045    ~KProtocolManagerPrivate();
    00046
    00047    KConfig *config;
    00048    KConfig *http_config;
    00049    bool init_busy;
    00050    KURL url;
    00051    QString protocol;
    00052    QString proxy;
    00053    QString modifiers;
    00054    QString useragent;
    00055 };
    00056
    00057 static KProtocolManagerPrivate* d = 0;
    00058 static KStaticDeleter<KProtocolManagerPrivate> kpmpksd;
    00059
    00060 KProtocolManagerPrivate::KProtocolManagerPrivate()
    00061                         :config(0), http_config(0), init_busy(false)
    00062 {
    00063    kpmpksd.setObject(d, this);
    00064 }
    00065
    00066 KProtocolManagerPrivate::~KProtocolManagerPrivate()
    00067 {
    00068    delete config;
    00069    delete http_config;
    00070 }
    00071
    00072
    00073 // DEFAULT USERAGENT STRING
    00074 #define CFG_DEFAULT_UAGENT(X) \
    00075 QString("Mozilla/5.0 (compatible; Konqueror/%1.%2%3) KHTML/%4.%5.%6 (like Gecko)") \
    00076         .arg(KDE_VERSION_MAJOR).arg(KDE_VERSION_MINOR).arg(X).arg(KDE_VERSION_MAJOR).arg(KDE_VERSION_MINOR).arg(KDE_VERSION_RELEASE)
    00077
    00078 void KProtocolManager::reparseConfiguration()
    00079 {
    00080   kpmpksd.destructObject();
    00081
    00082   // Force the slave config to re-read its config...
    00083   KIO::SlaveConfig::self()->reset ();
    00084 }
    00085
    00086 KConfig *KProtocolManager::config()
    00087 {
    00088   if (!d)
    00089      d = new KProtocolManagerPrivate;
    00090
    00091   if (!d->config)
    00092   {
    00093      d->config = new KConfig("kioslaverc", true, false);
    00094   }
    00095   return d->config;
    00096 }
    00097
    00098 KConfig *KProtocolManager::http_config()
    00099 {
    00100   if (!d)
    00101      d = new KProtocolManagerPrivate;
    00102
    00103   if (!d->http_config)
    00104   {
    00105      d->http_config = new KConfig("kio_httprc", false, false);
    00106   }
    00107   return d->http_config;
    00108 }
    00109
    00110 /*=============================== TIMEOUT SETTINGS ==========================*/
    00111
    00112 int KProtocolManager::readTimeout()
    00113 {
    00114   KConfig *cfg = config();
    00115   cfg->setGroup( QString::null );
    00116   int val = cfg->readNumEntry( "ReadTimeout", DEFAULT_READ_TIMEOUT );
    00117   return QMAX(MIN_TIMEOUT_VALUE, val);
    00118 }
    00119
    00120 int KProtocolManager::connectTimeout()
    00121 {
    00122   KConfig *cfg = config();
    00123   cfg->setGroup( QString::null );
    00124   int val = cfg->readNumEntry( "ConnectTimeout", DEFAULT_CONNECT_TIMEOUT );
    00125   return QMAX(MIN_TIMEOUT_VALUE, val);
    00126 }
    00127
    00128 int KProtocolManager::proxyConnectTimeout()
    00129 {
    00130   KConfig *cfg = config();
    00131   cfg->setGroup( QString::null );
    00132   int val = cfg->readNumEntry( "ProxyConnectTimeout", DEFAULT_PROXY_CONNECT_TIMEOUT );
    00133   return QMAX(MIN_TIMEOUT_VALUE, val);
    00134 }
    00135
    00136 int KProtocolManager::responseTimeout()
    00137 {
    00138   KConfig *cfg = config();
    00139   cfg->setGroup( QString::null );
    00140   int val = cfg->readNumEntry( "ResponseTimeout", DEFAULT_RESPONSE_TIMEOUT );
    00141   return QMAX(MIN_TIMEOUT_VALUE, val);
    00142 }
    00143
    00144 /*========================== PROXY SETTINGS =================================*/
    00145
    00146 bool KProtocolManager::useProxy()
    00147 {
    00148   return proxyType() != NoProxy;
    00149 }
    00150
    00151 bool KProtocolManager::useReverseProxy()
    00152 {
    00153   KConfig *cfg = config();
    00154   cfg->setGroup( "Proxy Settings" );
    00155   return cfg->readBoolEntry("ReversedException", false);
    00156 }
    00157
    00158 KProtocolManager::ProxyType KProtocolManager::proxyType()
    00159 {
    00160   KConfig *cfg = config();
    00161   cfg->setGroup( "Proxy Settings" );
    00162   return static_cast<ProxyType>(cfg->readNumEntry( "ProxyType" ));
    00163 }
    00164
    00165 KProtocolManager::ProxyAuthMode KProtocolManager::proxyAuthMode()
    00166 {
    00167   KConfig *cfg = config();
    00168   cfg->setGroup( "Proxy Settings" );
    00169   return static_cast<ProxyAuthMode>(cfg->readNumEntry( "AuthMode" ));
    00170 }
    00171
    00172 /*========================== CACHING =====================================*/
    00173
    00174 bool KProtocolManager::useCache()
    00175 {
    00176   KConfig *cfg = http_config();
    00177   return cfg->readBoolEntry( "UseCache", true );
    00178 }
    00179
    00180 KIO::CacheControl KProtocolManager::cacheControl()
    00181 {
    00182   KConfig *cfg = http_config();
    00183   QString tmp = cfg->readEntry("cache");
    00184   if (tmp.isEmpty())
    00185     return DEFAULT_CACHE_CONTROL;
    00186   return KIO::parseCacheControl(tmp);
    00187 }
    00188
    00189 QString KProtocolManager::cacheDir()
    00190 {
    00191   KConfig *cfg = http_config();
    00192   return cfg->readPathEntry("CacheDir", KGlobal::dirs()->saveLocation("cache","http"));
    00193 }
    00194
    00195 int KProtocolManager::maxCacheAge()
    00196 {
    00197   KConfig *cfg = http_config();
    00198   return cfg->readNumEntry( "MaxCacheAge", DEFAULT_MAX_CACHE_AGE ); // 14 days
    00199 }
    00200
    00201 int KProtocolManager::maxCacheSize()
    00202 {
    00203   KConfig *cfg = http_config();
    00204   return cfg->readNumEntry( "MaxCacheSize", DEFAULT_MAX_CACHE_SIZE ); // 5 MB
    00205 }
    00206
    00207 QString KProtocolManager::noProxyFor()
    00208 {
    00209   KProtocolManager::ProxyType type = proxyType();
    00210
    00211   KConfig *cfg = config();
    00212   cfg->setGroup( "Proxy Settings" );
    00213
    00214   QString noProxy = cfg->readEntry( "NoProxyFor" );
    00215   if (type == EnvVarProxy)
    00216     noProxy = QString::fromLocal8Bit(getenv(noProxy.local8Bit()));
    00217
    00218   return noProxy;
    00219 }
    00220
    00221 QString KProtocolManager::proxyFor( const QString& protocol )
    00222 {
    00223   QString scheme = protocol.lower();
    00224
    00225   if (scheme == "webdav")
    00226     scheme = "http";
    00227   else if (scheme == "webdavs")
    00228     scheme = "https";
    00229
    00230   KConfig *cfg = config();
    00231   cfg->setGroup( "Proxy Settings" );
    00232   return cfg->readEntry( scheme + "Proxy" );
    00233 }
    00234
    00235 QString KProtocolManager::proxyForURL( const KURL &url )
    00236 {
    00237   QString proxy;
    00238   ProxyType pt = proxyType();
    00239
    00240   switch (pt)
    00241   {
    00242       case PACProxy:
    00243       case WPADProxy:
    00244           if (!url.host().isEmpty())
    00245           {
    00246             KURL u (url);
    00247             QString p = u.protocol().lower();
    00248
    00249             // webdav is a KDE specific protocol. Look up proxy
    00250             // information using HTTP instead...
    00251             if ( p == "webdav" )
    00252             {
    00253               p = "http";
    00254               u.setProtocol( p );
    00255             }
    00256             else if ( p == "webdavs" )
    00257             {
    00258               p = "https";
    00259               u.setProtocol( p );
    00260             }
    00261
    00262             if ( p.startsWith("http") || p == "ftp" || p == "gopher" )
    00263               DCOPRef( "kded", "proxyscout" ).call( "proxyForURL", u ).get( proxy );
    00264           }
    00265           break;
    00266       case EnvVarProxy:
    00267           proxy = QString::fromLocal8Bit(getenv(proxyFor(url.protocol()).local8Bit())).stripWhiteSpace();
    00268           break;
    00269       case ManualProxy:
    00270           proxy = proxyFor( url.protocol() );
    00271           break;
    00272       case NoProxy:
    00273       default:
    00274           break;
    00275   }
    00276
    00277   return (proxy.isEmpty() ? QString::fromLatin1("DIRECT") : proxy);
    00278 }
    00279
    00280 void KProtocolManager::badProxy( const QString &proxy )
    00281 {
    00282   DCOPRef( "kded", "proxyscout" ).send( "blackListProxy", proxy );
    00283 }
    00284
    00285 /*
    00286     Domain suffix match. E.g. return true if host is "cuzco.inka.de" and
    00287     nplist is "inka.de,hadiko.de" or if host is "localhost" and nplist is
    00288     "localhost".
    00289 */
    00290 static bool revmatch(const char *host, const char *nplist)
    00291 {
    00292   if (host == 0)
    00293     return false;
    00294
    00295   const char *hptr = host + strlen( host ) - 1;
    00296   const char *nptr = nplist + strlen( nplist ) - 1;
    00297   const char *shptr = hptr;
    00298
    00299   while ( nptr >= nplist )
    00300   {
    00301     if ( *hptr != *nptr )
    00302     {
    00303       hptr = shptr;
    00304
    00305       // Try to find another domain or host in the list
    00306       while(--nptr>=nplist && *nptr!=',' && *nptr!=' ') ;
    00307
    00308       // Strip out multiple spaces and commas
    00309       while(--nptr>=nplist && (*nptr==',' || *nptr==' ')) ;
    00310     }
    00311     else
    00312     {
    00313       if ( nptr==nplist || nptr[-1]==',' || nptr[-1]==' ')
    00314         return true;
    00315       if ( hptr == host ) // e.g. revmatch("bugs.kde.org","mybugs.kde.org")
    00316         return false;
    00317
    00318       hptr--;
    00319       nptr--;
    00320     }
    00321   }
    00322
    00323   return false;
    00324 }
    00325
    00326 QString KProtocolManager::slaveProtocol(const KURL &url, QString &proxy)
    00327 {
    00328   if (url.hasSubURL()) // We don't want the suburl's protocol
    00329   {
    00330      KURL::List list = KURL::split(url);
    00331      KURL::List::Iterator it = list.fromLast();
    00332      return slaveProtocol(*it, proxy);
    00333   }
    00334
    00335   if (!d)
    00336     d = new KProtocolManagerPrivate;
    00337
    00338   if (d->url == url)
    00339   {
    00340      proxy = d->proxy;
    00341      return d->protocol;
    00342   }
    00343
    00344   if (useProxy())
    00345   {
    00346      proxy = proxyForURL(url);
    00347      if ((proxy != "DIRECT") && (!proxy.isEmpty()))
    00348      {
    00349         bool isRevMatch = false;
    00350         KProtocolManager::ProxyType type = proxyType();
    00351         bool useRevProxy = ((type == ManualProxy) && useReverseProxy());
    00352
    00353         QString noProxy;
    00354         // Check no proxy information iff the proxy type is either
    00355         // manual or environment variable based...
    00356         if ( (type == ManualProxy) || (type == EnvVarProxy) )
    00357           noProxy = noProxyFor();
    00358
    00359         if (!noProxy.isEmpty())
    00360         {
    00361            QString qhost = url.host().lower();
    00362            const char *host = qhost.latin1();
    00363            QString qno_proxy = noProxy.stripWhiteSpace().lower();
    00364            const char *no_proxy = qno_proxy.latin1();
    00365            isRevMatch = revmatch(host, no_proxy);
    00366
    00367            // If no match is found and the request url has a port
    00368            // number, try the combination of "host:port". This allows
    00369            // users to enter host:port in the No-proxy-For list.
    00370            if (!isRevMatch && url.port() > 0)
    00371            {
    00372               qhost += ':' + QString::number (url.port());
    00373               host = qhost.latin1();
    00374               isRevMatch = revmatch (host, no_proxy);
    00375            }
    00376
    00377            // If the hostname does not contain a dot, check if
    00378            // <local> is part of noProxy.
    00379            if (!isRevMatch && host && (strchr(host, '.') == NULL))
    00380               isRevMatch = revmatch("<local>", no_proxy);
    00381         }
    00382
    00383         if ( (!useRevProxy && !isRevMatch) || (useRevProxy && isRevMatch) )
    00384         {
    00385            d->url = proxy;
    00386            if ( d->url.isValid() )
    00387            {
    00388               // The idea behind slave protocols is not applicable to http
    00389               // and webdav protocols.
    00390               QString protocol = url.protocol().lower();
    00391               if (protocol.startsWith("http") || protocol.startsWith("webdav"))
    00392                 d->protocol = protocol;
    00393               else
    00394               {
    00395                 d->protocol = d->url.protocol();
    00396                 kdDebug () << "slaveProtocol: " << d->protocol << endl;
    00397               }
    00398
    00399               d->url = url;
    00400               d->proxy = proxy;
    00401               return d->protocol;
    00402            }
    00403         }
    00404      }
    00405   }
    00406
    00407   d->url = url;
    00408   d->proxy = proxy = QString::null;
    00409   d->protocol = url.protocol();
    00410   return d->protocol;
    00411 }
    00412
    00413 /*================================= USER-AGENT SETTINGS =====================*/
    00414
    00415 QString KProtocolManager::userAgentForHost( const QString& hostname )
    00416 {
    00417   QString sendUserAgent = KIO::SlaveConfig::self()->configData("http", hostname.lower(), "SendUserAgent").lower();
    00418   if (sendUserAgent == "false")
    00419      return QString::null;
    00420
    00421   QString useragent = KIO::SlaveConfig::self()->configData("http", hostname.lower(), "UserAgent");
    00422
    00423   // Return the default user-agent if none is specified
    00424   // for the requested host.
    00425   if (useragent.isEmpty())
    00426     return defaultUserAgent();
    00427
    00428   return useragent;
    00429 }
    00430
    00431 QString KProtocolManager::defaultUserAgent( )
    00432 {
    00433   QString modifiers = KIO::SlaveConfig::self()->configData("http", QString::null, "UserAgentKeys");
    00434   return defaultUserAgent(modifiers);
    00435 }
    00436
    00437 QString KProtocolManager::defaultUserAgent( const QString &_modifiers )
    00438 {
    00439   if (!d)
    00440      d = new KProtocolManagerPrivate;
    00441
    00442   QString modifiers = _modifiers.lower();
    00443   if (modifiers.isEmpty())
    00444      modifiers = DEFAULT_USER_AGENT_KEYS;
    00445
    00446   if (d->modifiers == modifiers)
    00447      return d->useragent;
    00448
    00449   QString supp;
    00450   struct utsname nam;
    00451   if( uname(&nam) >= 0 )
    00452   {
    00453     if( modifiers.contains('o') )
    00454     {
    00455       supp += QString("; %1").arg(nam.sysname);
    00456       if ( modifiers.contains('v') )
    00457         supp += QString(" %1").arg(nam.release);
    00458     }
    00459     if( modifiers.contains('p') )
    00460     {
    00461       supp += QString::fromLatin1("; X11");  // TODO: determine this valye instead of hardcoding...
    00462     }
    00463     if( modifiers.contains('m') )
    00464     {
    00465       supp += QString("; %1").arg(nam.machine);
    00466     }
    00467     if( modifiers.contains('l') )
    00468     {
    00469       QStringList languageList = KGlobal::locale()->languageList();
    00470       QStringList::Iterator it = languageList.find( QString::fromLatin1("C") );
    00471       if( it != languageList.end() )
    00472       {
    00473         if( languageList.contains( QString::fromLatin1("en") ) > 0 )
    00474           languageList.remove( it );
    00475         else
    00476           (*it) = QString::fromLatin1("en");
    00477       }
    00478       if( languageList.count() )
    00479         supp += QString("; %1").arg(languageList.join(", "));
    00480     }
    00481   }
    00482   d->modifiers = modifiers;
    00483   d->useragent = CFG_DEFAULT_UAGENT(supp);
    00484   return d->useragent;
    00485 }
    00486
    00487 /*==================================== OTHERS ===============================*/
    00488
    00489 bool KProtocolManager::markPartial()
    00490 {
    00491   KConfig *cfg = config();
    00492   cfg->setGroup( QString::null );
    00493   return cfg->readBoolEntry( "MarkPartial", true );
    00494 }
    00495
    00496 int KProtocolManager::minimumKeepSize()
    00497 {
    00498   KConfig *cfg = config();
    00499   cfg->setGroup( QString::null );
    00500   return cfg->readNumEntry( "MinimumKeepSize",
    00501                             DEFAULT_MINIMUM_KEEP_SIZE ); // 5000 byte
    00502 }
    00503
    00504 bool KProtocolManager::autoResume()
    00505 {
    00506   KConfig *cfg = config();
    00507   cfg->setGroup( QString::null );
    00508   return cfg->readBoolEntry( "AutoResume", false );
    00509 }
    00510
    00511 bool KProtocolManager::persistentConnections()
    00512 {
    00513   KConfig *cfg = config();
    00514   cfg->setGroup( QString::null );
    00515   return cfg->readBoolEntry( "PersistentConnections", true );
    00516 }
    00517
    00518 bool KProtocolManager::persistentProxyConnection()
    00519 {
    00520   KConfig *cfg = config();
    00521   cfg->setGroup( QString::null );
    00522   return cfg->readBoolEntry( "PersistentProxyConnection", false );
    00523 }
    00524
    00525 QString KProtocolManager::proxyConfigScript()
    00526 {
    00527   KConfig *cfg = config();
    00528   cfg->setGroup( "Proxy Settings" );
    00529   return cfg->readEntry( "Proxy Config Script" );
    00530 }

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:03 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003