added error and proxy handling for Curl backend
authorJiri Srain <jsrain@suse.cz>
Wed, 14 Dec 2005 17:47:30 +0000 (17:47 +0000)
committerJiri Srain <jsrain@suse.cz>
Wed, 14 Dec 2005 17:47:30 +0000 (17:47 +0000)
zypp/media/Makefile.am
zypp/media/MediaCallbacks.h
zypp/media/MediaCurl.cc
zypp/media/MediaException.cc
zypp/media/MediaException.h
zypp/media/ProxyInfo.cc [new file with mode: 0644]
zypp/media/ProxyInfo.h [new file with mode: 0644]

index ea1575a..138d555 100644 (file)
@@ -18,6 +18,7 @@ include_HEADERS =             \
        MediaDISK.h             \
        MediaSMB.h              \
        MediaCIFS.h             \
+       ProxyInfo.h             \
        MediaCurl.h
 
 
@@ -36,6 +37,7 @@ lib@PACKAGE@_media_la_SOURCES = \
        MediaDISK.cc            \
        MediaSMB.cc             \
        MediaCIFS.cc            \
+       ProxyInfo.cc            \
        MediaCurl.cc
 
 
index a5a7690..7a12168 100644 (file)
@@ -17,6 +17,7 @@
 
 #include "zypp/Url.h"
 #include "zypp/Callback.h"
