23 #include "config-kpac.h"
36 #include <solid/networking.h>
39 #include <QtCore/QFileSystemWatcher>
45 registerPlugin<KPAC::ProxyScout>();
58 static ProxyType proxyTypeFor(
const QString& mode)
60 if (mode.compare(QLatin1String(
"PROXY"), Qt::CaseInsensitive) == 0)
63 if (mode.compare(QLatin1String(
"DIRECT"), Qt::CaseInsensitive) == 0)
66 if (mode.compare(QLatin1String(
"SOCKS"), Qt::CaseInsensitive) == 0 ||
67 mode.compare(QLatin1String(
"SOCKS5"), Qt::CaseInsensitive) == 0)
73 ProxyScout::QueuedRequest::QueuedRequest(
const QDBusMessage &reply,
const KUrl& u,
bool sendall )
74 : transaction( reply ), url( u ), sendAll(sendall)
80 m_componentData(
"proxyscout"),
88 connect (Solid::Networking::notifier(), SIGNAL(shouldDisconnect()), SLOT(disconnectNetwork()));
92 ProxyScout::~ProxyScout()
97 QStringList ProxyScout::proxiesForUrl(
const QString& checkUrl,
const QDBusMessage &msg )
102 if ( std::time( 0 ) - m_suspendTime < 300 ) {
114 return handleRequest(url);
117 if (m_downloader || startDownload()) {
118 msg.setDelayedReply(
true);
119 m_requestQueue.append( QueuedRequest( msg, url,
true ) );
126 QString ProxyScout::proxyForUrl(
const QString& checkUrl,
const QDBusMessage &msg )
131 if ( std::time( 0 ) - m_suspendTime < 300 ) {
132 return QLatin1String(
"DIRECT");
139 return QLatin1String(
"DIRECT");
143 return handleRequest(url).first();
146 if (m_downloader || startDownload()) {
147 msg.setDelayedReply(
true);
148 m_requestQueue.append( QueuedRequest( msg, url ) );
152 return QLatin1String(
"DIRECT");
155 void ProxyScout::blackListProxy(
const QString& proxy )
157 m_blackList[ proxy ] = std::time( 0 );
160 void ProxyScout::reset()
173 bool ProxyScout::startDownload()
178 if (m_downloader && !qobject_cast<Discovery*>(m_downloader)) {
183 m_downloader =
new Discovery(
this);
184 connect(m_downloader, SIGNAL(result(
bool)),
this, SLOT(downloadResult(
bool)));
188 if (m_downloader && !qobject_cast<Downloader*>(m_downloader)) {
193 m_downloader =
new Downloader(
this);
194 connect(m_downloader, SIGNAL(result(
bool)),
this, SLOT(downloadResult(
bool)));
200 m_watcher =
new QFileSystemWatcher(
this);
201 connect (m_watcher, SIGNAL(fileChanged(
QString)), SLOT(proxyScriptFileChanged(
QString)));
203 proxyScriptFileChanged(url.
path());
207 m_downloader->download( url );
218 void ProxyScout::disconnectNetwork()
226 void ProxyScout::downloadResult(
bool success )
232 m_script =
new Script(m_downloader->script());
235 catch (
const Script::Error& e )
237 kWarning() <<
"Error:" << e.message();
239 notify->
setText(
i18n(
"The proxy configuration script is invalid:\n%1" , e.message() ) );
246 notify->
setText( m_downloader->error() );
252 for (RequestQueue::Iterator it = m_requestQueue.begin(), itEnd = m_requestQueue.end(); it != itEnd; ++it) {
254 const QVariant result (handleRequest((*it).url));
255 QDBusConnection::sessionBus().send((*it).transaction.createReply(result));
257 const QVariant result (handleRequest((*it).url).first());
258 QDBusConnection::sessionBus().send((*it).transaction.createReply(result));
262 for (RequestQueue::Iterator it = m_requestQueue.begin(), itEnd = m_requestQueue.end(); it != itEnd; ++it) {
263 QDBusConnection::sessionBus().send((*it).transaction.createReply(QString::fromLatin1(
"DIRECT")));
267 m_requestQueue.clear();
271 m_suspendTime = std::time( 0 );
275 void ProxyScout::proxyScriptFileChanged(
const QString& path)
281 if (!m_watcher->files().isEmpty()) {
282 m_watcher->removePaths(m_watcher->files());
287 m_watcher->addPath(path);
298 const QString result = m_script->evaluate(url).trimmed();
299 const QStringList proxies = result.split(QLatin1Char(
';'), QString::SkipEmptyParts);
300 const int size = proxies.count();
302 for (
int i = 0; i < size; ++i) {
304 const QString proxy = proxies.at(i).trimmed();
305 const int index = proxy.indexOf(QLatin1Char(
' '));
310 mode = proxy.left(index);
311 address = proxy.mid(index + 1).trimmed();
314 const ProxyType type = proxyTypeFor(mode);
319 if (type == Proxy || type == Socks) {
320 const int index = address.indexOf(QLatin1Char(
':'));
322 const QString protocol ((type == Proxy ? QLatin1String(
"http://") : QLatin1String(
"socks://")));
323 const KUrl url (protocol + address);
332 if (type == Direct || !m_blackList.contains(address)) {
333 proxyList << address;
334 }
else if (std::time(0) - m_blackList[address] > 1800) {
336 m_blackList.remove( address );
337 proxyList << address;
341 if (!proxyList.isEmpty()) {
342 kDebug(m_debugArea) << proxyList;
347 catch (
const Script::Error& e )
351 n->
setText(
i18n(
"The proxy configuration script returned an error:\n%1" , e.message() ) );
360 #include "proxyscout.moc"
QString i18n(const char *text)
static void reparseConfiguration()
Force a reload of the general config file of io-slaves ( kioslaverc).
static bool isKnownProtocol(const KUrl &url)
K_PLUGIN_FACTORY(ProxyScoutFactory, registerPlugin< KPAC::ProxyScout >();) namespace KPAC
static QDebug kError(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
static KUrl fromPath(const QString &text)
static QDebug kDebug(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
void setText(const QString &text)
static int registerArea(const QByteArray &areaName, bool enabled=true)
QString path(AdjustPathOption trailing=LeaveTrailingSlash) const
void setComponentData(const KComponentData &componentData)
static QString proxyConfigScript()
Returns the URL of the script for automatic proxy configuration.
static ProxyType proxyType()
Returns the type of proxy configuration that is used.
static QDebug kWarning(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
QString url(AdjustPathOption trailing=LeaveTrailingSlash) const
bool equals(const KUrl &u, const EqualsOptions &options=0) const
#define K_EXPORT_PLUGIN(factory)