kpac_impl.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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
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
00094
00095
00096
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
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
This file is part of the documentation for kdelibs Version 3.1.0.