14#include <zypp/APIConfig.h>
16#include <zypp-core/fs/PathInfo.h>
17#include <zypp-core/Pathname.h>
18#include <zypp-core/base/Logger.h>
19#include <zypp-core/base/String.h>
20#include <zypp-curl/ProxyInfo>
21#include <zypp-curl/auth/CurlAuthData>
22#include <zypp-media/MediaException>
35 inline int getZYPP_MEDIA_CURL_IPRESOLVE()
38 if (
const char * envp = getenv(
"ZYPP_MEDIA_CURL_IPRESOLVE" ) )
40 WAR <<
"env set: $ZYPP_MEDIA_CURL_IPRESOLVE='" << envp <<
"'" << std::endl;
41 if ( strcmp( envp,
"4" ) == 0 ) ret = 4;
42 else if ( strcmp( envp,
"6" ) == 0 ) ret = 6;
50 static int _v = getZYPP_MEDIA_CURL_IPRESOLVE();
62 static bool once __attribute__ ((__unused__)) = ( [] {
63 if ( curl_global_init( CURL_GLOBAL_ALL ) != 0 )
64 WAR <<
"curl global init failed" << std::endl;
69 char *ptr,
size_t len,
void *max_lvl)
71 if ( max_lvl ==
nullptr )
74 long maxlvl = *((
long *)max_lvl);
79 case CURLINFO_TEXT:
if ( maxlvl < 1 )
return 0; pfx =
'*';
break;
80 case CURLINFO_HEADER_IN:
if ( maxlvl < 2 )
return 0; pfx =
'<';
break;
81 case CURLINFO_HEADER_OUT:
if ( maxlvl < 2 )
return 0; pfx =
'>';
break;
86 std::vector<std::string> lines;
87 str::split( std::string(ptr,len), std::back_inserter(lines),
"\r\n" );
88 for(
const auto & line : lines )
92 if ( pos == std::string::npos )
94 DBG << pfx <<
" " << line.substr( 0, pos ) <<
" <credentials removed>" << std::endl;
97 DBG << pfx <<
" " << line << std::endl;
106 char * lstart = ptr, * lend = ptr;
108 size_t max = size * nmemb;
109 while (pos + 1 < max)
112 for (lstart = lend; *lend !=
'\n' && pos < max; ++lend, ++pos);
115 if ( strncasecmp( lstart,
"Location:", 9 ) == 0 )
117 std::string line { lstart, *(lend-1)==
'\r' ? lend-1 : lend };
118 DBG <<
"redirecting to " << line << std::endl;
120 *
reinterpret_cast<std::string *
>( userdata ) = line;
146 if( ! param.empty() )
148 long num = str::strtonum<long>(param);
155 if ( ! param.empty() )
159 if ( ! param.empty() )
174 const std::string & verify { url.
getQueryParam(
"ssl_verify") };
175 if( verify.empty() || verify ==
"yes" )
180 else if ( verify ==
"no" )
187 std::vector<std::string> flags;
188 str::split( verify, std::back_inserter(flags),
"," );
189 for (
const auto & flag : flags )
191 if ( flag ==
"host" )
193 else if ( flag ==
"peer" )
202 if( ! ca_path.empty() )
204 if( !
PathInfo(ca_path).isDir() || ! ca_path.absolute() )
212 if( ! client_cert.empty() )
214 if( !
PathInfo(client_cert).isFile() || ! client_cert.absolute() )
222 if( ! client_key.empty() )
224 if( !
PathInfo(client_key).isFile() || ! client_key.absolute() )
232 if ( ! param.empty() )
243 const std::string & proxyport { url.
getQueryParam(
"proxyport" ) };
244 if ( ! proxyport.empty() ) {
255 if ( ! param.empty() )
268 media::CurlAuthData::auth_type_str2long (param );
272 DBG <<
"Rethrowing as MediaUnauthorizedException.";
280 const std::string & param { url.
getQueryParam(
"head_requests") };
281 if( ! param.empty() && param ==
"no" )
299 s.
setProxy( u.
asString( url::ViewOption::WITH_SCHEME + url::ViewOption::WITH_HOST + url::ViewOption::WITH_PORT ) );
313 const char char_r,
const std::string & escaped_r ) {
315 pos != std::string::npos; pos = str_r.find( char_r, pos ) ) {
316 str_r.replace( pos, 1, escaped_r );
326 char * tmp = curl_unescape( text_r.c_str(), 0 );
327 std::string ret( tmp );
360 using namespace std::literals::string_literals;
361 for (
const std::string ¶m : {
"proxy"s,
"proxyport"s,
"proxyuser"s,
"proxypass"s} )
363 const std::string & value( template_r.
getQueryParam( param ) );
364 if ( ! value.empty() )
const std::string & msg() const
Return the message string provided to the ctor.
std::string getScheme() const
Returns the scheme name of the URL.
std::string asString() const
Returns a default string representation of the Url object.
std::string getUsername(EEncoding eflag=zypp::url::E_DECODED) const
Returns the username from the URL authority.
void setFragment(const std::string &fragment, EEncoding eflag=zypp::url::E_DECODED)
Set the fragment string in the URL.
std::string getQueryParam(const std::string ¶m, EEncoding eflag=zypp::url::E_DECODED) const
Return the value for the specified query parameter.
void delQueryParam(const std::string ¶m)
remove the specified query parameter.
void setPassword(const std::string &pass, EEncoding eflag=zypp::url::E_DECODED)
Set the password in the URL authority.
void setPathParams(const std::string ¶ms)
Set the path parameters.
void setQueryParam(const std::string ¶m, const std::string &value)
Set or add value for the specified query parameter.
void setUsername(const std::string &user, EEncoding eflag=zypp::url::E_DECODED)
Set the username in the URL authority.
std::string getPassword(EEncoding eflag=zypp::url::E_DECODED) const
Returns the password from the URL authority.
Wrapper class for ::stat/::lstat.
#define TRANSFER_TIMEOUT_MAX
#define EXPLICITLY_NO_PROXY
void fillSettingsFromUrl(const Url &url, media::TransferSettings &s)
Fills the settings structure using options passed on the url for example ?timeout=x&proxy=foo.
size_t log_redirects_curl(char *ptr, size_t size, size_t nmemb, void *userdata)
void globalInitCurlOnce()
zypp::Url propagateQueryParams(zypp::Url url_r, const zypp::Url &template_r)
std::string curlUnEscape(std::string text_r)
std::string curlEscapedPath(std::string path_r)
void fillSettingsSystemProxy(const Url &url, media::TransferSettings &s)
Reads the system proxy configuration and fills the settings structure proxy information.
Url clearQueryString(const Url &url)
int log_curl(CURL *, curl_infotype info, char *ptr, size_t len, void *max_lvl)
void curlEscape(std::string &str_r, const char char_r, const std::string &escaped_r)
int ZYPP_MEDIA_CURL_IPRESOLVE()
4/6 to force IPv4/v6
bool startsWith(const C_Str &str_r, const C_Str &prefix_r)
alias for hasPrefix
unsigned split(const C_Str &line_r, TOutputIterator result_r, const C_Str &sepchars_r=" \t", const Trim trim_r=NO_TRIM)
Split line_r into words.
@ E_ENCODED
Flag to request encoded string(s).
Easy-to use interface to the ZYPP dependency resolver.
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.