From 0d00344e303b3abdaca219160c51eab447efc959 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20W=C3=A4ckerlin?= Date: Wed, 11 Mar 2009 15:37:56 +0000 Subject: [PATCH] works with comol/updater --- autoproxy.hxx | 175 ++++++++++++++++++++++++++++++++++++++++-- proxyface/unix.hxx | 4 +- proxyface/windoze.hxx | 19 ++--- test.cxx | 14 ++-- 4 files changed, 185 insertions(+), 27 deletions(-) diff --git a/autoproxy.hxx b/autoproxy.hxx index ac572a1..4929639 100644 --- a/autoproxy.hxx +++ b/autoproxy.hxx @@ -8,8 +8,18 @@ #ifndef PROXYFACE_HXX #define PROXYFACE_HXX +#ifdef QT_NETWORK_LIB +#include +#include +#include +#include +#include +#include +#endif + #include #include +#include //! auto proxy configuration namespace proxy { @@ -35,9 +45,20 @@ namespace proxy { SOCKS //>port; + } + Type type; + std::string host; + unsigned int port; + }; + //! List of proxies, type -> url and port - typedef std::list< std::pair > > - List; + typedef std::list List; //! Unified Interface for accessing proxy::Face /*! Abstract interface, impementation for Unix and Windoze differs. @@ -49,15 +70,157 @@ namespace proxy { proxy::Auto pf; // keep for program life time (because of caching) proxy::List pf.proxies("http://swisssign.com"); [...] // set proxy, read from http://swisssign.com - @endcode */ - class Interface { + @endcode + + @example test.cxx */ + class Interface +#ifdef QT_NETWORK_LIB + : public QObject +#endif + { +#ifdef QT_NETWORK_LIB + Q_OBJECT; +#endif public: //! Keep your instance as long as possible, because of caching. - Interface() {} + Interface() { +#ifdef QT_NETWORK_LIB + if (!connect(&_timeout, SIGNAL(timeout()), SLOT(timeout()))) + qFatal("connect failed"); +#endif + } virtual ~Interface() {} //! Get list of proxies for a given URL. - /*! @throw a child of std::exception if anything fails */ virtual List proxies(const std::string& url) = 0; +#ifdef QT_NETWORK_LIB + //! If Qt Network is available you may check the proxies found + /*! First checks for direct access to the target. If this is not + possible, starts scan for proxies. + + Returns immediately and signals proxyFound() if a valid + configuration has been found, or proxyError() in case of + timeout. You should wait for either of the signals, before you + can call this method again. + + @param url the url to find a proxy for + @param timeout [ms] time to give up search */ + void proxy(const std::string& url, int timeout=2000) { + qDebug()<<"Search proxy for URL, direct and default" + <<"url="<second.first; + _requests.clear(); + _direct = true; // first try direct access + QNetworkProxy directProxy(QNetworkProxy::NoProxy); + setupProxyCheck(directProxy, url); + QNetworkProxy defaultProxy; + setupProxyCheck(defaultProxy, url); + _timeout.setSingleShot(true); + _timeout.setInterval(timeout); + _timeout.start(); + } + //! If Qt Network is available you may check the proxies found + /*! @copydoc proxy(const std::string&, int) */ + void proxy(const QUrl& url, int timeout=2000) { + proxy(url.toString().toStdString(), timeout); + } + //! If Qt Network is available you may check the proxies found + /*! @copydoc proxy(const std::string&, int) */ + void proxy(const QString& url, int timeout=2000) { + proxy(url.toStdString(), timeout); + } + static QString toString(const QNetworkProxy& p) { + switch (p.type()) { + case QNetworkProxy::NoProxy: + return QString("direct://"); + case QNetworkProxy::DefaultProxy: + if (QNetworkProxy::applicationProxy().type() + !=QNetworkProxy::DefaultProxy) + return QString("Default Proxy: %1") + .arg(toString(QNetworkProxy::applicationProxy())); + else + return QString("Default Proxy: **ERROR**" + " application proxy is configured as" + " QNetworkProxy::DefaultProxy"); + case QNetworkProxy::Socks5Proxy: + return QString("socks://%1:%2").arg(p.hostName()).arg(p.port()); + case QNetworkProxy::HttpProxy: + return QString("http://%1:%2").arg(p.hostName()).arg(p.port()); + case QNetworkProxy::HttpCachingProxy: + return QString("http-cache://%1:%2").arg(p.hostName()).arg(p.port()); + case QNetworkProxy::FtpCachingProxy: + return QString("ftp-cache://%1:%2").arg(p.hostName()).arg(p.port()); + } + return QString("**ERROR** illegal proxy type"); + } + Q_SIGNALS: + //! Signals a valid proxy for the URL requested earlier. + void proxyFound(const QUrl&, const QNetworkProxy&); + //! Signals a timeout, and no valid proxy for the URL requested earlier. + void proxyError(QNetworkReply::NetworkError); + private: + void setupProxyCheck(const QNetworkProxy& prxy, const std::string& url) { + qDebug()<<"Testing proxy for url:"<setProxy(prxy); + if (!connect(manager, SIGNAL(finished(QNetworkReply*)), + this, SLOT(replyFinished(QNetworkReply*)))) + qFatal("connect failed"); + _requests.insert + (std::make_pair(manager->head + (QNetworkRequest + (QUrl(QString::fromStdString(url)))), + std::make_pair(manager, prxy))); + } + private Q_SLOTS: + void timeout() { + _timeout.stop(); + std::string url; + for (Requests::iterator it(_requests.begin()); + it!=_requests.end(); ++it) { + url = it->first->url().toString().toStdString(); + delete it->second.first; + } + _requests.clear(); + qDebug()<<"Proxy detection timed out"<<"url="<type==DEFAULT?QNetworkProxy::DefaultProxy + :(it->type==HTTP?QNetworkProxy::HttpProxy + :(it->type==SOCKS?QNetworkProxy::Socks5Proxy + :QNetworkProxy::NoProxy))), + QString::fromStdString(it->host), it->port); + setupProxyCheck(prxy, url); + } + _timeout.start(); + } else { + qDebug()<<"No proxy at all, giving up - offline?"; + proxyError(QNetworkReply::TimeoutError); + } + } + void replyFinished(QNetworkReply* reply) { + _timeout.stop(); + QNetworkProxy prxy(_requests[reply].second); + QUrl url(reply->url()); + for (Requests::iterator it(_requests.begin()); it!=_requests.end(); ++it) + delete it->second.first; + _requests.clear(); + qDebug()<<"SUCCESS - Valid proxy found for url:" + <<"url="< > + Requests; + Requests _requests; + bool _direct; + QTimer _timeout; +#endif }; } diff --git a/proxyface/unix.hxx b/proxyface/unix.hxx index d2bdb03..8de595b 100644 --- a/proxyface/unix.hxx +++ b/proxyface/unix.hxx @@ -16,7 +16,7 @@ extern "C" { namespace proxy { - class Unix: Interface { + class Unix: public Interface { public: @@ -43,7 +43,7 @@ namespace proxy { std::string host(proxy.substr(0, proxy.rfind(":"))); std::cout<<"Proxy found: "< found " - <<(p.begin()->first==proxy::DIRECT?"DIRECT" - :(p.begin()->first==proxy::DEFAULT?"DEFAULT" - :(p.begin()->first==proxy::HTTP?"HTTP" - :(p.begin()->first==proxy::SOCKS?"SOCKS":"**ERROR**")))) - <<" proxy host: "<second.first - <<" (Port: "<second.second<<")"<type==proxy::DIRECT?"DIRECT" + :(p.begin()->type==proxy::DEFAULT?"DEFAULT" + :(p.begin()->type==proxy::HTTP?"HTTP" + :(p.begin()->type==proxy::SOCKS?"SOCKS":"**ERROR**")))) + <<" proxy host: "<host + <<" (Port: "<port<<")"<