kio Library API Documentation

kpac_impl.cpp

00001 /*
00002  *  $Id: kpac_impl.cpp,v 1.21.2.1 2003/05/17 11:19:24 mueller Exp $
00003  *  Proxy Auto Configuration
00004  *  
00005  *  Copyright (C) 2000 Malte Starostik <malte@kde.org>
00006  *
00007  *  This library is free software; you can redistribute it and/or
00008  *  modify it under the terms of the GNU Library General Public
00009  *  License as published by the Free Software Foundation; either
00010  *  version 2 of the License, or (at your option) any later version.
00011  *
00012  *  This library is distributed in the hope that it will be useful,
00013  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  *  Library General Public License for more details.
00016  *
00017  *  You should have received a copy of the GNU Library General Public License
00018  *  along with this library; see the file COPYING.LIB.  If not, write to
00019  *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00020  *  Boston, MA 02111-1307, USA.
00021  */
00022 
00023 #include <stdlib.h>
00024 #include <time.h>
00025 
00026 #include <kdebug.h>
00027 #include <kurl.h>
00028 #include <ksimpleconfig.h>
00029 #include <kstandarddirs.h>
00030 #include <kprocess.h>
00031 #include <kjs/object.h>
00032 #include <kjs/types.h>
00033 #include <kjs/interpreter.h>
00034 
00035 #include "kproxybindings.h"
00036 #include "kpac_impl.h"
00037 #include "kpac_downloader.h"
00038 #include "kpac_discovery.h"
00039 
00040 using namespace KJS;
00041 
00042 KPACImpl::KPACImpl()
00043     : m_interpreter(0),
00044       m_configRead(false),
00045       m_inDiscovery(false),
00046       m_downloader(0)
00047 {
00048 }
00049 
00050 KPACImpl::~KPACImpl()
00051 {
00052     delete m_interpreter;
00053 }
00054 
00055 QString KPACImpl::proxyForURL(const KURL &url)
00056 {
00057     kdDebug(7025) << "KPACImpl::proxyForURL(), url=" << url.prettyURL() << endl;
00058 
00059     QString p = url.protocol();
00060     if (p != "http" && p != "https" && p != "ftp" && p != "gopher")
00061       return "DIRECT";
00062 
00063     if (!m_configRead)
00064     {
00065         kdDebug(7025) << "KPACImpl::proxyForURL(): config not (yet) read, not using a proxy" << endl;
00066         return QString::null;
00067     }
00068     // don't use "return FindProxyForURL('%1','%2')" here - it breaks with URLs containing %20
00069     QString code = QString("return FindProxyForURL('" ) + url.url() + "', '" + url.host() + "');";
00070     UString ucode = code.local8Bit().data();
00071     Completion comp = m_interpreter->evaluate(ucode);
00072     if (comp.complType() == Throw)
00073     {
00074         kdDebug(7025) << "KPACImpl::proxyForURL(): JS evaluation error, not using a proxy" << endl;
00075         return QString::null;
00076     }
00077     else if (comp.complType() == ReturnValue)
00078     {
00079         QString val = comp.value().toString(m_interpreter->globalExec()).qstring();
00080         QStringList proxies = QStringList::split(';', val);
00081         if (!proxies.count())
00082         {
00083             kdDebug(7025) << "KPACImpl::proxyForULR(): JS returned an empty string, not using a proxy" << endl;
00084             return QString::null;
00085         }
00086         KSimpleConfig blackList(locate("tmp", "badproxies"));
00087         for (QStringList::ConstIterator it = proxies.begin(); it != proxies.end(); ++it)
00088         {
00089             QString proxy = (*it).simplifyWhiteSpace();
00090             if (proxy.left(5) == "PROXY")
00091             {
00092                 KURL proxyURL(proxy = proxy.mid(5).stripWhiteSpace());
00093                 // If the URL is invalid or the URL is valid but in opaque
00094                 // format which indicates a port number being present in
00095                 // this particular case, simply calling setProtocol() on
00096                 // it trashes the whole URL.
00097                 int len = proxyURL.protocol().length();
00098                 if (!proxyURL.isValid() || proxy.find(":/", len) != len)
00099                     proxy.prepend("http://");
00100                 time_t badMark = blackList.readNumEntry(proxy);
00101                 if (badMark < time(0) - 1800)
00102                 {
00103                     if (badMark)
00104                         blackList.deleteEntry(proxy, false);
00105                     kdDebug(7025) << "KPACImpl::proxyForURL(): returning " << proxy << endl;
00106                     return proxy;
00107                 }
00108             }
00109             else if (proxy.left(5) == "SOCKS")
00110             {
00111                 // FIXME
00112                 kdWarning(7025) << "KPACImpl::proxyForURL(): SOCKS support not implemented yet" << endl;
00113                 return "DIRECT";
00114             }
00115             else if (proxy == "DIRECT")
00116             {
00117                 kdDebug(7025) << "KPACImpl::proxyForURL(): returning DIRECT" << endl;
00118                 return proxy;
00119             }
00120         }
00121     }
00122     kdDebug(7025) << "KPACImpl::proxyForURL(): didn't find a proxy" << endl;
00123     return QString::null;
00124 }
00125 
00126 bool KPACImpl::init(const KURL &url)
00127 {
00128     kdDebug(7025) << "KPACImpl::init()" << endl;
00129     if (m_configRead)
00130     {
00131         delete m_interpreter;
00132         m_interpreter = 0;
00133         m_configRead = false;
00134     }
00135 
00136     bool ownDownloader = m_downloader == 0;
00137     if (ownDownloader)
00138         m_downloader = new KPACDownloader;
00139 
00140     if (m_downloader->download(url))
00141     {
00142         if (!m_interpreter)
00143         {
00144             m_interpreter = new Interpreter();
00145             Object global(m_interpreter->globalObject());
00146             KProxyFunc::init(m_interpreter->globalExec(),global);
00147         }
00148         UString code = m_downloader->data().data();
00149         Completion comp = m_interpreter->evaluate(code);
00150         m_configRead = (comp.complType() != Throw);
00151         if (!m_configRead)
00152         {
00153             kdError(7025) << "KPACImpl::init(): JS error in config file" << endl;
00154             delete m_interpreter;
00155             m_interpreter = 0;
00156         }
00157     }
00158     else
00159         kdError(7025) << "KPACImpl::init(): couldn't download proxy config script " << url.url() << endl;
00160     if (ownDownloader)
00161     {
00162         delete m_downloader;
00163         m_downloader = 0;
00164     }
00165 
00166     return m_configRead;
00167 }
00168 
00169 bool KPACImpl::discover()
00170 {
00171     if (m_inDiscovery)
00172         return false;
00173     m_inDiscovery = true;
00174     bool success = false;
00175     KPACDiscovery discovery;
00176     m_downloader = new KPACDownloader;
00177     while (discovery.tryDiscovery())
00178     {
00179         if ((success = init(discovery.curl())))
00180             break;
00181     }
00182     delete m_downloader;
00183     m_downloader = 0;
00184     m_inDiscovery = false;
00185     return success;
00186 }
00187 
00188 void KPACImpl::badProxy(const QString &proxy)
00189 {
00190     kdDebug(7025) << "KPACImpl::badProxy(), proxy=" << proxy << endl;
00191     KSimpleConfig blackList(locateLocal("tmp", "badproxies"));
00192     blackList.writeEntry(proxy, time(0));
00193 }
00194 
00195 extern "C"
00196 {
00197     KPAC *create_pac()
00198     {
00199         return new KPACImpl;
00200     }
00201 }
00202 
00203 // vim: ts=4 sw=4 et
KDE Logo
This file is part of the documentation for kdelibs Version 3.1.5.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Wed Jan 28 13:13:53 2004 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001