kprotocolmanager.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <string.h>
00022 #include <sys/utsname.h>
00023
00024 #include <kdebug.h>
00025 #include <kglobal.h>
00026 #include <klocale.h>
00027 #include <kconfig.h>
00028 #include <kio/kpac.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 KPAC *pac;
00050 bool init_busy;
00051 KURL url;
00052 QString protocol;
00053 QString proxy;
00054 QString modifiers;
00055 QString useragent;
00056 };
00057
00058 static KStaticDeleter<KProtocolManagerPrivate> kpmpksd;
00059
00060 KProtocolManagerPrivate::KProtocolManagerPrivate()
00061 :config(0), http_config(0), pac(0), init_busy(false)
00062 {
00063 kpmpksd.setObject(this);
00064 }
00065
00066 KProtocolManagerPrivate::~KProtocolManagerPrivate()
00067 {
00068 delete config;
00069 delete http_config;
00070 delete pac;
00071 kpmpksd.setObject(0);
00072 }
00073
00074 static KProtocolManagerPrivate* d = 0;
00075
00076
00077 #define CFG_DEFAULT_UAGENT(X) \
00078 QString("Mozilla/5.0 (compatible; Konqueror/%1.%2%3)") \
00079 .arg(KDE_VERSION_MAJOR).arg(KDE_VERSION_MINOR).arg(X)
00080
00081 void KProtocolManager::reparseConfiguration()
00082 {
00083 delete d;
00084 d = 0;
00085
00086
00087 KIO::SlaveConfig::self()->reset ();
00088 }
00089
00090 KConfig *KProtocolManager::config()
00091 {
00092 if (!d)
00093 d = new KProtocolManagerPrivate;
00094
00095 if (!d->config)
00096 {
00097 d->config = new KConfig("kioslaverc", true, false);
00098 }
00099 return d->config;
00100 }
00101
00102 KConfig *KProtocolManager::http_config()
00103 {
00104 if (!d)
00105 d = new KProtocolManagerPrivate;
00106
00107 if (!d->http_config)
00108 {
00109 d->http_config = new KConfig("kio_httprc", false, false);
00110 }
00111 return d->http_config;
00112 }
00113
00114 KPAC *KProtocolManager::pac()
00115 {
00116 ProxyType type = proxyType();
00117 if (type < PACProxy)
00118 return 0;
00119
00120 if (!d->pac)
00121 {
00122 if (d->init_busy) return 0;
00123 d->init_busy = true;
00124
00125 KLibrary *lib = KLibLoader::self()->library("libkpac");
00126 if (lib)
00127 {
00128 KPAC *(*create_pac)() = (KPAC *(*)())(lib->symbol("create_pac"));
00129 if (create_pac)
00130 {
00131 KPAC *newPAC = create_pac();
00132 switch (type)
00133 {
00134 case PACProxy:
00135 newPAC->init( proxyConfigScript() );
00136 break;
00137 case WPADProxy:
00138 newPAC->discover();
00139 default:
00140 break;
00141 }
00142 d->pac = newPAC;
00143 }
00144 }
00145 d->init_busy = false;
00146 }
00147 return d->pac;
00148 }
00149
00150
00151
00152 int KProtocolManager::readTimeout()
00153 {
00154 KConfig *cfg = config();
00155 cfg->setGroup( QString::null );
00156 int val = cfg->readNumEntry( "ReadTimeout", DEFAULT_READ_TIMEOUT );
00157 return QMAX(MIN_TIMEOUT_VALUE, val);
00158 }
00159
00160 int KProtocolManager::connectTimeout()
00161 {
00162 KConfig *cfg = config();
00163 cfg->setGroup( QString::null );
00164 int val = cfg->readNumEntry( "ConnectTimeout", DEFAULT_CONNECT_TIMEOUT );
00165 return QMAX(MIN_TIMEOUT_VALUE, val);
00166 }
00167
00168 int KProtocolManager::proxyConnectTimeout()
00169 {
00170 KConfig *cfg = config();
00171 cfg->setGroup( QString::null );
00172 int val = cfg->readNumEntry( "ProxyConnectTimeout", DEFAULT_PROXY_CONNECT_TIMEOUT );
00173 return QMAX(MIN_TIMEOUT_VALUE, val);
00174 }
00175
00176 int KProtocolManager::responseTimeout()
00177 {
00178 KConfig *cfg = config();
00179 cfg->setGroup( QString::null );
00180 int val = cfg->readNumEntry( "ResponseTimeout", DEFAULT_RESPONSE_TIMEOUT );
00181 return QMAX(MIN_TIMEOUT_VALUE, val);
00182 }
00183
00184
00185
00186 bool KProtocolManager::useProxy()
00187 {
00188 return proxyType() != NoProxy;
00189 }
00190
00191 bool KProtocolManager::useReverseProxy()
00192 {
00193 KConfig *cfg = config();
00194 cfg->setGroup( "Proxy Settings" );
00195 return cfg->readBoolEntry("ReversedException", false);
00196 }
00197
00198 KProtocolManager::ProxyType KProtocolManager::proxyType()
00199 {
00200 KConfig *cfg = config();
00201 cfg->setGroup( "Proxy Settings" );
00202 return static_cast<ProxyType>(cfg->readNumEntry( "ProxyType" ));
00203 }
00204
00205 KProtocolManager::ProxyAuthMode KProtocolManager::proxyAuthMode()
00206 {
00207 KConfig *cfg = config();
00208 cfg->setGroup( "Proxy Settings" );
00209 return static_cast<ProxyAuthMode>(cfg->readNumEntry( "AuthMode" ));
00210 }
00211
00212
00213
00214 bool KProtocolManager::useCache()
00215 {
00216 KConfig *cfg = http_config();
00217 return cfg->readBoolEntry( "UseCache", true );
00218 }
00219
00220 KIO::CacheControl KProtocolManager::cacheControl()
00221 {
00222 KConfig *cfg = http_config();
00223 QString tmp = cfg->readEntry("cache");
00224 if (tmp.isEmpty())
00225 return DEFAULT_CACHE_CONTROL;
00226 return KIO::parseCacheControl(tmp);
00227 }
00228
00229 QString KProtocolManager::cacheDir()
00230 {
00231 KConfig *cfg = http_config();
00232 return cfg->readEntry("CacheDir", KGlobal::dirs()->saveLocation("cache","http"));
00233 }
00234
00235 int KProtocolManager::maxCacheAge()
00236 {
00237 KConfig *cfg = http_config();
00238 return cfg->readNumEntry( "MaxCacheAge", DEFAULT_MAX_CACHE_AGE );
00239 }
00240
00241 int KProtocolManager::maxCacheSize()
00242 {
00243 KConfig *cfg = http_config();
00244 return cfg->readNumEntry( "MaxCacheSize", DEFAULT_MAX_CACHE_SIZE );
00245 }
00246
00247 QString KProtocolManager::noProxyFor()
00248 {
00249 KConfig *cfg = config();
00250 cfg->setGroup( "Proxy Settings" );
00251 return cfg->readEntry( "NoProxyFor" );
00252 }
00253
00254 QString KProtocolManager::proxyFor( const QString& protocol )
00255 {
00256 KConfig *cfg = config();
00257 cfg->setGroup( "Proxy Settings" );
00258 return cfg->readEntry( protocol.lower() + "Proxy" );
00259 }
00260
00261 QString KProtocolManager::proxyForURL( const KURL &url )
00262 {
00263 if (url.protocol().find("webdav",0,false) == 0)
00264 {
00265 KURL u(url);
00266 if (url.protocol().lower() == "webdav")
00267 u.setProtocol("http");
00268 else
00269 u.setProtocol("https");
00270
00271 QString result = proxyForURL(u);
00272 if (result.startsWith("http"))
00273 result.replace(0, 4, "webdav");
00274 return result;
00275 }
00276
00277 QString proxy;
00278 ProxyType pt = proxyType();
00279
00280 switch (pt)
00281 {
00282 case PACProxy:
00283 case WPADProxy:
00284 if (!url.host().isEmpty() && pac())
00285 proxy = pac()->proxyForURL( url ).stripWhiteSpace();
00286 break;
00287 case EnvVarProxy:
00288 proxy = QString::fromLocal8Bit(getenv(proxyFor(url.protocol()).local8Bit())).stripWhiteSpace();
00289 break;
00290 case ManualProxy:
00291 proxy = proxyFor( url.protocol() );
00292 break;
00293 case NoProxy:
00294 default:
00295 break;
00296 }
00297
00298 return (proxy.isEmpty() ? QString::fromLatin1("DIRECT") : proxy);
00299 }
00300
00301 void KProtocolManager::badProxy( const QString &proxy )
00302 {
00303 if ( d && d->pac )
00304 d->pac->badProxy( proxy );
00305 }
00306
00307
00308
00309
00310
00311
00312 static bool revmatch(const char *host, const char *nplist)
00313 {
00314 if (host == 0)
00315 return false;
00316
00317 const char *hptr = host + strlen( host ) - 1;
00318 const char *nptr = nplist + strlen( nplist ) - 1;
00319 const char *shptr = hptr;
00320
00321 while ( nptr >= nplist )
00322 {
00323 if ( *hptr != *nptr )
00324 {
00325 hptr = shptr;
00326
00327
00328 while(--nptr>=nplist && *nptr!=',' && *nptr!=' ') ;
00329
00330
00331 while(--nptr>=nplist && (*nptr==',' || *nptr==' ')) ;
00332 }
00333 else
00334 {
00335 if ( nptr==nplist || nptr[-1]==',' || nptr[-1]==' ')
00336 return true;
00337
00338 hptr--;
00339 nptr--;
00340 }
00341 }
00342
00343 return false;
00344 }
00345
00346 QString KProtocolManager::slaveProtocol(const KURL &url, QString &proxy)
00347 {
00348 if (!d)
00349 d = new KProtocolManagerPrivate;
00350
00351 if (d->url == url)
00352 {
00353 proxy = d->proxy;
00354 return d->protocol;
00355 }
00356
00357 if (useProxy())
00358 {
00359 proxy = proxyForURL(url);
00360 if ((proxy != "DIRECT") && (!proxy.isEmpty()))
00361 {
00362 QString noProxy = noProxyFor();
00363 ProxyType type = proxyType();
00364 bool useRevProxy = ( (type == ManualProxy || type == EnvVarProxy) &&
00365 useReverseProxy() );
00366 bool isRevMatch = false;
00367
00368 if (!noProxy.isEmpty())
00369 {
00370 QString qhost = url.host().lower();
00371 const char *host = qhost.latin1();
00372 QString qno_proxy = noProxy.stripWhiteSpace().lower();
00373 const char *no_proxy = qno_proxy.latin1();
00374 isRevMatch = revmatch(host, no_proxy);
00375
00376
00377 if (!isRevMatch && host && (strchr(host, '.') == NULL))
00378 isRevMatch = revmatch("<local>", no_proxy);
00379 }
00380
00381 if ( (!useRevProxy && !isRevMatch) || (useRevProxy && isRevMatch) )
00382 {
00383
00384
00385
00386
00387
00388 d->url = proxy;
00389 if ( d->url.isValid() )
00390 {
00391 d->protocol = d->url.protocol();
00392
00393
00394 if ( url.protocol() == QString::fromLatin1("https") &&
00395 d->protocol == QString::fromLatin1("http") )
00396 d->protocol = url.protocol();
00397 d->url = url;
00398 d->proxy = proxy;
00399 return d->protocol;
00400 }
00401 }
00402 }
00403 }
00404
00405 d->url = url;
00406 d->proxy = proxy = QString::null;
00407 d->protocol = url.protocol();
00408 return d->protocol;
00409 }
00410
00411
00412
00413 QString KProtocolManager::userAgentForHost( const QString& hostname )
00414 {
00415 QString useragent = KIO::SlaveConfig::self()->configData("http", hostname.lower(), "UserAgent");
00416
00417
00418
00419 if (useragent.isEmpty())
00420 return defaultUserAgent();
00421
00422 return useragent;
00423 }
00424
00425 QString KProtocolManager::defaultUserAgent( )
00426 {
00427 QString modifiers = KIO::SlaveConfig::self()->configData("http", QString::null, "UserAgentKeys");
00428 return defaultUserAgent(modifiers);
00429 }
00430
00431 QString KProtocolManager::defaultUserAgent( const QString &_modifiers )
00432 {
00433 if (!d)
00434 d = new KProtocolManagerPrivate;
00435
00436 QString modifiers = _modifiers.lower();
00437 if (modifiers.isEmpty())
00438 modifiers = DEFAULT_USER_AGENT_KEYS;
00439
00440 if (d->modifiers == modifiers)
00441 return d->useragent;
00442
00443 QString supp;
00444 struct utsname nam;
00445 if( uname(&nam) >= 0 )
00446 {
00447 if( modifiers.contains('o') )
00448 {
00449 supp += QString("; %1").arg(nam.sysname);
00450 if ( modifiers.contains('v') )
00451 supp += QString(" %1").arg(nam.release);
00452 }
00453 if( modifiers.contains('p') )
00454 {
00455 supp += QString::fromLatin1("; X11");
00456 }
00457 if( modifiers.contains('m') )
00458 {
00459 supp += QString("; %1").arg(nam.machine);
00460 }
00461 if( modifiers.contains('l') )
00462 {
00463 QStringList languageList = KGlobal::locale()->languageList();
00464 QStringList::Iterator it = languageList.find( QString::fromLatin1("C") );
00465 if( it != languageList.end() )
00466 {
00467 if( languageList.contains( QString::fromLatin1("en") ) > 0 )
00468 languageList.remove( it );
00469 else
00470 (*it) = QString::fromLatin1("en");
00471 }
00472 if( languageList.count() )
00473 supp += QString("; %1").arg(languageList.join(", "));
00474 }
00475 }
00476 d->modifiers = modifiers;
00477 d->useragent = CFG_DEFAULT_UAGENT(supp);
00478 return d->useragent;
00479 }
00480
00481
00482
00483 bool KProtocolManager::markPartial()
00484 {
00485 KConfig *cfg = config();
00486 cfg->setGroup( QString::null );
00487 return cfg->readBoolEntry( "MarkPartial", true );
00488 }
00489
00490 int KProtocolManager::minimumKeepSize()
00491 {
00492 KConfig *cfg = config();
00493 cfg->setGroup( QString::null );
00494 return cfg->readNumEntry( "MinimumKeepSize",
00495 DEFAULT_MINIMUM_KEEP_SIZE );
00496 }
00497
00498 bool KProtocolManager::autoResume()
00499 {
00500 KConfig *cfg = config();
00501 cfg->setGroup( QString::null );
00502 return cfg->readBoolEntry( "AutoResume", false );
00503 }
00504
00505 bool KProtocolManager::persistentConnections()
00506 {
00507 KConfig *cfg = config();
00508 cfg->setGroup( QString::null );
00509 return cfg->readBoolEntry( "PersistentConnections", true );
00510 }
00511
00512 bool KProtocolManager::persistentProxyConnection()
00513 {
00514 KConfig *cfg = config();
00515 cfg->setGroup( QString::null );
00516 return cfg->readBoolEntry( "PersistentProxyConnection", false );
00517 }
00518
00519 QString KProtocolManager::proxyConfigScript()
00520 {
00521 KConfig *cfg = config();
00522 cfg->setGroup( "Proxy Settings" );
00523 return cfg->readEntry( "Proxy Config Script" );
00524 }
This file is part of the documentation for kdelibs Version 3.1.0.