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> 44 #include <sys/types.h> 46 #include <sys/mount.h> 55 #ifdef ENABLE_ZCHUNK_COMPRESSION 75 MediaCurl2::MediaCurl2(
const Url & url_r,
76 const Pathname & attach_point_hint_r )
80 , _evDispatcher(
zyppng::ThreadData::current().ensureDispatcher() )
81 , _nwDispatcher(
std::make_shared<
zyppng::NetworkRequestDispatcher>() )
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)
120 if ( !zyppng::NetworkRequestDispatcher::supportsProtocol (
url ) )
122 std::string msg(
"Unsupported protocol '");
162 if ( cred && cred->valid() ) {
227 const auto &filename = srcFile.
filename();
278 auto req = std::make_shared<zyppng::NetworkRequest>( curlUrl,
"/dev/null" );
297 return ( !req->hasError() );
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);
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 );
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;
707 curlcred->setUsername(cmcred->username());
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;
751 if (credentials->authType() == CURLAUTH_NONE)
752 credentials->setAuthType(availAuthTypes);
755 if (credentials->authType() != CURLAUTH_NONE) {
761 credentials->setUrl(
url);
std::string getScheme() const
Returns the scheme name of the URL.
int assert_dir(const Pathname &path, unsigned mode)
Like 'mkdir -p'.
const Pathname & path() const
Return current Pathname.
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
static ZConfig & instance()
Singleton ctor.
Compute Message Digests (MD5, SHA1 etc)
Pathname extend(const std::string &r) const
Append string r to the last component of the path.
int chmod(const Pathname &path, mode_t mode)
Like 'chmod'.
Url clearQueryString(const Url &url)
const std::string & asString(const std::string &t)
Global asString() that works with std::string too.
AutoDispose<int> calling ::close
#define ZYPP_EXCPT_PTR(EXCPT)
Drops a logline and returns Exception as a std::exception_ptr.
std::list< DirEntry > DirContent
Returned by readdir.
static bool isZchunkFile(const zypp::Pathname &file)
AutoDispose< const Pathname > ManagedFile
A Pathname plus associated cleanup code to be executed when path is no longer needed.
static std::string digestVectorToString(const UByteArray &vec)
get hex string representation of the digest vector given as parameter
bool empty() const
Test for an empty path.
#define ZYPP_RETHROW(EXCPT)
Drops a logline and rethrows, updating the CodeLocation.
std::string asString() const
Returns a default string representation of the Url object.
Bottleneck filtering all DownloadProgressReport issued from Media[Muli]Curl.
const std::string & asString() const
String representation.
std::string asUserHistory() const
A single (multiline) string composed of asUserString and historyAsString.
Pathname dirname() const
Return all but the last component od this path.
The NetworkRequestError class Represents a error that occured in.
const long & ZYPP_MEDIA_CURL_DEBUG()
const long& for setting CURLOPT_DEBUGDATA Returns a reference to a static variable, so it's safe to pass ...
void fillSettingsFromUrl(const Url &url, media::TransferSettings &s)
Fills the settings structure using options passed on the url for example ?timeout=x&proxy=foo.
bool isValid() const
Verifies the Url.
int unlink(const Pathname &path)
Like 'unlink'.
const zypp::Pathname & targetFilePath() const
Returns the target filename path.
Pathname absolutename() const
Return this path, adding a leading '/' if relative.
Base class for Exception.
static bool validateZckFile(const zypp::Pathname &file, std::string &error)
std::string getPathName(EEncoding eflag=zypp::url::E_DECODED) const
Returns the path name from the URL.
std::string getHost(EEncoding eflag=zypp::url::E_DECODED) const
Returns the hostname or IP from the URL authority.
Wrapper class for ::stat/::lstat.
SignalProxy< void(NetworkRequest &req, const NetworkRequestError &err)> sigFinished()
Signals that the download finished.
void fillSettingsSystemProxy(const Url &url, media::TransferSettings &s)
Reads the system proxy configuration and fills the settings structure proxy information.
mode_t applyUmaskTo(mode_t mode_r)
Modify mode_r according to the current umask ( mode_r & ~getUmask() ).
int rename(const Pathname &oldpath, const Pathname &newpath)
Like 'rename'.
Easy-to use interface to the ZYPP dependency resolver.
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.
int rmdir(const Pathname &path)
Like 'rmdir'.
static PrepareResult prepareZck(const zypp::Pathname &delta, const zypp::Pathname &target, const zypp::ByteCount &expectedFileSize)
std::string getUsername(EEncoding eflag=zypp::url::E_DECODED) const
Returns the username from the URL authority.