libzypp  10.5.0
ProxyInfoLibproxy.cc
Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                          ____ _   __ __ ___                          |
00003 |                         |__  / \ / / . \ . \                         |
00004 |                           / / \ V /|  _/  _/                         |
00005 |                          / /__ | | | | | |                           |
00006 |                         /_____||_| |_| |_|                           |
00007 |                                                                      |
00008 \---------------------------------------------------------------------*/
00013 #include <iostream>
00014 #include <fstream>
00015 
00016 #include "zypp/base/Logger.h"
00017 #include "zypp/base/String.h"
00018 #include "zypp/base/WatchFile.h"
00019 #include "zypp/Pathname.h"
00020 
00021 #include "zypp/media/proxyinfo/ProxyInfoLibproxy.h"
00022 
00023 using namespace std;
00024 using namespace zypp::base;
00025 
00026 namespace zypp {
00027   namespace media {
00028 
00029     struct TmpUnsetEnv
00030     {
00031       TmpUnsetEnv( const char * var_r )
00032       : _set( false )
00033       , _var( var_r )
00034       {
00035         const char * val = getenv( _var.c_str() );
00036         if ( val )
00037         {
00038           _set = true;
00039           _val = val;
00040           ::unsetenv( _var.c_str() );
00041         }
00042       }
00043 
00044       ~TmpUnsetEnv()
00045       {
00046         if ( _set )
00047         {
00048           setenv( _var.c_str(), _val.c_str(), 1 );
00049         }
00050       }
00051 
00052       bool _set;
00053       std::string _var;
00054       std::string _val;
00055     };
00056 
00057     static pxProxyFactory * getProxyFactory()
00058     {
00059       static pxProxyFactory * proxyFactory = 0;
00060 
00061       // Force libproxy into using "/etc/sysconfig/proxy"
00062       // if it exists.
00063       static WatchFile sysconfigProxy( "/etc/sysconfig/proxy", WatchFile::NO_INIT );
00064       if ( sysconfigProxy.hasChanged() )
00065       {
00066         MIL << "Build Libproxy Factory from /etc/sysconfig/proxy" << endl;
00067         if ( proxyFactory )
00068           ::px_proxy_factory_free( proxyFactory );
00069 
00070         TmpUnsetEnv env[] = { "KDE_FULL_SESSION", "GNOME_DESKTOP_SESSION_ID", "DESKTOP_SESSION" };
00071         proxyFactory = ::px_proxy_factory_new();
00072       }
00073       else if ( ! proxyFactory )
00074       {
00075         MIL << "Build Libproxy Factory" << endl;
00076         proxyFactory = ::px_proxy_factory_new();
00077       }
00078 
00079       return proxyFactory;
00080     }
00081 
00082     ProxyInfoLibproxy::ProxyInfoLibproxy()
00083     : ProxyInfo::Impl()
00084     {
00085       _factory = getProxyFactory();
00086       _enabled = !(_factory == NULL);
00087     }
00088 
00089     ProxyInfoLibproxy::~ProxyInfoLibproxy()
00090     {}
00091 
00092     std::string ProxyInfoLibproxy::proxy(const Url & url_r) const
00093     {
00094       if (!_enabled)
00095         return "";
00096 
00097       const url::ViewOption vopt =
00098               url::ViewOption::WITH_SCHEME
00099               + url::ViewOption::WITH_HOST
00100               + url::ViewOption::WITH_PORT
00101               + url::ViewOption::WITH_PATH_NAME;
00102 
00103       char **proxies = px_proxy_factory_get_proxies(_factory,
00104                                                     (char *)url_r.asString(vopt).c_str());
00105       if (!proxies)
00106               return "";
00107 
00108       /* cURL can only handle HTTP proxies, not SOCKS. And can only handle
00109          one. So look through the list and find an appropriate one. */
00110       char *result = NULL;
00111 
00112       for (int i = 0; proxies[i]; i++) {
00113               if (!result &&
00114                   !strncmp(proxies[i], "http://", 7))
00115                       result = proxies[i];
00116               else
00117                       free(proxies[i]);
00118       }
00119       free(proxies);
00120 
00121       if (!result)
00122               return "";
00123 
00124       std::string sresult = result;
00125       free(result);
00126       return sresult;
00127     }
00128 
00129     ProxyInfo::NoProxyIterator ProxyInfoLibproxy::noProxyBegin() const
00130     { return _no_proxy.begin(); }
00131 
00132     ProxyInfo::NoProxyIterator ProxyInfoLibproxy::noProxyEnd() const
00133     { return _no_proxy.end(); }
00134 
00135   } // namespace media
00136 } // namespace zypp