kio: drop proxy support

because curl internally checks the environment for proxy-related variables
it is redundant to duplicate that feature, that however is possible due to
the rewrite of the ftp, sftp and http slaves that I did. some other changes
were made while at it such enable automatic resuming by default, if KIO
slaves cannot resume or do not resume transfers that is different thing

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2024-03-29 09:52:05 +02:00
parent 599c76018a
commit b43339cf19
18 changed files with 458 additions and 1267 deletions

View file

@ -26,9 +26,27 @@
#include <kconfig.h>
#include <kconfiggroup.h>
//
// Internal functions:
//
static void selectServiceOrHelper(const QString &protocol, KProtocolInfo::Ptr &returnProtocol, KService::Ptr &returnService)
{
// have up to two sources of data:
// 1) the exec line of the .protocol file, if there's one (could be a kioslave or a helper app)
// 2) the application associated with x-scheme-handler/<protocol> if there's one
// if both exist, then:
// A) if the .protocol file says "launch an application", then the new-style handler-app has priority
// B) but if the .protocol file is for a kioslave (e.g. kio_http) then this has priority over
// firefox or chromium saying x-scheme-handler/http. Gnome people want to send all HTTP urls
// to a webbrowser, but mimetype-determination-in-calling-application by default is done here
const KProtocolInfo::Ptr prot = KProtocolInfoFactory::self()->findProtocol(protocol);
if (prot) {
returnProtocol = prot;
return;
}
// no protocol file, use handler app if any
returnService = KMimeTypeTrader::self()->preferredService(QString::fromLatin1("x-scheme-handler/") + protocol);
}
KProtocolInfo::KProtocolInfo(const QString &path)
: KSycocaEntry(*new KProtocolInfoPrivate(path, this))
{
@ -73,7 +91,6 @@ KProtocolInfo::KProtocolInfo(const QString &path)
d->protClass.prepend(QLatin1Char(':'));
}
d->showPreviews = config.readEntry("ShowPreviews", d->protClass == QLatin1String(":local"));
d->proxyProtocol = config.readEntry("ProxiedBy");
}
KProtocolInfo::KProtocolInfo(QDataStream &str, int offset)
@ -109,7 +126,6 @@ void KProtocolInfo::load(QDataStream &str)
>> i_canCopyFromFile >> i_canCopyToFile
>> m_config >> m_maxSlaves >> d->docPath >> d->protClass
>> i_showPreviews
>> d->proxyProtocol
>> i_canRenameFromFile >> i_canRenameToFile
>> i_canDeleteRecursive >> i_fileNameUsedForCopying
>> d->maxSlavesPerHost;
@ -132,8 +148,7 @@ void KProtocolInfo::load(QDataStream &str)
d->showPreviews = (i_showPreviews != 0);
}
void
KProtocolInfoPrivate::save(QDataStream &str)
void KProtocolInfoPrivate::save(QDataStream &str)
{
KSycocaEntryPrivate::save(str);
@ -174,7 +189,6 @@ KProtocolInfoPrivate::save(QDataStream &str)
<< i_canCopyFromFile << i_canCopyToFile
<< q->m_config << q->m_maxSlaves << docPath << protClass
<< i_showPreviews
<< proxyProtocol
<< i_canRenameFromFile << i_canRenameToFile
<< i_canDeleteRecursive << i_fileNameUsedForCopying
<< maxSlavesPerHost;
@ -188,27 +202,6 @@ QStringList KProtocolInfo::protocols()
return KProtocolInfoFactory::self()->protocols();
}
void KProtocolInfo::selectServiceOrHelper(const QString &protocol, KProtocolInfo::Ptr &returnProtocol, KService::Ptr &returnService)
{
// have up to two sources of data:
// 1) the exec line of the .protocol file, if there's one (could be a kioslave or a helper app)
// 2) the application associated with x-scheme-handler/<protocol> if there's one
// if both exist, then:
// A) if the .protocol file says "launch an application", then the new-style handler-app has priority
// B) but if the .protocol file is for a kioslave (e.g. kio_http) then this has priority over
// firefox or chromium saying x-scheme-handler/http. Gnome people want to send all HTTP urls
// to a webbrowser, but mimetype-determination-in-calling-application by default is done here
const KProtocolInfo::Ptr prot = KProtocolInfoFactory::self()->findProtocol(protocol);
if (prot) {
returnProtocol = prot;
return;
}
// no protocol file, use handler app if any
returnService = KMimeTypeTrader::self()->preferredService(QString::fromLatin1("x-scheme-handler/") + protocol);
}
QString KProtocolInfo::icon(const QString &protocol)
{
KProtocolInfo::Ptr prot;
@ -224,7 +217,6 @@ QString KProtocolInfo::icon(const QString &protocol)
QString KProtocolInfo::config(const QString &protocol)
{
// call the findProtocol directly (not via KProtocolManager) to bypass any proxy settings
KProtocolInfo::Ptr prot = KProtocolInfoFactory::self()->findProtocol(protocol);
if (!prot) {
return QString();
@ -299,15 +291,6 @@ bool KProtocolInfo::showFilePreview(const QString &protocol)
return prot->d_func()->showPreviews;
}
QString KProtocolInfo::proxiedBy(const QString &protocol)
{
KProtocolInfo::Ptr prot = KProtocolInfoFactory::self()->findProtocol(protocol);
if (!prot) {
return QString();
}
return prot->d_func()->proxyProtocol;
}
QString KProtocolInfo::defaultMimeType() const
{
return m_defaultMimetype;
@ -349,7 +332,6 @@ bool KProtocolInfo::isHelperProtocol(const KUrl &url)
bool KProtocolInfo::isHelperProtocol(const QString &protocol)
{
// call the findProtocol directly (not via KProtocolManager) to bypass any proxy settings.
KProtocolInfo::Ptr prot = KProtocolInfoFactory::self()->findProtocol(protocol);
if (prot) {
return false;
@ -365,7 +347,6 @@ bool KProtocolInfo::isKnownProtocol(const KUrl &url)
bool KProtocolInfo::isKnownProtocol(const QString &protocol)
{
// call the findProtocol (const QString&) to bypass any proxy settings.
KProtocolInfo::Ptr prot = KProtocolInfoFactory::self()->findProtocol(protocol);
return prot || isHelperProtocol(protocol);
}

View file

@ -209,17 +209,6 @@ public:
*/
static bool showFilePreview(const QString &protocol);
/**
* Returns the name of the protocol through which the request
* will be routed if proxy support is enabled.
*
* A good example of this is the ftp protocol for which proxy
* support is commonly handled by the http protocol.
*
* This corresponds to the "ProxiedBy=" in the protocol description file.
*/
static QString proxiedBy(const QString &protocol);
public:
// Internal functions:
/**
@ -270,7 +259,6 @@ private:
Q_DECLARE_PRIVATE(KProtocolInfo)
void load(QDataStream &s);
static void selectServiceOrHelper(const QString &protocol, KProtocolInfo::Ptr &returnProtocol, KService::Ptr &returnService);
};
#endif // KPROTOCOLINFO_H

View file

@ -48,12 +48,11 @@ public:
KProtocolInfo *q;
QString docPath;
QString protClass;
bool showPreviews : 1;
bool canRenameFromFile : 1;
bool canRenameToFile : 1;
bool canDeleteRecursive : 1;
bool showPreviews;
bool canRenameFromFile;
bool canRenameToFile;
bool canDeleteRecursive;
KProtocolInfo::FileNameUsedForCopying fileNameUsedForCopying;
QString proxyProtocol;
int maxSlavesPerHost;
};

View file

@ -15,9 +15,9 @@ Key Value(s) Description
modified string The modification date of the document (set by kio before put)
accept string List of mimetypes to accept separated by a ", ". (read by http)
accept string List of mimetypes to accept separated by a ", ". (read by curl)
UserAgent string The user agent name to send to remote host (read by http)
UserAgent string The user agent name to send to remote host (read by curl)
window-id number winId() of the window the request is associated with.
@ -39,10 +39,6 @@ no-proxy-auth bool Flag that indicates that no HTTP proxy authentic
no-auth-prompt bool Flag that indicates that only cached authentication tokens should
be used.
UseProxy string URL representing the proxy settings (read by http)
ProxyUrls string Comma separated list of proxy urls. The first url in this list
matches one set in "UseProxy".
recurse bool When true, del() will be able to delete non-empty directories.
Otherwise, del() is supposed to give an error on non-empty
directories. (read by file)

View file

@ -872,12 +872,10 @@ KIO_EXPORT QByteArray KIO::rawErrorDetail(int errorCode, const QString &errorTex
"the request as follows:<ul>"
"<li>Timeout for establishing a connection: %1 seconds</li>"
"<li>Timeout for receiving a response: %2 seconds</li>"
"<li>Timeout for accessing proxy servers: %3 seconds</li></ul>"
"Please note that you can alter these timeout settings in the "
"System Settings, by selecting Network Settings -> Connection Preferences." ,
KProtocolManager::connectTimeout() ,
KProtocolManager::responseTimeout() ,
KProtocolManager::proxyConnectTimeout() );
KProtocolManager::responseTimeout() );
causes << cNetpath << i18n( "The server was too busy responding to other "
"requests to respond." );
solutions << sTryagain << sServeradmin;

View file

@ -23,13 +23,9 @@
#define DEFAULT_RESPONSE_TIMEOUT 600 // 10 min.
#define DEFAULT_CONNECT_TIMEOUT 20 // 20 secs.
#define DEFAULT_READ_TIMEOUT 15 // 15 secs.
#define DEFAULT_PROXY_CONNECT_TIMEOUT 10 // 10 secs.
#define MIN_TIMEOUT_VALUE 2 // 2 secs.
// MINMUM SIZE FOR ABORTED DOWNLOAD TO BE KEPT
#define DEFAULT_MINIMUM_KEEP_SIZE 5120 // 5 Kbs
// DEFAULT USER AGENT KEY - ENABLES OS NAME
#define DEFAULT_USER_AGENT_KEYS "om" // Show OS, Machine
#endif // KIO_IOSLAVE_DEFAULTS_H

View file

@ -136,7 +136,6 @@ namespace KIO {
// We schedule slaves based on (2) but tell the slave about (1) via
// Slave::setProtocol().
QString m_protocol;
QStringList m_proxyList;
int m_schedSerial;
bool m_redirectionHandlingEnabled;

View file

@ -20,108 +20,39 @@
*/
#include "kprotocolmanager.h"
#include "kdeversion.h"
#include "kdebug.h"
#include "kglobal.h"
#include "klocale.h"
#include "kconfiggroup.h"
#include "ksharedconfig.h"
#include "kurl.h"
#include "kprotocolinfofactory.h"
#include "kio/slaveconfig.h"
#include "kio/ioslave_defaults.h"
#include <QCoreApplication>
#include <string.h>
#include <unistd.h>
#include <sys/utsname.h>
#include <QtCore/QCoreApplication>
#include <QtNetwork/QHostAddress>
#include <QtNetwork/QHostInfo>
#include <QtDBus/QtDBus>
#include <QtCore/QCache>
#include <kdeversion.h>
#include <kdebug.h>
#include <kglobal.h>
#include <klocale.h>
#include <kconfiggroup.h>
#include <ksharedconfig.h>
#include <kstandarddirs.h>
#include <kurl.h>
#include <kmimetypetrader.h>
#include <kprotocolinfofactory.h>
#include <kio/slaveconfig.h>
#include <kio/ioslave_defaults.h>
#define QL1S(x) QLatin1String(x)
#define QL1C(x) QLatin1Char(x)
typedef QPair<QHostAddress, int> SubnetPair;
/*
Domain suffix match. E.g. return true if host is "cuzco.inka.de" and
nplist is "inka.de,hadiko.de" or if host is "localhost" and nplist is
"localhost".
*/
static bool revmatch(const char *host, const char *nplist)
static KProtocolInfo::Ptr findProtocol(const KUrl &url)
{
if (host == 0)
return false;
const char *hptr = host + strlen( host ) - 1;
const char *nptr = nplist + strlen( nplist ) - 1;
const char *shptr = hptr;
while ( nptr >= nplist )
{
if ( *hptr != *nptr )
{
hptr = shptr;
// Try to find another domain or host in the list
while(--nptr>=nplist && *nptr!=',' && *nptr!=' ') ;
// Strip out multiple spaces and commas
while(--nptr>=nplist && (*nptr==',' || *nptr==' ')) ;
}
else
{
if ( nptr==nplist || nptr[-1]==',' || nptr[-1]==' ')
return true;
if ( nptr[-1]=='/' && hptr == host ) // "bugs.kde.org" vs "http://bugs.kde.org", the config UI says URLs are ok
return true;
if ( hptr == host ) // e.g. revmatch("bugs.kde.org","mybugs.kde.org")
return false;
hptr--;
nptr--;
}
}
return false;
return KProtocolInfoFactory::self()->findProtocol(url.protocol());
}
class KProxyData : public QObject
{
public:
KProxyData(const QString& slaveProtocol, const QStringList& proxyAddresses)
:protocol(slaveProtocol)
,proxyList(proxyAddresses) {
}
void removeAddress(const QString& address) {
proxyList.removeAll(address);
}
QString protocol;
QStringList proxyList;
};
class KProtocolManagerPrivate
{
public:
KProtocolManagerPrivate();
~KProtocolManagerPrivate();
bool shouldIgnoreProxyFor(const KUrl& url);
KProtocolManagerPrivate();
~KProtocolManagerPrivate();
KSharedConfig::Ptr config;
QString modifiers;
QString useragent;
QString noProxyFor;
QList<SubnetPair> noProxySubnets;
QCache<QString, KProxyData> cachedProxyData;
KSharedConfig::Ptr config;
QString useragent;
};
K_GLOBAL_STATIC(KProtocolManagerPrivate, kProtocolManagerPrivate)
@ -130,7 +61,6 @@ KProtocolManagerPrivate::KProtocolManagerPrivate()
{
// post routine since KConfig::sync() breaks if called too late
qAddPostRoutine(kProtocolManagerPrivate.destroy);
cachedProxyData.setMaxCost(200); // double the max cost.
}
KProtocolManagerPrivate::~KProtocolManagerPrivate()
@ -138,82 +68,6 @@ KProtocolManagerPrivate::~KProtocolManagerPrivate()
qRemovePostRoutine(kProtocolManagerPrivate.destroy);
}
/*
* Returns true if url is in the no proxy list.
*/
bool KProtocolManagerPrivate::shouldIgnoreProxyFor(const KUrl& url)
{
bool isMatch = false;
const KProtocolManager::ProxyType type = KProtocolManager::proxyType();
const bool useRevProxy = ((type == KProtocolManager::ManualProxy) && KProtocolManager::useReverseProxy());
const bool useNoProxyList = (type == KProtocolManager::ManualProxy || type == KProtocolManager::EnvVarProxy);
// No proxy only applies to ManualProxy and EnvVarProxy types...
if (useNoProxyList && noProxyFor.isEmpty()) {
QStringList noProxyForList (KProtocolManager::noProxyFor().split(QL1C(',')));
QMutableStringListIterator it (noProxyForList);
while (it.hasNext()) {
SubnetPair subnet = QHostAddress::parseSubnet(it.next());
if (!subnet.first.isNull()) {
noProxySubnets << subnet;
it.remove();
}
}
noProxyFor = noProxyForList.join(QL1S(","));
}
if (!noProxyFor.isEmpty()) {
QString qhost = url.host().toLower();
QByteArray host = qhost.toLatin1();
const QString qno_proxy = noProxyFor.trimmed().toLower();
const QByteArray no_proxy = qno_proxy.toLatin1();
isMatch = revmatch(host, no_proxy);
// If no match is found and the request url has a port
// number, try the combination of "host:port". This allows
// users to enter host:port in the No-proxy-For list.
if (!isMatch && url.port() > 0) {
qhost += QL1C(':');
qhost += QString::number(url.port());
host = qhost.toLatin1();
isMatch = revmatch (host, no_proxy);
}
// If the hostname does not contain a dot, check if
// <local> is part of noProxy.
if (!isMatch && !host.isEmpty() && (strchr(host, '.') == NULL)) {
isMatch = revmatch("<local>", no_proxy);
}
}
const QString host (url.host());
if (!noProxySubnets.isEmpty() && !host.isEmpty()) {
QHostAddress address (host);
// If request url is not IP address, do a DNS lookup of the hostname.
// TODO: Perhaps we should make configurable ?
if (address.isNull()) {
kDebug() << "Performing DNS lookup for" << host;
QHostInfo info = QHostInfo::fromName(host);
const QList<QHostAddress> addresses = info.addresses();
if (!addresses.isEmpty())
address = addresses.first();
}
if (!address.isNull()) {
Q_FOREACH(const SubnetPair& subnet, noProxySubnets) {
if (address.isInSubnet(subnet)) {
isMatch = true;
break;
}
}
}
}
return (useRevProxy != isMatch);
}
#define PRIVATE_DATA \
KProtocolManagerPrivate *d = kProtocolManagerPrivate
@ -223,9 +77,6 @@ void KProtocolManager::reparseConfiguration()
if (d->config) {
d->config->reparseConfiguration();
}
d->cachedProxyData.clear();
d->noProxyFor.clear();
d->modifiers.clear();
d->useragent.clear();
// Force the slave config to re-read its config...
@ -234,587 +85,274 @@ void KProtocolManager::reparseConfiguration()
KSharedConfig::Ptr KProtocolManager::config()
{
PRIVATE_DATA;
if (!d->config)
{
d->config = KSharedConfig::openConfig("kioslaverc", KConfig::NoGlobals);
}
return d->config;
PRIVATE_DATA;
if (!d->config) {
d->config = KSharedConfig::openConfig("kioslaverc", KConfig::NoGlobals);
}
return d->config;
}
/*=============================== TIMEOUT SETTINGS ==========================*/
int KProtocolManager::readTimeout()
{
KConfigGroup cg( config(), QString() );
int val = cg.readEntry( "ReadTimeout", DEFAULT_READ_TIMEOUT );
return qMax(MIN_TIMEOUT_VALUE, val);
KConfigGroup cg(config(), QString());
const int value = cg.readEntry("ReadTimeout", DEFAULT_READ_TIMEOUT);
return qMax(MIN_TIMEOUT_VALUE, value);
}
int KProtocolManager::connectTimeout()
{
KConfigGroup cg( config(), QString() );
int val = cg.readEntry( "ConnectTimeout", DEFAULT_CONNECT_TIMEOUT );
return qMax(MIN_TIMEOUT_VALUE, val);
}
int KProtocolManager::proxyConnectTimeout()
{
KConfigGroup cg( config(), QString() );
int val = cg.readEntry( "ProxyConnectTimeout", DEFAULT_PROXY_CONNECT_TIMEOUT );
return qMax(MIN_TIMEOUT_VALUE, val);
KConfigGroup cg( config(), QString() );
const int value = cg.readEntry("ConnectTimeout", DEFAULT_CONNECT_TIMEOUT);
return qMax(MIN_TIMEOUT_VALUE, value);
}
int KProtocolManager::responseTimeout()
{
KConfigGroup cg( config(), QString() );
int val = cg.readEntry( "ResponseTimeout", DEFAULT_RESPONSE_TIMEOUT );
return qMax(MIN_TIMEOUT_VALUE, val);
}
/*========================== PROXY SETTINGS =================================*/
bool KProtocolManager::useProxy()
{
return proxyType() != NoProxy;
}
bool KProtocolManager::useReverseProxy()
{
KConfigGroup cg(config(), "Proxy Settings" );
return cg.readEntry("ReversedException", false);
}
KProtocolManager::ProxyType KProtocolManager::proxyType()
{
KConfigGroup cg(config(), "Proxy Settings" );
return static_cast<ProxyType>(cg.readEntry( "ProxyType" , 0));
}
QString KProtocolManager::noProxyFor()
{
QString noProxy = config()->group("Proxy Settings").readEntry( "NoProxyFor" );
if (proxyType() == EnvVarProxy)
noProxy = QString::fromLocal8Bit(qgetenv(noProxy.toLocal8Bit()));
return noProxy;
}
QString KProtocolManager::proxyFor( const QString& protocol )
{
const QString key = protocol.toLower() + QL1S("Proxy");
QString proxyStr (config()->group("Proxy Settings").readEntry(key));
const int index = proxyStr.lastIndexOf(QL1C(' '));
if (index > -1) {
bool ok = false;
const QString portStr(proxyStr.right(proxyStr.length() - index - 1));
portStr.toInt(&ok);
if (ok) {
proxyStr = proxyStr.left(index) + QL1C(':') + portStr;
} else {
proxyStr.clear();
}
}
return proxyStr;
}
QString KProtocolManager::proxyForUrl( const KUrl &url )
{
const QStringList proxies = proxiesForUrl(url);
if (proxies.isEmpty())
return QString();
return proxies.first();
}
static QStringList getSystemProxyFor( const KUrl& url )
{
QStringList proxies;
// On Unix/Linux use system environment variables if any are set.
QString proxyVar (KProtocolManager::proxyFor(url.protocol()));
// Check for SOCKS proxy, if not proxy is found for given url.
if (!proxyVar.isEmpty()) {
const QString proxy (QString::fromLocal8Bit(qgetenv(proxyVar.toLocal8Bit())).trimmed());
if (!proxy.isEmpty()) {
proxies << proxy;
}
}
// Add the socks proxy as an alternate proxy if it exists,
proxyVar = KProtocolManager::proxyFor(QL1S("socks"));
if (!proxyVar.isEmpty()) {
QString proxy = QString::fromLocal8Bit(qgetenv(proxyVar.toLocal8Bit())).trimmed();
// Make sure the scheme of SOCKS proxy is always set to "socks://".
const int index = proxy.indexOf(QL1S("://"));
proxy = QL1S("socks://") + (index == -1 ? proxy : proxy.mid(index+3));
if (!proxy.isEmpty()) {
proxies << proxy;
}
}
return proxies;
}
QStringList KProtocolManager::proxiesForUrl( const KUrl &url )
{
QStringList proxyList;
PRIVATE_DATA;
if (!d->shouldIgnoreProxyFor(url)) {
switch (proxyType())
{
case EnvVarProxy:
proxyList = getSystemProxyFor( url );
break;
case ManualProxy:
{
QString proxy (proxyFor(url.protocol()));
if (!proxy.isEmpty())
proxyList << proxy;
// Add the socks proxy as an alternate proxy if it exists,
proxy = proxyFor(QL1S("socks"));
if (!proxy.isEmpty()) {
// Make sure the scheme of SOCKS proxy is always set to "socks://".
const int index = proxy.indexOf(QL1S("://"));
proxy = QL1S("socks://") + (index == -1 ? proxy : proxy.mid(index+3));
proxyList << proxy;
}
break;
}
case NoProxy:
default:
break;
}
}
if (proxyList.isEmpty()) {
proxyList << QL1S("DIRECT");
}
return proxyList;
}
void KProtocolManager::badProxy( const QString &proxy )
{
PRIVATE_DATA;
const QStringList keys (d->cachedProxyData.keys());
Q_FOREACH(const QString& key, keys) {
d->cachedProxyData[key]->removeAddress(proxy);
}
}
QString KProtocolManager::slaveProtocol(const KUrl &url, QString &proxy)
{
QStringList proxyList;
const QString protocol = KProtocolManager::slaveProtocol(url, proxyList);
if (!proxyList.isEmpty()) {
proxy = proxyList.first();
}
return protocol;
}
// Generates proxy cache key from request given url.
static void extractProxyCacheKeyFromUrl(const KUrl& u, QString* key)
{
if (!key)
return;
*key = u.protocol();
*key += u.host();
if (u.port() > 0)
*key += QString::number(u.port());
}
QString KProtocolManager::slaveProtocol(const KUrl &url, QStringList &proxyList)
{
proxyList.clear();
// Do not perform a proxy lookup for any url classified as a ":local" url or
// one that does not have a host component or if proxy is disabled.
QString protocol (url.protocol());
if (!url.hasHost()
|| KProtocolInfo::protocolClass(protocol) == QL1S(":local")
|| KProtocolManager::proxyType() == KProtocolManager::NoProxy) {
return protocol;
}
QString proxyCacheKey;
extractProxyCacheKeyFromUrl(url, &proxyCacheKey);
PRIVATE_DATA;
// Look for cached proxy information to avoid more work.
if (d->cachedProxyData.contains(proxyCacheKey)) {
KProxyData* data = d->cachedProxyData.object(proxyCacheKey);
proxyList = data->proxyList;
return data->protocol;
}
const QStringList proxies = proxiesForUrl(url);
const int count = proxies.count();
if (count > 0 && !(count == 1 && proxies.first() == QL1S("DIRECT"))) {
Q_FOREACH(const QString& proxy, proxies) {
if (proxy == QL1S("DIRECT")) {
proxyList << proxy;
} else {
KUrl u (proxy);
if (!u.isEmpty() && u.isValid() && !u.protocol().isEmpty()) {
proxyList << proxy;
}
}
}
}
// The idea behind slave protocols is not applicable to http
// protocol as well as protocols unknown to KDE.
if (!proxyList.isEmpty()
&& !protocol.startsWith(QL1S("http"))
&& KProtocolInfo::isKnownProtocol(protocol)) {
Q_FOREACH(const QString& proxy, proxyList) {
KUrl u (proxy);
if (u.isValid() && KProtocolInfo::isKnownProtocol(u.protocol())) {
protocol = u.protocol();
break;
}
}
}
// cache the proxy information...
d->cachedProxyData.insert(proxyCacheKey, new KProxyData(protocol, proxyList));
return protocol;
KConfigGroup cg(config(), QString());
const int value = cg.readEntry("ResponseTimeout", DEFAULT_RESPONSE_TIMEOUT);
return qMax(MIN_TIMEOUT_VALUE, value);
}
/*================================= USER-AGENT SETTINGS =====================*/
QString KProtocolManager::defaultUserAgent( )
{
return defaultUserAgent(DEFAULT_USER_AGENT_KEYS);
}
static QString platform()
{
return QL1S("X11");
}
QString KProtocolManager::defaultUserAgent( const QString &_modifiers )
QString KProtocolManager::defaultUserAgent()
{
PRIVATE_DATA;
QString modifiers = _modifiers.toLower();
if (modifiers.isEmpty())
modifiers = DEFAULT_USER_AGENT_KEYS;
if (!d->useragent.isEmpty()) {
return d->useragent;
}
if (d->modifiers == modifiers && !d->useragent.isEmpty())
QString tmp;
QString systemName, systemVersion, machine, supp;
bool sysInfoFound = false;
struct utsname unameBuf;
if (uname(&unameBuf) == 0) {
sysInfoFound = true;
tmp += unameBuf.sysname;
tmp += QL1C(' ');
tmp += unameBuf.release;
tmp += QL1C(' ');
tmp += unameBuf.machine;
}
if (sysInfoFound) {
tmp += QL1S("; ");
}
tmp += QL1S("Katana ");
tmp += KDE::versionString();
d->useragent = tmp;
// kDebug() << "USERAGENT STRING:" << d->useragent;
return d->useragent;
d->modifiers = modifiers;
/*
The following code attempts to determine the default user agent string
from the 'X-KDE-UA-DEFAULT-STRING' property of the desktop file
for the preferred service that was configured to handle the 'text/html'
mime type. If the prefered service's desktop file does not specify this
property, the long standing default user agent string will be used.
The following keyword placeholders are automatically converted when the
user agent string is read from the property:
%SECURITY% Expands to"N" when SSL is not supported, otherwise it is ignored.
%OSNAME% Expands to operating system name, e.g. Linux.
%OSVERSION% Expands to operating system version, e.g. 2.6.32
%SYSTYPE% Expands to machine or system type, e.g. i386
%PLATFORM% Expands to windowing system, e.g. X11 on Unix/Linux.
%LANGUAGE% Expands to default language in use, e.g. en-US.
%APPVERSION% Expands to QCoreApplication applicationName()/applicationVerison(),
e.g. Konqueror/4.5.0. If application name and/or application version
number are not set, then "KDE" and the runtime KDE version numbers
are used respectively.
All of the keywords are handled case-insensitively.
*/
QString systemName, systemVersion, machine, supp;
const bool sysInfoFound = getSystemNameVersionAndMachine( systemName, systemVersion, machine );
supp += platform();
if (sysInfoFound)
{
if (modifiers.contains('o'))
{
supp += QL1S("; ");
supp += systemName;
if (modifiers.contains('v'))
{
supp += QL1C(' ');
supp += systemVersion;
}
if (modifiers.contains('m'))
{
supp += QL1C(' ');
supp += machine;
}
}
if (modifiers.contains('l'))
{
supp += QL1S("; ");
supp += KGlobal::locale()->language();
}
}
// Full format: Mozilla/5.0 (Linux
d->useragent = QL1S("Mozilla/5.0 (");
d->useragent += supp;
d->useragent += QL1S(") KHTML/");
d->useragent += QString::number(KDE::versionMajor());
d->useragent += QL1C('.');
d->useragent += QString::number(KDE::versionMinor());
d->useragent += QL1C('.');
d->useragent += QString::number(KDE::versionRelease());
d->useragent += QL1S(" (like Gecko) Konqueror/");
d->useragent += QString::number(KDE::versionMajor());
d->useragent += QL1C('.');
d->useragent += QString::number(KDE::versionMinor());
//kDebug() << "USERAGENT STRING:" << d->useragent;
return d->useragent;
}
bool KProtocolManager::getSystemNameVersionAndMachine(
QString& systemName, QString& systemVersion, QString& machine )
{
struct utsname unameBuf;
if ( 0 != uname( &unameBuf ) )
return false;
systemName = unameBuf.sysname;
systemVersion = unameBuf.release;
machine = unameBuf.machine;
return true;
}
QString KProtocolManager::acceptLanguagesHeader()
{
static const QString english = QString::fromLatin1("en");
static const QString english = QString::fromLatin1("en");
// User's desktop language preference.
QStringList languageList = KGlobal::locale()->languageList();
// User's desktop language preference.
QStringList languageList = KGlobal::locale()->languageList();
// Replace possible "C" in the language list with "en", unless "en" is
// already pressent. This is to keep user's priorities in order.
// If afterwards "en" is still not present, append it.
int idx = languageList.indexOf(QString::fromLatin1("C"));
if (idx != -1)
{
if (languageList.contains(english))
languageList.removeAt(idx);
else
languageList[idx] = english;
}
if (!languageList.contains(english))
languageList += english;
// Replace possible "C" in the language list with "en", unless "en" is
// already pressent. This is to keep user's priorities in order.
// If afterwards "en" is still not present, append it.
int idx = languageList.indexOf(QString::fromLatin1("C"));
if (idx != -1) {
if (languageList.contains(english)) {
languageList.removeAt(idx);
} else {
languageList[idx] = english;
}
}
if (!languageList.contains(english)) {
languageList += english;
}
// The header is composed of comma separated languages, with an optional
// associated priority estimate (q=1..0) defaulting to 1.
// As our language tags are already sorted by priority, we'll just decrease
// the value evenly
int prio = 10;
QString header;
Q_FOREACH (const QString &lang,languageList) {
header += lang;
if (prio < 10) {
header += QL1S(";q=0.");
header += QString::number(prio);
}
// do not add cosmetic whitespace in here : it is less compatible (#220677)
header += QL1S(",");
if (prio > 1)
--prio;
}
header.chop(1);
// The header is composed of comma separated languages, with an optional
// associated priority estimate (q=1..0) defaulting to 1.
// As our language tags are already sorted by priority, we'll just decrease
// the value evenly
int prio = 10;
QString header;
Q_FOREACH (const QString &lang,languageList) {
header += lang;
if (prio < 10) {
header += QL1S(";q=0.");
header += QString::number(prio);
}
// do not add cosmetic whitespace in here : it is less compatible (#220677)
header += QL1S(",");
if (prio > 1) {
--prio;
}
}
header.chop(1);
// Some of the languages may have country specifier delimited by
// underscore, or modifier delimited by at-sign.
// The header should use dashes instead.
header.replace('_', '-');
header.replace('@', '-');
// Some of the languages may have country specifier delimited by
// underscore, or modifier delimited by at-sign.
// The header should use dashes instead.
header.replace('_', '-');
header.replace('@', '-');
return header;
return header;
}
/*==================================== OTHERS ===============================*/
bool KProtocolManager::markPartial()
{
return config()->group(QByteArray()).readEntry( "MarkPartial", true );
return config()->group(QByteArray()).readEntry("MarkPartial", true);
}
int KProtocolManager::minimumKeepSize()
{
return config()->group(QByteArray()).readEntry( "MinimumKeepSize",
DEFAULT_MINIMUM_KEEP_SIZE ); // 5000 byte
return config()->group(QByteArray()).readEntry("MinimumKeepSize", DEFAULT_MINIMUM_KEEP_SIZE);
}
bool KProtocolManager::autoResume()
{
return config()->group(QByteArray()).readEntry( "AutoResume", false );
return config()->group(QByteArray()).readEntry("AutoResume", true);
}
/* =========================== PROTOCOL CAPABILITIES ============== */
static KProtocolInfo::Ptr findProtocol(const KUrl &url)
bool KProtocolManager::isSourceProtocol(const KUrl &url)
{
QString protocol = url.protocol();
if ( !KProtocolInfo::proxiedBy( protocol ).isEmpty() )
{
QString dummy;
protocol = KProtocolManager::slaveProtocol(url, dummy);
}
return KProtocolInfoFactory::self()->findProtocol(protocol);
KProtocolInfo::Ptr prot = findProtocol(url);
if (!prot) {
return false;
}
return prot->m_isSourceProtocol;
}
bool KProtocolManager::isSourceProtocol( const KUrl &url )
bool KProtocolManager::supportsListing(const KUrl &url)
{
KProtocolInfo::Ptr prot = findProtocol(url);
if ( !prot )
return false;
return prot->m_isSourceProtocol;
KProtocolInfo::Ptr prot = findProtocol(url);
if (!prot) {
return false;
}
return prot->m_supportsListing;
}
bool KProtocolManager::supportsListing( const KUrl &url )
bool KProtocolManager::supportsReading(const KUrl &url)
{
KProtocolInfo::Ptr prot = findProtocol(url);
if ( !prot )
return false;
return prot->m_supportsListing;
KProtocolInfo::Ptr prot = findProtocol(url);
if (!prot) {
return false;
}
return prot->m_supportsReading;
}
bool KProtocolManager::supportsReading( const KUrl &url )
bool KProtocolManager::supportsWriting(const KUrl &url)
{
KProtocolInfo::Ptr prot = findProtocol(url);
if ( !prot )
return false;
return prot->m_supportsReading;
KProtocolInfo::Ptr prot = findProtocol(url);
if (!prot) {
return false;
}
return prot->m_supportsWriting;
}
bool KProtocolManager::supportsWriting( const KUrl &url )
bool KProtocolManager::supportsMakeDir(const KUrl &url)
{
KProtocolInfo::Ptr prot = findProtocol(url);
if ( !prot )
return false;
return prot->m_supportsWriting;
KProtocolInfo::Ptr prot = findProtocol(url);
if (!prot) {
return false;
}
return prot->m_supportsMakeDir;
}
bool KProtocolManager::supportsMakeDir( const KUrl &url )
bool KProtocolManager::supportsDeleting(const KUrl &url)
{
KProtocolInfo::Ptr prot = findProtocol(url);
if ( !prot )
return false;
return prot->m_supportsMakeDir;
KProtocolInfo::Ptr prot = findProtocol(url);
if (!prot) {
return false;
}
return prot->m_supportsDeleting;
}
bool KProtocolManager::supportsDeleting( const KUrl &url )
bool KProtocolManager::supportsLinking(const KUrl &url)
{
KProtocolInfo::Ptr prot = findProtocol(url);
if ( !prot )
return false;
return prot->m_supportsDeleting;
KProtocolInfo::Ptr prot = findProtocol(url);
if (!prot) {
return false;
}
return prot->m_supportsLinking;
}
bool KProtocolManager::supportsLinking( const KUrl &url )
bool KProtocolManager::supportsMoving(const KUrl &url)
{
KProtocolInfo::Ptr prot = findProtocol(url);
if ( !prot )
return false;
return prot->m_supportsLinking;
KProtocolInfo::Ptr prot = findProtocol(url);
if (!prot) {
return false;
}
return prot->m_supportsMoving;
}
bool KProtocolManager::supportsMoving( const KUrl &url )
bool KProtocolManager::canCopyFromFile(const KUrl &url)
{
KProtocolInfo::Ptr prot = findProtocol(url);
if ( !prot )
return false;
return prot->m_supportsMoving;
KProtocolInfo::Ptr prot = findProtocol(url);
if (!prot) {
return false;
}
return prot->m_canCopyFromFile;
}
bool KProtocolManager::canCopyFromFile( const KUrl &url )
bool KProtocolManager::canCopyToFile(const KUrl &url)
{
KProtocolInfo::Ptr prot = findProtocol(url);
if ( !prot )
return false;
return prot->m_canCopyFromFile;
KProtocolInfo::Ptr prot = findProtocol(url);
if (!prot) {
return false;
}
return prot->m_canCopyToFile;
}
bool KProtocolManager::canCopyToFile( const KUrl &url )
bool KProtocolManager::canRenameFromFile(const KUrl &url)
{
KProtocolInfo::Ptr prot = findProtocol(url);
if ( !prot )
return false;
return prot->m_canCopyToFile;
KProtocolInfo::Ptr prot = findProtocol(url);
if (!prot) {
return false;
}
return prot->canRenameFromFile();
}
bool KProtocolManager::canRenameFromFile( const KUrl &url )
bool KProtocolManager::canRenameToFile(const KUrl &url)
{
KProtocolInfo::Ptr prot = findProtocol(url);
if ( !prot )
return false;
return prot->canRenameFromFile();
KProtocolInfo::Ptr prot = findProtocol(url);
if (!prot) {
return false;
}
return prot->canRenameToFile();
}
bool KProtocolManager::canRenameToFile( const KUrl &url )
bool KProtocolManager::canDeleteRecursive(const KUrl &url)
{
KProtocolInfo::Ptr prot = findProtocol(url);
if ( !prot )
return false;
return prot->canRenameToFile();
KProtocolInfo::Ptr prot = findProtocol(url);
if (!prot) {
return false;
}
return prot->canDeleteRecursive();
}
bool KProtocolManager::canDeleteRecursive( const KUrl &url )
KProtocolInfo::FileNameUsedForCopying KProtocolManager::fileNameUsedForCopying(const KUrl &url)
{
KProtocolInfo::Ptr prot = findProtocol(url);
if ( !prot )
return false;
return prot->canDeleteRecursive();
KProtocolInfo::Ptr prot = findProtocol(url);
if (!prot) {
return KProtocolInfo::FromUrl;
}
return prot->fileNameUsedForCopying();
}
KProtocolInfo::FileNameUsedForCopying KProtocolManager::fileNameUsedForCopying( const KUrl &url )
QString KProtocolManager::defaultMimetype(const KUrl &url)
{
KProtocolInfo::Ptr prot = findProtocol(url);
if ( !prot )
return KProtocolInfo::FromUrl;
return prot->fileNameUsedForCopying();
KProtocolInfo::Ptr prot = findProtocol(url);
if (!prot) {
return QString();
}
return prot->m_defaultMimetype;
}
QString KProtocolManager::defaultMimetype( const KUrl &url )
{
KProtocolInfo::Ptr prot = findProtocol(url);
if ( !prot )
return QString();
return prot->m_defaultMimetype;
}
QString KProtocolManager::charsetFor(const KUrl& url)
QString KProtocolManager::charsetFor(const KUrl &url)
{
return KIO::SlaveConfig::self()->configData(url.scheme(), url.host(), QLatin1String("Charset"));
}

View file

@ -30,23 +30,22 @@ class KSharedConfig;
template<class T>
class KSharedPtr;
typedef KSharedPtr<KSharedConfig> KSharedConfigPtr;
namespace KIO
{
class SlaveConfigPrivate;
} // namespace KIO
/**
* Provides information about I/O (Internet, etc.) settings chosen/set
* by the end user.
* Provides information about I/O (Internet, etc.) settings chosen/set by the end user.
*
* KProtocolManager has a heap of static functions that allows only read
* access to KDE's IO related settings. These include proxy, file
* transfer resumption, timeout and user-agent related settings.
* KProtocolManager has a heap of static functions that allows only read access to KDE's IO related
* settings. These include proxy, file transfer resumption, timeout and user-agent related
* settings.
*
* The information provided by this class is generic enough to be applicable
* to any application that makes use of KDE's IO sub-system. Note that this
* mean the proxy, timeout etc. settings are saved in a separate user-specific
* config file and not in the config file of the application.
* The information provided by this class is generic enough to be applicable to any application
* that makes use of KDE's IO sub-system. Note that this mean the proxy, timeout etc. settings
* are saved in a separate user-specific config file and not in the config file of the application.
*
* Original author:
* @author Torben Weis <weis@kde.org>
@ -54,454 +53,246 @@ namespace KIO
* Revised by:
* @author Waldo Bastain <bastain@kde.org>
* @author Dawit Alemayehu <adawit@kde.org>
* @see KPAC
*/
class KIO_EXPORT KProtocolManager
{
public:
/*=========================== USER-AGENT SETTINGS ===========================*/
/**
* Returns the default user-agent string used for web browsing.
*/
static QString defaultUserAgent();
/*=========================== TIMEOUT CONFIG ================================*/
/**
* Returns the preferred timeout value for reading from remote connections in seconds.
*/
static int readTimeout();
/*=========================== USER-AGENT SETTINGS ===========================*/
/**
* Returns the preferred timeout value for remote connections in seconds.
*/
static int connectTimeout();
/**
* Returns the preferred response timeout value for remote connecting in seconds.
*/
static int responseTimeout();
/**
* Returns the default user-agent string used for web browsing.
*
* @return the default user-agent string
*/
static QString defaultUserAgent();
/*============================ DOWNLOAD CONFIG ==============================*/
/**
* Returns true if partial downloads should be automatically resumed.
*/
static bool autoResume();
/**
* Returns the default user-agent value used for web browsing, for example
* "Mozilla/5.0 (compatible; Konqueror/4.0; Linux; X11; i686; en_US) KHTML/4.0.1 (like Gecko)"
*
* @param keys can be any of the following:
* @li 'o' Show OS
* @li 'v' Show OS Version
* @li 'p' Show platform (only for X11)
* @li 'm' Show machine architecture
* @li 'l' Show language
* @return the default user-agent value with the given @p keys
*/
static QString defaultUserAgent(const QString &keys);
/**
* Returns true if partial downloads should be marked with a ".part" extension.
*/
static bool markPartial();
/*
* Returns system name, version and machine type, for example "Windows", "5.1", "i686".
* This information can be used for constructing custom user-agent strings.
*
* @param systemName system name
* @param systemVersion system version
* @param machine machine type
/**
* Returns the minimum file size for keeping aborted downloads.
*
* Any data downloaded that does not meet this minimum requirement will simply be discarded.
* The default size is 5 KB.
*/
static int minimumKeepSize();
* @return true if system name, version and machine type has been provided
*
* @since 4.1
*/
static bool getSystemNameVersionAndMachine(
QString& systemName, QString& systemVersion, QString& machine );
/*===================== PROTOCOL CAPABILITIES ===============================*/
/**
* Returns whether the protocol can list files/objects. If a protocol supports listing it can
* be browsed in e.g. file managers.
*
* Whether a protocol supports listing is determined by the "listing=" field in the protocol
* description file. If the protocol support listing it should list the fields it provides in
* this field. If the protocol does not support listing this field should remain empty
* (default).
*
* @param url the url to check
*/
static bool supportsListing(const KUrl &url);
/**
* Returns whether the protocol can retrieve data from URLs.
*
* This corresponds to the "reading=" field in the protocol description file. Valid values for
* this field are "true" or "false" (default).
*
* @param url the url to check
*/
static bool supportsReading(const KUrl &url);
/*=========================== TIMEOUT CONFIG ================================*/
/**
* Returns whether the protocol can store data to URLs.
*
* This corresponds to the "writing=" field in the protocol description file. Valid values for
* this field are "true" or "false" (default).
*
* @param url the url to check
*/
static bool supportsWriting(const KUrl &url);
/**
* Returns whether the protocol can create directories/folders.
*
* This corresponds to the "makedir=" field in the protocol description file. Valid values for
* this field are "true" or "false" (default).
*
* @param url the url to check
*/
static bool supportsMakeDir(const KUrl &url);
/**
* Returns the preferred timeout value for reading from
* remote connections in seconds.
*
* @return timeout value for remote connection in secs.
*/
static int readTimeout();
/**
* Returns whether the protocol can delete files/objects.
*
* This corresponds to the "deleting=" field in the protocol description file. Valid values for
* this field are "true" or "false" (default).
*
* @param url the url to check
*/
static bool supportsDeleting(const KUrl &url);
/**
* Returns the preferred timeout value for remote connections
* in seconds.
*
* @return timeout value for remote connection in secs.
*/
static int connectTimeout();
/**
* Returns whether the protocol can create links between files/objects.
*
* This corresponds to the "linking=" field in the protocol description file. Valid values for
* this field are "true" or "false" (default).
*
* @param url the url to check
*/
static bool supportsLinking(const KUrl &url);
/**
* Returns the preferred timeout value for proxy connections
* in seconds.
*
* @return timeout value for proxy connection in secs.
*/
static int proxyConnectTimeout();
/**
* Returns whether the protocol can move files/objects between different locations.
*
* This corresponds to the "moving=" field in the protocol description file. Valid values for
* this field are "true" or "false" (default).
*
* @param url the url to check
*/
static bool supportsMoving(const KUrl &url);
/**
* Returns the preferred response timeout value for
* remote connecting in seconds.
*
* @return timeout value for remote connection in seconds.
*/
static int responseTimeout();
/**
* Returns whether the protocol can copy files/objects directly from the filesystem itself. If
* not, the application will read files from the filesystem using the file-protocol and pass
* the data on to the destination protocol.
*
* This corresponds to the "copyFromFile=" field in the protocol description file. Valid values
* for this field are "true" or "false" (default).
*
* @param url the url to check
*/
static bool canCopyFromFile(const KUrl &url);
/**
* Returns whether the protocol can copy files/objects directly to the filesystem itself. If
* not, the application will receive the data from the source protocol and store it in the
* filesystem using the file-protocol.
*
* This corresponds to the "copyToFile=" field in the protocol description file. Valid values
* for this field are "true" or "false" (default).
*
* @param url the url to check
*/
static bool canCopyToFile(const KUrl &url);
/*=============================== PROXY CONFIG ==============================*/
/**
* Returns whether the protocol can rename (i.e. move fast) files/objects directly from the
* filesystem itself. If not, the application will read files from the filesystem using the
* file-protocol and pass the data on to the destination protocol.
*
* This corresponds to the "renameFromFile=" field in the protocol description file. Valid
* values for this field are "true" or "false" (default).
*
* @param url the url to check
*/
static bool canRenameFromFile(const KUrl &url);
/**
* Returns whether the protocol can rename (i.e. move fast) files/objects directly to the
* filesystem itself. If not, the application will receive the data from the source protocol
* and store it in the filesystem using the file-protocol.
*
* This corresponds to the "renameToFile=" field in the protocol description file. Valid values
* for this field are "true" or "false" (default).
*
* @param url the url to check
*/
static bool canRenameToFile(const KUrl &url);
/**
* Returns whether or not the user specified the
* use of proxy server to make connections.
* @return true to use a proxy
*/
static bool useProxy();
/**
* Returns whether the protocol can recursively delete directories by itself. If not (the usual
* case) then KIO will list the directory and delete files and empty directories one by one.
*
* This corresponds to the "deleteRecursive=" field in the protocol description file. Valid
* values for this field are "true" or "false" (default).
*
* @param url the url to check
*/
static bool canDeleteRecursive(const KUrl &url);
/**
* Returns whether or not the proxy server
* lookup should be reversed or not.
* @return true to use a reversed proxy
*/
static bool useReverseProxy();
/**
* This setting defines the strategy to use for generating a filename, when copying a file or
* directory to another directory. By default the destination filename is made out of the
* filename in the source URL. However if the ioslave displays names that are different from
* the filename of the URL (e.g. kio_trash shows foo.txt and uses some internal URL), using
* Name means that the display name (UDS_NAME) will be used to as the filename in the
* destination directory.
*
* This corresponds to the "fileNameUsedForCopying=" field in the protocol description file.
* Valid values for this field are "Name" or "FromURL" (default).
*
* @param url the url to check
*/
static KProtocolInfo::FileNameUsedForCopying fileNameUsedForCopying(const KUrl &url);
/**
* Types of proxy configuration
* @li NoProxy - No proxy is used
* @li ManualProxy - Proxies are manually configured
* @li EnvVarProxy - Use the proxy values set through environment variables.
*/
enum ProxyType
{
NoProxy,
ManualProxy,
EnvVarProxy
};
/**
* Returns default mimetype for this URL based on the protocol, empty string if unknown.
*
* This corresponds to the "defaultMimetype=" field in the protocol description file.
*
* @param url the url to check
*/
static QString defaultMimetype(const KUrl &url);
/**
* Returns the type of proxy configuration that is used.
* @return the proxy type
*/
static ProxyType proxyType();
/**
* Returns whether the protocol can act as a source protocol.
*
* A source protocol retrieves data from or stores data to the location specified by a URL.
* A source protocol (e.g. http) is the opposite of a filter protocol (e.g. filenamesearch).
*
* The "source=" field in the protocol description file determines whether a protocol is a
* source protocol or a filter protocol.
* @param url the url to check
*/
static bool isSourceProtocol(const KUrl &url);
/**
* Returns the strings for hosts that should contacted
* DIRECTLY, bypassing any proxy settings.
* @return a list of (comma-separated) hostnames or partial host
* names
*/
static QString noProxyFor();
/*=============================== OTHERS ====================================*/
/**
* Force a reload of the general config file of io-slaves (kioslaverc).
*/
static void reparseConfiguration();
/**
* Returns the proxy server address for a given
* protocol.
*
* @param protocol the protocol whose proxy info is needed
* @returns the proxy server address if one is available,
* or QString() if not available
*/
static QString proxyFor( const QString& protocol );
/**
* Return Accept-Languages header built up according to user's desktop language settings.
*/
static QString acceptLanguagesHeader();
/**
* Returns the Proxy server address for a given URL.
*
* @ref proxyFor is used to find the proxy to use for the given url.
*
* If this function returns an empty string, then the request to a proxy server
* must be denied. For a direct connection, without the use of a proxy, this
* function will return "DIRECT".
*
* @param url the URL whose proxy info is needed
* @returns the proxy server address if one is available, otherwise a QString().
*/
static QString proxyForUrl( const KUrl& url );
/**
* Returns all the possible proxy server addresses for @p url.
*
* @ref proxyFor is used to find the proxy to use for the given url.
*
* If this function returns empty list, then the request is to a proxy server
* must be denied. For a direct connection, this function will return a single
* entry of "DIRECT".
*
* @since 4.7
*
* @param url the URL whose proxy info is needed
* @returns the proxy server address if one is available, otherwise an empty list .
*/
static QStringList proxiesForUrl( const KUrl& url );
/**
* Marks this proxy as bad (down). It will not be used for the
* next 30 minutes. (The script may supply an alternate proxy)
* @param proxy the proxy to mark as bad (as URL)
*/
static void badProxy( const QString & proxy );
/*============================ DOWNLOAD CONFIG ==============================*/
/**
* Returns true if partial downloads should be
* automatically resumed.
* @return true to resume partial downloads
*/
static bool autoResume();
/**
* Returns true if partial downloads should be marked
* with a ".part" extension.
* @return true if partial downloads should get an ".part" extension
*/
static bool markPartial();
/**
* Returns the minimum file size for keeping aborted
* downloads.
*
* Any data downloaded that does not meet this minimum
* requirement will simply be discarded. The default size
* is 5 KB.
*
* @return the minimum keep size for aborted downloads in bytes
*/
static int minimumKeepSize();
/*===================== PROTOCOL CAPABILITIES ===============================*/
/**
* Returns whether the protocol can list files/objects.
* If a protocol supports listing it can be browsed in e.g. file-dialogs
* and konqueror.
*
* Whether a protocol supports listing is determined by the "listing="
* field in the protocol description file.
* If the protocol support listing it should list the fields it provides in
* this field. If the protocol does not support listing this field should
* remain empty (default.)
*
* @param url the url to check
* @return true if the protocol support listing
* @see listing()
*/
static bool supportsListing( const KUrl &url );
/**
* Returns whether the protocol can retrieve data from URLs.
*
* This corresponds to the "reading=" field in the protocol description file.
* Valid values for this field are "true" or "false" (default).
*
* @param url the url to check
* @return true if it is possible to read from the URL
*/
static bool supportsReading( const KUrl &url );
/**
* Returns whether the protocol can store data to URLs.
*
* This corresponds to the "writing=" field in the protocol description file.
* Valid values for this field are "true" or "false" (default).
*
* @param url the url to check
* @return true if the protocol supports writing
*/
static bool supportsWriting( const KUrl &url );
/**
* Returns whether the protocol can create directories/folders.
*
* This corresponds to the "makedir=" field in the protocol description file.
* Valid values for this field are "true" or "false" (default).
*
* @param url the url to check
* @return true if the protocol can create directories
*/
static bool supportsMakeDir( const KUrl &url );
/**
* Returns whether the protocol can delete files/objects.
*
* This corresponds to the "deleting=" field in the protocol description file.
* Valid values for this field are "true" or "false" (default).
*
* @param url the url to check
* @return true if the protocol supports deleting
*/
static bool supportsDeleting( const KUrl &url );
/**
* Returns whether the protocol can create links between files/objects.
*
* This corresponds to the "linking=" field in the protocol description file.
* Valid values for this field are "true" or "false" (default).
*
* @param url the url to check
* @return true if the protocol supports linking
*/
static bool supportsLinking( const KUrl &url );
/**
* Returns whether the protocol can move files/objects between different
* locations.
*
* This corresponds to the "moving=" field in the protocol description file.
* Valid values for this field are "true" or "false" (default).
*
* @param url the url to check
* @return true if the protocol supports moving
*/
static bool supportsMoving( const KUrl &url );
/**
* Returns whether the protocol can copy files/objects directly from the
* filesystem itself. If not, the application will read files from the
* filesystem using the file-protocol and pass the data on to the destination
* protocol.
*
* This corresponds to the "copyFromFile=" field in the protocol description file.
* Valid values for this field are "true" or "false" (default).
*
* @param url the url to check
* @return true if the protocol can copy files from the local file system
*/
static bool canCopyFromFile( const KUrl &url );
/**
* Returns whether the protocol can copy files/objects directly to the
* filesystem itself. If not, the application will receive the data from
* the source protocol and store it in the filesystem using the
* file-protocol.
*
* This corresponds to the "copyToFile=" field in the protocol description file.
* Valid values for this field are "true" or "false" (default).
*
* @param url the url to check
* @return true if the protocol can copy files to the local file system
*/
static bool canCopyToFile( const KUrl &url );
/**
* Returns whether the protocol can rename (i.e. move fast) files/objects
* directly from the filesystem itself. If not, the application will read
* files from the filesystem using the file-protocol and pass the data on
* to the destination protocol.
*
* This corresponds to the "renameFromFile=" field in the protocol description file.
* Valid values for this field are "true" or "false" (default).
*
* @param url the url to check
* @return true if the protocol can rename/move files from the local file system
*/
static bool canRenameFromFile( const KUrl &url );
/**
* Returns whether the protocol can rename (i.e. move fast) files/objects
* directly to the filesystem itself. If not, the application will receive
* the data from the source protocol and store it in the filesystem using the
* file-protocol.
*
* This corresponds to the "renameToFile=" field in the protocol description file.
* Valid values for this field are "true" or "false" (default).
*
* @param url the url to check
* @return true if the protocol can rename files to the local file system
*/
static bool canRenameToFile( const KUrl &url );
/**
* Returns whether the protocol can recursively delete directories by itself.
* If not (the usual case) then KIO will list the directory and delete files
* and empty directories one by one.
*
* This corresponds to the "deleteRecursive=" field in the protocol description file.
* Valid values for this field are "true" or "false" (default).
*
* @param url the url to check
* @return true if the protocol can delete non-empty directories by itself.
*/
static bool canDeleteRecursive( const KUrl &url );
/**
* This setting defines the strategy to use for generating a filename, when
* copying a file or directory to another directory. By default the destination
* filename is made out of the filename in the source URL. However if the
* ioslave displays names that are different from the filename of the URL
* (e.g. kio_trash shows foo.txt and uses some internal URL), using Name means
* that the display name (UDS_NAME) will be used to as the filename in the
* destination directory.
*
* This corresponds to the "fileNameUsedForCopying=" field in the protocol description file.
* Valid values for this field are "Name" or "FromURL" (default).
*
* @param url the url to check
* @return how to generate the filename in the destination directory when copying/moving
*/
static KProtocolInfo::FileNameUsedForCopying fileNameUsedForCopying( const KUrl &url );
/**
* Returns default mimetype for this URL based on the protocol.
*
* This corresponds to the "defaultMimetype=" field in the protocol description file.
*
* @param url the url to check
* @return the default mime type of the protocol, or null if unknown
*/
static QString defaultMimetype( const KUrl& url );
/**
* Returns whether the protocol can act as a source protocol.
*
* A source protocol retrieves data from or stores data to the
* location specified by a URL.
* A source protocol is the opposite of a filter protocol.
*
* The "source=" field in the protocol description file determines
* whether a protocol is a source protocol or a filter protocol.
* @param url the url to check
* @return true if the protocol is a source of data (e.g. http), false if the
* protocol is a filter (e.g. gzip)
*/
static bool isSourceProtocol( const KUrl &url );
/*=============================== OTHERS ====================================*/
/**
* Force a reload of the general config file of
* io-slaves ( kioslaverc).
*/
static void reparseConfiguration();
/**
* Return the protocol to use in order to handle the given @p url
* It's usually the same, except that FTP, when handled by a proxy,
* needs an HTTP ioslave.
*
* When a proxy is to be used, proxy contains the URL for the proxy.
* @param url the url to check
* @param proxy the URL of the proxy to use
* @return the slave protocol (e.g. 'http'), can be null if unknown
*/
static QString slaveProtocol(const KUrl &url, QString &proxy);
/**
* Overloaded function that returns a list of all available proxy servers.
*
* @since 4.7
*/
static QString slaveProtocol(const KUrl &url, QStringList &proxy);
/**
* Return Accept-Languages header built up according to user's desktop
* language settings.
* @return Accept-Languages header string
*/
static QString acceptLanguagesHeader();
/**
* Returns the charset to use for the specified @ref url.
*
* @since 4.10
*/
static QString charsetFor(const KUrl& url);
/**
* Returns the charset to use for the specified @ref url.
*
* @since 4.10
*/
static QString charsetFor(const KUrl &url);
private:
friend class KIO::SlaveConfigPrivate;
friend class KIO::SlaveConfigPrivate;
/**
* @internal
* (Shared with SlaveConfig)
*/
KIO_NO_EXPORT static KSharedConfigPtr config();
/**
* @internal
* (Shared with SlaveConfig)
*/
KIO_NO_EXPORT static KSharedConfigPtr config();
};
#endif
#endif // KPROTOCOLMANAGER_H

View file

@ -61,8 +61,7 @@ static inline void startJob(SimpleJob *job, SlaveInterface *slave)
// here be uglies
// forward declaration to break cross-dependency of SlaveKeeper and SchedulerPrivate
static void setupSlave(KIO::SlaveInterface *slave, const KUrl &url, const QString &protocol,
const QStringList &proxyList, bool newSlave);
static void setupSlave(KIO::SlaveInterface *slave, const KUrl &url, const QString &protocol, bool newSlave);
// same reason as above
static Scheduler *scheduler();
@ -511,7 +510,7 @@ void ProtoQueue::startAJob()
if (slave) {
jobPriv->m_slave = slave;
setupSlave(slave, jobPriv->m_url, jobPriv->m_protocol, jobPriv->m_proxyList, isNewSlave);
setupSlave(slave, jobPriv->m_url, jobPriv->m_protocol, isNewSlave);
startJob(startingJob, slave);
} else {
// dispose of our records about the job and mark the job as unknown
@ -569,9 +568,7 @@ public:
void jobFinished(KIO::SimpleJob *job, KIO::SlaveInterface *slave);
void registerWindow(QWidget *wid);
MetaData metaDataFor(const QString &protocol, const QStringList &proxyList, const KUrl &url);
void setupSlave(KIO::SlaveInterface *slave, const KUrl &url, const QString &protocol,
const QStringList &proxyList, bool newSlave);
void setupSlave(KIO::SlaveInterface *slave, const KUrl &url, const QString &protocol, bool newSlave);
void slotSlaveDied(KIO::SlaveInterface *slave);
@ -722,8 +719,7 @@ void SchedulerPrivate::doJob(SimpleJob *job)
}
KIO::SimpleJobPrivate *const jobPriv = SimpleJobPrivate::get(job);
jobPriv->m_proxyList.clear();
jobPriv->m_protocol = KProtocolManager::slaveProtocol(job->url(), jobPriv->m_proxyList);
jobPriv->m_protocol = job->url().protocol();
ProtoQueue *proto = protoQ(jobPriv->m_protocol, job->url().host());
proto->queueJob(job);
@ -780,30 +776,12 @@ void SchedulerPrivate::jobFinished(SimpleJob *job, SlaveInterface *slave)
}
// static
void setupSlave(KIO::SlaveInterface *slave, const KUrl &url, const QString &protocol,
const QStringList &proxyList , bool newSlave)
void setupSlave(KIO::SlaveInterface *slave, const KUrl &url, const QString &protocol, bool newSlave)
{
schedulerPrivate->setupSlave(slave, url, protocol, proxyList, newSlave);
schedulerPrivate->setupSlave(slave, url, protocol, newSlave);
}
MetaData SchedulerPrivate::metaDataFor(const QString &protocol, const QStringList &proxyList, const KUrl &url)
{
const QString host = url.host();
MetaData configData = SlaveConfig::self()->configData(protocol, host);
sessionData.configDataFor( configData, protocol );
if (proxyList.isEmpty()) {
configData.remove(QLatin1String("UseProxy"));
configData.remove(QLatin1String("ProxyUrls"));
} else {
configData[QLatin1String("UseProxy")] = proxyList.first();
configData[QLatin1String("ProxyUrls")] = proxyList.join(QLatin1String(","));
}
return configData;
}
void SchedulerPrivate::setupSlave(KIO::SlaveInterface *slave, const KUrl &url, const QString &protocol,
const QStringList &proxyList, bool newSlave)
void SchedulerPrivate::setupSlave(KIO::SlaveInterface *slave, const KUrl &url, const QString &protocol, bool newSlave)
{
int port = url.port();
if ( port == -1 ) // no port is -1 in QUrl, but in kde3 we used 0 and the kioslaves assume that.
@ -814,8 +792,8 @@ void SchedulerPrivate::setupSlave(KIO::SlaveInterface *slave, const KUrl &url, c
if (newSlave || slave->host() != host || slave->port() != port ||
slave->user() != user || slave->passwd() != passwd) {
MetaData configData = metaDataFor(protocol, proxyList, url);
MetaData configData = SlaveConfig::self()->configData(protocol, host);
sessionData.configDataFor( configData, protocol );
slave->setConfig(configData);
slave->setProtocol(url.protocol());
slave->setHost(host, port, user, passwd);

View file

@ -1107,17 +1107,6 @@ int SlaveBase::connectTimeout()
return DEFAULT_CONNECT_TIMEOUT;
}
int SlaveBase::proxyConnectTimeout()
{
bool ok = false;
QString tmp = metaData(QLatin1String("ProxyConnectTimeout"));
int result = tmp.toInt(&ok);
if (ok) {
return result;
}
return DEFAULT_PROXY_CONNECT_TIMEOUT;
}
int SlaveBase::responseTimeout()
{
bool ok = false;

View file

@ -502,11 +502,6 @@ public:
*/
int connectTimeout();
/**
* @return timeout value for connecting to proxy in secs.
*/
int proxyConnectTimeout();
/**
* @return timeout value for read from first data from
* remote host in seconds.

View file

@ -42,9 +42,5 @@ int main(int argc, char **argv) {
assert( KProtocolInfo::showFilePreview( "http" ) == false );
assert( KGlobalSettings::showFilePreview( KUrl( "http:/" ) ) == false );
QString proxy;
QString protocol = KProtocolManager::slaveProtocol( KUrl( "http://bugs.kde.org" ), proxy );
assert( protocol == "http" );
return 0;
}

View file

@ -9,7 +9,6 @@ writing=true
makedir=true
deleting=true
moving=true
ProxiedBy=http
Icon=folder-remote
maxInstances=20
maxInstancesPerHost=5

View file

@ -9,7 +9,6 @@ writing=true
makedir=false
deleting=false
moving=false
ProxiedBy=http
Icon=text-html
maxInstances=20
maxInstancesPerHost=5

View file

@ -9,7 +9,6 @@ writing=true
makedir=false
deleting=false
moving=false
ProxiedBy=http
Icon=text-html
maxInstances=20
maxInstancesPerHost=5

View file

@ -149,38 +149,6 @@ qlonglong ftpTimeFromString(const QByteArray &ftpmonth, const QByteArray &ftpday
return ftpdatetime.toTime_t();
}
static inline QByteArray curlProxyBytes(const QString &proxy)
{
const KUrl proxyurl(proxy);
const QString proxyhost = proxyurl.host();
if (proxyurl.port() > 0) {
QByteArray curlproxybytes = proxyhost.toAscii();
curlproxybytes.append(':');
curlproxybytes.append(QByteArray::number(proxyurl.port()));
return curlproxybytes;
}
return proxyhost.toAscii();
}
static inline curl_proxytype curlProxyType(const QString &proxy)
{
const QString proxyprotocol = KUrl(proxy).protocol();
#if CURL_AT_LEAST_VERSION(7, 52, 0)
if (proxyprotocol.startsWith(QLatin1String("https"))) {
return CURLPROXY_HTTPS;
}
#endif
if (proxyprotocol.startsWith(QLatin1String("socks4"))) {
return CURLPROXY_SOCKS4;
} else if (proxyprotocol.startsWith(QLatin1String("socks4a"))) {
return CURLPROXY_SOCKS4A;
} else if (proxyprotocol.startsWith(QLatin1String("socks5"))) {
return CURLPROXY_SOCKS5;
}
return CURLPROXY_HTTP;
}
static inline QString HTTPMIMEType(const QString &contenttype)
{
const QList<QString> splitcontenttype = contenttype.split(QLatin1Char(';'));
@ -1019,29 +987,12 @@ bool CurlProtocol::setupCurl(const KUrl &url, const bool ftp)
}
const bool noauth = (metaData("no-auth") == QLatin1String("yes"));
if (hasMetaData(QLatin1String("UseProxy"))) {
const QString proxystring = metaData("UseProxy");
const QByteArray proxybytes = curlProxyBytes(proxystring);
const curl_proxytype curlproxytype = curlProxyType(proxystring);
kDebug(7103) << "Proxy" << proxybytes << curlproxytype;
curlresult = curl_easy_setopt(m_curl, CURLOPT_PROXY, proxybytes.constData());
if (curlresult != CURLE_OK) {
KIO_CURL_ERROR(curlresult);
return false;
}
curlresult = curl_easy_setopt(m_curl, CURLOPT_PROXYTYPE, curlproxytype);
if (curlresult != CURLE_OK) {
KIO_CURL_ERROR(curlresult);
return false;
}
const bool noproxyauth = (noauth || metaData("no-proxy-auth") == QLatin1String("yes"));
kDebug(7103) << "No proxy auth" << noproxyauth;
curlresult = curl_easy_setopt(m_curl, CURLOPT_PROXYAUTH, noproxyauth ? CURLAUTH_NONE : CURLAUTH_ANY);
if (curlresult != CURLE_OK) {
KIO_CURL_ERROR(curlresult);
return false;
}
const bool noproxyauth = (noauth || metaData("no-proxy-auth") == QLatin1String("yes"));
kDebug(7103) << "No proxy auth" << noproxyauth;
curlresult = curl_easy_setopt(m_curl, CURLOPT_PROXYAUTH, noproxyauth ? CURLAUTH_NONE : CURLAUTH_ANY);
if (curlresult != CURLE_OK) {
KIO_CURL_ERROR(curlresult);
return false;
}
const bool nowwwauth = (noauth || metaData("no-www-auth") == QLatin1String("true"));

View file

@ -9,7 +9,6 @@ writing=true
makedir=true
deleting=true
moving=true
ProxiedBy=http
Icon=folder-remote
maxInstances=20
maxInstancesPerHost=5