ref: refs/heads/master
commit 4cba0723fb6f61ea1b4a0d91bc0dfcfec5b43bbd
Author: Duncan Mac-Vicar P
Date: Sun Feb 22 02:00:25 2009 +0100
big MediaCurl refactoring, to share the settings initialization with
MediaAria2c.
- replace lot of curl_easy_setop with exception checking to a
macro to reduce duplicated code
- implement download.min_download_speed (default no limit)
download.max_download_speed (default no limit) for MediaCurl as well
Still thinking if MediaCurl should be still the default for https, because
aria does not support a CA dir (only files)
---
zypp/media/MediaAria2c.cc | 152 -----------
zypp/media/MediaAria2c.h | 2 -
zypp/media/MediaCurl.cc | 546 +++++++++++++++++-----------------------
zypp/media/MediaCurl.h | 27 ++-
zypp/media/TransferSettings.cc | 64 +++++
zypp/media/TransferSettings.h | 48 ++++
6 files changed, 368 insertions(+), 471 deletions(-)
diff --git a/zypp/media/MediaAria2c.cc b/zypp/media/MediaAria2c.cc
index e9d04e4..8d00e78 100644
--- a/zypp/media/MediaAria2c.cc
+++ b/zypp/media/MediaAria2c.cc
@@ -26,7 +26,6 @@
#include "zypp/Target.h"
#include "zypp/ZYppFactory.h"
-#include "zypp/media/TransferProgram.h"
#include "zypp/media/MediaAria2c.h"
#include "zypp/media/proxyinfo/ProxyInfos.h"
#include "zypp/media/ProxyInfo.h"
@@ -75,84 +74,6 @@ MediaAria2c::existsAria2cmd()
return ( aria.close() == 0 );
}
-void fillSettingsFromUrl( const Url &url, TransferSettings &s )
-{
- std::string param(url.getQueryParam("timeout"));
- if( !param.empty())
- {
- long num = str::strtonum<long>(param);
- if( num >= 0 && num <= TRANSFER_TIMEOUT_MAX)
- s.setTimeout(num);
- }
-
- if ( ! url.getUsername().empty() )
- {
- s.setUsername(url.getUsername());
- if ( url.getPassword().size() )
- {
- s.setPassword(url.getPassword());
- }
- }
-
- string proxy = url.getQueryParam( "proxy" );
-
- if ( ! proxy.empty() )
- {
- string proxyport( url.getQueryParam( "proxyport" ) );
- if ( ! proxyport.empty() ) {
- proxy += ":" + proxyport;
- }
- s.setProxy(proxy);
- s.setProxyEnabled(true);
- }
-}
-
-void fillSettingsSystemProxy( const Url&url, TransferSettings &s )
-{
- ProxyInfo proxy_info (ProxyInfo::ImplPtr(new ProxyInfoSysconfig("proxy")));
-
- if ( proxy_info.enabled())
- {
- s.setProxyEnabled(true);
- std::liststd::string nope = proxy_info.noProxy();
- for (ProxyInfo::NoProxyIterator it = proxy_info.noProxyBegin();
- it != proxy_info.noProxyEnd();
- it++)
- {
- std::string host( str::toLower(url.getHost()));
- std::string temp( str::toLower(*it));
-
- // no proxy if it points to a suffix
- // preceeded by a '.', that maches
- // the trailing portion of the host.
- if( temp.size() > 1 && temp.at(0) == '.')
- {
- if(host.size() > temp.size() &&
- host.compare(host.size() - temp.size(), temp.size(), temp) == 0)
- {
- DBG << "NO_PROXY: '" << *it << "' matches host '"
- << host << "'" << endl;
- s.setProxyEnabled(false);
- break;
- }
- }
- else
- // no proxy if we have an exact match
- if( host == temp)
- {
- DBG << "NO_PROXY: '" << *it << "' matches host '"
- << host << "'" << endl;
- s.setProxyEnabled(false);
- break;
- }
- }
-
- if ( s.proxyEnabled() )
- s.setProxy(proxy_info.proxy(url.getScheme()));
- }
-
-}
-
/**
* comannd line for aria.
* The argument list gets passed as reference
@@ -250,38 +171,6 @@ void fillAriaCmdLine( const Pathname &ariapath,
args.push_back(url.asString().c_str());
}
-static const char *const anonymousIdHeader()
-{
- // we need to add the release and identifier to the
- // agent string.
- // The target could be not initialized, and then this information
- // is not available.
- Target_Ptr target = zypp::getZYpp()->getTarget();
-
- static const std::string _value(
- str::form(
- "X-Zypp-AnonymousId: %s",
- target ? target->anonymousUniqueId().c_str() : "" )
- );
- return _value.c_str();
-}
-
-static const char *const distributionFlavorHeader()
-{
- // we need to add the release and identifier to the
- // agent string.
- // The target could be not initialized, and then this information
- // is not available.
- Target_Ptr target = zypp::getZYpp()->getTarget();
-
- static const std::string _value(
- str::trim( str::form(
- "X-ZYpp-DistributionFlavor: %s",
- target ? target->distributionFlavor().c_str() : "" ) )
- );
- return _value.c_str();
-}
-
const char *const MediaAria2c::agentString()
{
// we need to add the release and identifier to the
@@ -309,28 +198,6 @@ MediaAria2c::MediaAria2c( const Url & url_r,
{
MIL << "MediaAria2c::MediaAria2c(" << url_r << ", " << attach_point_hint_r << ")" << endl;
- /*
- if( !attachPoint().empty())
- {
- PathInfo ainfo(attachPoint());
- Pathname apath(attachPoint() + "XXXXXX");
- char *atemp = ::strdup( apath.asString().c_str());
- char *atest = NULL;
- if( !ainfo.isDir() || !ainfo.userMayRWX() ||
- atemp == NULL || (atest=::mkdtemp(atemp)) == NULL)
- {
- WAR << "attach point " << ainfo.path()
- << " is not useable for " << url_r.getScheme() << endl;
- setAttachPoint("", true);
- }
- else if( atest != NULL)
- ::rmdir(atest);
-
- if( atemp != NULL)
- ::free(atemp);
- }
- */
-
//At this point, we initialize aria2c path
_aria2cPath = Pathname( whereisAria2c().asString() );
@@ -341,25 +208,7 @@ MediaAria2c::MediaAria2c( const Url & url_r,
void MediaAria2c::attachTo (bool next)
{
MediaCurl::attachTo(next);
-
_settings.setUserAgentString(agentString());
- _settings.addHeader(anonymousIdHeader());
- _settings.addHeader(distributionFlavorHeader());
-
- _settings.setTimeout(TRANSFER_TIMEOUT);
- _settings.setConnectTimeout(CONNECT_TIMEOUT);
-
- // fill some settings from url query parameters
- fillSettingsFromUrl(_url, _settings);
-
- // if the proxy was not set by url, then look
- if ( _settings.proxy().empty() )
- {
- // at the system proxy settings
- fillSettingsSystemProxy(_url, _settings);
- }
-
- DBG << "Proxy: " << (_settings.proxy().empty() ? "-none-" : _settings.proxy()) << endl;
}
bool
@@ -371,7 +220,6 @@ MediaAria2c::checkAttachPoint(const Pathname &apoint) const
void MediaAria2c::disconnectFrom()
{
MediaCurl::disconnectFrom();
-
}
void MediaAria2c::releaseFrom( const std::string & ejectDev )
diff --git a/zypp/media/MediaAria2c.h b/zypp/media/MediaAria2c.h
index 33d49f7..544cc8f 100644
--- a/zypp/media/MediaAria2c.h
+++ b/zypp/media/MediaAria2c.h
@@ -107,8 +107,6 @@ class MediaAria2c : public MediaCurl {
/** External process to get aria2c version */
std::string getAria2cVersion();
static std::string _aria2cVersion;
-
- TransferSettings _settings;
};
///////////////////////////////////////////////////////////////////
diff --git a/zypp/media/MediaCurl.cc b/zypp/media/MediaCurl.cc
index 280c9a7..af797d2 100644
--- a/zypp/media/MediaCurl.cc
+++ b/zypp/media/MediaCurl.cc
@@ -183,6 +183,129 @@ namespace zypp {
//
///////////////////////////////////////////////////////////////////
+void fillSettingsFromUrl( const Url &url, TransferSettings &s )
+{
+ std::string param(url.getQueryParam("timeout"));
+ if( !param.empty())
+ {
+ long num = str::strtonum<long>(param);
+ if( num >= 0 && num <= TRANSFER_TIMEOUT_MAX)
+ s.setTimeout(num);
+ }
+
+ if ( ! url.getUsername().empty() )
+ {
+ s.setUsername(url.getUsername());
+ if ( url.getPassword().size() )
+ s.setPassword(url.getPassword());
+ }
+ else
+ {
+ // if there is no username, set anonymous auth
+ if ( url.getScheme() == "ftp" && s.username().empty() )
+ s.setAnonymousAuth();
+ }
+
+ if ( url.getScheme() == "https" )
+ {
+ s.setVerifyPeerEnabled(false);
+ s.setVerifyHostEnabled(false);
+
+ std::string verify( url.getQueryParam("ssl_verify"));
+ if( verify.empty() ||
+ verify == "yes")
+ {
+ s.setVerifyPeerEnabled(true);
+ s.setVerifyHostEnabled(true);
+ }
+ else if( verify == "no")
+ {
+ s.setVerifyPeerEnabled(false);
+ s.setVerifyHostEnabled(false);
+ }
+ else
+ {
+ std::vectorstd::string flags;
+ std::vectorstd::string::const_iterator flag;
+ str::split( verify, std::back_inserter(flags), ",");
+ for(flag = flags.begin(); flag != flags.end(); ++flag)
+ {
+ if( *flag == "host")
+ s.setVerifyHostEnabled(true);
+ else if( *flag == "peer")
+ s.setVerifyPeerEnabled(true);
+ else
+ ZYPP_THROW(MediaBadUrlException(url, "Unknown ssl_verify flag"));
+ }
+ }
+ }
+
+ Pathname ca_path = Pathname(url.getQueryParam("ssl_capath")).asString();
+ if( ! ca_path.empty())
+ {
+ if( !PathInfo(ca_path).isDir() || !Pathname(ca_path).absolute())
+ ZYPP_THROW(MediaBadUrlException(url, "Invalid ssl_capath path"));
+ else
+ s.setCertificateAuthoritiesPath(ca_path);
+ }
+
+ string proxy = url.getQueryParam( "proxy" );
+ if ( ! proxy.empty() )
+ {
+ string proxyport( url.getQueryParam( "proxyport" ) );
+ if ( ! proxyport.empty() ) {
+ proxy += ":" + proxyport;
+ }
+ s.setProxy(proxy);
+ s.setProxyEnabled(true);
+ }
+}
+
+void fillSettingsSystemProxy( const Url&url, TransferSettings &s )
+{
+ ProxyInfo proxy_info (ProxyInfo::ImplPtr(new ProxyInfoSysconfig("proxy")));
+
+ if ( proxy_info.enabled())
+ {
+ s.setProxyEnabled(true);
+ std::liststd::string nope = proxy_info.noProxy();
+ for (ProxyInfo::NoProxyIterator it = proxy_info.noProxyBegin();
+ it != proxy_info.noProxyEnd();
+ it++)
+ {
+ std::string host( str::toLower(url.getHost()));
+ std::string temp( str::toLower(*it));
+
+ // no proxy if it points to a suffix
+ // preceeded by a '.', that maches
+ // the trailing portion of the host.
+ if( temp.size() > 1 && temp.at(0) == '.')
+ {
+ if(host.size() > temp.size() &&
+ host.compare(host.size() - temp.size(), temp.size(), temp) == 0)
+ {
+ DBG << "NO_PROXY: '" << *it << "' matches host '"
+ << host << "'" << endl;
+ s.setProxyEnabled(false);
+ break;
+ }
+ }
+ else
+ // no proxy if we have an exact match
+ if( host == temp)
+ {
+ DBG << "NO_PROXY: '" << *it << "' matches host '"
+ << host << "'" << endl;
+ s.setProxyEnabled(false);
+ break;
+ }
+ }
+
+ if ( s.proxyEnabled() )
+ s.setProxy(proxy_info.proxy(url.getScheme()));
+ }
+}
+
Pathname MediaCurl::_cookieFile = "/var/lib/YaST2/cookies";
static const char *const anonymousIdHeader()
@@ -217,7 +340,6 @@ static const char *const distributionFlavorHeader()
return _value.c_str();
}
-
static const char *const agentString()
{
// we need to add the release and identifier to the
@@ -237,7 +359,15 @@ static const char *const agentString()
return _value.c_str();
}
-
+// we use this define to unbloat code
+#define SET_OPTION(opt,val) { \
+ ret = curl_easy_setopt ( _curl, opt, val ); \
+ if ( ret != 0) { \
+ disconnectFrom(); \
+ ZYPP_THROW(MediaCurlSetOptException(_url, _curlError)); \
+ } \
+ }
+
MediaCurl::MediaCurl( const Url & url_r,
const Pathname & attach_point_hint_r )
: MediaHandler( url_r, attach_point_hint_r,
@@ -280,13 +410,7 @@ void MediaCurl::setCookieFile( const Pathname &fileName )
}
///////////////////////////////////////////////////////////////////
-//
-//
-// METHOD NAME : MediaCurl::attachTo
-// METHOD TYPE : PMError
-//
-// DESCRIPTION : Asserted that not already attached, and attachPoint is a directory.
-//
+
void MediaCurl::attachTo (bool next)
{
if ( next )
@@ -353,148 +477,66 @@ void MediaCurl::attachTo (bool next)
ZYPP_THROW(MediaCurlSetOptException(_url, "Error setting error buffer"));
}
- ret = curl_easy_setopt( _curl, CURLOPT_FAILONERROR, true );
- if ( ret != 0 ) {
- disconnectFrom();
- ZYPP_THROW(MediaCurlSetOptException(_url, _curlError));
- }
+ SET_OPTION(CURLOPT_FAILONERROR,true);
+ SET_OPTION(CURLOPT_NOSIGNAL, 1);
- ret = curl_easy_setopt( _curl, CURLOPT_NOSIGNAL, 1 );
- if ( ret != 0 ) {
- disconnectFrom();
- ZYPP_THROW(MediaCurlSetOptException(_url, _curlError));
- }
+ // add custom headers
+ _settings.addHeader(anonymousIdHeader());
+ _settings.addHeader(distributionFlavorHeader());
+ _settings.addHeader("Pragma:");
- /**
- * Transfer timeout
- */
- {
- _xfer_timeout = TRANSFER_TIMEOUT;
+ _settings.setTimeout(TRANSFER_TIMEOUT);
+ _settings.setConnectTimeout(CONNECT_TIMEOUT);
- std::string param(_url.getQueryParam("timeout"));
- if( !param.empty())
- {
- long num = str::strtonum<long>( param);
- if( num >= 0 && num <= TRANSFER_TIMEOUT_MAX)
- _xfer_timeout = num;
- }
- }
+ _settings.setUserAgentString(agentString());
- /*
- ** Connect timeout
- */
- ret = curl_easy_setopt( _curl, CURLOPT_CONNECTTIMEOUT, CONNECT_TIMEOUT);
- if ( ret != 0 ) {
- disconnectFrom();
- ZYPP_THROW(MediaCurlSetOptException(_url, _curlError));
+ // fill some settings from url query parameters
+ try
+ {
+ fillSettingsFromUrl(_url, _settings);
}
-
- if ( _url.getScheme() == "http" ) {
- // follow any Location: header that the server sends as part of
- // an HTTP header (#113275)
- ret = curl_easy_setopt ( _curl, CURLOPT_FOLLOWLOCATION, true );
- if ( ret != 0) {
- disconnectFrom();
- ZYPP_THROW(MediaCurlSetOptException(_url, _curlError));
- }
- ret = curl_easy_setopt ( _curl, CURLOPT_MAXREDIRS, 3L );
- if ( ret != 0) {
+ catch ( const MediaException &e )
+ {
disconnectFrom();
- ZYPP_THROW(MediaCurlSetOptException(_url, _curlError));
- }
+ ZYPP_RETHROW(e);
+ }
+
+ // if the proxy was not set by url, then look
+ if ( _settings.proxy().empty() )
+ {
+ // at the system proxy settings
+ fillSettingsSystemProxy(_url, _settings);
+ }
- ret = curl_easy_setopt ( _curl, CURLOPT_USERAGENT, agentString() );
+ DBG << "Proxy: " << (_settings.proxy().empty() ? "-none-" : _settings.proxy()) << endl;
+ /**
+ * Connect timeout
+ */
+ SET_OPTION(CURLOPT_CONNECTTIMEOUT, _settings.connectTimeout());
- if ( ret != 0) {
- disconnectFrom();
- ZYPP_THROW(MediaCurlSetOptException(_url, _curlError));
- }
+ if ( _url.getScheme() == "http" )
+ {
+ // follow any Location: header that the server sends as part of
+ // an HTTP header (#113275)
+ SET_OPTION(CURLOPT_FOLLOWLOCATION, true);
+ SET_OPTION(CURLOPT_MAXREDIRS, 3L);
+ SET_OPTION(CURLOPT_USERAGENT, _settings.userAgentString().c_str() );
}
if ( _url.getScheme() == "https" )
{
- bool verify_peer = false;
- bool verify_host = false;
-
- std::string verify( _url.getQueryParam("ssl_verify"));
- if( verify.empty() ||
- verify == "yes")
- {
- verify_peer = true;
- verify_host = true;
- }
- else
- if( verify == "no")
- {
- verify_peer = false;
- verify_host = false;
- }
- else
- {
- std::vectorstd::string flags;
- std::vectorstd::string::const_iterator flag;
- str::split( verify, std::back_inserter(flags), ",");
- for(flag = flags.begin(); flag != flags.end(); ++flag)
- {
- if( *flag == "host")
- {
- verify_host = true;
- }
- else
- if( *flag == "peer")
- {
- verify_peer = true;
- }
- else
- {
- disconnectFrom();
- ZYPP_THROW(MediaBadUrlException(_url, "Unknown ssl_verify flag"));
- }
- }
- }
-
- _ca_path = Pathname(_url.getQueryParam("ssl_capath")).asString();
- if( _ca_path.empty())
- {
- _ca_path = "/etc/ssl/certs/";
- }
- else
- if( !PathInfo(_ca_path).isDir() || !Pathname(_ca_path).absolute())
- {
- disconnectFrom();
- ZYPP_THROW(MediaBadUrlException(_url, "Invalid ssl_capath path"));
- }
-
- if( verify_peer || verify_host)
+ if( _settings.verifyPeerEnabled() ||
+ _settings.verifyHostEnabled() )
{
- ret = curl_easy_setopt( _curl, CURLOPT_CAPATH, _ca_path.c_str());
- if ( ret != 0 ) {
- disconnectFrom();
- ZYPP_THROW(MediaCurlSetOptException(_url, _curlError));
- }
- }
-
- ret = curl_easy_setopt( _curl, CURLOPT_SSL_VERIFYPEER, verify_peer ? 1L : 0L);
- if ( ret != 0 ) {
- disconnectFrom();
- ZYPP_THROW(MediaCurlSetOptException(_url, _curlError));
- }
- ret = curl_easy_setopt( _curl, CURLOPT_SSL_VERIFYHOST, verify_host ? 2L : 0L);
- if ( ret != 0 ) {
- disconnectFrom();
- ZYPP_THROW(MediaCurlSetOptException(_url, _curlError));
- }
-
- ret = curl_easy_setopt ( _curl, CURLOPT_USERAGENT, agentString() );
- if ( ret != 0) {
- disconnectFrom();
- ZYPP_THROW(MediaCurlSetOptException(_url, _curlError));
+ SET_OPTION(CURLOPT_CAPATH, _settings.certificateAuthoritiesPath().c_str());
}
+ SET_OPTION(CURLOPT_SSL_VERIFYPEER, _settings.verifyPeerEnabled() ? 1L : 0L);
+ SET_OPTION(CURLOPT_SSL_VERIFYHOST, _settings.verifyHostEnabled() ? 2L : 0L);
+ SET_OPTION(CURLOPT_USERAGENT, _settings.userAgentString().c_str() );
}
-
/*---------------------------------------------------------------*
CURLOPT_USERPWD: [user name]:[password]
@@ -502,27 +544,12 @@ void MediaCurl::attachTo (bool next)
If not provided, anonymous FTP identification
*---------------------------------------------------------------*/
- if ( _url.getUsername().empty() ) {
- if ( _url.getScheme() == "ftp" ) {
- string id = "yast2@";
- id += VERSION;
- DBG << "Anonymous FTP identification: '" << id << "'" << endl;
- _userpwd = "anonymous:" + id;
- }
- } else {
- _userpwd = _url.getUsername();
- if ( _url.getPassword().size() ) {
- _userpwd += ":" + _url.getPassword();
- }
- }
+ if ( _settings.userPassword().size() )
+ {
+ SET_OPTION(CURLOPT_USERPWD, unEscape(_settings.userPassword()).c_str());
- if ( _userpwd.size() ) {
- _userpwd = unEscape( _userpwd );
- ret = curl_easy_setopt( _curl, CURLOPT_USERPWD, _userpwd.c_str() );
- if ( ret != 0 ) {
- disconnectFrom();
- ZYPP_THROW(MediaCurlSetOptException(_url, _curlError));
- }
+ //FIXME, we leave this here for now, as it does not make sense yet
+ // to refactor it to the fill settings from url function
// HTTP authentication type
if(_url.getScheme() == "http" || _url.getScheme() == "https")
@@ -539,11 +566,7 @@ void MediaCurl::attachTo (bool next)
DBG << "Enabling HTTP authentication methods: " << use_auth
<< " (CURLOPT_HTTPAUTH=" << auth << ")" << std::endl;
- ret = curl_easy_setopt( _curl, CURLOPT_HTTPAUTH, auth);
- if ( ret != 0 ) {
- disconnectFrom();
- ZYPP_THROW(MediaCurlSetOptException(_url, _curlError));
- }
+ SET_OPTION(CURLOPT_HTTPAUTH, auth);
}
}
catch (MediaException & ex_r)
@@ -560,177 +583,72 @@ void MediaCurl::attachTo (bool next)
}
}
- /*---------------------------------------------------------------*
- CURLOPT_PROXY: host[:port]
-
- Url::option(proxy and proxyport) -> CURLOPT_PROXY
- If not provided, /etc/sysconfig/proxy is evaluated
- *---------------------------------------------------------------*/
-
- _proxy = _url.getQueryParam( "proxy" );
-
- if ( ! _proxy.empty() ) {
- string proxyport( _url.getQueryParam( "proxyport" ) );
- if ( ! proxyport.empty() ) {
- _proxy += ":" + proxyport;
- }
- } else {
-
- ProxyInfo proxy_info (ProxyInfo::ImplPtr(new ProxyInfoSysconfig("proxy")));
-
- if ( proxy_info.enabled())
+ if ( _settings.proxyEnabled() )
+ {
+ if ( ! _settings.proxy().empty() )
{
- bool useproxy = true;
-
- std::liststd::string nope = proxy_info.noProxy();
- for (ProxyInfo::NoProxyIterator it = proxy_info.noProxyBegin();
- it != proxy_info.noProxyEnd();
- it++)
+ SET_OPTION(CURLOPT_PROXY, _settings.proxy().c_str());
+ /*---------------------------------------------------------------*
+ CURLOPT_PROXYUSERPWD: [user name]:[password]
+
+ Url::option(proxyuser and proxypassword) -> CURLOPT_PROXYUSERPWD
+ If not provided, $HOME/.curlrc is evaluated
+ *---------------------------------------------------------------*/
+
+ string proxyuserpwd = _settings.proxyUserPassword();
+
+ if ( proxyuserpwd.empty() )
{
- std::string host( str::toLower(_url.getHost()));
- std::string temp( str::toLower(*it));
-
- // no proxy if it points to a suffix
- // preceeded by a '.', that maches
- // the trailing portion of the host.
- if( temp.size() > 1 && temp.at(0) == '.')
- {
- if(host.size() > temp.size() &&
- host.compare(host.size() - temp.size(), temp.size(), temp) == 0)
- {
- DBG << "NO_PROXY: '" << *it << "' matches host '"
- << host << "'" << endl;
- useproxy = false;
- break;
- }
- }
+ if (curlconf.proxyuserpwd.empty())
+ DBG << "~/.curlrc does not contain the proxy-user option" << endl;
else
- // no proxy if we have an exact match
- if( host == temp)
{
- DBG << "NO_PROXY: '" << *it << "' matches host '"
- << host << "'" << endl;
- useproxy = false;
- break;
+ proxyuserpwd = curlconf.proxyuserpwd;
+ DBG << "using proxy-user from ~/.curlrc" << endl;
}
}
- if ( useproxy ) {
- _proxy = proxy_info.proxy(_url.getScheme());
- }
+ proxyuserpwd = unEscape( proxyuserpwd );
+ if ( ! proxyuserpwd.empty() )
+ SET_OPTION(CURLOPT_PROXYUSERPWD, proxyuserpwd.c_str());
}
}
-
-
- DBG << "Proxy: " << (_proxy.empty() ? "-none-" : _proxy) << endl;
-
- if ( ! _proxy.empty() ) {
-
- ret = curl_easy_setopt( _curl, CURLOPT_PROXY, _proxy.c_str() );
- if ( ret != 0 ) {
- disconnectFrom();
- ZYPP_THROW(MediaCurlSetOptException(_url, _curlError));
- }
-
- /*---------------------------------------------------------------*
- CURLOPT_PROXYUSERPWD: [user name]:[password]
-
- Url::option(proxyuser and proxypassword) -> CURLOPT_PROXYUSERPWD
- If not provided, $HOME/.curlrc is evaluated
- *---------------------------------------------------------------*/
-
- _proxyuserpwd = _url.getQueryParam( "proxyuser" );
-
- if ( ! _proxyuserpwd.empty() ) {
- string proxypassword( _url.getQueryParam( "proxypassword" ) );
- if ( ! proxypassword.empty() ) {
- _proxyuserpwd += ":" + proxypassword;
- }
- } else {
- if (curlconf.proxyuserpwd.empty())
- DBG << "~/.curlrc does not contain the proxy-user option" << endl;
- else
- {
- _proxyuserpwd = curlconf.proxyuserpwd;
- DBG << "using proxy-user from ~/.curlrc" << endl;
- }
- }
-
- _proxyuserpwd = unEscape( _proxyuserpwd );
- if ( ! _proxyuserpwd.empty() ) {
- ret = curl_easy_setopt( _curl, CURLOPT_PROXYUSERPWD, _proxyuserpwd.c_str() );
- if ( ret != 0 ) {
- disconnectFrom();
- ZYPP_THROW(MediaCurlSetOptException(_url, _curlError));
- }
- }
+
+ /** Speed limits */
+ if ( _settings.minDownloadSpeed() != 0 )
+ {
+ SET_OPTION(CURLOPT_LOW_SPEED_LIMIT, _settings.minDownloadSpeed());
+ // default to 10 seconds at low speed
+ SET_OPTION(CURLOPT_LOW_SPEED_TIME, 10);
}
+
+ if ( _settings.maxDownloadSpeed() != 0 )
+ SET_OPTION(CURLOPT_MAX_RECV_SPEED_LARGE, _settings.maxDownloadSpeed());
/*---------------------------------------------------------------*
*---------------------------------------------------------------*/
_currentCookieFile = _cookieFile.asString();
-
- ret = curl_easy_setopt( _curl, CURLOPT_COOKIEFILE,
- _currentCookieFile.c_str() );
- if ( ret != 0 ) {
- disconnectFrom();
- ZYPP_THROW(MediaCurlSetOptException(_url, _curlError));
- }
-
- ret = curl_easy_setopt( _curl, CURLOPT_COOKIEJAR,
- _currentCookieFile.c_str() );
- if ( ret != 0 ) {
- disconnectFrom();
- ZYPP_THROW(MediaCurlSetOptException(_url, _curlError));
- }
-
- ret = curl_easy_setopt( _curl, CURLOPT_PROGRESSFUNCTION,
- &progressCallback );
- if ( ret != 0 ) {
- disconnectFrom();
- ZYPP_THROW(MediaCurlSetOptException(_url, _curlError));
- }
-
- ret = curl_easy_setopt( _curl, CURLOPT_NOPROGRESS, false );
- if ( ret != 0 ) {
- disconnectFrom();
- ZYPP_THROW(MediaCurlSetOptException(_url, _curlError));
- }
+ SET_OPTION(CURLOPT_COOKIEFILE, _currentCookieFile.c_str() );
+ SET_OPTION(CURLOPT_COOKIEJAR, _currentCookieFile.c_str() );
+ SET_OPTION(CURLOPT_PROGRESSFUNCTION, &progressCallback );
+ SET_OPTION(CURLOPT_NOPROGRESS, false );
// bnc #306272
- ret = curl_easy_setopt( _curl, CURLOPT_PROXY_TRANSFER_MODE, 1 );
- if ( ret != 0 ) {
- disconnectFrom();
- ZYPP_THROW(MediaCurlSetOptException(_url, _curlError));
- }
-
- _customHeaders = curl_slist_append(_customHeaders, "Pragma:");
-
- if ( !_customHeaders ) {
- ZYPP_THROW(MediaCurlInitException(_url));
- }
-
- // now add the anonymous id header
- _customHeaders = curl_slist_append(_customHeaders, anonymousIdHeader());
+ SET_OPTION(CURLOPT_PROXY_TRANSFER_MODE, 1 );
- if ( !_customHeaders ) {
- ZYPP_THROW(MediaCurlInitException(_url));
- }
-
- // now add the product flavor header
- _customHeaders = curl_slist_append(_customHeaders, distributionFlavorHeader());
-
- if ( !_customHeaders ) {
- ZYPP_THROW(MediaCurlInitException(_url));
+ // append settings custom headers to curl
+ for ( TransferSettings::Headers::const_iterator it = _settings.headersBegin();
+ it != _settings.headersEnd();
+ ++it )
+ {
+
+ _customHeaders = curl_slist_append(_customHeaders, it->c_str());
+ if ( !_customHeaders )
+ ZYPP_THROW(MediaCurlInitException(_url));
}
- ret = curl_easy_setopt ( _curl, CURLOPT_HTTPHEADER, _customHeaders );
-
- if ( ret != 0) {
- disconnectFrom();
- ZYPP_THROW(MediaCurlSetOptException(_url, _curlError));
- }
+ SET_OPTION(CURLOPT_HTTPHEADER, _customHeaders);
// FIXME: need a derived class to propelly compare url's
MediaSourceRef media( new MediaSource(_url.getScheme(), _url.asString()));
@@ -1163,7 +1081,7 @@ bool MediaCurl::doGetDoesFileExist( const Pathname & filename ) const
}
-void MediaCurl::doGetFileCopy( const Pathname & filename , const Pathname & target, callback::SendReport<DownloadProgressReport> & report) const
+void MediaCurl::doGetFileCopy( const Pathname & filename , const Pathname & target, callback::SendReport<DownloadProgressReport> & report, RequestOptions options ) const
{
DBG << filename.asString() << endl;
@@ -1262,7 +1180,7 @@ void MediaCurl::doGetFileCopy( const Pathname & filename , const Pathname & targ
}
// Set callback and perform.
- ProgressData progressData(_xfer_timeout, url, &report);
+ ProgressData progressData(_settings.timeout(), url, &report);
report->start(url, dest);
if ( curl_easy_setopt( _curl, CURLOPT_PROGRESSDATA, &progressData ) != 0 ) {
WAR << "Can't set CURLOPT_PROGRESSDATA: " << _curlError << endl;;
@@ -1734,10 +1652,12 @@ bool MediaCurl::authenticate(const string & availAuthTypes, bool firstTry) const
// set username and password
if (credentials)
{
- _userpwd = credentials->getUserPwd();
+ // HACK, why is this const?
+ const_cast(this)->_settings.setUsername(credentials->username());
+ const_cast(this)->_settings.setPassword(credentials->password());
// set username and password
- CURLcode ret = curl_easy_setopt(_curl, CURLOPT_USERPWD, _userpwd.c_str());
+ CURLcode ret = curl_easy_setopt(_curl, CURLOPT_USERPWD, _settings.userPassword().c_str());
if ( ret != 0 ) ZYPP_THROW(MediaCurlSetOptException(_url, _curlError));
// set available authentication types from the exception
diff --git a/zypp/media/MediaCurl.h b/zypp/media/MediaCurl.h
index 248341b..6be4bdb 100644
--- a/zypp/media/MediaCurl.h
+++ b/zypp/media/MediaCurl.h
@@ -12,6 +12,8 @@
#ifndef ZYPP_MEDIA_MEDIACURL_H
#define ZYPP_MEDIA_MEDIACURL_H
+#include "zypp/base/Flags.h"
+#include "zypp/media/TransferSettings.h"
#include "zypp/media/MediaHandler.h"
#include "zypp/ZYppCallbacks.h"
@@ -27,7 +29,19 @@ namespace zypp {
* @short Implementation class for FTP, HTTP and HTTPS MediaHandler
* @see MediaHandler
**/
-class MediaCurl : public MediaHandler {
+class MediaCurl : public MediaHandler
+{
+ public:
+ enum RequestOption
+ {
+ /** Defaults */
+ OPTION_NONE = 0x0,
+ /** retrieve only a range of the file */
+ OPTION_RANGE = 0x1,
+ /** only issue a HEAD (or equivalent) request */
+ OPTION_HEAD = 0x02,
+ };
+ ZYPP_DECLARE_FLAGS(RequestOptions,RequestOption);
protected:
@@ -69,7 +83,7 @@ class MediaCurl : public MediaHandler {
* \throws MediaException
*
*/
- virtual void doGetFileCopy( const Pathname & srcFilename, const Pathname & targetFilename, callback::SendReport<DownloadProgressReport> & _report) const;
+ virtual void doGetFileCopy( const Pathname & srcFilename, const Pathname & targetFilename, callback::SendReport<DownloadProgressReport> & _report, RequestOptions options = OPTION_NONE ) const;
virtual bool checkAttachPoint(const Pathname &apoint) const;
@@ -109,15 +123,20 @@ class MediaCurl : public MediaHandler {
long _curlDebug;
curl_slist *_customHeaders;
+ /*
mutable std::string _userpwd;
std::string _proxy;
std::string _proxyuserpwd;
+ */
std::string _currentCookieFile;
- std::string _ca_path;
- long _xfer_timeout;
+ //std::string _ca_path;
+ //long _xfer_timeout;
static Pathname _cookieFile;
+protected:
+ TransferSettings _settings;
};
+ZYPP_DECLARE_OPERATORS_FOR_FLAGS(MediaCurl::RequestOptions);
///////////////////////////////////////////////////////////////////
diff --git a/zypp/media/TransferSettings.cc b/zypp/media/TransferSettings.cc
index b206d1b..e822f27 100644
--- a/zypp/media/TransferSettings.cc
+++ b/zypp/media/TransferSettings.cc
@@ -32,6 +32,9 @@ public:
, _minDownloadSpeed(ZConfig::instance().download_min_download_speed())
, _maxDownloadSpeed(ZConfig::instance().download_max_download_speed())
, _maxSilentTries(ZConfig::instance().download_max_silent_tries())
+ , _verify_host(false)
+ , _verify_peer(false)
+ , _ca_path("/etc/ssl/certs")
{}
virtual ~Impl()
@@ -68,6 +71,10 @@ public:
long _minDownloadSpeed;
long _maxDownloadSpeed;
long _maxSilentTries;
+
+ bool _verify_host;
+ bool _verify_peer;
+ Pathname _ca_path;
};
TransferSettings::TransferSettings()
@@ -116,11 +123,27 @@ void TransferSettings::setPassword( const std::string &password )
_impl->_password = password;
}
+void TransferSettings::setAnonymousAuth()
+{
+ setUsername("anonymous");
+ string id = "yast@";
+ setPassword(id + VERSION);
+}
+
std::string TransferSettings::password() const
{
return _impl->_password;
}
+std::string TransferSettings::userPassword() const
+{
+ string userpwd = username();
+ if ( password().size() ) {
+ userpwd += ":" + password();
+ }
+ return userpwd;
+}
+
void TransferSettings::setProxyEnabled( bool enabled )
{
_impl->_useproxy = enabled;
@@ -161,6 +184,15 @@ std::string TransferSettings::proxyPassword() const
return _impl->_proxy_password;
}
+std::string TransferSettings::proxyUserPassword() const
+{
+ string userpwd = proxyUsername();
+ if ( proxyPassword().size() ) {
+ userpwd += ":" + proxyPassword();
+ }
+ return userpwd;
+}
+
void TransferSettings::setTimeout( long t )
{
_impl->_timeout = t;
@@ -221,6 +253,38 @@ void TransferSettings::setMaxSilentTries(long v)
_impl->_maxSilentTries = v;
}
+bool TransferSettings::verifyHostEnabled() const
+{
+ return _impl->_verify_host;
+}
+
+void TransferSettings::setVerifyHostEnabled( bool enabled )
+{
+ _impl->_verify_host = enabled;
+}
+
+bool TransferSettings::verifyPeerEnabled() const
+{
+ return _impl->_verify_peer;
+}
+
+
+void TransferSettings::setVerifyPeerEnabled( bool enabled )
+{
+ _impl->_verify_peer = enabled;
+}
+
+Pathname TransferSettings::certificateAuthoritiesPath() const
+{
+ return _impl->_ca_path;
+}
+
+void TransferSettings::setCertificateAuthoritiesPath( const zypp::Pathname &path )
+{
+ _impl->_ca_path = path;
+}
+
+
} // ns media
} // ns zypp
diff --git a/zypp/media/TransferSettings.h b/zypp/media/TransferSettings.h
index 1491bb7..567fff9 100644
--- a/zypp/media/TransferSettings.h
+++ b/zypp/media/TransferSettings.h
@@ -79,6 +79,17 @@ public:
std::string password() const;
/**
+ * returns the user and password as
+ * a user:pass string
+ */
+ std::string userPassword() const;
+
+ /**
+ * sets anonymous authentication (ie: for ftp)
+ */
+ void setAnonymousAuth();
+
+ /**
* whether the proxy is used or not
*/
void setProxyEnabled( bool enabled );
@@ -119,6 +130,12 @@ public:
std::string proxyPassword() const;
/**
+ * returns the proxy user and password as
+ * a user:pass string
+ */
+ std::string proxyUserPassword() const;
+
+ /**
* set the connect timeout
*/
void setConnectTimeout( long t );
@@ -180,6 +197,37 @@ public:
*/
void setMaxSilentTries(long v);
+ /**
+ * Whether to verify host for ssl
+ */
+ bool verifyHostEnabled() const;
+
+ /**
+ * Sets whether to verify host for ssl
+ */
+ void setVerifyHostEnabled( bool enabled );
+
+ /**
+ * Whether to verify peer for ssl
+ */
+ bool verifyPeerEnabled() const;
+
+ /**
+ * Sets whether to verify host for ssl
+ */
+ void setVerifyPeerEnabled( bool enabled );
+
+ /**
+ * SSL certificate authorities path
+ * ( default: /etc/ssl/certs )
+ */
+ Pathname certificateAuthoritiesPath() const;
+
+ /**
+ * Sets the SSL certificate authorities path
+ */
+ void setCertificateAuthoritiesPath( const zypp::Pathname &path );
+
protected:
class Impl;
RWCOW_pointer<Impl> _impl;
--
To unsubscribe, e-mail: zypp-commit+unsubscribe@opensuse.org
For additional commands, e-mail: zypp-commit+help@opensuse.org