• Skip to content
  • Skip to link menu
KDE 4.7 API Reference
  • KDE API Reference
  • kdelibs
  • KDE Home
  • Contact Us
 

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 "hostinfo_p.h"
00025 
00026 #include <string.h>
00027 #include <unistd.h>
00028 #include <sys/utsname.h>
00029 
00030 #include <QtCore/QCoreApplication>
00031 #include <QtNetwork/QSslSocket>
00032 #include <QtNetwork/QHostAddress>
00033 #include <QtNetwork/QHostInfo>
00034 #include <QtDBus/QtDBus>
00035 
00036 #if !defined(QT_NO_NETWORKPROXY) && (defined (Q_OS_WIN32) || defined(Q_OS_MAC))
00037 #include <QtNetwork/QNetworkProxyFactory>
00038 #include <QtNetwork/QNetworkProxyQuery>
00039 #endif
00040 
00041 #include <kdeversion.h>
00042 #include <kdebug.h>
00043 #include <kglobal.h>
00044 #include <klocale.h>
00045 #include <kconfiggroup.h>
00046 #include <ksharedconfig.h>
00047 #include <kstandarddirs.h>
00048 #include <kurl.h>
00049 #include <kmimetypetrader.h>
00050 #include <kprotocolinfofactory.h>
00051 
00052 #include <kio/slaveconfig.h>
00053 #include <kio/ioslave_defaults.h>
00054 #include <kio/http_slave_defaults.h>
00055 
00056 #define QL1S(x)   QLatin1String(x)
00057 #define QL1C(x)   QLatin1Char(x)
00058 
00059 typedef QPair<QHostAddress, int> SubnetPair;
00060 
00061 /*
00062     Domain suffix match. E.g. return true if host is "cuzco.inka.de" and
00063     nplist is "inka.de,hadiko.de" or if host is "localhost" and nplist is
00064     "localhost".
00065 */
00066 static bool revmatch(const char *host, const char *nplist)
00067 {
00068   if (host == 0)
00069     return false;
00070 
00071   const char *hptr = host + strlen( host ) - 1;
00072   const char *nptr = nplist + strlen( nplist ) - 1;
00073   const char *shptr = hptr;
00074 
00075   while ( nptr >= nplist )
00076   {
00077     if ( *hptr != *nptr )
00078     {
00079       hptr = shptr;
00080 
00081       // Try to find another domain or host in the list
00082       while(--nptr>=nplist && *nptr!=',' && *nptr!=' ') ;
00083 
00084       // Strip out multiple spaces and commas
00085       while(--nptr>=nplist && (*nptr==',' || *nptr==' ')) ;
00086     }
00087     else
00088     {
00089       if ( nptr==nplist || nptr[-1]==',' || nptr[-1]==' ')
00090         return true;
00091       if ( nptr[-1]=='/' && hptr == host ) // "bugs.kde.org" vs "http://bugs.kde.org", the config UI says URLs are ok
00092         return true;
00093       if ( hptr == host ) // e.g. revmatch("bugs.kde.org","mybugs.kde.org")
00094         return false;
00095 
00096       hptr--;
00097       nptr--;
00098     }
00099   }
00100 
00101   return false;
00102 }
00103 
00104 class KProtocolManagerPrivate
00105 {
00106 public:
00107    KProtocolManagerPrivate();
00108    ~KProtocolManagerPrivate();
00109     bool shouldIgnoreProxyFor(const KUrl& url);
00110 
00111    KSharedConfig::Ptr config;
00112    KSharedConfig::Ptr http_config;
00113    KUrl url;
00114    QString protocol;
00115    QStringList proxyList;
00116    QString modifiers;
00117    QString useragent;
00118    QString noProxyFor;
00119    QList<SubnetPair> noProxySubnets;
00120 
00121    QMap<QString /*mimetype*/, QString /*protocol*/> protocolForArchiveMimetypes;
00122 };
00123 
00124 K_GLOBAL_STATIC(KProtocolManagerPrivate, kProtocolManagerPrivate)
00125 
00126 KProtocolManagerPrivate::KProtocolManagerPrivate()
00127 {
00128     // post routine since KConfig::sync() breaks if called too late
00129     qAddPostRoutine(kProtocolManagerPrivate.destroy);
00130 }
00131 
00132 KProtocolManagerPrivate::~KProtocolManagerPrivate()
00133 {
00134     qRemovePostRoutine(kProtocolManagerPrivate.destroy);
00135 }
00136 
00137 /*
00138  * Returns true if url is in the no proxy list.
00139  */
00140 bool KProtocolManagerPrivate::shouldIgnoreProxyFor(const KUrl& url)
00141 {
00142   bool isMatch = false;
00143   const KProtocolManager::ProxyType type = KProtocolManager::proxyType();
00144   const bool useRevProxy = ((type == KProtocolManager::ManualProxy) && KProtocolManager::useReverseProxy());
00145   const bool hasNoProxyList = (type == KProtocolManager::ManualProxy || type == KProtocolManager::EnvVarProxy);
00146 
00147   // No proxy only applies to ManualProxy and EnvVarProxy types...
00148   if (hasNoProxyList && !noProxyFor.isEmpty()) {
00149       QStringList noProxyForList (KProtocolManager::noProxyFor().split(QL1C(',')));
00150       QMutableStringListIterator it (noProxyForList);
00151       while (it.hasNext()) {
00152           SubnetPair subnet = QHostAddress::parseSubnet(it.next());
00153           if (!subnet.first.isNull()) {
00154               noProxySubnets << subnet;
00155               it.remove();
00156           }
00157       }
00158       noProxyFor =  noProxyForList.join(QL1S(","));
00159   }
00160 
00161   if (!noProxyFor.isEmpty()) {
00162     QString qhost = url.host().toLower();
00163     QByteArray host = qhost.toLatin1();
00164     const QString qno_proxy = noProxyFor.trimmed().toLower();
00165     const QByteArray no_proxy = qno_proxy.toLatin1();
00166     isMatch = revmatch(host, no_proxy);
00167 
00168     // If no match is found and the request url has a port
00169     // number, try the combination of "host:port". This allows
00170     // users to enter host:port in the No-proxy-For list.
00171     if (!isMatch && url.port() > 0) {
00172       qhost += QL1C(':');
00173       qhost += QString::number(url.port());
00174       host = qhost.toLatin1();
00175       isMatch = revmatch (host, no_proxy);
00176     }
00177 
00178     // If the hostname does not contain a dot, check if
00179     // <local> is part of noProxy.
00180     if (!isMatch && !host.isEmpty() && (strchr(host, '.') == NULL)) {
00181       isMatch = revmatch("<local>", no_proxy);
00182     }
00183   }
00184 
00185   if (!noProxySubnets.isEmpty()) {
00186     QHostAddress address (url.host());
00187     if (address.isNull()) {
00188       QHostInfo info = KIO::HostInfo::lookupHost(url.host(), 2000);
00189       address = info.addresses().first();
00190     }
00191 
00192     if (!address.isNull()) {
00193       Q_FOREACH(const SubnetPair& subnet, noProxySubnets) {
00194         if (address.isInSubnet(subnet)) {
00195           isMatch = true;
00196           break;
00197         }
00198       }
00199     }
00200   }
00201 
00202   return (useRevProxy != isMatch);
00203 }
00204 
00205 
00206 #define PRIVATE_DATA \
00207 KProtocolManagerPrivate *d = kProtocolManagerPrivate
00208 
00209 void KProtocolManager::reparseConfiguration()
00210 {
00211     PRIVATE_DATA;
00212     if (d->http_config) {
00213         d->http_config->reparseConfiguration();
00214     }
00215     if (d->config) {
00216         d->config->reparseConfiguration();
00217     }
00218     d->protocol.clear();
00219     d->proxyList.clear();
00220     d->noProxyFor.clear();
00221     d->modifiers.clear();
00222     d->useragent.clear();
00223     d->url.clear();
00224 
00225     // Force the slave config to re-read its config...
00226     KIO::SlaveConfig::self()->reset ();
00227 }
00228 
00229 KSharedConfig::Ptr KProtocolManager::config()
00230 {
00231   PRIVATE_DATA;
00232   if (!d->config)
00233   {
00234      d->config = KSharedConfig::openConfig("kioslaverc", KConfig::NoGlobals);
00235   }
00236   return d->config;
00237 }
00238 
00239 static KConfigGroup http_config()
00240 {
00241   PRIVATE_DATA;
00242   if (!d->http_config) {
00243      d->http_config = KSharedConfig::openConfig("kio_httprc", KConfig::NoGlobals);
00244   }
00245   return KConfigGroup(d->http_config, QString());
00246 }
00247 
00248 /*=============================== TIMEOUT SETTINGS ==========================*/
00249 
00250 int KProtocolManager::readTimeout()
00251 {
00252   KConfigGroup cg( config(), QString() );
00253   int val = cg.readEntry( "ReadTimeout", DEFAULT_READ_TIMEOUT );
00254   return qMax(MIN_TIMEOUT_VALUE, val);
00255 }
00256 
00257 int KProtocolManager::connectTimeout()
00258 {
00259   KConfigGroup cg( config(), QString() );
00260   int val = cg.readEntry( "ConnectTimeout", DEFAULT_CONNECT_TIMEOUT );
00261   return qMax(MIN_TIMEOUT_VALUE, val);
00262 }
00263 
00264 int KProtocolManager::proxyConnectTimeout()
00265 {
00266   KConfigGroup cg( config(), QString() );
00267   int val = cg.readEntry( "ProxyConnectTimeout", DEFAULT_PROXY_CONNECT_TIMEOUT );
00268   return qMax(MIN_TIMEOUT_VALUE, val);
00269 }
00270 
00271 int KProtocolManager::responseTimeout()
00272 {
00273   KConfigGroup cg( config(), QString() );
00274   int val = cg.readEntry( "ResponseTimeout", DEFAULT_RESPONSE_TIMEOUT );
00275   return qMax(MIN_TIMEOUT_VALUE, val);
00276 }
00277 
00278 /*========================== PROXY SETTINGS =================================*/
00279 
00280 bool KProtocolManager::useProxy()
00281 {
00282   return proxyType() != NoProxy;
00283 }
00284 
00285 bool KProtocolManager::useReverseProxy()
00286 {
00287   KConfigGroup cg(config(), "Proxy Settings" );
00288   return cg.readEntry("ReversedException", false);
00289 }
00290 
00291 KProtocolManager::ProxyType KProtocolManager::proxyType()
00292 {
00293   KConfigGroup cg(config(), "Proxy Settings" );
00294   return static_cast<ProxyType>(cg.readEntry( "ProxyType" , 0));
00295 }
00296 
00297 KProtocolManager::ProxyAuthMode KProtocolManager::proxyAuthMode()
00298 {
00299   KConfigGroup cg(config(), "Proxy Settings" );
00300   return static_cast<ProxyAuthMode>(cg.readEntry( "AuthMode" , 0));
00301 }
00302 
00303 /*========================== CACHING =====================================*/
00304 
00305 bool KProtocolManager::useCache()
00306 {
00307   return http_config().readEntry( "UseCache", true );
00308 }
00309 
00310 KIO::CacheControl KProtocolManager::cacheControl()
00311 {
00312   QString tmp = http_config().readEntry("cache");
00313   if (tmp.isEmpty())
00314     return DEFAULT_CACHE_CONTROL;
00315   return KIO::parseCacheControl(tmp);
00316 }
00317 
00318 QString KProtocolManager::cacheDir()
00319 {
00320   return http_config().readPathEntry("CacheDir", KGlobal::dirs()->saveLocation("cache","http"));
00321 }
00322 
00323 int KProtocolManager::maxCacheAge()
00324 {
00325   return http_config().readEntry( "MaxCacheAge", DEFAULT_MAX_CACHE_AGE ); // 14 days
00326 }
00327 
00328 int KProtocolManager::maxCacheSize()
00329 {
00330   return http_config().readEntry( "MaxCacheSize", DEFAULT_MAX_CACHE_SIZE ); // 5 MB
00331 }
00332 
00333 QString KProtocolManager::noProxyFor()
00334 {
00335   QString noProxy = config()->group("Proxy Settings").readEntry( "NoProxyFor" );
00336   if (proxyType() == EnvVarProxy)
00337     noProxy = QString::fromLocal8Bit(qgetenv(noProxy.toLocal8Bit()));
00338 
00339   return noProxy;
00340 }
00341 
00342 static QString adjustProtocol(const QString& scheme)
00343 {
00344   if (scheme.compare(QL1S("webdav"), Qt::CaseInsensitive) == 0)
00345     return QL1S("http");
00346 
00347   if (scheme.compare(QL1S("webdavs"), Qt::CaseInsensitive) == 0)
00348     return QL1S("https");
00349 
00350   return scheme.toLower();
00351 }
00352 
00353 QString KProtocolManager::proxyFor( const QString& protocol )
00354 {
00355   const QString key = adjustProtocol(protocol) + QL1S("Proxy");
00356   QString proxyStr (config()->group("Proxy Settings").readEntry(key));
00357   const int index = proxyStr.lastIndexOf(QL1C(' '));
00358 
00359   if (index > -1)  {
00360       bool ok = false;
00361       const QString portStr(proxyStr.right(proxyStr.length() - index - 1));
00362       portStr.toInt(&ok);
00363       if (ok) {
00364           proxyStr = proxyStr.left(index) + QL1C(':') + portStr;
00365       } else {
00366           proxyStr.clear();
00367       }
00368   }
00369 
00370   return proxyStr;
00371 }
00372 
00373 QString KProtocolManager::proxyForUrl( const KUrl &url )
00374 {
00375   const QStringList proxies = proxiesForUrl(url);
00376 
00377   if (proxies.isEmpty())
00378     return QString();
00379 
00380   return proxies.first();
00381 }
00382 
00383 static QStringList getSystemProxyFor( const KUrl& url )
00384 {
00385   QStringList proxies;
00386 
00387 #if !defined(QT_NO_NETWORKPROXY) && (defined(Q_OS_WIN32) || defined(Q_OS_MAC))
00388   QNetworkProxyQuery query ( url );
00389   const QList<QNetworkProxy> proxyList = QNetworkProxyFactory::systemProxyForQuery(query);
00390   Q_FOREACH(const QNetworkProxy& proxy, proxyList)
00391   {
00392     KUrl url;
00393     const QNetworkProxy::ProxyType type = proxy.type();
00394     if (type == QNetworkProxy::NoProxy || type == QNetworkProxy::DefaultProxy)
00395     {
00396       proxies << QL1S("DIRECT");
00397       continue;
00398     }
00399 
00400     if (type == QNetworkProxy::HttpProxy || type == QNetworkProxy::HttpCachingProxy)
00401       url.setProtocol(QL1S("http"));
00402     else if (type == QNetworkProxy::Socks5Proxy)
00403       url.setProtocol(QL1S("socks"));
00404     else if (type == QNetworkProxy::FtpCachingProxy)
00405       url.setProtocol(QL1S("ftp"));
00406 
00407     url.setHost(proxy.hostName());
00408     url.setPort(proxy.port());
00409     url.setUser(proxy.user());
00410     proxies << url.url();
00411   }
00412 #else
00413   // On Unix/Linux use system environment variables if any are set.
00414   QString proxyVar (KProtocolManager::proxyFor(url.protocol()));
00415   // Check for SOCKS proxy, if not proxy is found for given url.
00416   if (!proxyVar.isEmpty()) {
00417       QString proxy (QString::fromLocal8Bit(qgetenv(proxyVar.toLocal8Bit())).trimmed());
00418       if (proxy.isEmpty()) {
00419          proxyVar = KProtocolManager::proxyFor(QL1S("socks"));
00420          proxy = QString::fromLocal8Bit(qgetenv(proxyVar.toLocal8Bit())).trimmed();
00421       }
00422       proxies << proxy;
00423   }
00424 #endif
00425   return proxies;
00426 }
00427 
00428 QStringList KProtocolManager::proxiesForUrl( const KUrl &url )
00429 {
00430   QStringList proxyList;
00431 
00432   PRIVATE_DATA;
00433   if (!d->shouldIgnoreProxyFor(url)) {
00434     switch (proxyType())
00435     {
00436       case PACProxy:
00437       case WPADProxy:
00438       {
00439         KUrl u (url);
00440         const QString protocol = adjustProtocol(u.protocol());
00441         u.setProtocol(protocol);
00442 
00443         if (KProtocolInfo::protocolClass(protocol) != QL1S(":local"))
00444         {
00445           QDBusReply<QStringList> reply = QDBusInterface(QL1S("org.kde.kded"),
00446                                                           QL1S("/modules/proxyscout"),
00447                                                           QL1S("org.kde.KPAC.ProxyScout"))
00448                                           .call(QL1S("proxiesForUrl"), u.url());
00449           proxyList = reply;
00450         }
00451         break;
00452       }
00453       case EnvVarProxy:
00454         proxyList = getSystemProxyFor( url );
00455         break;
00456       case ManualProxy:
00457       {
00458         QString proxy (proxyFor(url.protocol()));
00459         // Check for SOCKS proxy, if not proxy is found for given url.
00460         if (proxy.isEmpty()) {
00461           proxy = proxyFor(QL1S("socks"));
00462           // Make sure the scheme of SOCKS proxy is always set to "socks://".
00463           if (!proxy.isEmpty()) {
00464             const int index = proxy.indexOf(QL1S("://"));
00465             proxy = QL1S("socks://") + (index == -1 ? proxy : proxy.mid(index+3));
00466           }
00467         }
00468         proxyList << proxy;
00469       }
00470       break;
00471       case NoProxy:
00472       default:
00473         break;
00474     }
00475   }
00476 
00477   if (proxyList.isEmpty()) {
00478     proxyList << QL1S("DIRECT");
00479   }
00480 
00481   return proxyList;
00482 }
00483 
00484 void KProtocolManager::badProxy( const QString &proxy )
00485 {
00486   QDBusInterface( QL1S("org.kde.kded"), QL1S("/modules/proxyscout"))
00487       .asyncCall(QL1S("blackListProxy"), proxy);
00488 }
00489 
00490 // For proxy address comparisons, we only need to compare
00491 // protocol, host and port number. Nothing else.
00492 static bool compareProxyUrls(const KUrl& u1, const KUrl& u2)
00493 {
00494   return ((u1.protocol() == u2.protocol()) &&
00495           (u1.host() == u2.host()) &&
00496           (u1.port() == u2.port()));
00497 }
00498 
00499 QString KProtocolManager::slaveProtocol(const KUrl &url, QString &proxy)
00500 {
00501     QStringList proxyList;
00502     const QString protocol = KProtocolManager::slaveProtocol(url, proxyList);
00503     if (!proxyList.isEmpty()) {
00504       proxy = proxyList.first();
00505     }
00506     return protocol;
00507 }
00508 
00509 QString KProtocolManager::slaveProtocol(const KUrl &url, QStringList &proxyList)
00510 {
00511   if (url.hasSubUrl()) // We don't want the suburl's protocol
00512   {
00513     const KUrl::List list = KUrl::split(url);
00514     return slaveProtocol(list.last(), proxyList);
00515   }
00516 
00517   PRIVATE_DATA;
00518   if (compareProxyUrls(d->url, url))
00519   {
00520     proxyList = d->proxyList;
00521     return d->protocol;
00522   }
00523 
00524   // Do not perform a proxy lookup for any url classified as a ":local" url or
00525   // one that does not have a host name.
00526   const QString scheme = url.protocol();
00527   if (KProtocolInfo::protocolClass(scheme) == QL1S(":local") || !url.hasHost())
00528   {
00529     return scheme;
00530   }
00531 
00532   d->url = url;
00533   d->protocol = scheme;
00534   d->proxyList.clear();
00535   proxyList.clear();
00536 
00537   const QStringList proxies = proxiesForUrl(url);
00538   const int count = proxies.count();
00539 
00540   if (count > 0 && !(count == 1 && proxies.first() == QL1S("DIRECT")))
00541   {
00542     // The idea behind slave protocols is not applicable to http
00543     // and webdav protocols as well as protocols unknown to KDE.
00544     const bool useRequestScheme = (scheme.startsWith(QL1S("http")) ||
00545                                    scheme.startsWith(QL1S("webdav")) ||
00546                                    !KProtocolInfo::isKnownProtocol(scheme));
00547     Q_FOREACH(const QString& proxy, proxies)
00548     {
00549       if (proxy == QL1S("DIRECT"))
00550       {
00551         proxyList << proxy;
00552       }
00553       else
00554       {
00555         KUrl u (proxy);
00556         if (!u.isEmpty() && u.isValid() && !u.protocol().isEmpty())
00557         {
00558           d->protocol = (useRequestScheme ? scheme : u.protocol());
00559           proxyList << proxy;
00560           // kDebug () << "Slave protocol:" << d->protocol;
00561         }
00562       }
00563     }
00564   }
00565 
00566   if (!proxyList.isEmpty())
00567   {
00568     d->proxyList = proxyList;
00569   }
00570 
00571   return d->protocol;
00572 }
00573 
00574 /*================================= USER-AGENT SETTINGS =====================*/
00575 
00576 QString KProtocolManager::userAgentForHost( const QString& hostname )
00577 {
00578   const QString sendUserAgent = KIO::SlaveConfig::self()->configData("http", hostname.toLower(), "SendUserAgent").toLower();
00579   if (sendUserAgent == QL1S("false"))
00580      return QString();
00581 
00582   const QString useragent = KIO::SlaveConfig::self()->configData("http", hostname.toLower(), "UserAgent");
00583 
00584   // Return the default user-agent if none is specified
00585   // for the requested host.
00586   if (useragent.isEmpty())
00587     return defaultUserAgent();
00588 
00589   return useragent;
00590 }
00591 
00592 QString KProtocolManager::defaultUserAgent( )
00593 {
00594   const QString modifiers = KIO::SlaveConfig::self()->configData("http", QString(), "UserAgentKeys");
00595   return defaultUserAgent(modifiers);
00596 }
00597 
00598 static QString defaultUserAgentFromPreferredService()
00599 {
00600   QString agentStr;
00601 
00602   // Check if the default COMPONENT contains a custom default UA string...
00603   KService::Ptr service = KMimeTypeTrader::self()->preferredService(QL1S("text/html"),
00604                                                       QL1S("KParts/ReadOnlyPart"));
00605   if (service && service->showInKDE())
00606     agentStr = service->property(QL1S("X-KDE-Default-UserAgent"),
00607                                  QVariant::String).toString();
00608   return agentStr;
00609 }
00610 
00611 static QString platform()
00612 {
00613 #if defined(Q_WS_X11)
00614     return QL1S("X11");
00615 #elif defined(Q_WS_MAC)
00616     return QL1S("Macintosh");
00617 #elif defined(Q_WS_WIN)
00618      return QL1S("Windows");
00619 #elif defined(Q_WS_S60)
00620      return QL1S("Symbian");
00621 #endif
00622 }
00623 
00624 QString KProtocolManager::defaultUserAgent( const QString &_modifiers )
00625 {
00626     PRIVATE_DATA;
00627   QString modifiers = _modifiers.toLower();
00628   if (modifiers.isEmpty())
00629     modifiers = DEFAULT_USER_AGENT_KEYS;
00630 
00631   if (d->modifiers == modifiers && !d->useragent.isEmpty())
00632     return d->useragent;
00633 
00634   d->modifiers = modifiers;
00635 
00636   /*
00637      The following code attempts to determine the default user agent string
00638      from the 'X-KDE-UA-DEFAULT-STRING' property of the desktop file
00639      for the preferred service that was configured to handle the 'text/html'
00640      mime type. If the prefered service's desktop file does not specify this
00641      property, the long standing default user agent string will be used.
00642      The following keyword placeholders are automatically converted when the
00643      user agent string is read from the property:
00644 
00645      %SECURITY%      Expands to"N" when SSL is not supported, otherwise it is ignored.
00646      %OSNAME%        Expands to operating system name, e.g. Linux.
00647      %OSVERSION%     Expands to operating system version, e.g. 2.6.32
00648      %SYSTYPE%       Expands to machine or system type, e.g. i386
00649      %PLATFORM%      Expands to windowing system, e.g. X11 on Unix/Linux.
00650      %LANGUAGE%      Expands to default language in use, e.g. en-US.
00651      %APPVERSION%    Expands to QCoreApplication applicationName()/applicationVerison(),
00652                      e.g. Konqueror/4.5.0. If application name and/or application version
00653                      number are not set, then "KDE" and the runtime KDE version numbers
00654                      are used respectively.
00655 
00656      All of the keywords are handled case-insensitively.
00657   */
00658 
00659   QString systemName, systemVersion, machine, supp;
00660   const bool sysInfoFound = getSystemNameVersionAndMachine( systemName, systemVersion, machine );
00661   QString agentStr = defaultUserAgentFromPreferredService();
00662 
00663   if (agentStr.isEmpty())
00664   {
00665     supp += platform();
00666 
00667     if (sysInfoFound)
00668     {
00669       if (modifiers.contains('o'))
00670       {
00671         supp += QL1S("; ");
00672         supp += systemName;
00673         if (modifiers.contains('v'))
00674         {
00675           supp += QL1C(' ');
00676           supp += systemVersion;
00677         }
00678 
00679         if (modifiers.contains('m'))
00680         {
00681           supp += QL1C(' ');
00682           supp += machine;
00683         }
00684       }
00685 
00686       if (modifiers.contains('l'))
00687       {
00688         supp += QL1S("; ");
00689         supp += KGlobal::locale()->language();
00690       }
00691     }
00692 
00693     // Full format: Mozilla/5.0 (Linux
00694     d->useragent = QL1S("Mozilla/5.0 (");
00695     d->useragent += supp;
00696     d->useragent += QL1S(") KHTML/");
00697     d->useragent += QString::number(KDE::versionMajor());
00698     d->useragent += QL1C('.');
00699     d->useragent += QString::number(KDE::versionMinor());
00700     d->useragent += QL1C('.');
00701     d->useragent += QString::number(KDE::versionRelease());
00702     d->useragent += QL1S(" (like Gecko) Konqueror/");
00703     d->useragent += QString::number(KDE::versionMajor());
00704     d->useragent += QL1C('.');
00705     d->useragent += QString::number(KDE::versionMinor());
00706     d->useragent += QL1S(" Fedora/4.7.2-5.fc16");
00707   }
00708   else
00709   {
00710     QString appName = QCoreApplication::applicationName();
00711     if (appName.isEmpty() || appName.startsWith(QL1S("kcmshell"), Qt::CaseInsensitive))
00712       appName = QL1S ("KDE");
00713 
00714     QString appVersion = QCoreApplication::applicationVersion();
00715     if (appVersion.isEmpty()) {
00716       appVersion += QString::number(KDE::versionMajor());
00717       appVersion += QL1C('.');
00718       appVersion += QString::number(KDE::versionMinor());
00719       appVersion += QL1C('.');
00720       appVersion += QString::number(KDE::versionRelease());
00721     }
00722 
00723     appName += QL1C('/');
00724     appName += appVersion;
00725 
00726     agentStr.replace(QL1S("%appversion%"), appName, Qt::CaseInsensitive);
00727 
00728     if (!QSslSocket::supportsSsl())
00729       agentStr.replace(QL1S("%security%"), QL1S("N"), Qt::CaseInsensitive);
00730     else
00731       agentStr.remove(QL1S("%security%"), Qt::CaseInsensitive);
00732 
00733     if (sysInfoFound)
00734     {
00735       // Platform (e.g. X11). It is no longer configurable from UI.
00736       agentStr.replace(QL1S("%platform%"), platform(), Qt::CaseInsensitive);
00737 
00738       // Operating system (e.g. Linux)
00739       if (modifiers.contains('o'))
00740       {
00741         agentStr.replace(QL1S("%osname%"), systemName, Qt::CaseInsensitive);
00742 
00743         // OS version (e.g. 2.6.36)
00744         if (modifiers.contains('v'))
00745           agentStr.replace(QL1S("%osversion%"), systemVersion, Qt::CaseInsensitive);
00746         else
00747           agentStr.remove(QL1S("%osversion%"), Qt::CaseInsensitive);
00748 
00749         // Machine type (i686, x86-64, etc.)
00750         if (modifiers.contains('m'))
00751           agentStr.replace(QL1S("%systype%"), machine, Qt::CaseInsensitive);
00752         else
00753           agentStr.remove(QL1S("%systype%"), Qt::CaseInsensitive);
00754       }
00755       else
00756       {
00757          agentStr.remove(QL1S("%osname%"), Qt::CaseInsensitive);
00758          agentStr.remove(QL1S("%osversion%"), Qt::CaseInsensitive);
00759          agentStr.remove(QL1S("%systype%"), Qt::CaseInsensitive);
00760       }
00761 
00762       // Language (e.g. en_US)
00763       if (modifiers.contains('l'))
00764         agentStr.replace(QL1S("%language%"), KGlobal::locale()->language(), Qt::CaseInsensitive);
00765       else
00766         agentStr.remove(QL1S("%language%"), Qt::CaseInsensitive);
00767 
00768       // Clean up unnecessary separators that could be left over from the
00769       // possible keyword removal above...
00770       agentStr.replace(QRegExp("[(]\\s*[;]\\s*"), QL1S("("));
00771       agentStr.replace(QRegExp("[;]\\s*[;]\\s*"), QL1S("; "));
00772       agentStr.replace(QRegExp("\\s*[;]\\s*[)]"), QL1S(")"));
00773     }
00774     else
00775     {
00776       agentStr.remove(QL1S("%osname%"));
00777       agentStr.remove(QL1S("%osversion%"));
00778       agentStr.remove(QL1S("%platform%"));
00779       agentStr.remove(QL1S("%systype%"));
00780       agentStr.remove(QL1S("%language%"));
00781     }
00782 
00783     d->useragent = agentStr.simplified();
00784   }
00785 
00786   //kDebug() << "USERAGENT STRING:" << d->useragent;
00787   return d->useragent;
00788 }
00789 
00790 QString KProtocolManager::userAgentForApplication( const QString &appName, const QString& appVersion,
00791   const QStringList& extraInfo )
00792 {
00793   QString systemName, systemVersion, machine, info;
00794 
00795   if (getSystemNameVersionAndMachine( systemName, systemVersion, machine ))
00796   {
00797     info +=  systemName;
00798     info += QL1C('/');
00799     info += systemVersion;
00800     info += QL1S("; ");
00801   }
00802 
00803   info += QL1S("KDE/");
00804   info += QString::number(KDE::versionMajor());
00805   info += QL1C('.');
00806   info += QString::number(KDE::versionMinor());
00807   info += QL1C('.');
00808   info += QString::number(KDE::versionRelease());
00809 
00810   if (!machine.isEmpty())
00811   {
00812     info += QL1S("; ");
00813     info += machine;
00814   }
00815 
00816   info += QL1S("; ");
00817   info += extraInfo.join(QL1S("; "));
00818 
00819   return (appName + QL1C('/') + appVersion + QL1S(" (") + info + QL1C(')'));
00820 }
00821 
00822 bool KProtocolManager::getSystemNameVersionAndMachine(
00823   QString& systemName, QString& systemVersion, QString& machine )
00824 {
00825   struct utsname unameBuf;
00826   if ( 0 != uname( &unameBuf ) )
00827     return false;
00828 #if defined(Q_WS_WIN) && !defined(_WIN32_WCE)
00829   // we do not use unameBuf.sysname information constructed in kdewin32
00830   // because we want to get separate name and version
00831   systemName = QL1S( "Windows" );
00832   OSVERSIONINFOEX versioninfo;
00833   ZeroMemory(&versioninfo, sizeof(OSVERSIONINFOEX));
00834   // try calling GetVersionEx using the OSVERSIONINFOEX, if that fails, try using the OSVERSIONINFO
00835   versioninfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
00836   bool ok = GetVersionEx( (OSVERSIONINFO *) &versioninfo );
00837   if ( !ok ) {
00838     versioninfo.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
00839     ok = GetVersionEx( (OSVERSIONINFO *) &versioninfo );
00840   }
00841   if ( ok ) {
00842     systemVersion = QString::number(versioninfo.dwMajorVersion);
00843     systemVersion +=  QL1C('.');
00844     systemVersion += QString::number(versioninfo.dwMinorVersion);
00845   }
00846 #else
00847   systemName = unameBuf.sysname;
00848   systemVersion = unameBuf.release;
00849 #endif
00850   machine = unameBuf.machine;
00851   return true;
00852 }
00853 
00854 QString KProtocolManager::acceptLanguagesHeader()
00855 {
00856   static const QString &english = KGlobal::staticQString("en");
00857 
00858   // User's desktop language preference.
00859   QStringList languageList = KGlobal::locale()->languageList();
00860 
00861   // Replace possible "C" in the language list with "en", unless "en" is
00862   // already pressent. This is to keep user's priorities in order.
00863   // If afterwards "en" is still not present, append it.
00864   int idx = languageList.indexOf(QString::fromLatin1("C"));
00865   if (idx != -1)
00866   {
00867     if (languageList.contains(english))
00868       languageList.removeAt(idx);
00869     else
00870       languageList[idx] = english;
00871   }
00872   if (!languageList.contains(english))
00873     languageList += english;
00874 
00875   // Some languages may have web codes different from locale codes,
00876   // read them from the config and insert in proper order.
00877   KConfig acclangConf("accept-languages.codes", KConfig::NoGlobals);
00878   KConfigGroup replacementCodes(&acclangConf, "ReplacementCodes");
00879   QStringList languageListFinal;
00880   Q_FOREACH (const QString &lang, languageList)
00881   {
00882     const QStringList langs = replacementCodes.readEntry(lang, QStringList());
00883     if (langs.isEmpty())
00884       languageListFinal += lang;
00885     else
00886       languageListFinal += langs;
00887   }
00888 
00889   // The header is composed of comma separated languages, with an optional
00890   // associated priority estimate (q=1..0) defaulting to 1.
00891   // As our language tags are already sorted by priority, we'll just decrease
00892   // the value evenly
00893   int prio = 10;
00894   QString header;
00895   Q_FOREACH (const QString &lang,languageListFinal) {
00896       header += lang;
00897       if (prio < 10) {
00898           header += QL1S(";q=0.");
00899           header += QString::number(prio);
00900       }
00901       // do not add cosmetic whitespace in here : it is less compatible (#220677)
00902       header += QL1S(",");
00903       if (prio > 1)
00904           --prio;
00905   }
00906   header.chop(1);
00907 
00908   // Some of the languages may have country specifier delimited by
00909   // underscore, or modifier delimited by at-sign.
00910   // The header should use dashes instead.
00911   header.replace('_', '-');
00912   header.replace('@', '-');
00913 
00914   return header;
00915 }
00916 
00917 /*==================================== OTHERS ===============================*/
00918 
00919 bool KProtocolManager::markPartial()
00920 {
00921   return config()->group(QByteArray()).readEntry( "MarkPartial", true );
00922 }
00923 
00924 int KProtocolManager::minimumKeepSize()
00925 {
00926     return config()->group(QByteArray()).readEntry( "MinimumKeepSize",
00927                                                 DEFAULT_MINIMUM_KEEP_SIZE ); // 5000 byte
00928 }
00929 
00930 bool KProtocolManager::autoResume()
00931 {
00932   return config()->group(QByteArray()).readEntry( "AutoResume", false );
00933 }
00934 
00935 bool KProtocolManager::persistentConnections()
00936 {
00937   return config()->group(QByteArray()).readEntry( "PersistentConnections", true );
00938 }
00939 
00940 bool KProtocolManager::persistentProxyConnection()
00941 {
00942   return config()->group(QByteArray()).readEntry( "PersistentProxyConnection", false );
00943 }
00944 
00945 QString KProtocolManager::proxyConfigScript()
00946 {
00947   return config()->group("Proxy Settings").readEntry( "Proxy Config Script" );
00948 }
00949 
00950 /* =========================== PROTOCOL CAPABILITIES ============== */
00951 
00952 static KProtocolInfo::Ptr findProtocol(const KUrl &url)
00953 {
00954    QString protocol = url.protocol();
00955 
00956    if ( !KProtocolInfo::proxiedBy( protocol ).isEmpty() )
00957    {
00958       QString dummy;
00959       protocol = KProtocolManager::slaveProtocol(url, dummy);
00960    }
00961 
00962    return KProtocolInfoFactory::self()->findProtocol(protocol);
00963 }
00964 
00965 
00966 KProtocolInfo::Type KProtocolManager::inputType( const KUrl &url )
00967 {
00968   KProtocolInfo::Ptr prot = findProtocol(url);
00969   if ( !prot )
00970     return KProtocolInfo::T_NONE;
00971 
00972   return prot->m_inputType;
00973 }
00974 
00975 KProtocolInfo::Type KProtocolManager::outputType( const KUrl &url )
00976 {
00977   KProtocolInfo::Ptr prot = findProtocol(url);
00978   if ( !prot )
00979     return KProtocolInfo::T_NONE;
00980 
00981   return prot->m_outputType;
00982 }
00983 
00984 
00985 bool KProtocolManager::isSourceProtocol( const KUrl &url )
00986 {
00987   KProtocolInfo::Ptr prot = findProtocol(url);
00988   if ( !prot )
00989     return false;
00990 
00991   return prot->m_isSourceProtocol;
00992 }
00993 
00994 bool KProtocolManager::supportsListing( const KUrl &url )
00995 {
00996   KProtocolInfo::Ptr prot = findProtocol(url);
00997   if ( !prot )
00998     return false;
00999 
01000   return prot->m_supportsListing;
01001 }
01002 
01003 QStringList KProtocolManager::listing( const KUrl &url )
01004 {
01005   KProtocolInfo::Ptr prot = findProtocol(url);
01006   if ( !prot )
01007     return QStringList();
01008 
01009   return prot->m_listing;
01010 }
01011 
01012 bool KProtocolManager::supportsReading( const KUrl &url )
01013 {
01014   KProtocolInfo::Ptr prot = findProtocol(url);
01015   if ( !prot )
01016     return false;
01017 
01018   return prot->m_supportsReading;
01019 }
01020 
01021 bool KProtocolManager::supportsWriting( const KUrl &url )
01022 {
01023   KProtocolInfo::Ptr prot = findProtocol(url);
01024   if ( !prot )
01025     return false;
01026 
01027   return prot->m_supportsWriting;
01028 }
01029 
01030 bool KProtocolManager::supportsMakeDir( const KUrl &url )
01031 {
01032   KProtocolInfo::Ptr prot = findProtocol(url);
01033   if ( !prot )
01034     return false;
01035 
01036   return prot->m_supportsMakeDir;
01037 }
01038 
01039 bool KProtocolManager::supportsDeleting( const KUrl &url )
01040 {
01041   KProtocolInfo::Ptr prot = findProtocol(url);
01042   if ( !prot )
01043     return false;
01044 
01045   return prot->m_supportsDeleting;
01046 }
01047 
01048 bool KProtocolManager::supportsLinking( const KUrl &url )
01049 {
01050   KProtocolInfo::Ptr prot = findProtocol(url);
01051   if ( !prot )
01052     return false;
01053 
01054   return prot->m_supportsLinking;
01055 }
01056 
01057 bool KProtocolManager::supportsMoving( const KUrl &url )
01058 {
01059   KProtocolInfo::Ptr prot = findProtocol(url);
01060   if ( !prot )
01061     return false;
01062 
01063   return prot->m_supportsMoving;
01064 }
01065 
01066 bool KProtocolManager::supportsOpening( const KUrl &url )
01067 {
01068   KProtocolInfo::Ptr prot = findProtocol(url);
01069   if ( !prot )
01070     return false;
01071 
01072   return prot->m_supportsOpening;
01073 }
01074 
01075 bool KProtocolManager::canCopyFromFile( const KUrl &url )
01076 {
01077   KProtocolInfo::Ptr prot = findProtocol(url);
01078   if ( !prot )
01079     return false;
01080 
01081   return prot->m_canCopyFromFile;
01082 }
01083 
01084 
01085 bool KProtocolManager::canCopyToFile( const KUrl &url )
01086 {
01087   KProtocolInfo::Ptr prot = findProtocol(url);
01088   if ( !prot )
01089     return false;
01090 
01091   return prot->m_canCopyToFile;
01092 }
01093 
01094 bool KProtocolManager::canRenameFromFile( const KUrl &url )
01095 {
01096   KProtocolInfo::Ptr prot = findProtocol(url);
01097   if ( !prot )
01098     return false;
01099 
01100   return prot->canRenameFromFile();
01101 }
01102 
01103 
01104 bool KProtocolManager::canRenameToFile( const KUrl &url )
01105 {
01106   KProtocolInfo::Ptr prot = findProtocol(url);
01107   if ( !prot )
01108     return false;
01109 
01110   return prot->canRenameToFile();
01111 }
01112 
01113 bool KProtocolManager::canDeleteRecursive( const KUrl &url )
01114 {
01115   KProtocolInfo::Ptr prot = findProtocol(url);
01116   if ( !prot )
01117     return false;
01118 
01119   return prot->canDeleteRecursive();
01120 }
01121 
01122 KProtocolInfo::FileNameUsedForCopying KProtocolManager::fileNameUsedForCopying( const KUrl &url )
01123 {
01124   KProtocolInfo::Ptr prot = findProtocol(url);
01125   if ( !prot )
01126     return KProtocolInfo::FromUrl;
01127 
01128   return prot->fileNameUsedForCopying();
01129 }
01130 
01131 QString KProtocolManager::defaultMimetype( const KUrl &url )
01132 {
01133   KProtocolInfo::Ptr prot = findProtocol(url);
01134   if ( !prot )
01135     return QString();
01136 
01137   return prot->m_defaultMimetype;
01138 }
01139 
01140 QString KProtocolManager::protocolForArchiveMimetype( const QString& mimeType )
01141 {
01142     PRIVATE_DATA;
01143     if (d->protocolForArchiveMimetypes.isEmpty()) {
01144         const KProtocolInfo::List allProtocols = KProtocolInfoFactory::self()->allProtocols();
01145         for (KProtocolInfo::List::const_iterator it = allProtocols.begin();
01146              it != allProtocols.end(); ++it) {
01147             const QStringList archiveMimetypes = (*it)->archiveMimeTypes();
01148             Q_FOREACH(const QString& mime, archiveMimetypes) {
01149                 d->protocolForArchiveMimetypes.insert(mime, (*it)->name());
01150             }
01151         }
01152     }
01153     return d->protocolForArchiveMimetypes.value(mimeType);
01154 }
01155 
01156 #undef PRIVATE_DATA

KIO

Skip menu "KIO"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.7.5
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal