21#include <zypp-core/parser/Sysconfig> 
   28#include <zypp-curl/ProxyInfo> 
   29#include <zypp-curl/auth/CurlAuthData> 
   30#include <zypp-media/auth/CredentialManager> 
   31#include <zypp-curl/CurlConfig> 
   55#ifdef ENABLE_ZCHUNK_COMPRESSION 
   76                            const Pathname & attach_point_hint_r )
 
   84      MIL << 
"MediaCurl2::MediaCurl2(" << url_r << 
", " << attach_point_hint_r << 
")" << endl;
 
   90        char    *atemp = ::strdup( apath.
asString().c_str());
 
   93            atemp == NULL || (atest=::mkdtemp(atemp)) == NULL)
 
   95          WAR << 
"attach point " << ainfo.
path()
 
   96              << 
" is not useable for " << url_r.
getScheme() << endl;
 
   99        else if( atest != NULL)
 
 
  113      return ::internal::clearQueryString(
url);
 
 
  120      if ( !zyppng::NetworkRequestDispatcher::supportsProtocol ( 
url ) )
 
  122        std::string msg(
"Unsupported protocol '");
 
  123        msg += 
url.getScheme();
 
 
  162        if ( cred && cred->valid() ) {
 
 
  175      if ( !
_url.isValid() )
 
 
  227      const auto &filename = srcFile.
filename();
 
 
  265      if(
_url.getHost().empty())
 
  270      DBG << 
"URL: " << 
url.asString() << endl;
 
  278      auto req = std::make_shared<zyppng::NetworkRequest>( curlUrl, 
"/dev/null" );
 
  297      return ( !req->hasError() );
 
 
  305      if( assert_dir( dest.
dirname() ) ) {
 
  306        DBG << 
"assert_dir " << dest.
dirname() << 
" failed" << endl;
 
  313          ERR << 
"out of memory for temp file name" << endl;
 
  317        AutoFD tmp_fd { ::mkostemp( buf, O_CLOEXEC ) };
 
  319          ERR << 
"mkstemp failed for file '" << destNew << 
"'" << endl;
 
  325      DBG << 
"dest: " << dest << endl;
 
  326      DBG << 
"temp: " << destNew << endl;
 
  328      Not implemented here yet because NetworkRequest can not 
do IFMODSINCE yet
 
  332        curl_easy_setopt(_curl, CURLOPT_TIMECONDITION, CURL_TIMECOND_IFMODSINCE);
 
  333        curl_easy_setopt(_curl, CURLOPT_TIMEVALUE, (
long)
PathInfo(
target).mtime());
 
  337        curl_easy_setopt(_curl, CURLOPT_TIMECONDITION, CURL_TIMECOND_NONE);
 
  338        curl_easy_setopt(_curl, CURLOPT_TIMEVALUE, 0L);
 
  347      if(
_url.getHost().empty())
 
  352      DBG << 
"URL: " << 
url.asString() << endl;
 
  363#ifdef ENABLE_ZCHUNK_COMPRESSION 
  367        req->resetRequestRanges();
 
  372      Also disabled IFMODSINCE code, see above 
while not yet implemented here
 
  373    #if CURLVERSION_AT_LEAST(7,19,4) 
  378          if ( ftell(file) == 0 && ret == 0 )
 
  380        long httpReturnCode = 33;
 
  381        if ( curl_easy_getinfo( _curl, CURLINFO_RESPONSE_CODE, &httpReturnCode ) == CURLE_OK && httpReturnCode == 200 )
 
  383          long conditionUnmet = 33;
 
  384          if ( curl_easy_getinfo( _curl, CURLINFO_CONDITION_UNMET, &conditionUnmet ) == CURLE_OK && conditionUnmet )
 
  386            WAR << 
"TIMECONDITION unmet - retry without." << endl;
 
  387            curl_easy_setopt(_curl, CURLOPT_TIMECONDITION, CURL_TIMECOND_NONE);
 
  388            curl_easy_setopt(_curl, CURLOPT_TIMEVALUE, 0L);
 
  400        ERR << 
"Failed to chmod file " << destNew << endl;
 
  404      if ( rename( destNew, dest ) != 0 ) {
 
  405        ERR << 
"Rename failed" << endl;
 
  408      destNew.resetDispose();   
 
 
  416#ifdef ENABLE_ZCHUNK_COMPRESSION 
  424        std::optional<zypp::Digest> digest;
 
  428        if ( !headerSum.empty () ) {
 
  430          if ( !digest->create( headerSum.type() ) ) {
 
  431            ERR << 
"Unknown header checksum type " << headerSum.type() << std::endl;
 
  434          sum = zypp::Digest::hexStringToUByteArray( headerSum.checksum() );
 
  437        req->addRequestRange( 0, srcFile.
headerSize(), std::move(digest), sum );
 
  440        req->resetRequestRanges();
 
  445            ERR << 
"Failed to setup zchunk because of: " << res._message << std::endl;
 
  456        for ( 
const auto &block : res._blocks ) {
 
  457          if ( block._checksum.size() && block._chksumtype.size() ) {
 
  459            if ( !dig->create( block._chksumtype ) ) {
 
  460              WAR_MEDIA << 
"Trying to create Digest with chksum type " << block._chksumtype << 
" failed " << std::endl;
 
  466            req->addRequestRange( block._start, block._len, std::move(dig), block._checksum, {}, block._relevantDigestLen, block._chksumPad );
 
  475          ERR << 
"ZCK failed with error: " << err << std::endl;
 
 
  493      for ( filesystem::DirContent::const_iterator it = content.begin(); it != content.end(); ++it ) {
 
  494        Pathname filename = dirname + it->name;
 
  497        switch ( it->type ) {
 
  504              getDir( filename, recurse_r );
 
  506              res = assert_dir( 
localPath( filename ) );
 
  508                WAR << 
"Ignore error (" << res <<  
") on creating local directory '" << 
localPath( filename ) << 
"'" << endl;
 
 
  522                                 const Pathname & dirname, 
bool dots )
 const 
 
  530                                 const Pathname & dirname, 
bool dots )
 const 
 
  541      bool firstAuth = 
true;
 
  546        std::optional<internal::ProgressTracker> progTracker;
 
  548        std::vector<zyppng::connection> signalConnections {
 
  550            if ( !report) 
return;
 
  554            if ( !report || !progTracker )
 
  557            progTracker->updateStats( dlTotal, dlNow );
 
  558            if ( !(*report)->progress( progTracker->_dnlPercent, req.
url(), progTracker-> _drateTotal, progTracker->_drateLast ) )
 
  569          std::for_each( signalConnections.begin(), signalConnections.end(), []( 
auto &conn ) { conn.disconnect(); });
 
  570          signalConnections.clear();
 
  588        if ( req->hasError() ) {
 
  590          std::exception_ptr excp;
 
  591          const auto &error = req->error();
 
  592          switch ( error.type() ) {
 
  636              std::string authHint = error.extraInfoValue(
"authHint", std::string());
 
  649              DBG << 
"BUG: Download error flag is set , but Error code is NoError" << std::endl;
 
  659            if ( maxTries > 0 ) {
 
  664            if ( report ) (*report)->finish( req->url(), errCode, error.toString() );
 
  665            std::rethrow_exception( excp );
 
 
  689      if (cmcred && firstTry)
 
  692        DBG << 
"got stored credentials:" << endl << *credentials << endl;
 
  703        if (!
url.getUsername().empty() && firstTry)
 
  704          curlcred->setUsername(
url.getUsername());
 
  707          curlcred->setUsername(cmcred->username());
 
  712        std::string prompt_msg = 
str::Format(
_(
"Authentication required for '%s'")) % 
url.asString();
 
  716        curlcred->setAuthType(availAuthTypes);
 
  719        if (auth_report->prompt(
url, prompt_msg, *curlcred))
 
  721          DBG << 
"callback answer: retry" << endl
 
  722              << 
"CurlAuthData: " << *curlcred << endl;
 
  724          if (curlcred->valid())
 
  726            credentials = curlcred;
 
  740          DBG << 
"callback answer: cancel" << endl;
 
  747        settings.setUsername(credentials->username());
 
  748        settings.setPassword(credentials->password());
 
  751        if (credentials->authType() == CURLAUTH_NONE)
 
  752          credentials->setAuthType(availAuthTypes);
 
  755        if (credentials->authType() != CURLAUTH_NONE) {
 
  756          settings.setAuthType(credentials->authTypeAsString());
 
  761          credentials->setUrl(
url);
 
 
Compute Message Digests (MD5, SHA1 etc)
static std::string digestVectorToString(const UByteArray &vec)
get hex string representation of the digest vector given as parameter
Base class for Exception.
std::string asUserHistory() const
A single (multiline) string composed of asUserString and historyAsString.
std::string getScheme() const
Returns the scheme name of the URL.
static ZConfig & instance()
Singleton ctor.
Wrapper class for stat/lstat.
const Pathname & path() const
Return current Pathname.
Pathname dirname() const
Return all but the last component od this path.
const std::string & asString() const
String representation.
bool empty() const
Test for an empty path.
Pathname absolutename() const
Return this path, adding a leading '/' if relative.
The NetworkRequestError class Represents a error that occured in.
const zypp::Pathname & targetFilePath() const
Returns the target filename path.
SignalProxy< void(NetworkRequest &req, const NetworkRequestError &err)> sigFinished()
Signals that the download finished.
SignalProxy< void(NetworkRequest &req, off_t dltotal, off_t dlnow, off_t ultotal, off_t ulnow)> sigProgress()
Signals if there was data read from the download.
static bool validateZckFile(const zypp::Pathname &file, std::string &error)
static bool isZchunkFile(const zypp::Pathname &file)
static PrepareResult prepareZck(const zypp::Pathname &delta, const zypp::Pathname &target, const zypp::ByteCount &expectedFileSize)
void fillSettingsFromUrl(const Url &url, media::TransferSettings &s)
Fills the settings structure using options passed on the url for example ?timeout=x&proxy=foo.
void fillSettingsSystemProxy(const Url &url, media::TransferSettings &s)
Reads the system proxy configuration and fills the settings structure proxy information.
const long & ZYPP_MEDIA_CURL_DEBUG()
const long& for setting CURLOPT_DEBUGDATA Returns a reference to a static variable,...
mode_t applyUmaskTo(mode_t mode_r)
Modify mode_r according to the current umask ( mode_r & ~getUmask() ).
std::list< DirEntry > DirContent
Returned by readdir.
int unlink(const Pathname &path)
Like 'unlink'.
const std::string & asString(const std::string &t)
Global asString() that works with std::string too.
Easy-to use interface to the ZYPP dependency resolver.
AutoDispose< const Pathname > ManagedFile
A Pathname plus associated cleanup code to be executed when path is no longer needed.
Bottleneck filtering all DownloadProgressReport issued from Media[Muli]Curl.
AutoDispose<int> calling ::close
#define ZYPP_RETHROW(EXCPT)
Drops a logline and rethrows, updating the CodeLocation.
#define ZYPP_EXCPT_PTR(EXCPT)
Drops a logline and returns Exception as a std::exception_ptr.
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.