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 <qplatformdefs.h>
19 #include <string.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 <QCache>
28 #include <QCoreApplication>
29 #include <QDBusInterface>
30 #include <QDBusReply>
31 #include <QHostAddress>
32 #include <QHostInfo>
33 #include <QLocale>
34 #include <QMimeDatabase>
35 #include <QRegularExpression>
36 #include <QSslSocket>
37 #include <QStandardPaths>
38 #include <QUrl>
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 <KConfigGroup>
46 #include <KSharedConfig>
47 #include <kio_version.h>
48 
49 #include <KMimeTypeTrader>
50 #include <kprotocolinfofactory_p.h>
51 
52 #include "http_slave_defaults.h"
53 #include "ioslave_defaults.h"
54 #include "slaveconfig.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 
84  // Strip out multiple spaces and commas
85  while (--nptr >= nplist && (*nptr == ',' || *nptr == ' '))
86  ;
87  } else {
88  if (nptr == nplist || nptr[-1] == ',' || nptr[-1] == ' ') {
89  return true;
90  }
91  if (nptr[-1] == '/' && hptr == host) { // "bugs.kde.org" vs "http://bugs.kde.org", the config UI says URLs are ok
92  return true;
93  }
94  if (hptr == host) { // e.g. revmatch("bugs.kde.org","mybugs.kde.org")
95  return false;
96  }
97 
98  hptr--;
99  nptr--;
100  }
101  }
102 
103  return false;
104 }
105 
106 class KProxyData : public QObject
107 {
108  Q_OBJECT
109 public:
110  KProxyData(const QString &slaveProtocol, const QStringList &proxyAddresses)
111  : protocol(slaveProtocol)
112  , proxyList(proxyAddresses)
113  {
114  }
115 
116  void removeAddress(const QString &address)
117  {
118  proxyList.removeAll(address);
119  }
120 
121  QString protocol;
122  QStringList proxyList;
123 };
124 
125 class KProtocolManagerPrivate
126 {
127 public:
128  KProtocolManagerPrivate();
129  ~KProtocolManagerPrivate();
130  bool shouldIgnoreProxyFor(const QUrl &url);
131  void sync();
132  KProtocolManager::ProxyType proxyType();
133  bool useReverseProxy();
134  QString readNoProxyFor();
135  QString proxyFor(const QString &protocol);
136  QStringList getSystemProxyFor(const QUrl &url);
137 
138  QMutex mutex; // protects all member vars
139  KSharedConfig::Ptr configPtr;
140  KSharedConfig::Ptr http_config;
141  QString modifiers;
142  QString useragent;
143  QString noProxyFor;
144  QList<SubnetPair> noProxySubnets;
145  QCache<QString, KProxyData> cachedProxyData;
146 
147  QMap<QString /*mimetype*/, QString /*protocol*/> protocolForArchiveMimetypes;
148 };
149 
150 Q_GLOBAL_STATIC(KProtocolManagerPrivate, kProtocolManagerPrivate)
151 
152 static void syncOnExit()
153 {
154  if (kProtocolManagerPrivate.exists())
155  kProtocolManagerPrivate()->sync();
156 }
157 
158 KProtocolManagerPrivate::KProtocolManagerPrivate()
159 {
160  // post routine since KConfig::sync() breaks if called too late
161  qAddPostRoutine(syncOnExit);
162  cachedProxyData.setMaxCost(200); // double the max cost.
163 }
164 
165 KProtocolManagerPrivate::~KProtocolManagerPrivate()
166 {
167 }
168 
169 /*
170  * Returns true if url is in the no proxy list.
171  */
172 bool KProtocolManagerPrivate::shouldIgnoreProxyFor(const QUrl &url)
173 {
174  bool isMatch = false;
175  const KProtocolManager::ProxyType type = proxyType();
176  const bool useRevProxy = ((type == KProtocolManager::ManualProxy) && useReverseProxy());
177  const bool useNoProxyList = (type == KProtocolManager::ManualProxy || type == KProtocolManager::EnvVarProxy);
178 
179  // No proxy only applies to ManualProxy and EnvVarProxy types...
180  if (useNoProxyList && noProxyFor.isEmpty()) {
181  QStringList noProxyForList(readNoProxyFor().split(QL1C(',')));
182  QMutableStringListIterator it(noProxyForList);
183  while (it.hasNext()) {
184  SubnetPair subnet = QHostAddress::parseSubnet(it.next());
185  if (!subnet.first.isNull()) {
186  noProxySubnets << subnet;
187  it.remove();
188  }
189  }
190  noProxyFor = noProxyForList.join(QLatin1Char(','));
191  }
192 
193  if (!noProxyFor.isEmpty()) {
194  QString qhost = url.host().toLower();
195  QByteArray host = qhost.toLatin1();
196  const QString qno_proxy = noProxyFor.trimmed().toLower();
197  const QByteArray no_proxy = qno_proxy.toLatin1();
198  isMatch = revmatch(host.constData(), no_proxy.constData());
199 
200  // If no match is found and the request url has a port
201  // number, try the combination of "host:port". This allows
202  // users to enter host:port in the No-proxy-For list.
203  if (!isMatch && url.port() > 0) {
204  qhost += QL1C(':') + QString::number(url.port());
205  host = qhost.toLatin1();
206  isMatch = revmatch(host.constData(), no_proxy.constData());
207  }
208 
209  // If the hostname does not contain a dot, check if
210  // <local> is part of noProxy.
211  if (!isMatch && !host.isEmpty() && (strchr(host.constData(), '.') == nullptr)) {
212  isMatch = revmatch("<local>", no_proxy.constData());
213  }
214  }
215 
216  const QString host(url.host());
217 
218  if (!noProxySubnets.isEmpty() && !host.isEmpty()) {
219  QHostAddress address(host);
220  // If request url is not IP address, do a DNS lookup of the hostname.
221  // TODO: Perhaps we should make configurable ?
222  if (address.isNull()) {
223  // qDebug() << "Performing DNS lookup for" << host;
224  QHostInfo info = KIO::HostInfo::lookupHost(host, 2000);
225  const QList<QHostAddress> addresses = info.addresses();
226  if (!addresses.isEmpty()) {
227  address = addresses.first();
228  }
229  }
230 
231  if (!address.isNull()) {
232  for (const SubnetPair &subnet : qAsConst(noProxySubnets)) {
233  if (address.isInSubnet(subnet)) {
234  isMatch = true;
235  break;
236  }
237  }
238  }
239  }
240 
241  return (useRevProxy != isMatch);
242 }
243 
244 void KProtocolManagerPrivate::sync()
245 {
246  QMutexLocker lock(&mutex);
247  if (http_config) {
248  http_config->sync();
249  }
250  if (configPtr) {
251  configPtr->sync();
252  }
253 }
254 
255 #define PRIVATE_DATA KProtocolManagerPrivate *d = kProtocolManagerPrivate()
256 
258 {
259  PRIVATE_DATA;
260  QMutexLocker lock(&d->mutex);
261  if (d->http_config) {
262  d->http_config->reparseConfiguration();
263  }
264  if (d->configPtr) {
265  d->configPtr->reparseConfiguration();
266  }
267  d->cachedProxyData.clear();
268  d->noProxyFor.clear();
269  d->modifiers.clear();
270  d->useragent.clear();
271  lock.unlock();
272 
273  // Force the slave config to re-read its config...
274  KIO::SlaveConfig::self()->reset();
275 }
276 
277 static KSharedConfig::Ptr config()
278 {
279  PRIVATE_DATA;
280  Q_ASSERT(!d->mutex.tryLock()); // the caller must have locked the mutex
281  if (!d->configPtr) {
282  d->configPtr = KSharedConfig::openConfig(QStringLiteral("kioslaverc"), KConfig::NoGlobals);
283  }
284  return d->configPtr;
285 }
286 
287 KProtocolManager::ProxyType KProtocolManagerPrivate::proxyType()
288 {
289  KConfigGroup cg(config(), "Proxy Settings");
290  return static_cast<KProtocolManager::ProxyType>(cg.readEntry("ProxyType", 0));
291 }
292 
293 bool KProtocolManagerPrivate::useReverseProxy()
294 {
295  KConfigGroup cg(config(), "Proxy Settings");
296  return cg.readEntry("ReversedException", false);
297 }
298 
299 QString KProtocolManagerPrivate::readNoProxyFor()
300 {
301  QString noProxy = config()->group("Proxy Settings").readEntry("NoProxyFor");
302  if (proxyType() == KProtocolManager::EnvVarProxy) {
303  noProxy = QString::fromLocal8Bit(qgetenv(noProxy.toLocal8Bit().constData()));
304  }
305  return noProxy;
306 }
307 
308 QMap<QString, QString> KProtocolManager::entryMap(const QString &group)
309 {
310  PRIVATE_DATA;
311  QMutexLocker lock(&d->mutex);
312  return config()->entryMap(group);
313 }
314 
315 static KConfigGroup http_config()
316 {
317  PRIVATE_DATA;
318  Q_ASSERT(!d->mutex.tryLock()); // the caller must have locked the mutex
319  if (!d->http_config) {
320  d->http_config = KSharedConfig::openConfig(QStringLiteral("kio_httprc"), KConfig::NoGlobals);
321  }
322  return KConfigGroup(d->http_config, QString());
323 }
324 
325 /*=============================== TIMEOUT SETTINGS ==========================*/
326 
328 {
329  PRIVATE_DATA;
330  QMutexLocker lock(&d->mutex);
331  KConfigGroup cg(config(), QString());
332  int val = cg.readEntry("ReadTimeout", DEFAULT_READ_TIMEOUT);
333  return qMax(MIN_TIMEOUT_VALUE, val);
334 }
335 
337 {
338  PRIVATE_DATA;
339  QMutexLocker lock(&d->mutex);
340  KConfigGroup cg(config(), QString());
341  int val = cg.readEntry("ConnectTimeout", DEFAULT_CONNECT_TIMEOUT);
342  return qMax(MIN_TIMEOUT_VALUE, val);
343 }
344 
346 {
347  PRIVATE_DATA;
348  QMutexLocker lock(&d->mutex);
349  KConfigGroup cg(config(), QString());
350  int val = cg.readEntry("ProxyConnectTimeout", DEFAULT_PROXY_CONNECT_TIMEOUT);
351  return qMax(MIN_TIMEOUT_VALUE, val);
352 }
353 
355 {
356  PRIVATE_DATA;
357  QMutexLocker lock(&d->mutex);
358  KConfigGroup cg(config(), QString());
359  int val = cg.readEntry("ResponseTimeout", DEFAULT_RESPONSE_TIMEOUT);
360  return qMax(MIN_TIMEOUT_VALUE, val);
361 }
362 
363 /*========================== PROXY SETTINGS =================================*/
364 
366 {
367  return proxyType() != NoProxy;
368 }
369 
371 {
372  PRIVATE_DATA;
373  QMutexLocker lock(&d->mutex);
374  return d->useReverseProxy();
375 }
376 
378 {
379  PRIVATE_DATA;
380  QMutexLocker lock(&d->mutex);
381  return d->proxyType();
382 }
383 
385 {
386  PRIVATE_DATA;
387  QMutexLocker lock(&d->mutex);
388  KConfigGroup cg(config(), "Proxy Settings");
389  return static_cast<ProxyAuthMode>(cg.readEntry("AuthMode", 0));
390 }
391 
392 /*========================== CACHING =====================================*/
393 
395 {
396  PRIVATE_DATA;
397  QMutexLocker lock(&d->mutex);
398  return http_config().readEntry("UseCache", true);
399 }
400 
402 {
403  PRIVATE_DATA;
404  QMutexLocker lock(&d->mutex);
405  QString tmp = http_config().readEntry("cache");
406  if (tmp.isEmpty()) {
407  return DEFAULT_CACHE_CONTROL;
408  }
409  return KIO::parseCacheControl(tmp);
410 }
411 
413 {
414  PRIVATE_DATA;
415  QMutexLocker lock(&d->mutex);
417 }
418 
420 {
421  PRIVATE_DATA;
422  QMutexLocker lock(&d->mutex);
423  return http_config().readEntry("MaxCacheAge", DEFAULT_MAX_CACHE_AGE);
424 }
425 
427 {
428  PRIVATE_DATA;
429  QMutexLocker lock(&d->mutex);
430  return http_config().readEntry("MaxCacheSize", DEFAULT_MAX_CACHE_SIZE);
431 }
432 
434 {
435  PRIVATE_DATA;
436  QMutexLocker lock(&d->mutex);
437  return d->readNoProxyFor();
438 }
439 
440 static QString adjustProtocol(const QString &scheme)
441 {
442  if (scheme.compare(QL1S("webdav"), Qt::CaseInsensitive) == 0) {
443  return QStringLiteral("http");
444  }
445 
446  if (scheme.compare(QL1S("webdavs"), Qt::CaseInsensitive) == 0) {
447  return QStringLiteral("https");
448  }
449 
450  return scheme.toLower();
451 }
452 
454 {
455  PRIVATE_DATA;
456  QMutexLocker lock(&d->mutex);
457  return d->proxyFor(protocol);
458 }
459 
460 QString KProtocolManagerPrivate::proxyFor(const QString &protocol)
461 {
462  const QString key = adjustProtocol(protocol) + QL1S("Proxy");
463  QString proxyStr(config()->group("Proxy Settings").readEntry(key));
464  const int index = proxyStr.lastIndexOf(QL1C(' '));
465 
466  if (index > -1) {
467  bool ok = false;
468  const QStringRef portStr(proxyStr.rightRef(proxyStr.length() - index - 1));
469  portStr.toInt(&ok);
470  if (ok) {
471  proxyStr = proxyStr.leftRef(index) + QL1C(':') + portStr;
472  } else {
473  proxyStr.clear();
474  }
475  }
476 
477  return proxyStr;
478 }
479 
481 {
482  const QStringList proxies = proxiesForUrl(url);
483 
484  if (proxies.isEmpty()) {
485  return QString();
486  }
487 
488  return proxies.first();
489 }
490 
491 QStringList KProtocolManagerPrivate::getSystemProxyFor(const QUrl &url)
492 {
493  QStringList proxies;
494 
495 #if !defined(QT_NO_NETWORKPROXY) && (defined(Q_OS_WIN32) || defined(Q_OS_MAC))
496  QNetworkProxyQuery query(url);
498  proxies.reserve(proxyList.size());
499  for (const QNetworkProxy &proxy : proxyList) {
500  QUrl url;
501  const QNetworkProxy::ProxyType type = proxy.type();
502  if (type == QNetworkProxy::NoProxy || type == QNetworkProxy::DefaultProxy) {
503  proxies << QL1S("DIRECT");
504  continue;
505  }
506 
508  url.setScheme(QL1S("http"));
509  } else if (type == QNetworkProxy::Socks5Proxy) {
510  url.setScheme(QL1S("socks"));
511  } else if (type == QNetworkProxy::FtpCachingProxy) {
512  url.setScheme(QL1S("ftp"));
513  }
514 
515  url.setHost(proxy.hostName());
516  url.setPort(proxy.port());
517  url.setUserName(proxy.user());
518  proxies << url.url();
519  }
520 #else
521  // On Unix/Linux use system environment variables if any are set.
522  QString proxyVar(proxyFor(url.scheme()));
523  // Check for SOCKS proxy, if not proxy is found for given url.
524  if (!proxyVar.isEmpty()) {
525  const QString proxy(QString::fromLocal8Bit(qgetenv(proxyVar.toLocal8Bit().constData())).trimmed());
526  if (!proxy.isEmpty()) {
527  proxies << proxy;
528  }
529  }
530  // Add the socks proxy as an alternate proxy if it exists,
531  proxyVar = proxyFor(QStringLiteral("socks"));
532  if (!proxyVar.isEmpty()) {
533  QString proxy = QString::fromLocal8Bit(qgetenv(proxyVar.toLocal8Bit().constData())).trimmed();
534  // Make sure the scheme of SOCKS proxy is always set to "socks://".
535  const int index = proxy.indexOf(QL1S("://"));
536  const int offset = (index == -1) ? 0 : (index + 3);
537  proxy = QL1S("socks://") + proxy.midRef(offset);
538  if (!proxy.isEmpty()) {
539  proxies << proxy;
540  }
541  }
542 #endif
543  return proxies;
544 }
545 
547 {
548  QStringList proxyList;
549 
550  PRIVATE_DATA;
551  QMutexLocker lock(&d->mutex);
552  if (!d->shouldIgnoreProxyFor(url)) {
553  switch (d->proxyType()) {
554  case PACProxy:
555  case WPADProxy: {
556  QUrl u(url);
557  const QString protocol = adjustProtocol(u.scheme());
558  u.setScheme(protocol);
559 
560  if (protocol.startsWith(QLatin1String("http")) || protocol.startsWith(QLatin1String("ftp"))) {
562  QDBusInterface(QStringLiteral("org.kde.kded5"), QStringLiteral("/modules/proxyscout"), 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  break;
586  }
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")).asyncCall(QStringLiteral("blackListProxy"), proxy);
602 
603  PRIVATE_DATA;
604  QMutexLocker lock(&d->mutex);
605  const QStringList keys(d->cachedProxyData.keys());
606  for (const QString &key : keys) {
607  d->cachedProxyData[key]->removeAddress(proxy);
608  }
609 }
610 
612 {
613  QStringList proxyList;
614  const QString protocol = KProtocolManager::slaveProtocol(url, proxyList);
615  if (!proxyList.isEmpty()) {
616  proxy = proxyList.first();
617  }
618  return protocol;
619 }
620 
621 // Generates proxy cache key from request given url.
622 static void extractProxyCacheKeyFromUrl(const QUrl &u, QString *key)
623 {
624  if (!key) {
625  return;
626  }
627 
628  *key = u.scheme();
629  *key += u.host();
630 
631  if (u.port() > 0) {
632  *key += QString::number(u.port());
633  }
634 }
635 
637 {
638  proxyList.clear();
639 
640  // Do not perform a proxy lookup for any url classified as a ":local" url or
641  // one that does not have a host component or if proxy is disabled.
642  QString protocol(url.scheme());
643  if (url.host().isEmpty() || KProtocolInfo::protocolClass(protocol) == QL1S(":local") || KProtocolManager::proxyType() == KProtocolManager::NoProxy) {
644  return protocol;
645  }
646 
647  QString proxyCacheKey;
648  extractProxyCacheKeyFromUrl(url, &proxyCacheKey);
649 
650  PRIVATE_DATA;
651  QMutexLocker lock(&d->mutex);
652  // Look for cached proxy information to avoid more work.
653  if (d->cachedProxyData.contains(proxyCacheKey)) {
654  KProxyData *data = d->cachedProxyData.object(proxyCacheKey);
655  proxyList = data->proxyList;
656  return data->protocol;
657  }
658  lock.unlock();
659 
660  const QStringList proxies = proxiesForUrl(url);
661  const int count = proxies.count();
662 
663  if (count > 0 && !(count == 1 && proxies.first() == QL1S("DIRECT"))) {
664  for (const QString &proxy : proxies) {
665  if (proxy == QL1S("DIRECT")) {
666  proxyList << proxy;
667  } else {
668  QUrl u(proxy);
669  if (!u.isEmpty() && u.isValid() && !u.scheme().isEmpty()) {
670  proxyList << proxy;
671  }
672  }
673  }
674  }
675 
676  // The idea behind slave protocols is not applicable to http
677  // and webdav protocols as well as protocols unknown to KDE.
678  /* clang-format off */
679  if (!proxyList.isEmpty()
680  && !protocol.startsWith(QLatin1String("http"))
681  && !protocol.startsWith(QLatin1String("webdav"))
682  && KProtocolInfo::isKnownProtocol(protocol)) { /* clang-format on */
683  for (const QString &proxy : qAsConst(proxyList)) {
684  QUrl u(proxy);
686  protocol = u.scheme();
687  break;
688  }
689  }
690  }
691 
692  lock.relock();
693  // cache the proxy information...
694  d->cachedProxyData.insert(proxyCacheKey, new KProxyData(protocol, proxyList));
695  return protocol;
696 }
697 
698 /*================================= USER-AGENT SETTINGS =====================*/
699 
701 {
702  const QString sendUserAgent = KIO::SlaveConfig::self()->configData(QStringLiteral("http"), hostname.toLower(), QStringLiteral("SendUserAgent")).toLower();
703  if (sendUserAgent == QL1S("false")) {
704  return QString();
705  }
706 
707  const QString useragent = KIO::SlaveConfig::self()->configData(QStringLiteral("http"), hostname.toLower(), QStringLiteral("UserAgent"));
708 
709  // Return the default user-agent if none is specified
710  // for the requested host.
711  if (useragent.isEmpty()) {
712  return defaultUserAgent();
713  }
714 
715  return useragent;
716 }
717 
719 {
720  const QString modifiers = KIO::SlaveConfig::self()->configData(QStringLiteral("http"), QString(), QStringLiteral("UserAgentKeys"));
721  return defaultUserAgent(modifiers);
722 }
723 
724 static QString defaultUserAgentFromPreferredService()
725 {
726  QString agentStr;
727 
728  // Check if the default COMPONENT contains a custom default UA string...
729  KService::Ptr service = KMimeTypeTrader::self()->preferredService(QStringLiteral("text/html"), QStringLiteral("KParts/ReadOnlyPart"));
730  if (service && service->showInCurrentDesktop())
731  agentStr = service->property(QStringLiteral("X-KDE-Default-UserAgent"), QVariant::String).toString();
732  return agentStr;
733 }
734 
735 // This is not the OS, but the windowing system, e.g. X11 on Unix/Linux.
736 static QString platform()
737 {
738 #if defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN)
739  return QStringLiteral("X11");
740 #elif defined(Q_OS_MAC)
741  return QStringLiteral("Macintosh");
742 #elif defined(Q_OS_WIN)
743  return QStringLiteral("Windows");
744 #else
745  return QStringLiteral("Unknown");
746 #endif
747 }
748 
750 {
751  PRIVATE_DATA;
752  QMutexLocker lock(&d->mutex);
753  QString modifiers = _modifiers.toLower();
754  if (modifiers.isEmpty()) {
755  modifiers = QStringLiteral(DEFAULT_USER_AGENT_KEYS);
756  }
757 
758  if (d->modifiers == modifiers && !d->useragent.isEmpty()) {
759  return d->useragent;
760  }
761 
762  d->modifiers = modifiers;
763 
764  /*
765  The following code attempts to determine the default user agent string
766  from the 'X-KDE-Default-UserAgent' property of the desktop file
767  for the preferred service that was configured to handle the 'text/html'
768  MIME type. If the preferred service's desktop file does not specify this
769  property, the long standing default user agent string will be used.
770  The following keyword placeholders are automatically converted when the
771  user agent string is read from the property:
772 
773  %SECURITY% Expands to"N" when SSL is not supported, otherwise it is ignored.
774  %OSNAME% Expands to operating system name, e.g. Linux.
775  %OSVERSION% Expands to operating system version, e.g. 2.6.32
776  %SYSTYPE% Expands to machine or system type, e.g. i386
777  %PLATFORM% Expands to windowing system, e.g. X11 on Unix/Linux.
778  %LANGUAGE% Expands to default language in use, e.g. en-US.
779  %APPVERSION% Expands to QCoreApplication applicationName()/applicationVerison(),
780  e.g. Konqueror/4.5.0. If application name and/or application version
781  number are not set, then "KDE" and the runtime KDE version numbers
782  are used respectively.
783 
784  All of the keywords are handled case-insensitively.
785  */
786 
787  QString systemName, systemVersion, machine, supp;
788  const bool sysInfoFound = getSystemNameVersionAndMachine(systemName, systemVersion, machine);
789  QString agentStr = defaultUserAgentFromPreferredService();
790 
791  if (agentStr.isEmpty()) {
792  supp += platform();
793 
794  if (sysInfoFound) {
795  if (modifiers.contains(QL1C('o'))) {
796  supp += QL1S("; ") + systemName;
797  if (modifiers.contains(QL1C('v'))) {
798  supp += QL1C(' ') + systemVersion;
799  }
800 
801  if (modifiers.contains(QL1C('m'))) {
802  supp += QL1C(' ') + machine;
803  }
804  }
805 
806  if (modifiers.contains(QL1C('l'))) {
807  supp += QL1S("; ") + QLocale::languageToString(QLocale().language());
808  }
809  }
810 
811  // Full format: Mozilla/5.0 (Linux
812  d->useragent = QLatin1String("Mozilla/5.0 (%1) KHTML/").arg(supp) + QLatin1String(KIO_VERSION_STRING)
813  + QLatin1String(" (like Gecko) Konqueror/%1 KIO/%1.%2").arg(QString::number(KIO_VERSION_MAJOR), QString::number(KIO_VERSION_MINOR));
814  } else {
816  if (appName.isEmpty() || appName.startsWith(QLatin1String("kcmshell"), Qt::CaseInsensitive)) {
817  appName = QStringLiteral("KDE");
818  }
819 
821  if (appVersion.isEmpty()) {
822  appVersion += QLatin1String(KIO_VERSION_STRING);
823  }
824 
825  appName += QL1C('/') + appVersion;
826 
827  agentStr.replace(QL1S("%appversion%"), appName, Qt::CaseInsensitive);
828 
829  if (!QSslSocket::supportsSsl()) {
830  agentStr.replace(QLatin1String("%security%"), QL1S("N"), Qt::CaseInsensitive);
831  } else {
832  agentStr.remove(QStringLiteral("%security%"), Qt::CaseInsensitive);
833  }
834 
835  if (sysInfoFound) {
836  // Platform (e.g. X11). It is no longer configurable from UI.
837  agentStr.replace(QL1S("%platform%"), platform(), Qt::CaseInsensitive);
838 
839  // Operating system (e.g. Linux)
840  if (modifiers.contains(QL1C('o'))) {
841  agentStr.replace(QL1S("%osname%"), systemName, Qt::CaseInsensitive);
842 
843  // OS version (e.g. 2.6.36)
844  if (modifiers.contains(QL1C('v'))) {
845  agentStr.replace(QL1S("%osversion%"), systemVersion, Qt::CaseInsensitive);
846  } else {
847  agentStr.remove(QStringLiteral("%osversion%"), Qt::CaseInsensitive);
848  }
849 
850  // Machine type (i686, x86-64, etc.)
851  if (modifiers.contains(QL1C('m'))) {
852  agentStr.replace(QL1S("%systype%"), machine, Qt::CaseInsensitive);
853  } else {
854  agentStr.remove(QStringLiteral("%systype%"), Qt::CaseInsensitive);
855  }
856  } else {
857  agentStr.remove(QStringLiteral("%osname%"), Qt::CaseInsensitive);
858  agentStr.remove(QStringLiteral("%osversion%"), Qt::CaseInsensitive);
859  agentStr.remove(QStringLiteral("%systype%"), Qt::CaseInsensitive);
860  }
861 
862  // Language (e.g. en_US)
863  if (modifiers.contains(QL1C('l'))) {
864  agentStr.replace(QL1S("%language%"), QLocale::languageToString(QLocale().language()), Qt::CaseInsensitive);
865  } else {
866  agentStr.remove(QStringLiteral("%language%"), Qt::CaseInsensitive);
867  }
868 
869  // Clean up unnecessary separators that could be left over from the
870  // possible keyword removal above...
871  agentStr.replace(QRegularExpression(QStringLiteral("[(]\\s*[;]\\s*")), QStringLiteral("("));
872  agentStr.replace(QRegularExpression(QStringLiteral("[;]\\s*[;]\\s*")), QStringLiteral("; "));
873  agentStr.replace(QRegularExpression(QStringLiteral("\\s*[;]\\s*[)]")), QStringLiteral(")"));
874  } else {
875  agentStr.remove(QStringLiteral("%osname%"));
876  agentStr.remove(QStringLiteral("%osversion%"));
877  agentStr.remove(QStringLiteral("%platform%"));
878  agentStr.remove(QStringLiteral("%systype%"));
879  agentStr.remove(QStringLiteral("%language%"));
880  }
881 
882  d->useragent = agentStr.simplified();
883  }
884 
885  // qDebug() << "USERAGENT STRING:" << d->useragent;
886  return d->useragent;
887 }
888 
889 QString KProtocolManager::userAgentForApplication(const QString &appName, const QString &appVersion, const QStringList &extraInfo)
890 {
891  QString systemName, systemVersion, machine, info;
892 
893  if (getSystemNameVersionAndMachine(systemName, systemVersion, machine)) {
894  info += systemName + QL1C('/') + systemVersion + QL1S("; ");
895  }
896 
897  info += QL1S("KDE/") + QString::number(KIO_VERSION_MAJOR) + QL1C('.') + QString::number(KIO_VERSION_MINOR) + QL1C('.') + QString::number(KIO_VERSION_PATCH);
898 
899  if (!machine.isEmpty()) {
900  info += QL1S("; ") + machine;
901  }
902 
903  info += QL1S("; ") + extraInfo.join(QLatin1String("; "));
904 
905  return (appName + QL1C('/') + appVersion + QStringLiteral(" (") + info + QL1C(')'));
906 }
907 
908 bool KProtocolManager::getSystemNameVersionAndMachine(QString &systemName, QString &systemVersion, QString &machine)
909 {
910 #if defined(Q_OS_WIN) && !defined(_WIN32_WCE)
911  // we do not use unameBuf.sysname information constructed in kdewin32
912  // because we want to get separate name and version
913  systemName = QStringLiteral("Windows");
914  OSVERSIONINFOEX versioninfo;
915  ZeroMemory(&versioninfo, sizeof(OSVERSIONINFOEX));
916  // try calling GetVersionEx using the OSVERSIONINFOEX, if that fails, try using the OSVERSIONINFO
917  versioninfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
918  bool ok = GetVersionEx((OSVERSIONINFO *)&versioninfo);
919  if (!ok) {
920  versioninfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
921  ok = GetVersionEx((OSVERSIONINFO *)&versioninfo);
922  }
923  if (ok) {
924  systemVersion = QString::number(versioninfo.dwMajorVersion);
925  systemVersion += QL1C('.');
926  systemVersion += QString::number(versioninfo.dwMinorVersion);
927  }
928 #else
929  struct utsname unameBuf;
930  if (0 != uname(&unameBuf)) {
931  return false;
932  }
933  systemName = QString::fromUtf8(unameBuf.sysname);
934  systemVersion = QString::fromUtf8(unameBuf.release);
935  machine = QString::fromUtf8(unameBuf.machine);
936 #endif
937  return true;
938 }
939 
941 {
942  const QLatin1String english("en");
943 
944  // User's desktop language preference.
945  QStringList languageList = QLocale().uiLanguages();
946 
947  // Replace possible "C" in the language list with "en", unless "en" is
948  // already pressent. This is to keep user's priorities in order.
949  // If afterwards "en" is still not present, append it.
950  int idx = languageList.indexOf(QLatin1String("C"));
951  if (idx != -1) {
952  if (languageList.contains(english)) {
953  languageList.removeAt(idx);
954  } else {
955  languageList[idx] = english;
956  }
957  }
958  if (!languageList.contains(english)) {
959  languageList += english;
960  }
961 
962  // Some languages may have web codes different from locale codes,
963  // read them from the config and insert in proper order.
964  KConfig acclangConf(QStringLiteral("accept-languages.codes"), KConfig::NoGlobals);
965  KConfigGroup replacementCodes(&acclangConf, "ReplacementCodes");
966  QStringList languageListFinal;
967  for (const QString &lang : qAsConst(languageList)) {
968  const QStringList langs = replacementCodes.readEntry(lang, QStringList());
969  if (langs.isEmpty()) {
970  languageListFinal += lang;
971  } else {
972  languageListFinal += langs;
973  }
974  }
975 
976  // The header is composed of comma separated languages, with an optional
977  // associated priority estimate (q=1..0) defaulting to 1.
978  // As our language tags are already sorted by priority, we'll just decrease
979  // the value evenly
980  int prio = 10;
981  QString header;
982  for (const QString &lang : qAsConst(languageListFinal)) {
983  header += lang;
984  if (prio < 10) {
985  header += QL1S(";q=0.") + QString::number(prio);
986  }
987  // do not add cosmetic whitespace in here : it is less compatible (#220677)
988  header += QL1C(',');
989  if (prio > 1) {
990  --prio;
991  }
992  }
993  header.chop(1);
994 
995  // Some of the languages may have country specifier delimited by
996  // underscore, or modifier delimited by at-sign.
997  // The header should use dashes instead.
998  header.replace(QL1C('_'), QL1C('-'));
999  header.replace(QL1C('@'), QL1C('-'));
1000 
1001  return header;
1002 }
1003 
1004 /*==================================== OTHERS ===============================*/
1005 
1007 {
1008  PRIVATE_DATA;
1009  QMutexLocker lock(&d->mutex);
1010  return config()->group(QByteArray()).readEntry("MarkPartial", true);
1011 }
1012 
1014 {
1015  PRIVATE_DATA;
1016  QMutexLocker lock(&d->mutex);
1017  return config()->group(QByteArray()).readEntry("MinimumKeepSize",
1018  DEFAULT_MINIMUM_KEEP_SIZE); // 5000 byte
1019 }
1020 
1022 {
1023  PRIVATE_DATA;
1024  QMutexLocker lock(&d->mutex);
1025  return config()->group(QByteArray()).readEntry("AutoResume", false);
1026 }
1027 
1029 {
1030  PRIVATE_DATA;
1031  QMutexLocker lock(&d->mutex);
1032  return config()->group(QByteArray()).readEntry("PersistentConnections", true);
1033 }
1034 
1036 {
1037  PRIVATE_DATA;
1038  QMutexLocker lock(&d->mutex);
1039  return config()->group(QByteArray()).readEntry("PersistentProxyConnection", false);
1040 }
1041 
1043 {
1044  PRIVATE_DATA;
1045  QMutexLocker lock(&d->mutex);
1046  return config()->group("Proxy Settings").readEntry("Proxy Config Script");
1047 }
1048 
1049 /* =========================== PROTOCOL CAPABILITIES ============== */
1050 
1051 static KProtocolInfoPrivate *findProtocol(const QUrl &url)
1052 {
1053  if (!url.isValid()) {
1054  return nullptr;
1055  }
1056  QString protocol = url.scheme();
1057  if (!KProtocolInfo::proxiedBy(protocol).isEmpty()) {
1058  QString dummy;
1059  protocol = KProtocolManager::slaveProtocol(url, dummy);
1060  }
1061 
1062  return KProtocolInfoFactory::self()->findProtocol(protocol);
1063 }
1064 
1066 {
1067  KProtocolInfoPrivate *prot = findProtocol(url);
1068  if (!prot) {
1069  return KProtocolInfo::T_NONE;
1070  }
1071 
1072  return prot->m_inputType;
1073 }
1074 
1076 {
1077  KProtocolInfoPrivate *prot = findProtocol(url);
1078  if (!prot) {
1079  return KProtocolInfo::T_NONE;
1080  }
1081 
1082  return prot->m_outputType;
1083 }
1084 
1086 {
1087  KProtocolInfoPrivate *prot = findProtocol(url);
1088  if (!prot) {
1089  return false;
1090  }
1091 
1092  return prot->m_isSourceProtocol;
1093 }
1094 
1096 {
1097  KProtocolInfoPrivate *prot = findProtocol(url);
1098  if (!prot) {
1099  return false;
1100  }
1101 
1102  return prot->m_supportsListing;
1103 }
1104 
1106 {
1107  KProtocolInfoPrivate *prot = findProtocol(url);
1108  if (!prot) {
1109  return QStringList();
1110  }
1111 
1112  return prot->m_listing;
1113 }
1114 
1116 {
1117  KProtocolInfoPrivate *prot = findProtocol(url);
1118  if (!prot) {
1119  return false;
1120  }
1121 
1122  return prot->m_supportsReading;
1123 }
1124 
1126 {
1127  KProtocolInfoPrivate *prot = findProtocol(url);
1128  if (!prot) {
1129  return false;
1130  }
1131 
1132  return prot->m_supportsWriting;
1133 }
1134 
1136 {
1137  KProtocolInfoPrivate *prot = findProtocol(url);
1138  if (!prot) {
1139  return false;
1140  }
1141 
1142  return prot->m_supportsMakeDir;
1143 }
1144 
1146 {
1147  KProtocolInfoPrivate *prot = findProtocol(url);
1148  if (!prot) {
1149  return false;
1150  }
1151 
1152  return prot->m_supportsDeleting;
1153 }
1154 
1156 {
1157  KProtocolInfoPrivate *prot = findProtocol(url);
1158  if (!prot) {
1159  return false;
1160  }
1161 
1162  return prot->m_supportsLinking;
1163 }
1164 
1166 {
1167  KProtocolInfoPrivate *prot = findProtocol(url);
1168  if (!prot) {
1169  return false;
1170  }
1171 
1172  return prot->m_supportsMoving;
1173 }
1174 
1176 {
1177  KProtocolInfoPrivate *prot = findProtocol(url);
1178  if (!prot) {
1179  return false;
1180  }
1181 
1182  return prot->m_supportsOpening;
1183 }
1184 
1186 {
1187  KProtocolInfoPrivate *prot = findProtocol(url);
1188  if (!prot) {
1189  return false;
1190  }
1191 
1192  return prot->m_supportsTruncating;
1193 }
1194 
1196 {
1197  KProtocolInfoPrivate *prot = findProtocol(url);
1198  if (!prot) {
1199  return false;
1200  }
1201 
1202  return prot->m_canCopyFromFile;
1203 }
1204 
1206 {
1207  KProtocolInfoPrivate *prot = findProtocol(url);
1208  if (!prot) {
1209  return false;
1210  }
1211 
1212  return prot->m_canCopyToFile;
1213 }
1214 
1216 {
1217  KProtocolInfoPrivate *prot = findProtocol(url);
1218  if (!prot) {
1219  return false;
1220  }
1221 
1222  return prot->m_canRenameFromFile;
1223 }
1224 
1226 {
1227  KProtocolInfoPrivate *prot = findProtocol(url);
1228  if (!prot) {
1229  return false;
1230  }
1231 
1232  return prot->m_canRenameToFile;
1233 }
1234 
1236 {
1237  KProtocolInfoPrivate *prot = findProtocol(url);
1238  if (!prot) {
1239  return false;
1240  }
1241 
1242  return prot->m_canDeleteRecursive;
1243 }
1244 
1245 KProtocolInfo::FileNameUsedForCopying KProtocolManager::fileNameUsedForCopying(const QUrl &url)
1246 {
1247  KProtocolInfoPrivate *prot = findProtocol(url);
1248  if (!prot) {
1249  return KProtocolInfo::FromUrl;
1250  }
1251 
1252  return prot->m_fileNameUsedForCopying;
1253 }
1254 
1256 {
1257  KProtocolInfoPrivate *prot = findProtocol(url);
1258  if (!prot) {
1259  return QString();
1260  }
1261 
1262  return prot->m_defaultMimetype;
1263 }
1264 
1266 {
1267  PRIVATE_DATA;
1268  QMutexLocker lock(&d->mutex);
1269  if (d->protocolForArchiveMimetypes.isEmpty()) {
1270  const QList<KProtocolInfoPrivate *> allProtocols = KProtocolInfoFactory::self()->allProtocols();
1271  for (KProtocolInfoPrivate *allProtocol : allProtocols) {
1272  const QStringList archiveMimetypes = allProtocol->m_archiveMimeTypes;
1273  for (const QString &mime : archiveMimetypes) {
1274  d->protocolForArchiveMimetypes.insert(mime, allProtocol->m_name);
1275  }
1276  }
1277  }
1278  return d->protocolForArchiveMimetypes.value(mimeType);
1279 }
1280 
1282 {
1283  return KIO::SlaveConfig::self()->configData(url.scheme(), url.host(), QStringLiteral("Charset"));
1284 }
1285 
1286 #undef PRIVATE_DATA
1287 
1288 #include "kprotocolmanager.moc"
QString url(QUrl::FormattingOptions options) const const
no information about the type available
Definition: kprotocolinfo.h:84
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:241
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 MIME type for this URL based on the protocol.
static QString protocolForArchiveMimetype(const QString &mimeType)
Returns which protocol handles this MIME type, if it&#39;s an archive MIME type.
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:285
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:158
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 arg(Args &&...args) const const
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-2021 The KDE developers.
Generated on Tue Mar 2 2021 23:59:04 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.