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 hptr--;
00332 nptr--;
00333 }
00334 }
00335
00336 return false;
00337 }
00338
00339 QString KProtocolManager::slaveProtocol(const KURL &url, QString &proxy)
00340 {
00341 if (!d)
00342 d = new KProtocolManagerPrivate;
00343
00344 if (d->url == url)
00345 {
00346 proxy = d->proxy;
00347 return d->protocol;
00348 }
00349
00350 if (useProxy())
00351 {
00352 proxy = proxyForURL(url);
00353 if ((proxy != "DIRECT") && (!proxy.isEmpty()))
00354 {
00355 QString noProxy = noProxyFor();
00356 ProxyType type = proxyType();
00357 bool useRevProxy = ( (type == ManualProxy || type == EnvVarProxy) &&
00358 useReverseProxy() );
00359 bool isRevMatch = false;
00360
00361 if (!noProxy.isEmpty())
00362 {
00363 QString qhost = url.host().lower();
00364 const char *host = qhost.latin1();
00365 QString qno_proxy = noProxy.stripWhiteSpace().lower();
00366 const char *no_proxy = qno_proxy.latin1();
00367 isRevMatch = revmatch(host, no_proxy);
00368
00369
00370
00371
00372 if (!isRevMatch && url.port() > 0)
00373 {
00374 qhost += ':' + QString::number (url.port());
00375 host = qhost.latin1();
00376 isRevMatch = revmatch (host, no_proxy);
00377 }
00378
00379
00380
00381 if (!isRevMatch && host && (strchr(host, '.') == NULL))
00382 isRevMatch = revmatch("<local>", no_proxy);
00383 }
00384
00385 if ( (!useRevProxy && !isRevMatch) || (useRevProxy && isRevMatch) )
00386 {
00387 d->url = proxy;
00388 if ( d->url.isValid() )
00389 {
00390
00391
00392 QString protocol = url.protocol().lower();
00393 if (protocol.startsWith("http") || protocol.startsWith("webdav"))
00394 d->protocol = protocol;
00395 else
00396 d->protocol = d->url.protocol();
00397
00398 d->url = url;
00399 d->proxy = proxy;
00400 return d->protocol;
00401 }
00402 }
00403 }
00404 }
00405
00406 d->url = url;
00407 d->proxy = proxy = QString::null;
00408 d->protocol = url.protocol();
00409 return d->protocol;
00410 }
00411
00412
00413
00414 QString KProtocolManager::userAgentForHost( const QString& hostname )
00415 {
00416 QString useragent = KIO::SlaveConfig::self()->configData("http", hostname.lower(), "UserAgent");
00417
00418
00419
00420 if (useragent.isEmpty())
00421 return defaultUserAgent();
00422
00423 return useragent;
00424 }
00425
00426 QString KProtocolManager::defaultUserAgent( )
00427 {
00428 QString modifiers = KIO::SlaveConfig::self()->configData("http", QString::null, "UserAgentKeys");
00429 return defaultUserAgent(modifiers);
00430 }
00431
00432 QString KProtocolManager::defaultUserAgent( const QString &_modifiers )
00433 {
00434 if (!d)
00435 d = new KProtocolManagerPrivate;
00436
00437 QString modifiers = _modifiers.lower();
00438 if (modifiers.isEmpty())
00439 modifiers = DEFAULT_USER_AGENT_KEYS;
00440
00441 if (d->modifiers == modifiers)
00442 return d->useragent;
00443
00444 QString supp;
00445 struct utsname nam;
00446 if( uname(&nam) >= 0 )
00447 {
00448 if( modifiers.contains('o') )
00449 {
00450 supp += QString("; %1").arg(nam.sysname);
00451 if ( modifiers.contains('v') )
00452 supp += QString(" %1").arg(nam.release);
00453 }
00454 if( modifiers.contains('p') )
00455 {
00456 supp += QString::fromLatin1("; X11");
00457 }
00458 if( modifiers.contains('m') )
00459 {
00460 supp += QString("; %1").arg(nam.machine);
00461 }
00462 if( modifiers.contains('l') )
00463 {
00464 QStringList languageList = KGlobal::locale()->languageList();
00465 QStringList::Iterator it = languageList.find( QString::fromLatin1("C") );
00466 if( it != languageList.end() )
00467 {
00468 if( languageList.contains( QString::fromLatin1("en") ) > 0 )
00469 languageList.remove( it );
00470 else
00471 (*it) = QString::fromLatin1("en");
00472 }
00473 if( languageList.count() )
00474 supp += QString("; %1").arg(languageList.join(", "));
00475 }
00476 }
00477 d->modifiers = modifiers;
00478 d->useragent = CFG_DEFAULT_UAGENT(supp);
00479 return d->useragent;
00480 }
00481
00482
00483
00484 bool KProtocolManager::markPartial()
00485 {
00486 KConfig *cfg = config();
00487 cfg->setGroup( QString::null );
00488 return cfg->readBoolEntry( "MarkPartial", true );
00489 }
00490
00491 int KProtocolManager::minimumKeepSize()
00492 {
00493 KConfig *cfg = config();
00494 cfg->setGroup( QString::null );
00495 return cfg->readNumEntry( "MinimumKeepSize",
00496 DEFAULT_MINIMUM_KEEP_SIZE );
00497 }
00498
00499 bool KProtocolManager::autoResume()
00500 {
00501 KConfig *cfg = config();
00502 cfg->setGroup( QString::null );
00503 return cfg->readBoolEntry( "AutoResume", false );
00504 }
00505
00506 bool KProtocolManager::persistentConnections()
00507 {
00508 KConfig *cfg = config();
00509 cfg->setGroup( QString::null );
00510 return cfg->readBoolEntry( "PersistentConnections", true );
00511 }
00512
00513 bool KProtocolManager::persistentProxyConnection()
00514 {
00515 KConfig *cfg = config();
00516 cfg->setGroup( QString::null );
00517 return cfg->readBoolEntry( "PersistentProxyConnection", false );
00518 }
00519
00520 QString KProtocolManager::proxyConfigScript()
00521 {
00522 KConfig *cfg = config();
00523 cfg->setGroup( "Proxy Settings" );
00524 return cfg->readEntry( "Proxy Config Script" );
00525 }
This file is part of the documentation for kdelibs Version 3.1.4.