19#include <zypp-core/parser/Sysconfig>
25#include <zypp-curl/ProxyInfo>
26#include <zypp-curl/CurlConfig>
48#ifdef ENABLE_ZCHUNK_COMPRESSION
69 const Pathname & attach_point_hint_r )
76 MIL <<
"MediaCurl2::MediaCurl2(" << url_r.url() <<
", " << attach_point_hint_r <<
")" << endl;
82 char *atemp = ::strdup( apath.
asString().c_str());
85 atemp == NULL || (atest=::mkdtemp(atemp)) == NULL)
87 WAR <<
"attach point " << ainfo.
path()
88 <<
" is not useable for " << url_r.url().getScheme() << endl;
91 else if( atest != NULL)
103 if ( !zyppng::NetworkRequestDispatcher::supportsProtocol (
url ) )
105 std::string msg(
"Unsupported protocol '");
106 msg +=
url.getScheme();
130 const auto &filename = srcFile.
filename();
136 for (
unsigned mirr = 0; mirr <
_urls.size(); ++mirr ) {
138 MIL <<
"Trying to fetch file " << srcFile <<
" with mirror " <<
_urls[mirr].url() << std::endl;
146 if(
_urls[mirr].
url().getHost().empty())
151 if( assert_dir( dest.
dirname() ) ) {
152 DBG <<
"assert_dir " << dest.
dirname() <<
" failed" << endl;
159 ERR <<
"out of memory for temp file name" << endl;
163 AutoFD tmp_fd { ::mkostemp( buf, O_CLOEXEC ) };
165 ERR <<
"mkstemp failed for file '" << destNew <<
"'" << endl;
171 DBG <<
"dest: " << dest << endl;
172 DBG <<
"temp: " << destNew << endl;
174 Not implemented here yet because NetworkRequest can not
do IFMODSINCE yet
176 if(
PathInfo(
target).isExist() && !(options & OPTION_NO_IFMODSINCE) )
178 curl_easy_setopt(_curl, CURLOPT_TIMECONDITION, CURL_TIMECOND_IFMODSINCE);
179 curl_easy_setopt(_curl, CURLOPT_TIMEVALUE, (
long)
PathInfo(
target).mtime());
183 curl_easy_setopt(_curl, CURLOPT_TIMECONDITION, CURL_TIMECOND_NONE);
184 curl_easy_setopt(_curl, CURLOPT_TIMEVALUE, 0L);
204 #ifdef ENABLE_ZCHUNK_COMPRESSION
208 r.
_req->resetRequestRanges();
213 Also disabled IFMODSINCE code, see above
while not yet implemented here
214 #if CURLVERSION_AT_LEAST(7,19,4)
219 if ( ftell(file) == 0 && ret == 0 )
221 long httpReturnCode = 33;
222 if ( curl_easy_getinfo( _curl, CURLINFO_RESPONSE_CODE, &httpReturnCode ) == CURLE_OK && httpReturnCode == 200 )
224 long conditionUnmet = 33;
225 if ( curl_easy_getinfo( _curl, CURLINFO_CONDITION_UNMET, &conditionUnmet ) == CURLE_OK && conditionUnmet )
227 WAR <<
"TIMECONDITION unmet - retry without." << endl;
228 curl_easy_setopt(_curl, CURLOPT_TIMECONDITION, CURL_TIMECOND_NONE);
229 curl_easy_setopt(_curl, CURLOPT_TIMEVALUE, 0L);
241 ERR <<
"Failed to chmod file " << destNew << endl;
245 if ( rename( destNew, dest ) != 0 ) {
246 ERR <<
"Rename failed" << endl;
249 destNew.resetDispose();
277 std::exception_ptr lastErr;
278 for (
unsigned mirr = 0; mirr <
_urls.size(); ++mirr ) {
282 if(
_urls[mirr].
url().getHost().empty() )
287 DBG <<
"URL: " <<
url.asString() << endl;
297 r.
_req = std::make_shared<zyppng::NetworkRequest>( curlUrl,
"/dev/null" );
316 return ( !r.
_req->hasError() );
333#ifdef ENABLE_ZCHUNK_COMPRESSION
341 std::optional<zypp::Digest> digest;
345 if ( !headerSum.empty () ) {
347 if ( !digest->create( headerSum.type() ) ) {
348 ERR <<
"Unknown header checksum type " << headerSum.type() << std::endl;
351 sum = zypp::Digest::hexStringToUByteArray( headerSum.checksum() );
354 reqData.
_req->addRequestRange( 0, srcFile.
headerSize(), std::move(digest), sum );
357 reqData.
_req->resetRequestRanges();
362 ERR <<
"Failed to setup zchunk because of: " << res._message << std::endl;
373 for (
const auto &block : res._blocks ) {
374 if ( block._checksum.size() && block._chksumtype.size() ) {
376 if ( !dig->create( block._chksumtype ) ) {
377 WAR_MEDIA <<
"Trying to create Digest with chksum type " << block._chksumtype <<
" failed " << std::endl;
383 reqData.
_req->addRequestRange( block._start, block._len, std::move(dig), block._checksum, {}, block._relevantDigestLen, block._chksumPad );
392 ERR <<
"ZCK failed with error: " << err << std::endl;
403 const auto &authCb = [&](
const zypp::Url &,
TransferSettings &settings,
const std::string & availAuthTypes,
bool firstTry,
bool &canContinue ) {
412 auto conn =
_executor->sigAuthRequired().connect (authCb);
Compute Message Digests (MD5, SHA1 etc)
static std::string digestVectorToString(const UByteArray &vec)
get hex string representation of the digest vector given as parameter
std::string asString() const
Returns a default string representation of the Url object.
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.
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)
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() ).
int unlink(const Pathname &path)
Like 'unlink'.
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_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
#define ZYPP_FWD_CURRENT_EXCPT()
Drops a logline and returns the current Exception as a std::exception_ptr.
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.