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->readPathEntry("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 QString scheme = protocol.lower();
00257
00258 if (scheme == "webdav")
00259 scheme = "http";
00260 else if (scheme == "webdavs")
00261 scheme = "https";
00262
00263 KConfig *cfg = config();
00264 cfg->setGroup( "Proxy Settings" );
00265 return cfg->readEntry( scheme + "Proxy" );
00266 }
00267
00268 QString KProtocolManager::proxyForURL( const KURL &url )
00269 {
00270 QString proxy;
00271 ProxyType pt = proxyType();
00272
00273 switch (pt)
00274 {
00275 case PACProxy:
00276 case WPADProxy:
00277 if (!url.host().isEmpty() && pac())
00278 proxy = pac()->proxyForURL( url ).stripWhiteSpace();
00279 break;
00280 case EnvVarProxy:
00281 proxy = QString::fromLocal8Bit(getenv(proxyFor(url.protocol()).local8Bit())).stripWhiteSpace();
00282 break;
00283 case ManualProxy:
00284 proxy = proxyFor( url.protocol() );
00285 break;
00286 case NoProxy:
00287 default:
00288 break;
00289 }
00290
00291 return (proxy.isEmpty() ? QString::fromLatin1("DIRECT") : proxy);
00292 }
00293
00294 void KProtocolManager::badProxy( const QString &proxy )
00295 {
00296 if ( d && d->pac )
00297 d->pac->badProxy( proxy );
00298 }
00299
00300
00301
00302
00303
00304
00305 static bool revmatch(const char *host, const char *nplist)
00306 {
00307 if (host == 0)
00308 return false;
00309
00310 const char *hptr = host + strlen( host ) - 1;
00311 const char *nptr = nplist + strlen( nplist ) - 1;
00312 const char *shptr = hptr;
00313
00314 while ( nptr >= nplist )
00315 {
00316 if ( *hptr != *nptr )
00317 {
00318 hptr = shptr;
00319
00320
00321 while(--nptr>=nplist && *nptr!=',' && *nptr!=' ') ;
00322
00323
00324 while(--nptr>=nplist && (*nptr==',' || *nptr==' ')) ;
00325 }
00326 else
00327 {
00328 if ( nptr==nplist || nptr[-1]==',' || nptr[-1]==' ')
00329 return true;
00330
00331 if (hptr == host)
00332 return false;
00333
00334 hptr--;
00335 nptr--;
00336 }
00337 }
00338
00339 return false;
00340 }
00341
00342 QString KProtocolManager::slaveProtocol(const KURL &url, QString &proxy)
00343 {
00344 if (!d)
00345 d = new KProtocolManagerPrivate;
00346
00347 if (d->url == url)
00348 {
00349 proxy = d->proxy;
00350 return d->protocol;
00351 }
00352
00353 if (useProxy())
00354 {
00355 proxy = proxyForURL(url);
00356 if ((proxy != "DIRECT") && (!proxy.isEmpty()))
00357 {
00358 QString noProxy = noProxyFor();
00359 ProxyType type = proxyType();
00360 bool useRevProxy = ( (type == ManualProxy || type == EnvVarProxy) &&
00361 useReverseProxy() );
00362 bool isRevMatch = false;
00363
00364 if (!noProxy.isEmpty())
00365 {
00366 QString qhost = url.host().lower();
00367 const char *host = qhost.latin1();
00368 QString qno_proxy = noProxy.stripWhiteSpace().lower();
00369 const char *no_proxy = qno_proxy.latin1();
00370 isRevMatch = revmatch(host, no_proxy);
00371
00372
00373
00374
00375 if (!isRevMatch && url.port() > 0)
00376 {
00377 qhost += ':' + QString::number (url.port());
00378 host = qhost.latin1();
00379 isRevMatch = revmatch (host, no_proxy);
00380 }
00381
00382
00383
00384 if (!isRevMatch && host && (strchr(host, '.') == NULL))
00385 isRevMatch = revmatch("<local>", no_proxy);
00386 }
00387
00388 if ( (!useRevProxy && !isRevMatch) || (useRevProxy && isRevMatch) )
00389 {
00390 d->url = proxy;
00391 if ( d->url.isValid() )
00392 {
00393
00394
00395 QString protocol = url.protocol().lower();
00396 if (protocol.startsWith("http") || protocol.startsWith("webdav"))
00397 d->protocol = protocol;
00398 else
00399 d->protocol = d->url.protocol();
00400
00401 d->url = url;
00402 d->proxy = proxy;
00403 return d->protocol;
00404 }
00405 }
00406 }
00407 }
00408
00409 d->url = url;
00410 d->proxy = proxy = QString::null;
00411 d->protocol = url.protocol();
00412 return d->protocol;
00413 }
00414
00415
00416
00417 QString KProtocolManager::userAgentForHost( const QString& hostname )
00418 {
00419 QString useragent = KIO::SlaveConfig::self()->configData("http", hostname.lower(), "UserAgent");
00420
00421
00422
00423 if (useragent.isEmpty())
00424 return defaultUserAgent();
00425
00426 return useragent;
00427 }
00428
00429 QString KProtocolManager::defaultUserAgent( )
00430 {
00431 QString modifiers = KIO::SlaveConfig::self()->configData("http", QString::null, "UserAgentKeys");
00432 return defaultUserAgent(modifiers);
00433 }
00434
00435 QString KProtocolManager::defaultUserAgent( const QString &_modifiers )
00436 {
00437 if (!d)
00438 d = new KProtocolManagerPrivate;
00439
00440 QString modifiers = _modifiers.lower();
00441 if (modifiers.isEmpty())
00442 modifiers = DEFAULT_USER_AGENT_KEYS;
00443
00444 if (d->modifiers == modifiers)
00445 return d->useragent;
00446
00447 QString supp;
00448 struct utsname nam;
00449 if( uname(&nam) >= 0 )
00450 {
00451 if( modifiers.contains('o') )
00452 {
00453 supp += QString("; %1").arg(nam.sysname);
00454 if ( modifiers.contains('v') )
00455 supp += QString(" %1").arg(nam.release);
00456 }
00457 if( modifiers.contains('p') )
00458 {
00459 supp += QString::fromLatin1("; X11");
00460 }
00461 if( modifiers.contains('m') )
00462 {
00463 supp += QString("; %1").arg(nam.machine);
00464 }
00465 if( modifiers.contains('l') )
00466 {
00467 QStringList languageList = KGlobal::locale()->languageList();
00468 QStringList::Iterator it = languageList.find( QString::fromLatin1("C") );
00469 if( it != languageList.end() )
00470 {
00471 if( languageList.contains( QString::fromLatin1("en") ) > 0 )
00472 languageList.remove( it );
00473 else
00474 (*it) = QString::fromLatin1("en");
00475 }
00476 if( languageList.count() )
00477 supp += QString("; %1").arg(languageList.join(", "));
00478 }
00479 }
00480 d->modifiers = modifiers;
00481 d->useragent = CFG_DEFAULT_UAGENT(supp);
00482 return d->useragent;
00483 }
00484
00485
00486
00487 bool KProtocolManager::markPartial()
00488 {
00489 KConfig *cfg = config();
00490 cfg->setGroup( QString::null );
00491 return cfg->readBoolEntry( "MarkPartial", true );
00492 }
00493
00494 int KProtocolManager::minimumKeepSize()
00495 {
00496 KConfig *cfg = config();
00497 cfg->setGroup( QString::null );
00498 return cfg->readNumEntry( "MinimumKeepSize",
00499 DEFAULT_MINIMUM_KEEP_SIZE );
00500 }
00501
00502 bool KProtocolManager::autoResume()
00503 {
00504 KConfig *cfg = config();
00505 cfg->setGroup( QString::null );
00506 return cfg->readBoolEntry( "AutoResume", false );
00507 }
00508
00509 bool KProtocolManager::persistentConnections()
00510 {
00511 KConfig *cfg = config();
00512 cfg->setGroup( QString::null );
00513 return cfg->readBoolEntry( "PersistentConnections", true );
00514 }
00515
00516 bool KProtocolManager::persistentProxyConnection()
00517 {
00518 KConfig *cfg = config();
00519 cfg->setGroup( QString::null );
00520 return cfg->readBoolEntry( "PersistentProxyConnection", false );
00521 }
00522
00523 QString KProtocolManager::proxyConfigScript()
00524 {
00525 KConfig *cfg = config();
00526 cfg->setGroup( "Proxy Settings" );
00527 return cfg->readEntry( "Proxy Config Script" );
00528 }
This file is part of the documentation for kdelibs Version 3.1.5.