KIO

kprotocolmanager.cpp
1 /*
2  This file is part of the KDE libraries
3  SPDX-FileCopyrightText: 1999 Torben Weis <[email protected]>
4  SPDX-FileCopyrightText: 2000 Waldo Bastain <[email protected]>
5  SPDX-FileCopyrightText: 2000 Dawit Alemayehu <[email protected]>
6  SPDX-FileCopyrightText: 2008 JarosÅ‚aw Staniek <[email protected]>
7 
8  SPDX-License-Identifier: LGPL-2.0-only
9 */
10 
11 #include "kprotocolmanager.h"
12 #include "kprotocolinfo_p.h"
13 
14 #include "hostinfo.h"
15 
16 #include <config-kiocore.h>
17 
18 #include <string.h>
19 #include <qplatformdefs.h>
20 #ifdef Q_OS_WIN
21 #include <qt_windows.h>
22 #undef interface //windows.h defines this, breaks QtDBus since it has parameters named interface
23 #else
24 #include <sys/utsname.h>
25 #endif
26 
27 #include <QCoreApplication>
28 #include <QUrl>
29 #include <QSslSocket>
30 #include <QHostAddress>
31 #include <QHostInfo>
32 #include <QDBusReply>
33 #include <QDBusInterface>
34 #include <QCache>
35 #include <QLocale>
36 #include <QRegularExpression>
37 #include <QStandardPaths>
38 #include <QMimeDatabase>
39 
40 #if !defined(QT_NO_NETWORKPROXY) && (defined (Q_OS_WIN32) || defined(Q_OS_MAC))
41 #include <QNetworkProxyFactory>
42 #include <QNetworkProxyQuery>
43 #endif
44 
45 #include <kio_version.h>
46 #include <KConfigGroup>
47 #include <KSharedConfig>
48 
49 #include <KMimeTypeTrader>
50 #include <kprotocolinfofactory_p.h>
51 
52 #include "slaveconfig.h"
53 #include "ioslave_defaults.h"
54 #include "http_slave_defaults.h"
55 
56 #define QL1S(x) QLatin1String(x)
57 #define QL1C(x) QLatin1Char(x)
58 
60 
61 /*
62  Domain suffix match. E.g. return true if host is "cuzco.inka.de" and
63  nplist is "inka.de,hadiko.de" or if host is "localhost" and nplist is
64  "localhost".
65 */
66 static bool revmatch(const char *host, const char *nplist)
67 {
68  if (host == nullptr) {
69  return false;
70  }
71 
72  const char *hptr = host + strlen(host) - 1;
73  const char *nptr = nplist + strlen(nplist) - 1;
74  const char *shptr = hptr;
75 
76  while (nptr >= nplist) {
77  if (*hptr != *nptr) {
78  hptr = shptr;
79 
80  // Try to find another domain or host in the list
81  while (--nptr >= nplist && *nptr != ',' && *nptr != ' ');
82 
83  // Strip out multiple spaces and commas
84  while (--nptr >= nplist && (*nptr == ',' || *nptr == ' '));
85  } else {
86  if (nptr == nplist || nptr[-1] == ',' || nptr[-1] == ' ') {
87  return true;
88  }
89  if (nptr[-1] == '/' && hptr == host) { // "bugs.kde.org" vs "http://bugs.kde.org", the config UI says URLs are ok
90  return true;
91  }
92  if (hptr == host) { // e.g. revmatch("bugs.kde.org","mybugs.kde.org")
93  return false;
94  }
95 
96  hptr--;
97  nptr--;
98  }
99  }
100 
101  return false;
102 }
103 
104 class KProxyData : public QObject
105 {
106  Q_OBJECT
107 public:
108  KProxyData(const QString &slaveProtocol, const QStringList &proxyAddresses)
109  : protocol(slaveProtocol)
110  , proxyList(proxyAddresses)
111  {
112  }
113 
114  void removeAddress(const QString &address)
115  {
116  proxyList.removeAll(address);
117  }
118 
119  QString protocol;
120  QStringList proxyList;
121 };
122 
123 class KProtocolManagerPrivate
124 {
125 public:
126  KProtocolManagerPrivate();
127  ~KProtocolManagerPrivate();
128  bool shouldIgnoreProxyFor(const QUrl &url);
129  void sync();
130  KProtocolManager::ProxyType proxyType();
131  bool useReverseProxy();
132  QString readNoProxyFor();
133  QString proxyFor(const QString &protocol);
134  QStringList getSystemProxyFor(const QUrl &url);
135 
136  QMutex mutex; // protects all member vars
137  KSharedConfig::Ptr configPtr;
138  KSharedConfig::Ptr http_config;
139  QString modifiers;
140  QString useragent;
141  QString noProxyFor;
142  QList<SubnetPair> noProxySubnets;
143  QCache<QString, KProxyData> cachedProxyData;
144 
145  QMap<QString /*mimetype*/, QString /*protocol*/> protocolForArchiveMimetypes;
146 };
147 
148 Q_GLOBAL_STATIC(KProtocolManagerPrivate, kProtocolManagerPrivate)
149 
150 static void syncOnExit()
151 {
152  if (kProtocolManagerPrivate.exists())
153  kProtocolManagerPrivate()->sync();
154 }
155 
156 KProtocolManagerPrivate::KProtocolManagerPrivate()
157 {
158  // post routine since KConfig::sync() breaks if called too late
159  qAddPostRoutine(syncOnExit);
160  cachedProxyData.setMaxCost(200); // double the max cost.
161 }
162 
163 KProtocolManagerPrivate::~KProtocolManagerPrivate()
164 {
165 }
166 
167 /*
168  * Returns true if url is in the no proxy list.
169  */
170 bool KProtocolManagerPrivate::shouldIgnoreProxyFor(const QUrl &url)
171 {
172  bool isMatch = false;
173  const KProtocolManager::ProxyType type = proxyType();
174  const bool useRevProxy = ((type == KProtocolManager::ManualProxy) && useReverseProxy());
175  const bool useNoProxyList = (type == KProtocolManager::ManualProxy || type == KProtocolManager::EnvVarProxy);
176 
177  // No proxy only applies to ManualProxy and EnvVarProxy types...
178  if (useNoProxyList && noProxyFor.isEmpty()) {
179  QStringList noProxyForList(readNoProxyFor().split(QL1C(',')));
180  QMutableStringListIterator it(noProxyForList);
181  while (it.hasNext()) {
182  SubnetPair subnet = QHostAddress::parseSubnet(it.next());
183  if (!subnet.first.isNull()) {
184  noProxySubnets << subnet;
185  it.remove();
186  }
187  }
188  noProxyFor = noProxyForList.join(QLatin1Char(','));
189  }
190 
191  if (!noProxyFor.isEmpty()) {
192  QString qhost = url.host().toLower();
193  QByteArray host = qhost.toLatin1();
194  const QString qno_proxy = noProxyFor.trimmed().toLower();
195  const QByteArray no_proxy = qno_proxy.toLatin1();
196  isMatch = revmatch(host.constData(), no_proxy.constData());
197 
198  // If no match is found and the request url has a port
199  // number, try the combination of "host:port". This allows
200  // users to enter host:port in the No-proxy-For list.
201  if (!isMatch && url.port() > 0) {
202  qhost += QL1C(':') + QString::number(url.port());
203  host = qhost.toLatin1();
204  isMatch = revmatch(host.constData(), no_proxy.constData());
205  }
206 
207  // If the hostname does not contain a dot, check if
208  // <local> is part of noProxy.
209  if (!isMatch && !host.isEmpty() && (strchr(host.constData(), '.') == nullptr)) {
210  isMatch = revmatch("<local>", no_proxy.constData());
211  }
212  }
213 
214  const QString host(url.host());
215 
216  if (!noProxySubnets.isEmpty() && !host.isEmpty()) {
217  QHostAddress address(host);
218  // If request url is not IP address, do a DNS lookup of the hostname.
219  // TODO: Perhaps we should make configurable ?
220  if (address.isNull()) {
221  //qDebug() << "Performing DNS lookup for" << host;
222  QHostInfo info = KIO::HostInfo::lookupHost(host, 2000);
223  const QList<QHostAddress> addresses = info.addresses();
224  if (!addresses.isEmpty()) {
225  address = addresses.first();
226  }
227  }
228 
229  if (!address.isNull()) {
230  for (const SubnetPair &subnet : qAsConst(noProxySubnets)) {
231  if (address.isInSubnet(subnet)) {
232  isMatch = true;
233  break;
234  }
235  }
236  }
237  }
238 
239  return (useRevProxy != isMatch);
240 }
241 
242 void KProtocolManagerPrivate::sync()
243 {
244  QMutexLocker lock(&mutex);
245  if (http_config) {
246  http_config->sync();
247  }
248  if (configPtr) {
249  configPtr->sync();
250  }
251 }
252 
253 #define PRIVATE_DATA \
254  KProtocolManagerPrivate *d = kProtocolManagerPrivate()
255 
257 {
258  PRIVATE_DATA;
259  QMutexLocker lock(&d->mutex);
260  if (d->http_config) {
261  d->http_config->reparseConfiguration();
262  }
263  if (d->configPtr) {
264  d->configPtr->reparseConfiguration();
265  }
266  d->cachedProxyData.clear();
267  d->noProxyFor.clear();
268  d->modifiers.clear();
269  d->useragent.clear();
270  lock.unlock();
271 
272  // Force the slave config to re-read its config...
273  KIO::SlaveConfig::self()->reset();
274 }
275 
276 static KSharedConfig::Ptr config()
277 {
278  PRIVATE_DATA;
279  Q_ASSERT(!d->mutex.tryLock()); // the caller must have locked the mutex
280  if (!d->configPtr) {
281  d->configPtr = KSharedConfig::openConfig(QStringLiteral("kioslaverc"), KConfig::NoGlobals);
282  }
283  return d->configPtr;
284 }
285 
286 KProtocolManager::ProxyType KProtocolManagerPrivate::proxyType()
287 {
288  KConfigGroup cg(config(), "Proxy Settings");
289  return static_cast<KProtocolManager::ProxyType>(cg.readEntry("ProxyType", 0));
290 }
291 
292 bool KProtocolManagerPrivate::useReverseProxy()
293 {
294  KConfigGroup cg(config(), "Proxy Settings");
295  return cg.readEntry("ReversedException", false);
296 }
297 
298 QString KProtocolManagerPrivate::readNoProxyFor()
299 {
300  QString noProxy = config()->group("Proxy Settings").readEntry("NoProxyFor");
301  if (proxyType() == KProtocolManager::EnvVarProxy) {
302  noProxy = QString::fromLocal8Bit(qgetenv(noProxy.toLocal8Bit().constData()));
303  }
304  return noProxy;
305 }
306 
307 QMap<QString, QString> KProtocolManager::entryMap(const QString &group)
308 {
309  PRIVATE_DATA;
310  QMutexLocker lock(&d->mutex);
311  return config()->entryMap(group);
312 }
313 
314 static KConfigGroup http_config()
315 {
316  PRIVATE_DATA;
317  Q_ASSERT(!d->mutex.tryLock()); // the caller must have locked the mutex
318  if (!d->http_config) {
319  d->http_config = KSharedConfig::openConfig(QStringLiteral("kio_httprc"), KConfig::NoGlobals);
320  }
321  return KConfigGroup(d->http_config, QString());
322 }
323 
324 /*=============================== TIMEOUT SETTINGS ==========================*/
325 
327 {
328  PRIVATE_DATA;
329  QMutexLocker lock(&d->mutex);
330  KConfigGroup cg(config(), QString());
331  int val = cg.readEntry("ReadTimeout", DEFAULT_READ_TIMEOUT);
332  return qMax(MIN_TIMEOUT_VALUE, val);
333 }
334 
336 {
337  PRIVATE_DATA;
338  QMutexLocker lock(&d->mutex);
339  KConfigGroup cg(config(), QString());
340  int val = cg.readEntry("ConnectTimeout", DEFAULT_CONNECT_TIMEOUT);
341  return qMax(MIN_TIMEOUT_VALUE, val);
342 }
343 
345 {
346  PRIVATE_DATA;
347  QMutexLocker lock(&d->mutex);
348  KConfigGroup cg(config(), QString());
349  int val = cg.readEntry("ProxyConnectTimeout", DEFAULT_PROXY_CONNECT_TIMEOUT);
350  return qMax(MIN_TIMEOUT_VALUE, val);
351 }
352 
354 {
355  PRIVATE_DATA;
356  QMutexLocker lock(&d->mutex);
357  KConfigGroup cg(config(), QString());
358  int val = cg.readEntry("ResponseTimeout", DEFAULT_RESPONSE_TIMEOUT);
359  return qMax(MIN_TIMEOUT_VALUE, val);
360 }
361 
362 /*========================== PROXY SETTINGS =================================*/
363 
365 {
366  return proxyType() != NoProxy;
367 }
368 
370 {
371  PRIVATE_DATA;
372  QMutexLocker lock(&d->mutex);
373  return d->useReverseProxy();
374 }
375 
377 {
378  PRIVATE_DATA;
379  QMutexLocker lock(&d->mutex);
380  return d->proxyType();
381 }
382 
384 {
385  PRIVATE_DATA;
386  QMutexLocker lock(&d->mutex);
387  KConfigGroup cg(config(), "Proxy Settings");
388  return static_cast<ProxyAuthMode>(cg.readEntry("AuthMode", 0));
389 }
390 
391 /*========================== CACHING =====================================*/
392 
394 {
395  PRIVATE_DATA;
396  QMutexLocker lock(&d->mutex);
397  return http_config().readEntry("UseCache", true);
398 }
399 
401 {
402  PRIVATE_DATA;
403  QMutexLocker lock(&d->mutex);
404  QString tmp = http_config().readEntry("cache");
405  if (tmp.isEmpty()) {
406  return DEFAULT_CACHE_CONTROL;
407  }
408  return KIO::parseCacheControl(tmp);
409 }
410 
412 {
413  PRIVATE_DATA;
414  QMutexLocker lock(&d->mutex);
416 }
417 
419 {
420  PRIVATE_DATA;
421  QMutexLocker lock(&d->mutex);
422  return http_config().readEntry("MaxCacheAge", DEFAULT_MAX_CACHE_AGE);
423 }
424 
426 {
427  PRIVATE_DATA;
428  QMutexLocker lock(&d->mutex);
429  return http_config().readEntry("MaxCacheSize", DEFAULT_MAX_CACHE_SIZE);
430 }
431 
433 {
434  PRIVATE_DATA;
435  QMutexLocker lock(&d->mutex);
436  return d->readNoProxyFor();
437 }
438 
439 static QString adjustProtocol(const QString &scheme)
440 {
441 if (scheme.compare(QL1S("webdav"), Qt::CaseInsensitive) == 0) {
442  return QStringLiteral("http");
443  }
444 
445  if (scheme.compare(QL1S("webdavs"), Qt::CaseInsensitive) == 0) {
446  return QStringLiteral("https");
447  }
448 
449  return scheme.toLower();
450 }
451 
453 {
454  PRIVATE_DATA;
455  QMutexLocker lock(&d->mutex);
456  return d->proxyFor(protocol);
457 }
458 
459 QString KProtocolManagerPrivate::proxyFor(const QString &protocol)
460 {
461  const QString key = adjustProtocol(protocol) + QL1S("Proxy");
462  QString proxyStr(config()->group("Proxy Settings").readEntry(key));
463  const int index = proxyStr.lastIndexOf(QL1C(' '));
464 
465  if (index > -1) {
466  bool ok = false;
467  const QStringRef portStr(proxyStr.rightRef(proxyStr.length() - index - 1));
468  portStr.toInt(&ok);
469  if (ok) {
470  proxyStr = proxyStr.leftRef(index) + QL1C(':') + portStr;
471  } else {
472  proxyStr.clear();
473  }
474  }
475 
476  return proxyStr;
477 }
478 
480 {
481  const QStringList proxies = proxiesForUrl(url);
482 
483  if (proxies.isEmpty()) {
484  return QString();
485  }
486 
487  return proxies.first();
488 }
489 
490 QStringList KProtocolManagerPrivate::getSystemProxyFor(const QUrl &url)
491 {
492  QStringList proxies;
493 
494 #if !defined(QT_NO_NETWORKPROXY) && (defined(Q_OS_WIN32) || defined(Q_OS_MAC))
495  QNetworkProxyQuery query(url);
497  proxies.reserve(proxyList.size());
498  for (const QNetworkProxy &proxy : proxyList) {
499  QUrl url;
500  const QNetworkProxy::ProxyType type = proxy.type();
501  if (type == QNetworkProxy::NoProxy || type == QNetworkProxy::DefaultProxy) {
502  proxies << QL1S("DIRECT");
503  continue;
504  }
505 
507  url.setScheme(QL1S("http"));
508  } else if (type == QNetworkProxy::Socks5Proxy) {
509  url.setScheme(QL1S("socks"));
510  } else if (type == QNetworkProxy::FtpCachingProxy) {
511  url.setScheme(QL1S("ftp"));
512  }
513 
514  url.setHost(proxy.hostName());
515  url.setPort(proxy.port());
516  url.setUserName(proxy.user());
517  proxies << url.url();
518  }
519 #else
520  // On Unix/Linux use system environment variables if any are set.
521  QString proxyVar(proxyFor(url.scheme()));
522  // Check for SOCKS proxy, if not proxy is found for given url.
523  if (!proxyVar.isEmpty()) {
524  const QString proxy(QString::fromLocal8Bit(qgetenv(proxyVar.toLocal8Bit().constData())).trimmed());
525  if (!proxy.isEmpty()) {
526  proxies << proxy;
527  }
528  }
529  // Add the socks proxy as an alternate proxy if it exists,
530  proxyVar = proxyFor(QStringLiteral("socks"));
531  if (!proxyVar.isEmpty()) {
532  QString proxy = QString::fromLocal8Bit(qgetenv(proxyVar.toLocal8Bit().constData())).trimmed();
533  // Make sure the scheme of SOCKS proxy is always set to "socks://".
534  const int index = proxy.indexOf(QL1S("://"));
535  const int offset = (index == -1) ? 0 : (index + 3);
536  proxy = QL1S("socks://") + proxy.midRef(offset);
537  if (!proxy.isEmpty()) {
538  proxies << proxy;
539  }
540  }
541 #endif
542  return proxies;
543 }
544 
546 {
547  QStringList proxyList;
548 
549  PRIVATE_DATA;
550  QMutexLocker lock(&d->mutex);
551  if (!d->shouldIgnoreProxyFor(url)) {
552  switch (d->proxyType()) {
553  case PACProxy:
554  case WPADProxy: {
555  QUrl u(url);
556  const QString protocol = adjustProtocol(u.scheme());
557  u.setScheme(protocol);
558 
559  if (protocol.startsWith(QLatin1String("http")) || protocol.startsWith(QLatin1String("ftp"))) {
560  QDBusReply<QStringList> reply = QDBusInterface(QStringLiteral("org.kde.kded5"),
561  QStringLiteral("/modules/proxyscout"),
562  QStringLiteral("org.kde.KPAC.ProxyScout"))
563  .call(QStringLiteral("proxiesForUrl"), u.toString());
564  proxyList = reply;
565  }
566  break;
567  }
568  case EnvVarProxy:
569  proxyList = d->getSystemProxyFor(url);
570  break;
571  case ManualProxy: {
572  QString proxy(d->proxyFor(url.scheme()));
573  if (!proxy.isEmpty()) {
574  proxyList << proxy;
575  }
576  // Add the socks proxy as an alternate proxy if it exists,
577  proxy = d->proxyFor(QStringLiteral("socks"));
578  if (!proxy.isEmpty()) {
579  // Make sure the scheme of SOCKS proxy is always set to "socks://".
580  const int index = proxy.indexOf(QL1S("://"));
581  const int offset = (index == -1) ? 0 : (index + 3);
582  proxy = QL1S("socks://") + proxy.midRef(offset);
583  proxyList << proxy;
584  }
585  }
586  break;
587  case NoProxy:
588  break;
589  }
590  }
591 
592  if (proxyList.isEmpty()) {
593  proxyList << QStringLiteral("DIRECT");
594  }
595 
596  return proxyList;
597 }
598 
600 {
601  QDBusInterface(QStringLiteral("org.kde.kded5"), QStringLiteral("/modules/proxyscout"))
602  .asyncCall(QStringLiteral("blackListProxy"), proxy);
603 
604  PRIVATE_DATA;
605  QMutexLocker lock(&d->mutex);
606  const QStringList keys(d->cachedProxyData.keys());
607  for (const QString &key : keys) {
608  d->cachedProxyData[key]->removeAddress(proxy);
609  }
610 }
611 
613 {
614  QStringList proxyList;
615  const QString protocol = KProtocolManager::slaveProtocol(url, proxyList);
616  if (!proxyList.isEmpty()) {
617  proxy = proxyList.first();
618  }
619  return protocol;
620 }
621 
622 // Generates proxy cache key from request given url.
623 static void extractProxyCacheKeyFromUrl(const QUrl &u, QString *key)
624 {
625  if (!key) {
626  return;
627  }
628 
629  *key = u.scheme();
630  *key += u.host();
631 
632  if (u.port() > 0) {
633  *key += QString::number(u.port());
634  }
635 }
636 
638 {
639  proxyList.clear();
640 
641  // Do not perform a proxy lookup for any url classified as a ":local" url or
642  // one that does not have a host component or if proxy is disabled.
643  QString protocol(url.scheme());
644  if (url.host().isEmpty()
645  || KProtocolInfo::protocolClass(protocol) == QL1S(":local")
646  || KProtocolManager::proxyType() == KProtocolManager::NoProxy) {
647  return protocol;
648  }
649 
650  QString proxyCacheKey;
651  extractProxyCacheKeyFromUrl(url, &proxyCacheKey);
652 
653  PRIVATE_DATA;
654  QMutexLocker lock(&d->mutex);
655  // Look for cached proxy information to avoid more work.
656  if (d->cachedProxyData.contains(proxyCacheKey)) {
657  KProxyData *data = d->cachedProxyData.object(proxyCacheKey);
658  proxyList = data->proxyList;
659  return data->protocol;
660  }
661  lock.unlock();
662 
663  const QStringList proxies = proxiesForUrl(url);
664  const int count = proxies.count();
665 
666  if (count > 0 && !(count == 1 && proxies.first() == QL1S("DIRECT"))) {
667  for (const QString &proxy : proxies) {
668  if (proxy == QL1S("DIRECT")) {
669  proxyList << proxy;
670  } else {
671  QUrl u(proxy);
672  if (!u.isEmpty() && u.isValid() && !u.scheme().isEmpty()) {
673  proxyList << proxy;
674  }
675  }
676  }
677  }
678 
679  // The idea behind slave protocols is not applicable to http
680  // and webdav protocols as well as protocols unknown to KDE.
681  if (!proxyList.isEmpty()
682  && !protocol.startsWith(QLatin1String("http"))
683  && !protocol.startsWith(QLatin1String("webdav"))
684  && KProtocolInfo::isKnownProtocol(protocol)) {
685  for (const QString &proxy : qAsConst(proxyList)) {
686  QUrl u(proxy);
688  protocol = u.scheme();
689  break;
690  }
691  }
692  }
693 
694  lock.relock();
695  // cache the proxy information...
696  d->cachedProxyData.insert(proxyCacheKey, new KProxyData(protocol, proxyList));
697  return protocol;
698 }
699 
700 /*================================= USER-AGENT SETTINGS =====================*/
701 
703 {
704  const QString sendUserAgent = KIO::SlaveConfig::self()->configData(QStringLiteral("http"), hostname.toLower(), QStringLiteral("SendUserAgent")).toLower();
705  if (sendUserAgent == QL1S("false")) {
706  return QString();
707  }
708 
709  const QString useragent = KIO::SlaveConfig::self()->configData(QStringLiteral("http"), hostname.toLower(), QStringLiteral("UserAgent"));
710 
711  // Return the default user-agent if none is specified
712  // for the requested host.
713  if (useragent.isEmpty()) {
714  return defaultUserAgent();
715  }
716 
717  return useragent;
718 }
719 
721 {
722  const QString modifiers = KIO::SlaveConfig::self()->configData(QStringLiteral("http"), QString(), QStringLiteral("UserAgentKeys"));
723  return defaultUserAgent(modifiers);
724 }
725 
726 static QString defaultUserAgentFromPreferredService()
727 {
728  QString agentStr;
729 
730  // Check if the default COMPONENT contains a custom default UA string...
731  KService::Ptr service = KMimeTypeTrader::self()->preferredService(QStringLiteral("text/html"),
732  QStringLiteral("KParts/ReadOnlyPart"));
733  if (service && service->showInCurrentDesktop())
734  agentStr = service->property(QStringLiteral("X-KDE-Default-UserAgent"),
736  return agentStr;
737 }
738 
739 // This is not the OS, but the windowing system, e.g. X11 on Unix/Linux.
740 static QString platform()
741 {
742 #if defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN)
743  return QStringLiteral("X11");
744 #elif defined(Q_OS_MAC)
745  return QStringLiteral("Macintosh");
746 #elif defined(Q_OS_WIN)
747  return QStringLiteral("Windows");
748 #else
749  return QStringLiteral("Unknown");
750 #endif
751 }
752 
754 {
755  PRIVATE_DATA;
756  QMutexLocker lock(&d->mutex);
757  QString modifiers = _modifiers.toLower();
758  if (modifiers.isEmpty()) {
759  modifiers = QStringLiteral(DEFAULT_USER_AGENT_KEYS);
760  }
761 
762  if (d->modifiers == modifiers && !d->useragent.isEmpty()) {
763  return d->useragent;
764  }
765 
766  d->modifiers = modifiers;
767 
768  /*
769  The following code attempts to determine the default user agent string
770  from the 'X-KDE-UA-DEFAULT-STRING' property of the desktop file
771  for the preferred service that was configured to handle the 'text/html'
772  mime type. If the preferred service's desktop file does not specify this
773  property, the long standing default user agent string will be used.
774  The following keyword placeholders are automatically converted when the
775  user agent string is read from the property:
776 
777  %SECURITY% Expands to"N" when SSL is not supported, otherwise it is ignored.
778  %OSNAME% Expands to operating system name, e.g. Linux.
779  %OSVERSION% Expands to operating system version, e.g. 2.6.32
780  %SYSTYPE% Expands to machine or system type, e.g. i386
781  %PLATFORM% Expands to windowing system, e.g. X11 on Unix/Linux.
782  %LANGUAGE% Expands to default language in use, e.g. en-US.
783  %APPVERSION% Expands to QCoreApplication applicationName()/applicationVerison(),
784  e.g. Konqueror/4.5.0. If application name and/or application version
785  number are not set, then "KDE" and the runtime KDE version numbers
786  are used respectively.
787 
788  All of the keywords are handled case-insensitively.
789  */
790 
791  QString systemName, systemVersion, machine, supp;
792  const bool sysInfoFound = getSystemNameVersionAndMachine(systemName, systemVersion, machine);
793  QString agentStr = defaultUserAgentFromPreferredService();
794 
795  if (agentStr.isEmpty()) {
796  supp += platform();
797 
798  if (sysInfoFound) {
799  if (modifiers.contains(QL1C('o'))) {
800  supp += QL1S("; ") + systemName;
801  if (modifiers.contains(QL1C('v'))) {
802  supp += QL1C(' ') + systemVersion;
803  }
804 
805  if (modifiers.contains(QL1C('m'))) {
806  supp += QL1C(' ') + machine;
807  }
808  }
809 
810  if (modifiers.contains(QL1C('l'))) {
811  supp += QL1S("; ") + QLocale::languageToString(QLocale().language());
812  }
813  }
814 
815  // Full format: Mozilla/5.0 (Linux
816  d->useragent =
817  QL1S("Mozilla/5.0 (") +
818  supp +
819  QL1S(") KHTML/") +
820  QString::number(KIO_VERSION_MAJOR) +
821  QL1C('.') +
822  QString::number(KIO_VERSION_MINOR) +
823  QL1C('.') +
824  QString::number(KIO_VERSION_PATCH) +
825  QL1S(" (like Gecko) Konqueror/") +
826  QString::number(KIO_VERSION_MAJOR) +
827  QL1S(" KIO/") +
828  QString::number(KIO_VERSION_MAJOR) +
829  QL1C('.') +
830  QString::number(KIO_VERSION_MINOR);
831  } else {
833  if (appName.isEmpty() || appName.startsWith(QLatin1String("kcmshell"), Qt::CaseInsensitive)) {
834  appName = QStringLiteral("KDE");
835  }
836 
838  if (appVersion.isEmpty()) {
839  appVersion +=
840  QString::number(KIO_VERSION_MAJOR) +
841  QL1C('.') +
842  QString::number(KIO_VERSION_MINOR) +
843  QL1C('.') +
844  QString::number(KIO_VERSION_PATCH);
845  }
846 
847  appName += QL1C('/') + appVersion;
848 
849  agentStr.replace(QL1S("%appversion%"), appName, Qt::CaseInsensitive);
850 
851  if (!QSslSocket::supportsSsl()) {
852  agentStr.replace(QLatin1String("%security%"), QL1S("N"), Qt::CaseInsensitive);
853  } else {
854  agentStr.remove(QStringLiteral("%security%"), Qt::CaseInsensitive);
855  }
856 
857  if (sysInfoFound) {
858  // Platform (e.g. X11). It is no longer configurable from UI.
859  agentStr.replace(QL1S("%platform%"), platform(), Qt::CaseInsensitive);
860 
861  // Operating system (e.g. Linux)
862  if (modifiers.contains(QL1C('o'))) {
863  agentStr.replace(QL1S("%osname%"), systemName, Qt::CaseInsensitive);
864 
865  // OS version (e.g. 2.6.36)
866  if (modifiers.contains(QL1C('v'))) {
867  agentStr.replace(QL1S("%osversion%"), systemVersion, Qt::CaseInsensitive);
868  } else {
869  agentStr.remove(QStringLiteral("%osversion%"), Qt::CaseInsensitive);
870  }
871 
872  // Machine type (i686, x86-64, etc.)
873  if (modifiers.contains(QL1C('m'))) {
874  agentStr.replace(QL1S("%systype%"), machine, Qt::CaseInsensitive);
875  } else {
876  agentStr.remove(QStringLiteral("%systype%"), Qt::CaseInsensitive);
877  }
878  } else {
879  agentStr.remove(QStringLiteral("%osname%"), Qt::CaseInsensitive);
880  agentStr.remove(QStringLiteral("%osversion%"), Qt::CaseInsensitive);
881  agentStr.remove(QStringLiteral("%systype%"), Qt::CaseInsensitive);
882  }
883 
884  // Language (e.g. en_US)
885  if (modifiers.contains(QL1C('l'))) {
886  agentStr.replace(QL1S("%language%"), QLocale::languageToString(QLocale().language()), Qt::CaseInsensitive);
887  } else {
888  agentStr.remove(QStringLiteral("%language%"), Qt::CaseInsensitive);
889  }
890 
891  // Clean up unnecessary separators that could be left over from the
892  // possible keyword removal above...
893  agentStr.replace(QRegularExpression(QStringLiteral("[(]\\s*[;]\\s*")), QStringLiteral("("));
894  agentStr.replace(QRegularExpression(QStringLiteral("[;]\\s*[;]\\s*")), QStringLiteral("; "));
895  agentStr.replace(QRegularExpression(QStringLiteral("\\s*[;]\\s*[)]")), QStringLiteral(")"));
896  } else {
897  agentStr.remove(QStringLiteral("%osname%"));
898  agentStr.remove(QStringLiteral("%osversion%"));
899  agentStr.remove(QStringLiteral("%platform%"));
900  agentStr.remove(QStringLiteral("%systype%"));
901  agentStr.remove(QStringLiteral("%language%"));
902  }
903 
904  d->useragent = agentStr.simplified();
905  }
906 
907  //qDebug() << "USERAGENT STRING:" << d->useragent;
908  return d->useragent;
909 }
910 
912  const QStringList &extraInfo)
913 {
914  QString systemName, systemVersion, machine, info;
915 
916  if (getSystemNameVersionAndMachine(systemName, systemVersion, machine)) {
917  info += systemName + QL1C('/') + systemVersion + QL1S("; ");
918  }
919 
920  info +=
921  QL1S("KDE/") +
922  QString::number(KIO_VERSION_MAJOR) +
923  QL1C('.') +
924  QString::number(KIO_VERSION_MINOR) +
925  QL1C('.') +
926  QString::number(KIO_VERSION_PATCH);
927 
928  if (!machine.isEmpty()) {
929  info += QL1S("; ") + machine;
930  }
931 
932  info += QL1S("; ") + extraInfo.join(QLatin1String("; "));
933 
934  return (appName + QL1C('/') + appVersion + QStringLiteral(" (") + info + QL1C(')'));
935 }
936 
938  QString &systemName, QString &systemVersion, QString &machine)
939 {
940 #if defined(Q_OS_WIN) && !defined(_WIN32_WCE)
941  // we do not use unameBuf.sysname information constructed in kdewin32
942  // because we want to get separate name and version
943  systemName = QStringLiteral("Windows");
944  OSVERSIONINFOEX versioninfo;
945  ZeroMemory(&versioninfo, sizeof(OSVERSIONINFOEX));
946  // try calling GetVersionEx using the OSVERSIONINFOEX, if that fails, try using the OSVERSIONINFO
947  versioninfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
948  bool ok = GetVersionEx((OSVERSIONINFO *) &versioninfo);
949  if (!ok) {
950  versioninfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
951  ok = GetVersionEx((OSVERSIONINFO *) &versioninfo);
952  }
953  if (ok) {
954  systemVersion = QString::number(versioninfo.dwMajorVersion);
955  systemVersion += QL1C('.');
956  systemVersion += QString::number(versioninfo.dwMinorVersion);
957  }
958 #else
959  struct utsname unameBuf;
960  if (0 != uname(&unameBuf)) {
961  return false;
962  }
963  systemName = QString::fromUtf8(unameBuf.sysname);
964  systemVersion = QString::fromUtf8(unameBuf.release);
965  machine = QString::fromUtf8(unameBuf.machine);
966 #endif
967  return true;
968 }
969 
971 {
972  const QLatin1String english("en");
973 
974  // User's desktop language preference.
975  QStringList languageList = QLocale().uiLanguages();
976 
977  // Replace possible "C" in the language list with "en", unless "en" is
978  // already pressent. This is to keep user's priorities in order.
979  // If afterwards "en" is still not present, append it.
980  int idx = languageList.indexOf(QLatin1String("C"));
981  if (idx != -1) {
982  if (languageList.contains(english)) {
983  languageList.removeAt(idx);
984  } else {
985  languageList[idx] = english;
986  }
987  }
988  if (!languageList.contains(english)) {
989  languageList += english;
990  }
991 
992  // Some languages may have web codes different from locale codes,
993  // read them from the config and insert in proper order.
994  KConfig acclangConf(QStringLiteral("accept-languages.codes"), KConfig::NoGlobals);
995  KConfigGroup replacementCodes(&acclangConf, "ReplacementCodes");
996  QStringList languageListFinal;
997  for (const QString &lang : qAsConst(languageList)) {
998  const QStringList langs = replacementCodes.readEntry(lang, QStringList());
999  if (langs.isEmpty()) {
1000  languageListFinal += lang;
1001  } else {
1002  languageListFinal += langs;
1003  }
1004  }
1005 
1006  // The header is composed of comma separated languages, with an optional
1007  // associated priority estimate (q=1..0) defaulting to 1.
1008  // As our language tags are already sorted by priority, we'll just decrease
1009  // the value evenly
1010  int prio = 10;
1011  QString header;
1012  for (const QString &lang : qAsConst(languageListFinal)) {
1013  header += lang;
1014  if (prio < 10) {
1015  header += QL1S(";q=0.") + QString::number(prio);
1016  }
1017  // do not add cosmetic whitespace in here : it is less compatible (#220677)
1018  header += QL1C(',');
1019  if (prio > 1) {
1020  --prio;
1021  }
1022  }
1023  header.chop(1);
1024 
1025  // Some of the languages may have country specifier delimited by
1026  // underscore, or modifier delimited by at-sign.
1027  // The header should use dashes instead.
1028  header.replace(QL1C('_'), QL1C('-'));
1029  header.replace(QL1C('@'), QL1C('-'));
1030 
1031  return header;
1032 }
1033 
1034 /*==================================== OTHERS ===============================*/
1035 
1037 {
1038  PRIVATE_DATA;
1039  QMutexLocker lock(&d->mutex);
1040  return config()->group(QByteArray()).readEntry("MarkPartial", true);
1041 }
1042 
1044 {
1045  PRIVATE_DATA;
1046  QMutexLocker lock(&d->mutex);
1047  return config()->group(QByteArray()).readEntry("MinimumKeepSize",
1048  DEFAULT_MINIMUM_KEEP_SIZE); // 5000 byte
1049 }
1050 
1052 {
1053  PRIVATE_DATA;
1054  QMutexLocker lock(&d->mutex);
1055  return config()->group(QByteArray()).readEntry("AutoResume", false);
1056 }
1057 
1059 {
1060  PRIVATE_DATA;
1061  QMutexLocker lock(&d->mutex);
1062  return config()->group(QByteArray()).readEntry("PersistentConnections", true);
1063 }
1064 
1066 {
1067  PRIVATE_DATA;
1068  QMutexLocker lock(&d->mutex);
1069  return config()->group(QByteArray()).readEntry("PersistentProxyConnection", false);
1070 }
1071 
1073 {
1074  PRIVATE_DATA;
1075  QMutexLocker lock(&d->mutex);
1076  return config()->group("Proxy Settings").readEntry("Proxy Config Script");
1077 }
1078 
1079 /* =========================== PROTOCOL CAPABILITIES ============== */
1080 
1081 static KProtocolInfoPrivate *findProtocol(const QUrl &url)
1082 {
1083  if (!url.isValid()) {
1084  return nullptr;
1085  }
1086  QString protocol = url.scheme();
1087  if (!KProtocolInfo::proxiedBy(protocol).isEmpty()) {
1088  QString dummy;
1089  protocol = KProtocolManager::slaveProtocol(url, dummy);
1090  }
1091 
1092  return KProtocolInfoFactory::self()->findProtocol(protocol);
1093 }
1094 
1096 {
1097  KProtocolInfoPrivate *prot = findProtocol(url);
1098  if (!prot) {
1099  return KProtocolInfo::T_NONE;
1100  }
1101 
1102  return prot->m_inputType;
1103 }
1104 
1106 {
1107  KProtocolInfoPrivate *prot = findProtocol(url);
1108  if (!prot) {
1109  return KProtocolInfo::T_NONE;
1110  }
1111 
1112  return prot->m_outputType;
1113 }
1114 
1116 {
1117  KProtocolInfoPrivate *prot = findProtocol(url);
1118  if (!prot) {
1119  return false;
1120  }
1121 
1122  return prot->m_isSourceProtocol;
1123 }
1124 
1126 {
1127  KProtocolInfoPrivate *prot = findProtocol(url);
1128  if (!prot) {
1129  return false;
1130  }
1131 
1132  return prot->m_supportsListing;
1133 }
1134 
1136 {
1137  KProtocolInfoPrivate *prot = findProtocol(url);
1138  if (!prot) {
1139  return QStringList();
1140  }
1141 
1142  return prot->m_listing;
1143 }
1144 
1146 {
1147  KProtocolInfoPrivate *prot = findProtocol(url);
1148  if (!prot) {
1149  return false;
1150  }
1151 
1152  return prot->m_supportsReading;
1153 }
1154 
1156 {
1157  KProtocolInfoPrivate *prot = findProtocol(url);
1158  if (!prot) {
1159  return false;
1160  }
1161 
1162  return prot->m_supportsWriting;
1163 }
1164 
1166 {
1167  KProtocolInfoPrivate *prot = findProtocol(url);
1168  if (!prot) {
1169  return false;
1170  }
1171 
1172  return prot->m_supportsMakeDir;
1173 }
1174 
1176 {
1177  KProtocolInfoPrivate *prot = findProtocol(url);
1178  if (!prot) {
1179  return false;
1180  }
1181 
1182  return prot->m_supportsDeleting;
1183 }
1184 
1186 {
1187  KProtocolInfoPrivate *prot = findProtocol(url);
1188  if (!prot) {
1189  return false;
1190  }
1191 
1192  return prot->m_supportsLinking;
1193 }
1194 
1196 {
1197  KProtocolInfoPrivate *prot = findProtocol(url);
1198  if (!prot) {
1199  return false;
1200  }
1201 
1202  return prot->m_supportsMoving;
1203 }
1204 
1206 {
1207  KProtocolInfoPrivate *prot = findProtocol(url);
1208  if (!prot) {
1209  return false;
1210  }
1211 
1212  return prot->m_supportsOpening;
1213 }
1214 
1216 {
1217  KProtocolInfoPrivate *prot = findProtocol(url);
1218  if (!prot) {
1219  return false;
1220  }
1221 
1222  return prot->m_supportsTruncating;
1223 }
1224 
1226 {
1227  KProtocolInfoPrivate *prot = findProtocol(url);
1228  if (!prot) {
1229  return false;
1230  }
1231 
1232  return prot->m_canCopyFromFile;
1233 }
1234 
1236 {
1237  KProtocolInfoPrivate *prot = findProtocol(url);
1238  if (!prot) {
1239  return false;
1240  }
1241 
1242  return prot->m_canCopyToFile;
1243 }
1244 
1246 {
1247  KProtocolInfoPrivate *prot = findProtocol(url);
1248  if (!prot) {
1249  return false;
1250  }
1251 
1252  return prot->m_canRenameFromFile;
1253 }
1254 
1256 {
1257  KProtocolInfoPrivate *prot = findProtocol(url);
1258  if (!prot) {
1259  return false;
1260  }
1261 
1262  return prot->m_canRenameToFile;
1263 }
1264 
1266 {
1267  KProtocolInfoPrivate *prot = findProtocol(url);
1268  if (!prot) {
1269  return false;
1270  }
1271 
1272  return prot->m_canDeleteRecursive;
1273 }
1274 
1275 KProtocolInfo::FileNameUsedForCopying KProtocolManager::fileNameUsedForCopying(const QUrl &url)
1276 {
1277  KProtocolInfoPrivate *prot = findProtocol(url);
1278  if (!prot) {
1279  return KProtocolInfo::FromUrl;
1280  }
1281 
1282  return prot->m_fileNameUsedForCopying;
1283 }
1284 
1286 {
1287  KProtocolInfoPrivate *prot = findProtocol(url);
1288  if (!prot) {
1289  return QString();
1290  }
1291 
1292  return prot->m_defaultMimetype;
1293 }
1294 
1296 {
1297  PRIVATE_DATA;
1298  QMutexLocker lock(&d->mutex);
1299  if (d->protocolForArchiveMimetypes.isEmpty()) {
1300  const QList<KProtocolInfoPrivate *> allProtocols = KProtocolInfoFactory::self()->allProtocols();
1301  for (KProtocolInfoPrivate *allProtocol : allProtocols) {
1302  const QStringList archiveMimetypes = allProtocol->m_archiveMimeTypes;
1303  for (const QString &mime : archiveMimetypes) {
1304  d->protocolForArchiveMimetypes.insert(mime, allProtocol->m_name);
1305  }
1306  }
1307  }
1308  return d->protocolForArchiveMimetypes.value(mimeType);
1309 }
1310 
1312 {
1313  return KIO::SlaveConfig::self()->configData(url.scheme(), url.host(), QStringLiteral("Charset"));
1314 }
1315 
1316 #undef PRIVATE_DATA
1317 
1318 
1319 #include "kprotocolmanager.moc"
QString url(QUrl::FormattingOptions options) const const
no information about the type available
Definition: kprotocolinfo.h:83
static bool persistentProxyConnection()
Returns true if proxy connections should be persistent.
static QStringList listing(const QUrl &url)
Returns the list of fields this protocol returns when listing The current possibilities are Name...
void clear()
static QString proxyFor(const QString &protocol)
Returns the proxy server address for a given protocol.
QString readPathEntry(const QString &pKey, const QString &aDefault) const
int toInt(bool *ok, int base) const const
ProxyAuthMode
Proxy authorization modes.
MetaData configData(const QString &protocol, const QString &host)
Query slave configuration for slaves of type protocol when dealing with host.
static KProtocolInfo::FileNameUsedForCopying fileNameUsedForCopying(const QUrl &url)
This setting defines the strategy to use for generating a filename, when copying a file or directory ...
int indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const const
bool sync() override
ProxyType
Types of proxy configuration.
static bool supportsReading(const QUrl &url)
Returns whether the protocol can retrieve data from URLs.
QString writableLocation(QStandardPaths::StandardLocation type)
static void reparseConfiguration()
Force a reload of the general config file of io-slaves ( kioslaverc).
static KProtocolInfo::Type inputType(const QUrl &url)
Returns whether the protocol should be treated as a filesystem or as a stream when reading from it...
static void badProxy(const QString &proxy)
Marks this proxy as bad (down).
void setPort(int port)
static QString noProxyFor()
Returns the strings for hosts that should contacted DIRECTLY, bypassing any proxy settings...
static QStringList proxiesForUrl(const QUrl &url)
Returns all the possible proxy server addresses for url.
bool showInCurrentDesktop() const
static QString userAgentForHost(const QString &hostname)
Returns the user-agent string configured for the specified host.
void reserve(int alloc)
QPair< QHostAddress, int > parseSubnet(const QString &subnet)
static int maxCacheSize()
Returns the maximum size that can be used for caching.
QVariant property(const QString &_name, QVariant::Type t) const
QString host(QUrl::ComponentFormattingOptions options) const const
static bool supportsOpening(const QUrl &url)
Returns whether the protocol can be opened using KIO::open(const QUrl&).
void removeAt(int i)
bool contains(const QString &str, Qt::CaseSensitivity cs) const const
QString simplified() const const
QString languageToString(QLocale::Language language)
KIOCORE_EXPORT void lookupHost(const QString &hostName, QObject *receiver, const char *member)
Definition: hostinfo.cpp:233
static bool isSourceProtocol(const QUrl &url)
Returns whether the protocol can act as a source protocol.
QString join(const QString &separator) const const
QString & remove(int position, int n)
int port(int defaultPort) const const
void chop(int n)
bool isEmpty() const const
QString toString(QUrl::FormattingOptions options) const const
static bool canCopyToFile(const QUrl &url)
Returns whether the protocol can copy files/objects directly to the filesystem itself.
void reset()
Undo any changes made by calls to setConfigData.
static QString slaveProtocol(const QUrl &url, QString &proxy)
Return the protocol to use in order to handle the given url It&#39;s usually the same, except that FTP, when handled by a proxy, needs an HTTP ioslave.
static QString userAgentForApplication(const QString &appName, const QString &appVersion, const QStringList &extraInfo=QStringList())
Returns the application&#39;s user-agent string.
static bool useProxy()
Returns whether or not the user specified the use of proxy server to make connections.
bool supportsSsl()
int size() const const
int lastIndexOf(QChar ch, int from, Qt::CaseSensitivity cs) const const
void clear()
static bool useCache()
Returns true/false to indicate whether a cache should be used.
QString number(int n, int base)
int count(const T &value) const const
QString fromLocal8Bit(const char *str, int size)
QString applicationVersion()
QString fromUtf8(const char *str, int size)
PostalAddress address(const QVariant &location)
static int responseTimeout()
Returns the preferred response timeout value for remote connecting in seconds.
static int readTimeout()
Returns the preferred timeout value for reading from remote connections in seconds.
static bool supportsDeleting(const QUrl &url)
Returns whether the protocol can delete files/objects.
Q_OBJECTQ_OBJECT
static bool useReverseProxy()
Returns whether or not the proxy server lookup should be reversed or not.
Type type(const QSqlDatabase &db)
QStringRef leftRef(int n) const const
static QString defaultMimetype(const QUrl &url)
Returns default mimetype for this URL based on the protocol.
static QString protocolForArchiveMimetype(const QString &mimeType)
Returns which protocol handles this mimetype, if it&#39;s an archive mimetype.
CaseInsensitive
bool isEmpty() const const
static bool supportsListing(const QUrl &url)
Returns whether the protocol can list files/objects.
bool isEmpty() const const
QString trimmed() const const
static bool canDeleteRecursive(const QUrl &url)
Returns whether the protocol can recursively delete directories by itself.
const char * constData() const const
KService::Ptr preferredService(const QString &mimeType, const QString &genericServiceType=QStringLiteral("Application"))
static bool canRenameToFile(const QUrl &url)
Returns whether the protocol can rename (i.e.
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const const
void setScheme(const QString &scheme)
CacheControl
Specifies how to use the cache.
Definition: global.h:286
static KProtocolInfo::Type outputType(const QUrl &url)
Returns whether the protocol should be treated as a filesystem or as a stream when writing to it...
static KMimeTypeTrader * self()
QStringRef rightRef(int n) const const
static QString proxiedBy(const QString &protocol)
Returns the name of the protocol through which the request will be routed if proxy support is enabled...
T & first()
static QString protocolClass(const QString &protocol)
Returns the protocol class for the specified protocol.
static QString charsetFor(const QUrl &url)
Returns the charset to use for the specified url.
static bool supportsLinking(const QUrl &url)
Returns whether the protocol can create links between files/objects.
static int connectTimeout()
Returns the preferred timeout value for remote connections in seconds.
int indexOf(QStringView str, int from) const const
QString scheme() const const
static QString defaultUserAgent()
Returns the default user-agent string used for web browsing.
KIOCORE_EXPORT KIO::CacheControl parseCacheControl(const QString &cacheControl)
Parses the string representation of the cache control option.
Definition: global.cpp:160
QString toLower() const const
QByteArray toLocal8Bit() const const
bool contains(QChar ch, Qt::CaseSensitivity cs) const const
void setUserName(const QString &userName, QUrl::ParsingMode mode)
static bool supportsTruncating(const QUrl &url)
Returns whether the protocol can be truncated with FileJob::truncate(KIO::filesize_t length)...
QStringRef midRef(int position, int n) const const
static KSharedConfig::Ptr openConfig(const QString &fileName=QString(), OpenFlags mode=FullConfig, QStandardPaths::StandardLocation type=QStandardPaths::GenericConfigLocation)
QString & replace(int position, int n, QChar after)
static QString proxyConfigScript()
Returns the URL of the script for automatic proxy configuration.
bool isValid() const const
static QString proxyForUrl(const QUrl &url)
Returns the Proxy server address for a given URL.
QDBusMessage call(const QString &method, Args &&...args)
QByteArray toLatin1() const const
static QString cacheDir()
The directory which contains the cache files.
QList< QHostAddress > addresses() const const
static ProxyType proxyType()
Returns the type of proxy configuration that is used.
void insert(int i, const T &value)
static int minimumKeepSize()
Returns the minimum file size for keeping aborted downloads.
static bool autoResume()
Returns true if partial downloads should be automatically resumed.
QList< QNetworkProxy > systemProxyForQuery(const QNetworkProxyQuery &query)
static bool getSystemNameVersionAndMachine(QString &systemName, QString &systemVersion, QString &machine)
Returns system name, version and machine type, for example "Windows", "5.1", "i686".
static ProxyAuthMode proxyAuthMode()
Returns the way proxy authorization should be handled.
int length() const const
static int proxyConnectTimeout()
Returns the preferred timeout value for proxy connections in seconds.
static bool canRenameFromFile(const QUrl &url)
Returns whether the protocol can rename (i.e.
static bool supportsWriting(const QUrl &url)
Returns whether the protocol can store data to URLs.
static bool persistentConnections()
Returns true if connections should be persistent.
void setHost(const QString &host, QUrl::ParsingMode mode)
static bool markPartial()
Returns true if partial downloads should be marked with a ".part" extension.
static QString acceptLanguagesHeader()
Return Accept-Languages header built up according to user&#39;s desktop language settings.
static int maxCacheAge()
Returns the maximum age in seconds cached files should be kept before they are deleted as necessary...
static bool supportsMakeDir(const QUrl &url)
Returns whether the protocol can create directories/folders.
static KIO::CacheControl cacheControl()
Returns the Cache control directive to be used.
static bool supportsMoving(const QUrl &url)
Returns whether the protocol can move files/objects between different locations.
QStringList uiLanguages() const const
static bool isKnownProtocol(const QUrl &url)
Returns whether a protocol is installed that is able to handle url.
int compare(const QString &other, Qt::CaseSensitivity cs) const const
QString toString() const const
T readEntry(const QString &key, const T &aDefault) const
QDBusPendingCall asyncCall(const QString &method, Args &&...args)
QString applicationName()
Type
Describes the type of a protocol.
Definition: kprotocolinfo.h:81
static bool canCopyFromFile(const QUrl &url)
Returns whether the protocol can copy files/objects directly from the filesystem itself.
QCA_EXPORT QString appName()
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Thu Nov 26 2020 22:59:25 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.