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 <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
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
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
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
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
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 );
00199 }
00200
00201 int KProtocolManager::maxCacheSize()
00202 {
00203
KConfig *cfg = http_config();
00204
return cfg->
readNumEntry(
"MaxCacheSize", DEFAULT_MAX_CACHE_SIZE );
00205 }
00206
00207 QString KProtocolManager::noProxyFor()
00208 {
00209
KProtocolManager::ProxyType type =
proxyType();
00210
00211
if ( (type != ManualProxy) && (type != EnvVarProxy) )
00212
return QString::null;
00213
00214
KConfig *cfg = config();
00215 cfg->
setGroup(
"Proxy Settings" );
00216
00217
QString noProxy = cfg->
readEntry(
"NoProxyFor" );
00218
if (type == EnvVarProxy)
00219 noProxy = QString::fromLocal8Bit(getenv(noProxy.
local8Bit()));
00220
00221
return noProxy;
00222 }
00223
00224 QString KProtocolManager::proxyFor(
const QString& protocol )
00225 {
00226
QString scheme = protocol.
lower();
00227
00228
if (scheme ==
"webdav")
00229 scheme =
"http";
00230
else if (scheme ==
"webdavs")
00231 scheme =
"https";
00232
00233
KConfig *cfg = config();
00234 cfg->
setGroup(
"Proxy Settings" );
00235
return cfg->
readEntry( scheme +
"Proxy" );
00236 }
00237
00238 QString KProtocolManager::proxyForURL(
const KURL &url )
00239 {
00240
QString proxy;
00241
ProxyType pt =
proxyType();
00242
00243
switch (pt)
00244 {
00245
case PACProxy:
00246
case WPADProxy:
00247
if (!url.
host().
isEmpty())
00248 {
00249
KURL u (url);
00250
QString p = u.
protocol().
lower();
00251
00252
00253
00254
if ( p ==
"webdav" )
00255 {
00256 p =
"http";
00257 u.
setProtocol( p );
00258 }
00259
else if ( p ==
"webdavs" )
00260 {
00261 p =
"https";
00262 u.
setProtocol( p );
00263 }
00264
00265
if ( p.
startsWith(
"http") || p ==
"ftp" || p ==
"gopher" )
00266
DCOPRef(
"kded",
"proxyscout" ).call(
"proxyForURL", u ).get( proxy );
00267 }
00268
break;
00269
case EnvVarProxy:
00270 proxy = QString::fromLocal8Bit(getenv(
proxyFor(url.
protocol()).
local8Bit())).stripWhiteSpace();
00271
break;
00272
case ManualProxy:
00273 proxy =
proxyFor( url.
protocol() );
00274
break;
00275
case NoProxy:
00276
default:
00277
break;
00278 }
00279
00280
return (proxy.
isEmpty() ? QString::fromLatin1(
"DIRECT") : proxy);
00281 }
00282
00283 void KProtocolManager::badProxy(
const QString &proxy )
00284 {
00285
DCOPRef(
"kded",
"proxyscout" ).send(
"blackListProxy", proxy );
00286 }
00287
00288
00289
00290
00291
00292
00293
static bool revmatch(
const char *host,
const char *nplist)
00294 {
00295
if (host == 0)
00296
return false;
00297
00298
const char *hptr = host + strlen( host ) - 1;
00299
const char *nptr = nplist + strlen( nplist ) - 1;
00300
const char *shptr = hptr;
00301
00302
while ( nptr >= nplist )
00303 {
00304
if ( *hptr != *nptr )
00305 {
00306 hptr = shptr;
00307
00308
00309
while(--nptr>=nplist && *nptr!=
',' && *nptr!=
' ') ;
00310
00311
00312
while(--nptr>=nplist && (*nptr==
',' || *nptr==
' ')) ;
00313 }
00314
else
00315 {
00316
if ( nptr==nplist || nptr[-1]==
',' || nptr[-1]==
' ')
00317
return true;
00318
if ( hptr == host )
00319
return false;
00320
00321 hptr--;
00322 nptr--;
00323 }
00324 }
00325
00326
return false;
00327 }
00328
00329 QString KProtocolManager::slaveProtocol(
const KURL &url,
QString &proxy)
00330 {
00331
if (url.
hasSubURL())
00332 {
00333
KURL::List list = KURL::split(url);
00334 KURL::List::Iterator it = list.
fromLast();
00335
return slaveProtocol(*it, proxy);
00336 }
00337
00338
if (!d)
00339 d =
new KProtocolManagerPrivate;
00340
00341
if (d->url == url)
00342 {
00343 proxy = d->proxy;
00344
return d->protocol;
00345 }
00346
00347
if (
useProxy())
00348 {
00349 proxy =
proxyForURL(url);
00350
if ((proxy !=
"DIRECT") && (!proxy.
isEmpty()))
00351 {
00352
bool isRevMatch =
false;
00353
bool useRevProxy = ((
proxyType() == ManualProxy) &&
useReverseProxy());
00354
00355
QString noProxy =
noProxyFor();
00356
00357
if (!noProxy.
isEmpty())
00358 {
00359
QString qhost = url.
host().
lower();
00360
const char *host = qhost.
latin1();
00361
QString qno_proxy = noProxy.
stripWhiteSpace().lower();
00362
const char *no_proxy = qno_proxy.
latin1();
00363 isRevMatch = revmatch(host, no_proxy);
00364
00365
00366
00367
00368
if (!isRevMatch && url.
port() > 0)
00369 {
00370 qhost +=
':' + QString::number (url.
port());
00371 host = qhost.
latin1();
00372 isRevMatch = revmatch (host, no_proxy);
00373 }
00374
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 d->url = proxy;
00384
if ( d->url.isValid() )
00385 {
00386
00387
00388
QString protocol = url.
protocol().
lower();
00389
if (protocol.
startsWith(
"http") || protocol.
startsWith(
"webdav"))
00390 d->protocol = protocol;
00391
else
00392 {
00393 d->protocol = d->url.protocol();
00394
kdDebug () <<
"slaveProtocol: " << d->protocol <<
endl;
00395 }
00396
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 sendUserAgent = KIO::SlaveConfig::self()->configData(
"http", hostname.
lower(),
"SendUserAgent").lower();
00416
if (sendUserAgent ==
"false")
00417
return QString::null;
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 }