+#include "zypp/base/Exception.h"
 
 namespace zypp {
   namespace media {
index cfe2472..cca16a1 100644 (file)
 #include "zypp/base/Logger.h"
 #include "zypp/ExternalProgram.h"
 #include "zypp/base/String.h"
-//#include <y2util/SysConfig.h>
 
 #include "zypp/media/MediaCurl.h"
 #include "zypp/media/MediaCallbacks.h"
+#include "zypp/media/ProxyInfo.h"
 
 #include <sys/types.h>
 #include <sys/mount.h>
@@ -99,29 +99,26 @@ void MediaCurl::setCookieFile( const Pathname &fileName )
 void MediaCurl::attachTo (bool next)
 {
   if ( next )
-    ZYPP_THROW( MediaException("Error::E_not_supported_by_media") );
+    ZYPP_THROW(MediaNotSupportedException(_url));
 
   if ( !_url.isValid() )
     ZYPP_THROW(MediaBadUrlException(_url));
 
   _curl = curl_easy_init();
   if ( !_curl ) {
-    ERR << "curl easy init failed" << endl;
-    ZYPP_THROW( MediaException("Error::E_error") );
+    ZYPP_THROW(MediaCurlInitException(_url));
   }
 
   _connected = true;
 
   CURLcode ret = curl_easy_setopt( _curl, CURLOPT_ERRORBUFFER, _curlError );
   if ( ret != 0 ) {
-    ERR << "Error setting error buffer" << endl;
-    ZYPP_THROW( MediaException("Error::E_curl_setopt_failed") );
+    ZYPP_THROW(MediaCurlSetOptException(_url, "Error setting error buffer"));
   }
 
   ret = curl_easy_setopt( _curl, CURLOPT_FAILONERROR, true );
   if ( ret != 0 ) {
-    ERR << _curlError << endl;
-    ZYPP_THROW( MediaException("Error::E_curl_setopt_failed") );
+    ZYPP_THROW(MediaCurlSetOptException(_url, _curlError));
   }
 
   if ( _url.getScheme() == "http" ) {
@@ -129,13 +126,11 @@ void MediaCurl::attachTo (bool next)
     // an HTTP header (#113275)
     ret = curl_easy_setopt ( _curl, CURLOPT_FOLLOWLOCATION, true );
     if ( ret != 0) {
-      ERR << _curlError << endl;
-      ZYPP_THROW( MediaException("Error::E_curl_setopt_failed") );
+      ZYPP_THROW(MediaCurlSetOptException(_url, _curlError));
     }
     ret = curl_easy_setopt ( _curl, CURLOPT_MAXREDIRS, 3L );
     if ( ret != 0) {
-      ERR << _curlError << endl;
-      ZYPP_THROW( MediaException("Error::E_curl_setopt_failed") );
+      ZYPP_THROW(MediaCurlSetOptException(_url, _curlError));
     }
   }
 
@@ -145,14 +140,12 @@ void MediaCurl::attachTo (bool next)
     WAR << "Disable certificate verification for https." << endl;
     ret = curl_easy_setopt( _curl, CURLOPT_SSL_VERIFYPEER, 0 );
     if ( ret != 0 ) {
-      ERR << _curlError << endl;
-      ZYPP_THROW( MediaException("Error::E_curl_setopt_failed") );
+      ZYPP_THROW(MediaCurlSetOptException(_url, _curlError));
     }
 
     ret = curl_easy_setopt( _curl, CURLOPT_SSL_VERIFYHOST, 0 );
     if ( ret != 0 ) {
-      ERR << _curlError << endl;
-      ZYPP_THROW( MediaException("Error::E_curl_setopt_failed") );
+      ZYPP_THROW(MediaCurlSetOptException(_url, _curlError));
     }
   }
 
@@ -182,8 +175,7 @@ void MediaCurl::attachTo (bool next)
     _userpwd = unEscape( _userpwd );
     ret = curl_easy_setopt( _curl, CURLOPT_USERPWD, _userpwd.c_str() );
     if ( ret != 0 ) {
-      ERR << _curlError << endl;
-      ZYPP_THROW( MediaException("Error::E_curl_setopt_failed") );
+      ZYPP_THROW(MediaCurlSetOptException(_url, _curlError));
     }
   }
 
@@ -194,50 +186,49 @@ void MediaCurl::attachTo (bool next)
    If not provided, /etc/sysconfig/proxy is evaluated
    *---------------------------------------------------------------*/
 
-#warning FIX once I understand how to get this info
-#warning FIXME enable proxy via sysconfig somehow
-#if 0
-  _proxy = _url.option( "proxy" );
+  _proxy = _url.getQueryParam( "proxy" );
 
   if ( ! _proxy.empty() ) {
-    string proxyport( _url.option( "proxyport" ) );
+    string proxyport( _url.getQueryParam( "proxyport" ) );
     if ( ! proxyport.empty() ) {
       _proxy += ":" + proxyport;
     }
   } else {
 
-    SysConfig cfg( "proxy" );
+    ProxyInfo proxy_info (RW_pointer<ProxyInfo::Impl>(new ProxyInfo_sysconfig("proxy")));
 
-    if ( cfg.readBoolEntry( "PROXY_ENABLED", false ) ) {
+    if ( proxy_info.enabled())
+    {
       bool useproxy = true;
 
-      std::vector<std::string> nope;
-      stringutil::split( cfg.readEntry( "NO_PROXY" ), nope, ", \t" );
-      for ( unsigned i = 0; i < nope.size(); ++i ) {
+      std::list<std::string> nope = proxy_info.noProxy();
+      for (std::list<std::string>::const_iterator it = nope.begin();
+           it != nope.end();
+           it++)
+      {
        // no proxy: if nope equals host,
        // or is a suffix preceeded by a '.'
-       string::size_type pos = _url.getHost().find( nope[i] );
+       string::size_type pos = _url.getHost().find( *it );
        if ( pos != string::npos
-            && ( pos + nope[i].size() == _url.getHost().size() )
+            && ( pos + it->size() == _url.getHost().size() )
             && ( pos == 0 || _url.getHost()[pos -1] == '.' ) ) {
-         DBG << "NO_PROXY: " << nope[i] << " matches host " << _url.getHost() << endl;
+         DBG << "NO_PROXY: " << *it << " matches host " << _url.getHost() << endl;
          useproxy = false;
          break;
        }
       }
 
       if ( useproxy ) {
-       if ( _url.getScheme() == Url::ftp ) {
-         _proxy = cfg.readEntry( "FTP_PROXY" );
-       } else if ( _url.getScheme() == Url::http ) {
-         _proxy = cfg.readEntry( "HTTP_PROXY" );
-       } else if ( _url.getScheme() == Url::https ) {
-         _proxy = cfg.readEntry( "HTTPS_PROXY" );
+       if ( _url.getScheme() == "ftp" ) {
+         _proxy = proxy_info.ftp();
+       } else if ( _url.getScheme() == "http" ) {
+         _proxy = proxy_info.http();
+       } else if ( _url.getScheme() == "https" ) {
+         _proxy = proxy_info.https();
        }
       }
     }
   }
-#endif
 
 
   DBG << "Proxy: " << _proxy << endl;
@@ -246,8 +237,7 @@ void MediaCurl::attachTo (bool next)
 
     ret = curl_easy_setopt( _curl, CURLOPT_PROXY, _proxy.c_str() );
     if ( ret != 0 ) {
-      ERR << _curlError << endl;
-      ZYPP_THROW( MediaException("Error::E_curl_setopt_failed") );
+      ZYPP_THROW(MediaCurlSetOptException(_url, _curlError));
     }
 
     /*---------------------------------------------------------------*
@@ -257,14 +247,11 @@ void MediaCurl::attachTo (bool next)
      If not provided, $HOME/.curlrc is evaluated
      *---------------------------------------------------------------*/
 
-#warning FIXME once I know how to get this info
-#warning FIXME enable proxy via sysconfig somehow
-#if 0
-    _proxyuserpwd = _url.option( "proxyuser" );
+    _proxyuserpwd = _url.getQueryParam( "proxyuser" );
 
     if ( ! _proxyuserpwd.empty() ) {
 
-      string proxypassword( _url.option( "proxypassword" ) );
+      string proxypassword( _url.getQueryParam( "proxypassword" ) );
       if ( ! proxypassword.empty() ) {
        _proxyuserpwd += ":" + proxypassword;
       }
@@ -272,17 +259,17 @@ void MediaCurl::attachTo (bool next)
     } else {
 
       string curlrcFile = string( getenv("HOME") ) + string( "/.curlrc" );
-      SysConfig curlrc( curlrcFile );
-      _proxyuserpwd = curlrc.readEntry( "proxy-user" );
-
+      map<string,string> rc_data
+       = proxyinfo::sysconfigRead(Pathname(curlrcFile));
+      map<string,string>::const_iterator it = rc_data.find("proxy-user");
+      if (it != rc_data.end())
+       _proxyuserpwd = it->second;
     }
-#endif
 
     _proxyuserpwd = unEscape( _proxyuserpwd );
     ret = curl_easy_setopt( _curl, CURLOPT_PROXYUSERPWD, _proxyuserpwd.c_str() );
     if ( ret != 0 ) {
-      ERR << _curlError << endl;
-      ZYPP_THROW( MediaException("Error::E_curl_setopt_failed") );
+      ZYPP_THROW(MediaCurlSetOptException(_url, _curlError));
     }
 
   }
@@ -295,28 +282,24 @@ void MediaCurl::attachTo (bool next)
   ret = curl_easy_setopt( _curl, CURLOPT_COOKIEFILE,
                           _currentCookieFile.c_str() );
   if ( ret != 0 ) {
-    ERR << _curlError << endl;
-    ZYPP_THROW( MediaException("Error::E_curl_setopt_failed") );
+    ZYPP_THROW(MediaCurlSetOptException(_url, _curlError));
   }
 
   ret = curl_easy_setopt( _curl, CURLOPT_COOKIEJAR,
                           _currentCookieFile.c_str() );
   if ( ret != 0 ) {
-    ERR << _curlError << endl;
-    ZYPP_THROW( MediaException("Error::E_curl_setopt_failed") );
+    ZYPP_THROW(MediaCurlSetOptException(_url, _curlError));
   }
 
   ret = curl_easy_setopt( _curl, CURLOPT_PROGRESSFUNCTION,
                           &MediaCurl::progressCallback );
   if ( ret != 0 ) {
-    ERR << _curlError << endl;
-    ZYPP_THROW( MediaException("Error::E_curl_setopt_failed") );
+    ZYPP_THROW(MediaCurlSetOptException(_url, _curlError));
   }
 
   ret = curl_easy_setopt( _curl, CURLOPT_NOPROGRESS, false );
   if ( ret != 0 ) {
-    ERR << _curlError << endl;
-    ZYPP_THROW( MediaException("Error::E_curl_setopt_failed") );
+    ZYPP_THROW(MediaCurlSetOptException(_url, _curlError));
   }
 }
 
@@ -368,7 +351,7 @@ void MediaCurl::getFileCopy( const Pathname & filename , const Pathname & target
       ZYPP_THROW(MediaBadUrlException(_url));
 
     if(_url.getHost().empty())
-      ZYPP_THROW( MediaException("Error::E_no_host_specified") );
+      ZYPP_THROW(MediaBadUrlEmptyHostException(_url));
 
     string path = _url.getPathName();
     if ( !path.empty() && path != "/" && *path.rbegin() == '/' &&
@@ -397,7 +380,7 @@ void MediaCurl::getFileCopy( const Pathname & filename , const Pathname & target
     if( assert_dir( dest.dirname() ) )
     {
       DBG << "assert_dir " << dest.dirname() << " failed" << endl;
-      ZYPP_THROW( MediaException(string("Error::E_system") + string(" ") + dest.dirname().asString()) );
+      ZYPP_THROW( MediaSystemException(_url, "System error on " + dest.dirname().asString()) );
     }
 
     DBG << "URL: " << url.toString().c_str() << endl;
@@ -414,21 +397,19 @@ void MediaCurl::getFileCopy( const Pathname & filename , const Pathname & target
     CURLcode ret = curl_easy_setopt( _curl, CURLOPT_URL,
                                      urlBuffer.c_str() );
     if ( ret != 0 ) {
-      ERR << _curlError << endl;
-      ZYPP_THROW( MediaException("Error::E_curl_setopt_failed") );
+      ZYPP_THROW(MediaCurlSetOptException(_url, _curlError));
     }
 
     FILE *file = fopen( destNew.c_str(), "w" );
     if ( !file ) {
       ERR << "fopen failed for file '" << destNew << "'" << endl;
-      ZYPP_THROW( MediaException(string("Error::E_write_error") + string(" ") + destNew) );
+      ZYPP_THROW(MediaWriteException(destNew));
     }
 
     ret = curl_easy_setopt( _curl, CURLOPT_WRITEDATA, file );
     if ( ret != 0 ) {
       fclose( file );
-      ERR << _curlError << endl;
-      ZYPP_THROW( MediaException("Error::E_curl_setopt_failed") );
+      ZYPP_THROW(MediaCurlSetOptException(_url, _curlError));
     }
 
     // Set callback and perform.
@@ -453,12 +434,12 @@ void MediaCurl::getFileCopy( const Pathname & filename , const Pathname & target
 
       ERR << "curl error: " << ret << ": " << _curlError << endl;
       std::string err;
-      switch ( ret ) {
+      try {
+       switch ( ret ) {
         case CURLE_UNSUPPORTED_PROTOCOL:
         case CURLE_URL_MALFORMAT:
         case CURLE_URL_MALFORMAT_USER:
-          err = "Error::E_bad_url";
-          break;
+         err = "Bad URL";
         case CURLE_HTTP_NOT_FOUND:
           {
             long httpReturnCode;
@@ -472,51 +453,51 @@ void MediaCurl::getFileCopy( const Pathname & filename , const Pathname & target
               if ( httpReturnCode == 401 )
              {
                msg = "URL: " + url.toString();
-                err = "Error::E_login_failed";
+                err = "Login failed";
              }
               else
              {
-               err = "Error::E_file_not_found";
+               err = "File not found";
              }
-#warning FIXME reenable change report
-#if 0
-             report->stop( err );
-#endif
-             ZYPP_THROW( MediaException(err + string(" ") + _curlError) );
+             ZYPP_THROW( MediaCurlException(_url, err, _curlError));
             }
           }
           break;
         case CURLE_FTP_COULDNT_RETR_FILE:
         case CURLE_FTP_ACCESS_DENIED:
-          err = "Error::E_file_not_found";
+          err = "File not found";
           break;
         case CURLE_BAD_PASSWORD_ENTERED:
         case CURLE_FTP_USER_PASSWORD_INCORRECT:
-          err = "Error::E_login_failed";
+          err = "Login failed";
           break;
         case CURLE_COULDNT_RESOLVE_PROXY:
         case CURLE_COULDNT_RESOLVE_HOST:
         case CURLE_COULDNT_CONNECT:
         case CURLE_FTP_CANT_GET_HOST:
-          err = "Error::E_connection_failed";
+          err = "Connection failed";
           break;
         case CURLE_WRITE_ERROR:
-          err = "Error::E_write_error";
+          err = "Write error";
           break;
         case CURLE_ABORTED_BY_CALLBACK:
-          err = "Error::E_user_abort";
+          err = "User abort";
           break;
         case CURLE_SSL_PEER_CERTIFICATE:
         default:
-          err = "Error::E_error";
+          err = "Unrecognized error";
           break;
+       }
+       ZYPP_THROW(MediaCurlException(_url, err, _curlError));
       }
-
+      catch (const MediaException & excpt_r)
+      {
 #warning FIXME reenable change report
 #if 0
-      report->stop( err );
+       report->stop( err );
 #endif
-      ZYPP_THROW( MediaException(err + string(" ") + _curlError) );
+       ZYPP_RETHROW(excpt_r);
+      }
     }
 
     if ( rename( destNew, dest ) != 0 ) {
@@ -525,7 +506,7 @@ void MediaCurl::getFileCopy( const Pathname & filename , const Pathname & target
 #if 0
       report->stop( Error::E_write_error );
 #endif
-      ZYPP_THROW( MediaException("Error::E_write_error") );
+      ZYPP_THROW(MediaWriteException(dest));
     }
 
 #warning FIXME reenable change report
index 6c3cb86..a31fc1a 100644 (file)
@@ -66,6 +66,11 @@ namespace zypp
       return str << "Bad media attach point: " << _url << endl;
     }
 
+    std::ostream & MediaCurlInitException::dumpOn( std::ostream & str) const
+    {
+      return str << "Curl init failed for: " << _url << endl;
+    }
+
     std::ostream & MediaSystemException::dumpOn( std::ostream & str) const
     {
       return str << "System exception: " << _message
@@ -116,6 +121,18 @@ namespace zypp
       return str << "Operation not supported by media: " << _url << endl;
     }
 
+    std::ostream & MediaCurlException::dumpOn( std::ostream & str) const
+    {
+      return str << "Curl error for: " << _url
+       << ": Error code: " << _err
+       << " Error message: " << _msg << endl;
+    }
+
+    std::ostream & MediaCurlSetOptException::dumpOn( std::ostream & str) const
+    {
+      return str << "Error occurred while setting CURL options for " << _url
+       << ": " << _msg << endl;
+    }
 
   /////////////////////////////////////////////////////////////////
   } // namespace media
index 44860c3..1a57283 100644 (file)
@@ -182,6 +182,20 @@ namespace zypp
       std::string _url;
     };
 
+    class MediaCurlInitException : public MediaException
+    {
+    public:
+      MediaCurlInitException(const Url & url_r)
+      : MediaException()
+      , _url(url_r.toString())
+      {}
+      virtual ~MediaCurlInitException() throw() {};
+    protected:
+      virtual std::ostream & dumpOn( std::ostream & str ) const;
+    private:
+      std::string _url;
+    };
+
     class MediaSystemException : public MediaException
     {
     public:
@@ -303,6 +317,40 @@ namespace zypp
       std::string _url;
     };
 
+    class MediaCurlException : public MediaException
+    {
+    public:
+      MediaCurlException(const Url & url_r,
+                        const std::string & err_r,
+                        const std::string & msg_r)
+      : MediaException()
+      , _url(url_r.toString())
+      , _err(err_r)
+      , _msg(msg_r)
+      {}
+      virtual ~MediaCurlException() throw() {};
+    protected:
+      virtual std::ostream & dumpOn( std::ostream & str ) const;
+      std::string _url;
+      std::string _err;
+      std::string _msg;
+    };
+
+    class MediaCurlSetOptException : public MediaException
+    {
+    public:
+      MediaCurlSetOptException(const Url & url_r, const std::string & msg_r)
+      : MediaException()
+      , _url(url_r.toString())
+      , _msg(msg_r)
+      {}
+      virtual ~MediaCurlSetOptException() throw() {};
+    protected:
+      virtual std::ostream & dumpOn( std::ostream & str ) const;
+      std::string _url;
+      std::string _msg;
+    };
+
   /////////////////////////////////////////////////////////////////
   } // namespace media
 } // namespace zypp
diff --git a/zypp/media/ProxyInfo.cc b/zypp/media/ProxyInfo.cc
new file mode 100644 (file)
index 0000000..05522f3
--- /dev/null
@@ -0,0 +1,114 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file zypp/media/ProxyInfo.cc
+ *
+*/
+
+#include <iostream>
+#include <fstream>
+
+#include "zypp/base/Logger.h"
+#include "zypp/base/String.h"
+#include "zypp/Pathname.h"
+
+#include "zypp/media/ProxyInfo.h"
+
+using namespace std;
+using namespace zypp::base;
+
+namespace zypp {
+  namespace media {
+
+    shared_ptr<ProxyInfo::Impl> ProxyInfo::Impl::_nullimpl;
+
+    ProxyInfo::ProxyInfo()
+    : _pimpl( Impl::_nullimpl )
+    {}
+    ProxyInfo::ProxyInfo(RW_pointer<Impl> impl)
+    : _pimpl(impl)
+    {}
+
+    bool ProxyInfo::enabled()
+    { return _pimpl->enabled(); }
+
+    std::string ProxyInfo::http()
+    { return _pimpl->http(); }
+
+    std::string ProxyInfo::ftp()
+    { return _pimpl->ftp(); }
+
+    std::string ProxyInfo::https()
+    { return _pimpl->https(); }
+
+    std::list<std::string> ProxyInfo::noProxy()
+    { return _pimpl->noProxy(); }
+
+    namespace proxyinfo {
+      map<string,string> sysconfigRead(const Pathname & _path)
+      {
+        DBG << "Load '" << _path << "'" << endl;
+        map<string,string> ret;
+      
+        string line;
+        ifstream in( _path.asString().c_str() );
+        if ( in.fail() ) {
+          WAR << "Unable to load '" << _path << "'" << endl;
+          return ret;
+        }
+        while( getline( in, line ) ) {
+          if ( *line.begin() != '#' ) {
+            string::size_type pos = line.find( '=', 0 );
+            if ( pos != string::npos ) {
+              string key = str::trim( line.substr( 0, pos ) );
+              string value = str::trim( line.substr( pos + 1, line.length() - pos - 1 ) );
+              if ( value.length() >= 2 && *(value.begin()) == '"' &&
+                   *(value.rbegin()) == '"' ) {
+                value = value.substr( 1, value.length() - 2 );
+              }
+              if ( value.length() >= 2 && *(value.begin()) == '\'' &&
+                   *(value.rbegin()) == '\'' ) {
+                value = value.substr( 1, value.length() - 2 );
+              }
+              DBG << "KEY: '" << key << "' VALUE: '" << value << "'" << endl;
+              ret[key] = value;
+            }
+          }
+        }
+      return ret;
+      }
+    } // namespace proxyinfo
+
+    ProxyInfo_sysconfig::ProxyInfo_sysconfig(const Pathname & path)
+    : ProxyInfo::Impl()
+    {
+      map<string,string> data = proxyinfo::sysconfigRead(
+       path.relative()
+         ? "/etc/sysconfig" + path
+         : path);
+      map<string,string>::const_iterator it = data.find("PROXY_ENABLED");
+      if (it != data.end())
+       _enabled = it->second != "no";
+      it = data.find("HTTP_PROXY");
+      if (it != data.end())
+       _http = it->second;
+      it = data.find("HTTPS_PROXY");
+      if (it != data.end())
+       _https = it->second;
+      it = data.find("FTP_PROXY");
+      if (it != data.end())
+       _ftp = it->second;
+      it = data.find("NO_PROXY");
+      if (it != data.end())
+       _no_proxy.push_back(it->second);
+#warning FIXME once splitting a string is in str:: namespace
+    }
+
+
+  } // namespace media
+} // namespace zypp
diff --git a/zypp/media/ProxyInfo.h b/zypp/media/ProxyInfo.h
new file mode 100644 (file)
index 0000000..6a2219d
--- /dev/null
@@ -0,0 +1,114 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file zypp/media/ProxyInfo.h
+ *
+*/
+#ifndef ZYPP_MEDIA_PROXYINFO_H
+#define ZYPP_MEDIA_PROXYINFO_H
+
+#include <string>
+#include <map>
+
+#include "zypp/base/ReferenceCounted.h"
+#include "zypp/base/NonCopyable.h"
+#include "zypp/base/PtrTypes.h"
+
+namespace zypp {
+  namespace media {
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    // CLASS NAME : ProxyInfo
+    class ProxyInfo : public base::ReferenceCounted, private base::NonCopyable
+    {
+    public:
+      typedef intrusive_ptr<ProxyInfo> Ptr;
+      typedef intrusive_ptr<ProxyInfo> constPtr;
+      /** Implementation */
+      struct Impl;
+      ProxyInfo();
+      ProxyInfo(RW_pointer<Impl> impl);
+      bool enabled();
+      std::string http();
+      std::string ftp();
+      std::string https();
+      std::list<std::string> noProxy();
+
+    private:
+      /** Pointer to implementation */
+      RW_pointer<Impl> _pimpl;
+    };
+
+    struct ProxyInfo::Impl
+    {
+      /** Ctor */
+      Impl()
+      : _enabled( false )
+      , _http( "" )
+      , _ftp( "" )
+      , _https( "" )
+      , _no_proxy()
+      {}
+      /** Ctor */
+      Impl( const bool enabled,
+           const std::string & http_r,
+           const std::string & ftp_r,
+           const std::string & https_r,
+           const std::list<std::string> & no_proxy_r )
+      : _enabled( enabled )
+      , _http( http_r )
+      , _ftp( ftp_r )
+      , _https( https_r )
+      , _no_proxy( no_proxy_r )
+      {}
+  
+    public:
+      /**  */
+      const bool & enabled() const
+      { return _enabled; }
+      /**  */
+      const std::string & http() const
+      { return _http; }
+      /**  */
+      const std::string & ftp() const
+      { return _ftp; }
+      /**  */
+      const std::string & https() const
+      { return _https; }
+      /**  */
+      const std::list<std::string> & noProxy() const
+      { return _no_proxy; }
+  
+     protected:
+      bool _enabled;
+      std::string _http;
+      std::string _ftp;
+      std::string _https;
+      std::list<std::string> _no_proxy;
+    public:
+      /** Default Impl: empty sets. */
+      static shared_ptr<Impl> _nullimpl;
+    };
+
+    class ProxyInfo_sysconfig : public ProxyInfo::Impl
+    {
+    public:
+      ProxyInfo_sysconfig(const Pathname & path);
+    };
+
+    namespace proxyinfo {
+      std::map<std::string,std::string> sysconfigRead(const Pathname & _path);
+    } // namespace proxyinfo
+
+///////////////////////////////////////////////////////////////////
+
+  } // namespace media
+} // namespace zypp
+
+#endif // ZYPP_MEDIA_PROXYINFO_H