From 39050ebb4c303cda2afda189efa6ac417ad4dce6 Mon Sep 17 00:00:00 2001 From: Duncan Mac-Vicar P Date: Mon, 22 Nov 2010 13:44:39 +0100 Subject: [PATCH] libproxy implementation for ProxyInfo. Right now it is used if libproxy is present. We need to improve this, and either read sysconfig in a libproxy reader or another solution and get rid of the ifdefs. --- CMakeLists.txt | 8 +++ zypp/CMakeLists.txt | 8 +++ zypp/media/MediaCurl.cc | 28 +++++----- zypp/media/proxyinfo/ProxyInfoLibproxy.cc | 88 +++++++++++++++++++++++++++++++ zypp/media/proxyinfo/ProxyInfoLibproxy.h | 57 ++++++++++++++++++++ zypp/media/proxyinfo/ProxyInfos.h | 3 ++ 6 files changed, 180 insertions(+), 12 deletions(-) create mode 100644 zypp/media/proxyinfo/ProxyInfoLibproxy.cc create mode 100644 zypp/media/proxyinfo/ProxyInfoLibproxy.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 0629b1f..fffec8f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -110,6 +110,14 @@ FIND_PACKAGE(EXPAT REQUIRED) FIND_PACKAGE(OpenSSL REQUIRED) FIND_PACKAGE(Udev REQUIRED) +FIND_PACKAGE(libproxy) +IF ( NOT LIBPROXY_FOUND ) + MESSAGE( FATAL_ERROR " libproxy not found" ) +ELSE ( NOT LIBPROXY_FOUND ) + INCLUDE_DIRECTORIES( ${LIBPROXY_INCLUDE_DIR} ) + ADD_DEFINITIONS(-D_WITH_LIBPROXY_SUPPORT_) +ENDIF( NOT LIBPROXY_FOUND ) + FIND_PROGRAM( DOXYGEN doxygen ) IF ( NOT DOXYGEN ) MESSAGE( FATAL_ERROR "doxygen not found: install doxygen to build the documentation." ) diff --git a/zypp/CMakeLists.txt b/zypp/CMakeLists.txt index d4f4682..7a0aebc 100644 --- a/zypp/CMakeLists.txt +++ b/zypp/CMakeLists.txt @@ -324,13 +324,20 @@ INSTALL( FILES DESTINATION ${CMAKE_INSTALL_PREFIX}/include/zypp/media ) +IF ( LIBPROXY_FOUND ) + SET(zypp_media_proxyinfo_libproxy_SRCS media/proxyinfo/ProxyInfoLibproxy.cc) + SET(zypp_media_proxyinfo_libproxy_HEADERS media/proxyinfo/ProxyInfoLibproxy.h) +ENDIF( LIBPROXY_FOUND ) + SET( zypp_media_proxyinfo_SRCS media/proxyinfo/ProxyInfoSysconfig.cc + ${zypp_media_proxyinfo_libproxy_SRCS} ) SET( zypp_media_proxyinfo_HEADERS media/proxyinfo/ProxyInfoImpl.h media/proxyinfo/ProxyInfoSysconfig.h + ${zypp_media_proxyinfo_libproxy_HEADERS} media/proxyinfo/ProxyInfos.h ) @@ -912,6 +919,7 @@ TARGET_LINK_LIBRARIES(zypp ${OPENSSL_LIBRARIES} ) TARGET_LINK_LIBRARIES(zypp ${CRYPTO_LIBRARIES} ) TARGET_LINK_LIBRARIES(zypp ${SIGNALS_LIBRARY} ) TARGET_LINK_LIBRARIES(zypp ${UDEV_LIBRARY} ) +TARGET_LINK_LIBRARIES(zypp ${LIBPROXY_LIBRARIES} ) INSTALL(TARGETS zypp LIBRARY DESTINATION ${LIB_INSTALL_DIR} ) diff --git a/zypp/media/MediaCurl.cc b/zypp/media/MediaCurl.cc index bf06908..0699e59 100644 --- a/zypp/media/MediaCurl.cc +++ b/zypp/media/MediaCurl.cc @@ -295,7 +295,7 @@ void fillSettingsFromUrl( const Url &url, TransferSettings &s ) } s.setProxy(proxy); s.setProxyEnabled(true); - } + } } // HTTP authentication type @@ -326,7 +326,11 @@ void fillSettingsFromUrl( const Url &url, TransferSettings &s ) */ void fillSettingsSystemProxy( const Url&url, TransferSettings &s ) { +#ifdef _WITH_LIBPROXY_SUPPORT_ + ProxyInfo proxy_info (ProxyInfo::ImplPtr(new ProxyInfoLibproxy())); +#else ProxyInfo proxy_info (ProxyInfo::ImplPtr(new ProxyInfoSysconfig("proxy"))); +#endif s.setProxyEnabled( proxy_info.useProxyFor( url ) ); if ( s.proxyEnabled() ) s.setProxy(proxy_info.proxy(url)); @@ -465,9 +469,9 @@ Url MediaCurl::clearQueryString(const Url &url) const TransferSettings & MediaCurl::settings() { - return _settings; + return _settings; } - + void MediaCurl::setCookieFile( const Pathname &fileName ) { @@ -487,17 +491,17 @@ void MediaCurl::checkProtocol(const Url &url) const std::string scheme( url.getScheme()); bool found = false; for(proto=curl_info->protocols; !found && *proto; ++proto) - { + { if( scheme == std::string((const char *)*proto)) found = true; - } + } if( !found) - { + { std::string msg("Unsupported protocol '"); msg += scheme; - msg += "'"; + msg += "'"; ZYPP_THROW(MediaBadUrlException(_url, msg)); - } + } } } @@ -525,7 +529,7 @@ void MediaCurl::setupEasy() // create non persistant settings // so that we don't add headers twice - TransferSettings vol_settings(_settings); + TransferSettings vol_settings(_settings); // add custom headers vol_settings.addHeader(anonymousIdHeader()); @@ -643,7 +647,7 @@ void MediaCurl::setupEasy() { SET_OPTION(CURLOPT_NOPROXY, "*"); } - + /** Speed limits */ if ( _settings.minDownloadSpeed() != 0 ) { @@ -676,7 +680,7 @@ void MediaCurl::setupEasy() ++it ) { MIL << "HEADER " << *it << std::endl; - + _customHeaders = curl_slist_append(_customHeaders, it->c_str()); if ( !_customHeaders ) ZYPP_THROW(MediaCurlInitException(_url)); @@ -997,7 +1001,7 @@ void MediaCurl::evaluateCurlCode( const Pathname &filename, bool MediaCurl::doGetDoesFileExist( const Pathname & filename ) const { DBG << filename.asString() << endl; - + if(!_url.isValid()) ZYPP_THROW(MediaBadUrlException(_url)); diff --git a/zypp/media/proxyinfo/ProxyInfoLibproxy.cc b/zypp/media/proxyinfo/ProxyInfoLibproxy.cc new file mode 100644 index 0000000..9baaa22 --- /dev/null +++ b/zypp/media/proxyinfo/ProxyInfoLibproxy.cc @@ -0,0 +1,88 @@ +/*---------------------------------------------------------------------\ +| ____ _ __ __ ___ | +| |__ / \ / / . \ . \ | +| / / \ V /| _/ _/ | +| / /__ | | | | | | | +| /_____||_| |_| |_| | +| | +\---------------------------------------------------------------------*/ +/** \file zypp/media/proxyinfo/ProxyInfoLibproxy.cc + * +*/ + +#include +#include + +#include "zypp/base/Logger.h" +#include "zypp/base/String.h" +#include "zypp/Pathname.h" + +#include "zypp/media/proxyinfo/ProxyInfoLibproxy.h" + +using namespace std; +using namespace zypp::base; + +namespace zypp { + namespace media { + + ProxyInfoLibproxy::ProxyInfoLibproxy() + : ProxyInfo::Impl() + { + _factory = px_proxy_factory_new(); + _enabled = !(_factory == NULL); + } + + ProxyInfoLibproxy::~ProxyInfoLibproxy() + { + if (_enabled) { + px_proxy_factory_free(_factory); + _factory = NULL; + _enabled = false; + } + } + + std::string ProxyInfoLibproxy::proxy(const Url & url_r) const + { + if (!_enabled) + return ""; + + const url::ViewOption vopt = + url::ViewOption::WITH_SCHEME + + url::ViewOption::WITH_HOST + + url::ViewOption::WITH_PORT + + url::ViewOption::WITH_PATH_NAME; + + char **proxies = px_proxy_factory_get_proxies(_factory, + (char *)url_r.asString(vopt).c_str()); + if (!proxies) + return ""; + + /* cURL can only handle HTTP proxies, not SOCKS. And can only handle + one. So look through the list and find an appropriate one. */ + char *result = NULL; + + for (int i = 0; proxies[i]; i++) { + if (!result && + !strncmp(proxies[i], "http://", 7)) + result = proxies[i]; + else + free(proxies[i]); + } + free(proxies); + + if (!result) + return ""; + + std::string sresult = result; + free(result); + return sresult; + } + + ProxyInfo::NoProxyIterator ProxyInfoLibproxy::noProxyBegin() const + { return _no_proxy.begin(); } + + ProxyInfo::NoProxyIterator ProxyInfoLibproxy::noProxyEnd() const + { return _no_proxy.end(); } + + } // namespace media +} // namespace zypp diff --git a/zypp/media/proxyinfo/ProxyInfoLibproxy.h b/zypp/media/proxyinfo/ProxyInfoLibproxy.h new file mode 100644 index 0000000..b181064 --- /dev/null +++ b/zypp/media/proxyinfo/ProxyInfoLibproxy.h @@ -0,0 +1,57 @@ +/*---------------------------------------------------------------------\ +| ____ _ __ __ ___ | +| |__ / \ / / . \ . \ | +| / / \ V /| _/ _/ | +| / /__ | | | | | | | +| /_____||_| |_| |_| | +| | +\---------------------------------------------------------------------*/ +/** \file zypp/media/proxyinfo/ProxyInfoLibproxy.h + * +*/ +#ifndef ZYPP_MEDIA_PROXYINFO_PROXYINFOLIBPROXY_H +#define ZYPP_MEDIA_PROXYINFO_PROXYINFOLIBPROXY_H + +#include +#include + +#include + +#include "zypp/base/DefaultIntegral.h" +#include "zypp/media/ProxyInfo.h" +#include "zypp/media/proxyinfo/ProxyInfoImpl.h" + +namespace zypp { + namespace media { + + + class ProxyInfoLibproxy : public ProxyInfo::Impl + { + public: + ProxyInfoLibproxy(); + /** */ + ~ProxyInfoLibproxy(); + /** */ + bool enabled() const + { return _enabled; } + /** */ + std::string proxy(const Url & url_r) const; + /** */ + ProxyInfo::NoProxyList noProxy() const + { return _no_proxy; } + /** */ + virtual ProxyInfo::NoProxyIterator noProxyBegin() const; + /** */ + virtual ProxyInfo::NoProxyIterator noProxyEnd() const; + private: + DefaultIntegral _enabled; + ProxyInfo::NoProxyList _no_proxy; + pxProxyFactory *_factory; + }; + +/////////////////////////////////////////////////////////////////// + + } // namespace media +} // namespace zypp + +#endif // ZYPP_MEDIA_PROXYINFO_PROXYINFOLIBPROXY_H diff --git a/zypp/media/proxyinfo/ProxyInfos.h b/zypp/media/proxyinfo/ProxyInfos.h index 9cfe78a..408b9f3 100644 --- a/zypp/media/proxyinfo/ProxyInfos.h +++ b/zypp/media/proxyinfo/ProxyInfos.h @@ -16,5 +16,8 @@ #include #include "zypp/media/proxyinfo/ProxyInfoSysconfig.h" +#ifdef _WITH_LIBPROXY_SUPPORT_ +#include "zypp/media/proxyinfo/ProxyInfoLibproxy.h" +#endif #endif // ZYPP_MEDIA_PROXYINFO_PROXYINFOS_H -- 2.7.4