KIO
kprotocolmanager.cpp
Go to the documentation of this file.
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 Copyright (C) 2008 Jarosław Staniek <staniek@kde.org> 00006 00007 This library is free software; you can redistribute it and/or 00008 modify it under the terms of the GNU Library General Public 00009 License version 2 as published by the Free Software Foundation. 00010 00011 This library is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 Library General Public License for more details. 00015 00016 You should have received a copy of the GNU Library General Public License 00017 along with this library; see the file COPYING.LIB. If not, write to 00018 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00019 Boston, MA 02110-1301, USA. 00020 */ 00021 00022 #include "kprotocolmanager.h" 00023 00024 #include <string.h> 00025 #include <unistd.h> 00026 #include <sys/utsname.h> 00027 00028 #include <QtCore/QCoreApplication> 00029 #include <QtCore/QStringBuilder> 00030 #include <QtNetwork/QSslSocket> 00031 #include <QtDBus/QtDBus> 00032 00033 #include <kdeversion.h> 00034 #include <kdebug.h> 00035 #include <kglobal.h> 00036 #include <klocale.h> 00037 #include <kconfiggroup.h> 00038 #include <ksharedconfig.h> 00039 #include <kstandarddirs.h> 00040 #include <kstringhandler.h> 00041 #include <kurl.h> 00042 #include <kmimetypetrader.h> 00043 #include <kio/slaveconfig.h> 00044 #include <kio/ioslave_defaults.h> 00045 #include <kio/http_slave_defaults.h> 00046 #include <kprotocolinfofactory.h> 00047 00048 #define QL1S(x) QLatin1String(x) 00049 #define QL1C(x) QLatin1Char(x) 00050 00051 class 00052 KProtocolManagerPrivate 00053 { 00054 public: 00055 KProtocolManagerPrivate(); 00056 00057 ~KProtocolManagerPrivate(); 00058 00059 KSharedConfig::Ptr config; 00060 KSharedConfig::Ptr http_config; 00061 KUrl url; 00062 QString protocol; 00063 QString proxy; 00064 QString modifiers; 00065 QString useragent; 00066 00067 QMap<QString /*mimetype*/, QString /*protocol*/> protocolForArchiveMimetypes; 00068 }; 00069 00070 K_GLOBAL_STATIC(KProtocolManagerPrivate, kProtocolManagerPrivate) 00071 00072 KProtocolManagerPrivate::KProtocolManagerPrivate() 00073 { 00074 // post routine since KConfig::sync() breaks if called too late 00075 qAddPostRoutine(kProtocolManagerPrivate.destroy); 00076 } 00077 00078 KProtocolManagerPrivate::~KProtocolManagerPrivate() 00079 { 00080 qRemovePostRoutine(kProtocolManagerPrivate.destroy); 00081 } 00082 00083 00084 // DEFAULT USERAGENT STRING 00085 #define CFG_DEFAULT_UAGENT(X) \ 00086 QL1S("Mozilla/5.0 (compatible; Konqueror/") % \ 00087 QString::number(KDE::versionMajor()) % QL1C('.') % QString::number(KDE::versionMinor()) % \ 00088 X % QL1S(") KHTML/") % \ 00089 QString::number(KDE::versionMajor()) % QL1C('.') % QString::number(KDE::versionMinor()) % \ 00090 QL1C('.') % QString::number(KDE::versionRelease()) % QL1S(" (like Gecko)") 00091 00092 #define PRIVATE_DATA \ 00093 KProtocolManagerPrivate *d = kProtocolManagerPrivate 00094 00095 void KProtocolManager::reparseConfiguration() 00096 { 00097 PRIVATE_DATA; 00098 if (d->http_config) { 00099 d->http_config->reparseConfiguration(); 00100 } 00101 if (d->config) { 00102 d->config->reparseConfiguration(); 00103 } 00104 d->protocol.clear(); 00105 d->proxy.clear(); 00106 d->modifiers.clear(); 00107 d->useragent.clear(); 00108 d->url.clear(); 00109 00110 // Force the slave config to re-read its config... 00111 KIO::SlaveConfig::self()->reset (); 00112 } 00113 00114 KSharedConfig::Ptr KProtocolManager::config() 00115 { 00116 PRIVATE_DATA; 00117 if (!d->config) 00118 { 00119 d->config = KSharedConfig::openConfig("kioslaverc", KConfig::NoGlobals); 00120 } 00121 return d->config; 00122 } 00123 00124 static KConfigGroup http_config() 00125 { 00126 PRIVATE_DATA; 00127 if (!d->http_config) { 00128 d->http_config = KSharedConfig::openConfig("kio_httprc", KConfig::NoGlobals); 00129 } 00130 return KConfigGroup(d->http_config, QString()); 00131 } 00132 00133 /*=============================== TIMEOUT SETTINGS ==========================*/ 00134 00135 int KProtocolManager::readTimeout() 00136 { 00137 KConfigGroup cg( config(), QString() ); 00138 int val = cg.readEntry( "ReadTimeout", DEFAULT_READ_TIMEOUT ); 00139 return qMax(MIN_TIMEOUT_VALUE, val); 00140 } 00141 00142 int KProtocolManager::connectTimeout() 00143 { 00144 KConfigGroup cg( config(), QString() ); 00145 int val = cg.readEntry( "ConnectTimeout", DEFAULT_CONNECT_TIMEOUT ); 00146 return qMax(MIN_TIMEOUT_VALUE, val); 00147 } 00148 00149 int KProtocolManager::proxyConnectTimeout() 00150 { 00151 KConfigGroup cg( config(), QString() ); 00152 int val = cg.readEntry( "ProxyConnectTimeout", DEFAULT_PROXY_CONNECT_TIMEOUT ); 00153 return qMax(MIN_TIMEOUT_VALUE, val); 00154 } 00155 00156 int KProtocolManager::responseTimeout() 00157 { 00158 KConfigGroup cg( config(), QString() ); 00159 int val = cg.readEntry( "ResponseTimeout", DEFAULT_RESPONSE_TIMEOUT ); 00160 return qMax(MIN_TIMEOUT_VALUE, val); 00161 } 00162 00163 /*========================== PROXY SETTINGS =================================*/ 00164 00165 bool KProtocolManager::useProxy() 00166 { 00167 return proxyType() != NoProxy; 00168 } 00169 00170 bool KProtocolManager::useReverseProxy() 00171 { 00172 KConfigGroup cg(config(), "Proxy Settings" ); 00173 return cg.readEntry("ReversedException", false); 00174 } 00175 00176 KProtocolManager::ProxyType KProtocolManager::proxyType() 00177 { 00178 KConfigGroup cg(config(), "Proxy Settings" ); 00179 return static_cast<ProxyType>(cg.readEntry( "ProxyType" , 0)); 00180 } 00181 00182 KProtocolManager::ProxyAuthMode KProtocolManager::proxyAuthMode() 00183 { 00184 KConfigGroup cg(config(), "Proxy Settings" ); 00185 return static_cast<ProxyAuthMode>(cg.readEntry( "AuthMode" , 0)); 00186 } 00187 00188 /*========================== CACHING =====================================*/ 00189 00190 bool KProtocolManager::useCache() 00191 { 00192 return http_config().readEntry( "UseCache", true ); 00193 } 00194 00195 KIO::CacheControl KProtocolManager::cacheControl() 00196 { 00197 QString tmp = http_config().readEntry("cache"); 00198 if (tmp.isEmpty()) 00199 return DEFAULT_CACHE_CONTROL; 00200 return KIO::parseCacheControl(tmp); 00201 } 00202 00203 QString KProtocolManager::cacheDir() 00204 { 00205 return http_config().readPathEntry("CacheDir", KGlobal::dirs()->saveLocation("cache","http")); 00206 } 00207 00208 int KProtocolManager::maxCacheAge() 00209 { 00210 return http_config().readEntry( "MaxCacheAge", DEFAULT_MAX_CACHE_AGE ); // 14 days 00211 } 00212 00213 int KProtocolManager::maxCacheSize() 00214 { 00215 return http_config().readEntry( "MaxCacheSize", DEFAULT_MAX_CACHE_SIZE ); // 5 MB 00216 } 00217 00218 QString KProtocolManager::noProxyFor() 00219 { 00220 KProtocolManager::ProxyType type = proxyType(); 00221 00222 QString noProxy = config()->group("Proxy Settings").readEntry( "NoProxyFor" ); 00223 if (type == EnvVarProxy) 00224 noProxy = QString::fromLocal8Bit(qgetenv(noProxy.toLocal8Bit())); 00225 00226 return noProxy; 00227 } 00228 00229 QString KProtocolManager::proxyFor( const QString& protocol ) 00230 { 00231 QString key = protocol.toLower(); 00232 00233 if (key == QL1S("webdav")) 00234 key = QL1S("http"); 00235 else if (key == QL1S("webdavs")) 00236 key = QL1S("https"); 00237 00238 key += QL1S("Proxy"); 00239 00240 return config()->group("Proxy Settings").readEntry(key, QString()); 00241 } 00242 00243 QString KProtocolManager::proxyForUrl( const KUrl &url ) 00244 { 00245 QString proxy; 00246 ProxyType pt = proxyType(); 00247 00248 switch (pt) 00249 { 00250 case PACProxy: 00251 case WPADProxy: 00252 if (!url.host().isEmpty()) 00253 { 00254 KUrl u (url); 00255 QString p = u.protocol().toLower(); 00256 00257 // webdav is a KDE specific protocol. Look up proxy 00258 // information using HTTP instead... 00259 if (p == QL1S("webdav")) 00260 { 00261 p = QL1S("http"); 00262 u.setProtocol(p); 00263 } 00264 else if (p == QL1S("webdavs")) 00265 { 00266 p = QL1S("https"); 00267 u.setProtocol(p); 00268 } 00269 00270 if (p.startsWith(QL1S("http")) || p.startsWith(QL1S("ftp"))) 00271 { 00272 QDBusReply<QString> reply = QDBusInterface(QL1S("org.kde.kded"), 00273 QL1S("/modules/proxyscout"), 00274 QL1S("org.kde.KPAC.ProxyScout")) 00275 .call(QL1S("proxyForUrl"), u.url() ); 00276 proxy = reply; 00277 } 00278 } 00279 break; 00280 case EnvVarProxy: 00281 proxy = QString::fromLocal8Bit(qgetenv(proxyFor(url.protocol()).toLocal8Bit())).trimmed(); 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() ? QL1S("DIRECT") : proxy); 00292 } 00293 00294 void KProtocolManager::badProxy( const QString &proxy ) 00295 { 00296 QDBusInterface( QL1S("org.kde.kded"), QL1S("/modules/proxyscout")) 00297 .call(QL1S("blackListProxy"), proxy); 00298 } 00299 00300 /* 00301 Domain suffix match. E.g. return true if host is "cuzco.inka.de" and 00302 nplist is "inka.de,hadiko.de" or if host is "localhost" and nplist is 00303 "localhost". 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 // Try to find another domain or host in the list 00321 while(--nptr>=nplist && *nptr!=',' && *nptr!=' ') ; 00322 00323 // Strip out multiple spaces and commas 00324 while(--nptr>=nplist && (*nptr==',' || *nptr==' ')) ; 00325 } 00326 else 00327 { 00328 if ( nptr==nplist || nptr[-1]==',' || nptr[-1]==' ') 00329 return true; 00330 if ( nptr[-1]=='/' && hptr == host ) // "bugs.kde.org" vs "http://bugs.kde.org", the config UI says URLs are ok 00331 return true; 00332 if ( hptr == host ) // e.g. revmatch("bugs.kde.org","mybugs.kde.org") 00333 return false; 00334 00335 hptr--; 00336 nptr--; 00337 } 00338 } 00339 00340 return false; 00341 } 00342 00343 QString KProtocolManager::slaveProtocol(const KUrl &url, QString &proxy) 00344 { 00345 if (url.hasSubUrl()) // We don't want the suburl's protocol 00346 { 00347 KUrl::List list = KUrl::split(url); 00348 KUrl l = list.last(); 00349 return slaveProtocol(l, proxy); 00350 } 00351 00352 PRIVATE_DATA; 00353 if (d->url == url) 00354 { 00355 proxy = d->proxy; 00356 return d->protocol; 00357 } 00358 00359 if (useProxy()) 00360 { 00361 proxy = proxyForUrl(url); 00362 if ((proxy != "DIRECT") && (!proxy.isEmpty())) 00363 { 00364 bool isRevMatch = false; 00365 KProtocolManager::ProxyType type = proxyType(); 00366 bool useRevProxy = ((type == ManualProxy) && useReverseProxy()); 00367 00368 QString noProxy; 00369 // Check no proxy information iff the proxy type is either 00370 // manual or environment variable based... 00371 if ( (type == ManualProxy) || (type == EnvVarProxy) ) 00372 noProxy = noProxyFor(); 00373 00374 if (!noProxy.isEmpty()) 00375 { 00376 QString qhost = url.host().toLower(); 00377 QByteArray host = qhost.toLatin1(); 00378 QString qno_proxy = noProxy.trimmed().toLower(); 00379 const QByteArray no_proxy = qno_proxy.toLatin1(); 00380 isRevMatch = revmatch(host, no_proxy); 00381 00382 // If no match is found and the request url has a port 00383 // number, try the combination of "host:port". This allows 00384 // users to enter host:port in the No-proxy-For list. 00385 if (!isRevMatch && url.port() > 0) 00386 { 00387 qhost += QL1C(':'); 00388 qhost += QString::number(url.port()); 00389 host = qhost.toLatin1(); 00390 isRevMatch = revmatch (host, no_proxy); 00391 } 00392 00393 // If the hostname does not contain a dot, check if 00394 // <local> is part of noProxy. 00395 if (!isRevMatch && !host.isEmpty() && (strchr(host, '.') == NULL)) 00396 isRevMatch = revmatch("<local>", no_proxy); 00397 } 00398 00399 if ( (!useRevProxy && !isRevMatch) || (useRevProxy && isRevMatch) ) 00400 { 00401 d->url = proxy; 00402 if (d->url.isValid() && !d->url.protocol().isEmpty()) 00403 { 00404 // The idea behind slave protocols is not applicable to http 00405 // and webdav protocols. 00406 const QString protocol = url.protocol().toLower(); 00407 if (protocol.startsWith(QL1S("http")) || protocol.startsWith(QL1S("webdav"))) 00408 d->protocol = protocol; 00409 else 00410 { 00411 d->protocol = d->url.protocol(); 00412 kDebug () << "slaveProtocol: " << d->protocol; 00413 } 00414 00415 d->url = url; 00416 d->proxy = proxy; 00417 return d->protocol; 00418 } 00419 } 00420 } 00421 } 00422 00423 d->url = url; 00424 d->proxy.clear(); proxy.clear(); 00425 d->protocol = url.protocol(); 00426 return d->protocol; 00427 } 00428 00429 /*================================= USER-AGENT SETTINGS =====================*/ 00430 00431 QString KProtocolManager::userAgentForHost( const QString& hostname ) 00432 { 00433 const QString sendUserAgent = KIO::SlaveConfig::self()->configData("http", hostname.toLower(), "SendUserAgent").toLower(); 00434 if (sendUserAgent == QL1S("false")) 00435 return QString(); 00436 00437 const QString useragent = KIO::SlaveConfig::self()->configData("http", hostname.toLower(), "UserAgent"); 00438 00439 // Return the default user-agent if none is specified 00440 // for the requested host. 00441 if (useragent.isEmpty()) 00442 return defaultUserAgent(); 00443 00444 return useragent; 00445 } 00446 00447 QString KProtocolManager::defaultUserAgent( ) 00448 { 00449 const QString modifiers = KIO::SlaveConfig::self()->configData("http", QString(), "UserAgentKeys"); 00450 return defaultUserAgent(modifiers); 00451 } 00452 00453 static QString defaultUserAgentFromPreferredService() 00454 { 00455 QString agentStr; 00456 00457 // Check if the default COMPONENT contains a custom default UA string... 00458 KService::Ptr service = KMimeTypeTrader::self()->preferredService(QL1S("text/html"), 00459 QL1S("KParts/ReadOnlyPart")); 00460 if (service && service->showInKDE()) 00461 agentStr = service->property(QL1S("X-KDE-Default-UserAgent"), 00462 QVariant::String).toString(); 00463 return agentStr; 00464 } 00465 00466 QString KProtocolManager::defaultUserAgent( const QString &_modifiers ) 00467 { 00468 PRIVATE_DATA; 00469 QString modifiers = _modifiers.toLower(); 00470 if (modifiers.isEmpty()) 00471 modifiers = DEFAULT_USER_AGENT_KEYS; 00472 00473 if (d->modifiers == modifiers && !d->useragent.isEmpty()) 00474 return d->useragent; 00475 00476 d->modifiers = modifiers; 00477 00478 /* 00479 The following code attempts to determine the default user agent string 00480 from the 'X-KDE-UA-DEFAULT-STRING' property of the desktop file 00481 for the preferred service that was configured to handle the 'text/html' 00482 mime type. If the prefered service's desktop file does not specify this 00483 property, the long standing default user agent string will be used. 00484 The following keyword placeholders are automatically converted when the 00485 user agent string is read from the property: 00486 00487 %SECURITY% Expands to"U" when SSL is supported, "N" otherwise. 00488 %OSNAME% Expands to operating system name, e.g. Linux. 00489 %OSVERSION% Expands to operating system version, e.g. 2.6.32 00490 %SYSTYPE% Expands to machine or system type, e.g. i386 00491 %PLATFORM% Expands to windowing system, e.g. X11 on Unix/Linux. 00492 %LANGUAGE% Expands to default language in use, e.g. en-US. 00493 %APPVERSION% Expands to QCoreApplication applicationName()/applicationVerison(), 00494 e.g. Konqueror/4.5.0. If application name and/or application version 00495 number are not set, then "KDE" and the runtime KDE version numbers 00496 are used respectively. 00497 00498 All of the keywords are handled case-insensitively. 00499 */ 00500 00501 QString systemName, systemVersion, machine, supp; 00502 const bool sysInfoFound = getSystemNameVersionAndMachine( systemName, systemVersion, machine ); 00503 QString agentStr = defaultUserAgentFromPreferredService(); 00504 00505 if (agentStr.isEmpty()) 00506 { 00507 if (sysInfoFound) 00508 { 00509 if( modifiers.contains('o') ) 00510 { 00511 supp += QL1S("; "); 00512 supp += systemName; 00513 if ( modifiers.contains('v') ) 00514 { 00515 supp += QL1C(' '); 00516 supp += systemVersion; 00517 } 00518 } 00519 #ifdef Q_WS_X11 00520 if( modifiers.contains('p') ) 00521 supp += QL1S("; X11"); 00522 #endif 00523 if( modifiers.contains('m') ) 00524 { 00525 supp += QL1S("; "); 00526 supp += machine; 00527 } 00528 if( modifiers.contains('l') ) 00529 { 00530 supp += QL1S("; "); 00531 supp += KGlobal::locale()->language(); 00532 } 00533 } 00534 00535 d->useragent = CFG_DEFAULT_UAGENT(supp); 00536 } 00537 else 00538 { 00539 QString appName = QCoreApplication::applicationName(); 00540 if (appName.isEmpty() || appName.startsWith(QL1S("kcmshell"), Qt::CaseInsensitive)) 00541 appName = QL1S ("KDE"); 00542 00543 QString appVersion = QCoreApplication::applicationVersion(); 00544 if (appVersion.isEmpty()) 00545 appVersion += (QString::number(KDE::versionMajor()) % QL1C('.') % 00546 QString::number(KDE::versionMinor()) % QL1C('.') % 00547 QString::number(KDE::versionRelease())); 00548 00549 appName += QL1C('/') % appVersion; 00550 00551 agentStr.replace(QL1S("%appversion%"), appName, Qt::CaseInsensitive); 00552 00553 if (QSslSocket::supportsSsl()) 00554 agentStr.replace(QL1S("%security%"), QL1S("U"), Qt::CaseInsensitive); 00555 else 00556 agentStr.replace(QL1S("%security%"), QL1S("N"), Qt::CaseInsensitive); 00557 00558 if (sysInfoFound) 00559 { 00560 if (modifiers.contains('o')) 00561 { 00562 agentStr.replace(QL1S("%osname%"), systemName, Qt::CaseInsensitive); 00563 if (modifiers.contains('v')) 00564 agentStr.replace(QL1S("%osversion%"), systemVersion, Qt::CaseInsensitive); 00565 else 00566 agentStr.remove(QL1S("%osversion%"), Qt::CaseInsensitive); 00567 } 00568 else 00569 { 00570 agentStr.remove(QL1S("%osname%"), Qt::CaseInsensitive); 00571 agentStr.remove(QL1S("%osversion%"), Qt::CaseInsensitive); 00572 } 00573 00574 if (modifiers.contains('p')) 00575 #if defined(Q_WS_X11) 00576 agentStr.replace(QL1S("%platform%"), QL1S("X11"), Qt::CaseInsensitive); 00577 #elif defined(Q_WS_MAC) 00578 agentStr.replace(QL1S("%platform%"), QL1S("Macintosh"), Qt::CaseInsensitive); 00579 #elif defined(Q_WS_WIN) 00580 agentStr.replace(QL1S("%platform%"), QL1S("Windows"), Qt::CaseInsensitive); 00581 #elif defined (Q_WS_S60) 00582 agentStr.replace(QL1S("%platform%"), QL1S("Symbian"), Qt::CaseInsensitive); 00583 #endif 00584 else 00585 agentStr.remove(QL1S("%platform%"), Qt::CaseInsensitive); 00586 00587 if (modifiers.contains('m')) 00588 agentStr.replace(QL1S("%systype%"), machine, Qt::CaseInsensitive); 00589 else 00590 agentStr.remove(QL1S("%systype%"), Qt::CaseInsensitive); 00591 00592 if (modifiers.contains('l')) 00593 agentStr.replace(QL1S("%language%"), KGlobal::locale()->language(), Qt::CaseInsensitive); 00594 else 00595 agentStr.remove(QL1S("%language%"), Qt::CaseInsensitive); 00596 00597 // Clean up unnecessary separators that could be left over from the 00598 // possible keyword removal above... 00599 agentStr.replace(QRegExp("[(]\\s*[;]\\s*"), QL1S("(")); 00600 agentStr.replace(QRegExp("[;]\\s*[;]\\s*"), QL1S(";")); 00601 agentStr.replace(QRegExp("\\s*[;]\\s*[)]"), QL1S(")")); 00602 } 00603 else 00604 { 00605 agentStr.remove(QL1S("%osname%")); 00606 agentStr.remove(QL1S("%osversion%")); 00607 agentStr.remove(QL1S("%platform%")); 00608 agentStr.remove(QL1S("%systype%")); 00609 agentStr.remove(QL1S("%language%")); 00610 } 00611 00612 d->useragent = agentStr.simplified(); 00613 } 00614 00615 //kDebug() << "USERAGENT STRING:" << d->useragent; 00616 return d->useragent; 00617 } 00618 00619 QString KProtocolManager::userAgentForApplication( const QString &appName, const QString& appVersion, 00620 const QStringList& extraInfo ) 00621 { 00622 QString systemName, systemVersion, machine, info; 00623 00624 if (getSystemNameVersionAndMachine( systemName, systemVersion, machine )) 00625 { 00626 info += systemName; 00627 info += QL1C('/'); 00628 info += systemVersion; 00629 info += QL1S("; "); 00630 } 00631 00632 info += QL1S("KDE/"); 00633 info += QString::number(KDE::versionMajor()); 00634 info += QL1C('.'); 00635 info += QString::number(KDE::versionMinor()); 00636 info += QL1C('.'); 00637 info += QString::number(KDE::versionRelease()); 00638 00639 if (!machine.isEmpty()) 00640 { 00641 info += QL1S("; "); 00642 info += machine; 00643 } 00644 00645 info += QL1S("; "); 00646 info += extraInfo.join(QL1S("; ")); 00647 00648 return (appName % QL1C('/') % appVersion % QL1S(" (") % info % QL1C(')')); 00649 } 00650 00651 bool KProtocolManager::getSystemNameVersionAndMachine( 00652 QString& systemName, QString& systemVersion, QString& machine ) 00653 { 00654 struct utsname unameBuf; 00655 if ( 0 != uname( &unameBuf ) ) 00656 return false; 00657 #if defined(Q_WS_WIN) && !defined(_WIN32_WCE) 00658 // we do not use unameBuf.sysname information constructed in kdewin32 00659 // because we want to get separate name and version 00660 systemName = QL1S( "Windows" ); 00661 OSVERSIONINFOEX versioninfo; 00662 ZeroMemory(&versioninfo, sizeof(OSVERSIONINFOEX)); 00663 // try calling GetVersionEx using the OSVERSIONINFOEX, if that fails, try using the OSVERSIONINFO 00664 versioninfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); 00665 bool ok = GetVersionEx( (OSVERSIONINFO *) &versioninfo ); 00666 if ( !ok ) { 00667 versioninfo.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); 00668 ok = GetVersionEx( (OSVERSIONINFO *) &versioninfo ); 00669 } 00670 if ( ok ) 00671 systemVersion = (QString::number(versioninfo.dwMajorVersion) % 00672 QL1C('.') % QString::number(versioninfo.dwMinorVersion)); 00673 #else 00674 systemName = unameBuf.sysname; 00675 systemVersion = unameBuf.release; 00676 #endif 00677 machine = unameBuf.machine; 00678 return true; 00679 } 00680 00681 QString KProtocolManager::acceptLanguagesHeader() 00682 { 00683 static const QString &english = KGlobal::staticQString("en"); 00684 00685 // User's desktop language preference. 00686 QStringList languageList = KGlobal::locale()->languageList(); 00687 00688 // Replace possible "C" in the language list with "en", unless "en" is 00689 // already pressent. This is to keep user's priorities in order. 00690 // If afterwards "en" is still not present, append it. 00691 int idx = languageList.indexOf(QString::fromLatin1("C")); 00692 if (idx != -1) 00693 { 00694 if (languageList.contains(english)) 00695 languageList.removeAt(idx); 00696 else 00697 languageList[idx] = english; 00698 } 00699 if (!languageList.contains(english)) 00700 languageList += english; 00701 00702 // Some languages may have web codes different from locale codes, 00703 // read them from the config and insert in proper order. 00704 KConfig acclangConf("accept-languages.codes", KConfig::NoGlobals); 00705 KConfigGroup replacementCodes(&acclangConf, "ReplacementCodes"); 00706 QStringList languageListFinal; 00707 Q_FOREACH (const QString &lang, languageList) 00708 { 00709 const QStringList langs = replacementCodes.readEntry(lang, QStringList()); 00710 if (langs.isEmpty()) 00711 languageListFinal += lang; 00712 else 00713 languageListFinal += langs; 00714 } 00715 00716 // The header is composed of comma separated languages, with an optional 00717 // associated priority estimate (q=1..0) defaulting to 1. 00718 // As our language tags are already sorted by priority, we'll just decrease 00719 // the value evenly 00720 int prio = 10; 00721 QString header; 00722 Q_FOREACH (const QString &lang,languageListFinal) { 00723 header += lang; 00724 if (prio < 10) { 00725 header += QL1S(";q=0."); 00726 header += QString::number(prio); 00727 } 00728 // do not add cosmetic whitespace in here : it is less compatible (#220677) 00729 header += QL1S(","); 00730 if (prio > 1) 00731 --prio; 00732 } 00733 header.chop(1); 00734 00735 // Some of the languages may have country specifier delimited by 00736 // underscore, or modifier delimited by at-sign. 00737 // The header should use dashes instead. 00738 header.replace('_', '-'); 00739 header.replace('@', '-'); 00740 00741 return header; 00742 } 00743 00744 /*==================================== OTHERS ===============================*/ 00745 00746 bool KProtocolManager::markPartial() 00747 { 00748 return config()->group(QByteArray()).readEntry( "MarkPartial", true ); 00749 } 00750 00751 int KProtocolManager::minimumKeepSize() 00752 { 00753 return config()->group(QByteArray()).readEntry( "MinimumKeepSize", 00754 DEFAULT_MINIMUM_KEEP_SIZE ); // 5000 byte 00755 } 00756 00757 bool KProtocolManager::autoResume() 00758 { 00759 return config()->group(QByteArray()).readEntry( "AutoResume", false ); 00760 } 00761 00762 bool KProtocolManager::persistentConnections() 00763 { 00764 return config()->group(QByteArray()).readEntry( "PersistentConnections", true ); 00765 } 00766 00767 bool KProtocolManager::persistentProxyConnection() 00768 { 00769 return config()->group(QByteArray()).readEntry( "PersistentProxyConnection", false ); 00770 } 00771 00772 QString KProtocolManager::proxyConfigScript() 00773 { 00774 return config()->group("Proxy Settings").readEntry( "Proxy Config Script" ); 00775 } 00776 00777 /* =========================== PROTOCOL CAPABILITIES ============== */ 00778 00779 static KProtocolInfo::Ptr findProtocol(const KUrl &url) 00780 { 00781 QString protocol = url.protocol(); 00782 00783 if ( !KProtocolInfo::proxiedBy( protocol ).isEmpty() ) 00784 { 00785 QString dummy; 00786 protocol = KProtocolManager::slaveProtocol(url, dummy); 00787 } 00788 00789 return KProtocolInfoFactory::self()->findProtocol(protocol); 00790 } 00791 00792 00793 KProtocolInfo::Type KProtocolManager::inputType( const KUrl &url ) 00794 { 00795 KProtocolInfo::Ptr prot = findProtocol(url); 00796 if ( !prot ) 00797 return KProtocolInfo::T_NONE; 00798 00799 return prot->m_inputType; 00800 } 00801 00802 KProtocolInfo::Type KProtocolManager::outputType( const KUrl &url ) 00803 { 00804 KProtocolInfo::Ptr prot = findProtocol(url); 00805 if ( !prot ) 00806 return KProtocolInfo::T_NONE; 00807 00808 return prot->m_outputType; 00809 } 00810 00811 00812 bool KProtocolManager::isSourceProtocol( const KUrl &url ) 00813 { 00814 KProtocolInfo::Ptr prot = findProtocol(url); 00815 if ( !prot ) 00816 return false; 00817 00818 return prot->m_isSourceProtocol; 00819 } 00820 00821 bool KProtocolManager::supportsListing( const KUrl &url ) 00822 { 00823 KProtocolInfo::Ptr prot = findProtocol(url); 00824 if ( !prot ) 00825 return false; 00826 00827 return prot->m_supportsListing; 00828 } 00829 00830 QStringList KProtocolManager::listing( const KUrl &url ) 00831 { 00832 KProtocolInfo::Ptr prot = findProtocol(url); 00833 if ( !prot ) 00834 return QStringList(); 00835 00836 return prot->m_listing; 00837 } 00838 00839 bool KProtocolManager::supportsReading( const KUrl &url ) 00840 { 00841 KProtocolInfo::Ptr prot = findProtocol(url); 00842 if ( !prot ) 00843 return false; 00844 00845 return prot->m_supportsReading; 00846 } 00847 00848 bool KProtocolManager::supportsWriting( const KUrl &url ) 00849 { 00850 KProtocolInfo::Ptr prot = findProtocol(url); 00851 if ( !prot ) 00852 return false; 00853 00854 return prot->m_supportsWriting; 00855 } 00856 00857 bool KProtocolManager::supportsMakeDir( const KUrl &url ) 00858 { 00859 KProtocolInfo::Ptr prot = findProtocol(url); 00860 if ( !prot ) 00861 return false; 00862 00863 return prot->m_supportsMakeDir; 00864 } 00865 00866 bool KProtocolManager::supportsDeleting( const KUrl &url ) 00867 { 00868 KProtocolInfo::Ptr prot = findProtocol(url); 00869 if ( !prot ) 00870 return false; 00871 00872 return prot->m_supportsDeleting; 00873 } 00874 00875 bool KProtocolManager::supportsLinking( const KUrl &url ) 00876 { 00877 KProtocolInfo::Ptr prot = findProtocol(url); 00878 if ( !prot ) 00879 return false; 00880 00881 return prot->m_supportsLinking; 00882 } 00883 00884 bool KProtocolManager::supportsMoving( const KUrl &url ) 00885 { 00886 KProtocolInfo::Ptr prot = findProtocol(url); 00887 if ( !prot ) 00888 return false; 00889 00890 return prot->m_supportsMoving; 00891 } 00892 00893 bool KProtocolManager::supportsOpening( const KUrl &url ) 00894 { 00895 KProtocolInfo::Ptr prot = findProtocol(url); 00896 if ( !prot ) 00897 return false; 00898 00899 return prot->m_supportsOpening; 00900 } 00901 00902 bool KProtocolManager::canCopyFromFile( const KUrl &url ) 00903 { 00904 KProtocolInfo::Ptr prot = findProtocol(url); 00905 if ( !prot ) 00906 return false; 00907 00908 return prot->m_canCopyFromFile; 00909 } 00910 00911 00912 bool KProtocolManager::canCopyToFile( const KUrl &url ) 00913 { 00914 KProtocolInfo::Ptr prot = findProtocol(url); 00915 if ( !prot ) 00916 return false; 00917 00918 return prot->m_canCopyToFile; 00919 } 00920 00921 bool KProtocolManager::canRenameFromFile( const KUrl &url ) 00922 { 00923 KProtocolInfo::Ptr prot = findProtocol(url); 00924 if ( !prot ) 00925 return false; 00926 00927 return prot->canRenameFromFile(); 00928 } 00929 00930 00931 bool KProtocolManager::canRenameToFile( const KUrl &url ) 00932 { 00933 KProtocolInfo::Ptr prot = findProtocol(url); 00934 if ( !prot ) 00935 return false; 00936 00937 return prot->canRenameToFile(); 00938 } 00939 00940 bool KProtocolManager::canDeleteRecursive( const KUrl &url ) 00941 { 00942 KProtocolInfo::Ptr prot = findProtocol(url); 00943 if ( !prot ) 00944 return false; 00945 00946 return prot->canDeleteRecursive(); 00947 } 00948 00949 KProtocolInfo::FileNameUsedForCopying KProtocolManager::fileNameUsedForCopying( const KUrl &url ) 00950 { 00951 KProtocolInfo::Ptr prot = findProtocol(url); 00952 if ( !prot ) 00953 return KProtocolInfo::FromUrl; 00954 00955 return prot->fileNameUsedForCopying(); 00956 } 00957 00958 QString KProtocolManager::defaultMimetype( const KUrl &url ) 00959 { 00960 KProtocolInfo::Ptr prot = findProtocol(url); 00961 if ( !prot ) 00962 return QString(); 00963 00964 return prot->m_defaultMimetype; 00965 } 00966 00967 QString KProtocolManager::protocolForArchiveMimetype( const QString& mimeType ) 00968 { 00969 PRIVATE_DATA; 00970 if (d->protocolForArchiveMimetypes.isEmpty()) { 00971 const KProtocolInfo::List allProtocols = KProtocolInfoFactory::self()->allProtocols(); 00972 for (KProtocolInfo::List::const_iterator it = allProtocols.begin(); 00973 it != allProtocols.end(); ++it) { 00974 const QStringList archiveMimetypes = (*it)->archiveMimeTypes(); 00975 Q_FOREACH(const QString& mime, archiveMimetypes) { 00976 d->protocolForArchiveMimetypes.insert(mime, (*it)->name()); 00977 } 00978 } 00979 } 00980 return d->protocolForArchiveMimetypes.value(mimeType); 00981 } 00982 00983 #undef PRIVATE_DATA
KDE 4.6 API Reference