libzypp 17.36.3
MediaCurl2.cc
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8\---------------------------------------------------------------------*/
12
13#include <iostream>
14#include <chrono>
15#include <list>
16
17#include <zypp/base/Logger.h>
19#include <zypp/base/String.h>
20#include <zypp/base/Gettext.h>
21#include <zypp-core/parser/Sysconfig>
22#include <zypp/base/Gettext.h>
23
25
28#include <zypp-curl/ProxyInfo>
29#include <zypp-curl/auth/CurlAuthData>
30#include <zypp-media/auth/CredentialManager>
31#include <zypp-curl/CurlConfig>
33#include <zypp/Target.h>
34#include <zypp/ZYppFactory.h>
35#include <zypp/ZConfig.h>
36#include <zypp/zypp_detail/ZYppImpl.h> // for zypp_poll
37
42
43#include <cstdlib>
44#include <sys/types.h>
45#include <sys/stat.h>
46#include <sys/mount.h>
47#include <dirent.h>
48#include <unistd.h>
49#include <glib.h>
50
53
54#ifdef ENABLE_ZCHUNK_COMPRESSION
56#endif
57
58
64
65using std::endl;
66
67namespace internal {
68 using namespace zypp;
69
71
72 using clock = std::chrono::steady_clock;
73
74 std::optional<clock::time_point> _timeStart;
75 std::optional<clock::time_point> _timeLast;
76
77 double _dnlTotal = 0.0;
78 double _dnlLast = 0.0;
79 double _dnlNow = 0.0;
80
81 int _dnlPercent= 0;
82
83 double _drateTotal= 0.0;
84 double _drateLast = 0.0;
85
86 void updateStats( double dltotal = 0.0, double dlnow = 0.0 )
87 {
88 clock::time_point now = clock::now();
89
90 if ( !_timeStart )
91 _timeStart = _timeLast = now;
92
93 // If called without args (0.0), recompute based on the last values seen
94 if ( dltotal && dltotal != _dnlTotal )
95 _dnlTotal = dltotal;
96
97 if ( dlnow && dlnow != _dnlNow ) {
98 _dnlNow = dlnow;
99 }
100
101 // percentage:
102 if ( _dnlTotal )
103 _dnlPercent = int(_dnlNow * 100 / _dnlTotal);
104
105 // download rates:
106 _drateTotal = _dnlNow / std::max( std::chrono::duration_cast<std::chrono::seconds>(now - *_timeStart).count(), int64_t(1) );
107
108 if ( _timeLast < now )
109 {
110 _drateLast = (_dnlNow - _dnlLast) / int( std::chrono::duration_cast<std::chrono::seconds>(now - *_timeLast).count() );
111 // start new period
112 _timeLast = now;
114 }
115 else if ( _timeStart == _timeLast )
117 }
118 };
119}
120
121using namespace internal;
122using namespace zypp::base;
123
124namespace zypp {
125
126 namespace media {
127
129 const Pathname & attach_point_hint_r )
130 : MediaNetworkCommonHandler( url_r, attach_point_hint_r,
131 "/", // urlpath at attachpoint
132 true ) // does_download
133 , _evDispatcher( zyppng::ThreadData::current().ensureDispatcher() )
134 , _nwDispatcher( std::make_shared<zyppng::NetworkRequestDispatcher>() )
135 {
136
137 MIL << "MediaCurl2::MediaCurl2(" << url_r << ", " << attach_point_hint_r << ")" << endl;
138
139 if( !attachPoint().empty())
140 {
141 PathInfo ainfo(attachPoint());
142 Pathname apath(attachPoint() + "XXXXXX");
143 char *atemp = ::strdup( apath.asString().c_str());
144 char *atest = NULL;
145 if( !ainfo.isDir() || !ainfo.userMayRWX() ||
146 atemp == NULL || (atest=::mkdtemp(atemp)) == NULL)
147 {
148 WAR << "attach point " << ainfo.path()
149 << " is not useable for " << url_r.getScheme() << endl;
150 setAttachPoint("", true);
151 }
152 else if( atest != NULL)
153 ::rmdir(atest);
154
155 if( atemp != NULL)
156 ::free(atemp);
157 }
158
159 _nwDispatcher->setAgentString ( str::asString( agentString () ) );
160 _nwDispatcher->setHostSpecificHeader ("download.opensuse.org", "X-ZYpp-DistributionFlavor", str::asString(distributionFlavorHeader()) );
161 _nwDispatcher->setHostSpecificHeader ("download.opensuse.org", "X-ZYpp-AnonymousId", str::asString(anonymousIdHeader()) );
162 }
163
168
170
172 {
173 if ( !zyppng::NetworkRequestDispatcher::supportsProtocol ( url ) )
174 {
175 std::string msg("Unsupported protocol '");
176 msg += url.getScheme();
177 msg += "'";
179 }
180 }
181
183 {
184 // fill some settings from url query parameters
185 try
186 {
189 }
190 catch ( const MediaException &e )
191 {
193 ZYPP_RETHROW(e);
194 }
195 // if the proxy was not set (or explicitly unset) by url, then look...
196 if ( _effectiveSettings.proxy().empty() )
197 {
198 // ...at the system proxy settings
200 }
201
202 /* Fixes bsc#1174011 "auth=basic ignored in some cases"
203 * We should proactively add the password to the request if basic auth is configured
204 * and a password is available in the credentials but not in the URL.
205 *
206 * We will be a bit paranoid here and require that the URL has a user embedded, otherwise we go the default route
207 * and ask the server first about the auth method
208 */
209 if ( _effectiveSettings.authType() == "basic"
210 && _effectiveSettings.username().size()
211 && !_effectiveSettings.password().size() ) {
212
214 const auto cred = cm.getCred( _url );
215 if ( cred && cred->valid() ) {
216 if ( !_effectiveSettings.username().size() )
217 _effectiveSettings.setUsername(cred->username());
218 _effectiveSettings.setPassword(cred->password());
219 }
220 }
221 }
222
223 void MediaCurl2::attachTo (bool next)
224 {
225 if ( next )
227
228 if ( !_url.isValid() )
230
233 {
235 }
236
237 disconnectFrom(); // clean state if needed
238
239 // here : setup TransferSettings
240 setupEasy();
241
242 // FIXME: need a derived class to propelly compare url's
243 MediaSourceRef media( new MediaSource(_url.getScheme(), _url.asString()));
245 }
246
247 bool
249 {
250 return MediaHandler::checkAttachPoint( apoint, true, true);
251 }
252
254 {
255 // clear effective settings
257 }
258
260
261 void MediaCurl2::releaseFrom( const std::string & ejectDev )
262 {
263 disconnect();
264 }
265
267
268 void MediaCurl2::getFile( const OnMediaLocation &file ) const
269 {
270 // Use absolute file name to prevent access of files outside of the
271 // hierarchy below the attach point.
272 getFileCopy( file, localPath(file.filename()).absolutename() );
273 }
274
276
277 void MediaCurl2::getFileCopy( const OnMediaLocation & srcFile , const Pathname & target ) const
278 {
279
280 const auto &filename = srcFile.filename();
281
282 // Optional files will send no report until data are actually received (we know it exists).
283 OptionalDownloadProgressReport reportfilter( srcFile.optional() );
285
286 Url fileurl(getFileUrl(filename));
287 do
288 {
289 try
290 {
291 doGetFileCopy( srcFile, target, report );
292 break; // success!
293 }
294 // unexpected exception
295 catch (MediaException & excpt_r)
296 {
298 if( typeid(excpt_r) == typeid( media::MediaFileNotFoundException ) ||
299 typeid(excpt_r) == typeid( media::MediaNotAFileException ) )
300 {
302 }
303 report->finish(fileurl, reason, excpt_r.asUserHistory());
304 ZYPP_RETHROW(excpt_r);
305 }
306 }
307 while ( true );
308 report->finish(fileurl, zypp::media::DownloadProgressReport::NO_ERROR, "");
309 }
310
311 bool MediaCurl2::getDoesFileExist( const Pathname & filename ) const
312 {
313 DBG << filename.asString() << endl;
314
315 if(!_url.isValid())
317
318 if(_url.getHost().empty())
320
321 Url url(getFileUrl(filename));
322
323 DBG << "URL: " << url.asString() << endl;
324
325 // Use URL without options and without username and passwd
326 // (some proxies dislike them in the URL).
327 // Curl seems to need the just scheme, hostname and a path;
328 // the rest was already passed as curl options (in attachTo).
329 Url curlUrl( clearQueryString(url) );
330
331 auto req = std::make_shared<zyppng::NetworkRequest>( curlUrl, "/dev/null" );
332 req->setOptions ( zyppng::NetworkRequest::HeadRequest ); // just check for existance
333
334 // as we are not having user interaction, the user can't cancel
335 // the file existence checking, a callback or timeout return code
336 // will be always a timeout.
337 try {
338 const_cast<MediaCurl2*>(this)->executeRequest ( req );
339 }
340 catch ( const MediaFileNotFoundException &e ) {
341 // if the file did not exist then we can return false
342 return false;
343 }
344 catch ( const MediaException &e ) {
345 // some error, we are not sure about file existence, rethrw
346 ZYPP_RETHROW(e);
347 }
348
349 // exists
350 return ( !req->hasError() );
351 }
352
354
355 void MediaCurl2::doGetFileCopy( const OnMediaLocation &srcFile , const Pathname & target, callback::SendReport<DownloadProgressReport> & report, RequestOptions options ) const
356 {
357 Pathname dest = target.absolutename();
358 if( assert_dir( dest.dirname() ) ) {
359 DBG << "assert_dir " << dest.dirname() << " failed" << endl;
360 ZYPP_THROW( MediaSystemException(getFileUrl(srcFile.filename()), "System error on " + dest.dirname().asString()) );
361 }
362
363 ManagedFile destNew { target.extend( ".new.zypp.XXXXXX" ) }; {
364 AutoFREE<char> buf { ::strdup( (*destNew).c_str() ) };
365 if( ! buf ) {
366 ERR << "out of memory for temp file name" << endl;
367 ZYPP_THROW(MediaSystemException(getFileUrl(srcFile.filename()), "out of memory for temp file name"));
368 }
369
370 AutoFD tmp_fd { ::mkostemp( buf, O_CLOEXEC ) };
371 if( tmp_fd == -1 ) {
372 ERR << "mkstemp failed for file '" << destNew << "'" << endl;
374 }
375 destNew = ManagedFile( (*buf), filesystem::unlink );
376 }
377
378 DBG << "dest: " << dest << endl;
379 DBG << "temp: " << destNew << endl;
380#if 0
381 Not implemented here yet because NetworkRequest can not do IFMODSINCE yet
382 // set IFMODSINCE time condition (no download if not modified)
383 if( PathInfo(target).isExist() && !(options & OPTION_NO_IFMODSINCE) )
384 {
385 curl_easy_setopt(_curl, CURLOPT_TIMECONDITION, CURL_TIMECOND_IFMODSINCE);
386 curl_easy_setopt(_curl, CURLOPT_TIMEVALUE, (long)PathInfo(target).mtime());
387 }
388 else
389 {
390 curl_easy_setopt(_curl, CURLOPT_TIMECONDITION, CURL_TIMECOND_NONE);
391 curl_easy_setopt(_curl, CURLOPT_TIMEVALUE, 0L);
392 }
393#endif
394
395 DBG << srcFile.filename().asString() << endl;
396
397 if(!_url.isValid())
399
400 if(_url.getHost().empty())
402
403 Url url(getFileUrl(srcFile.filename()));
404
405 DBG << "URL: " << url.asString() << endl;
406 // Use URL without options and without username and passwd
407 // (some proxies dislike them in the URL).
408 // Curl seems to need the just scheme, hostname and a path;
409 // the rest was already passed as curl options (in attachTo).
410 Url curlUrl( clearQueryString(url) );
411
412 auto req = std::make_shared<zyppng::NetworkRequest>( curlUrl, destNew, zyppng::NetworkRequest::WriteShared /*do not truncate*/ );
413 req->setExpectedFileSize ( srcFile.downloadSize () );
414
415 bool done = false;
416#ifdef ENABLE_ZCHUNK_COMPRESSION
417 done = const_cast<MediaCurl2*>(this)->tryZchunk(req, srcFile, destNew, report);
418#endif
419 if ( !done ) {
420 req->resetRequestRanges();
421 const_cast<MediaCurl2 *>(this)->executeRequest ( req, &report );
422 }
423
424#if 0
425 Also disabled IFMODSINCE code, see above while not yet implemented here
426 #if CURLVERSION_AT_LEAST(7,19,4)
427 // bnc#692260: If the client sends a request with an If-Modified-Since header
428 // with a future date for the server, the server may respond 200 sending a
429 // zero size file.
430 // curl-7.19.4 introduces CURLINFO_CONDITION_UNMET to check this condition.
431 if ( ftell(file) == 0 && ret == 0 )
432 {
433 long httpReturnCode = 33;
434 if ( curl_easy_getinfo( _curl, CURLINFO_RESPONSE_CODE, &httpReturnCode ) == CURLE_OK && httpReturnCode == 200 )
435 {
436 long conditionUnmet = 33;
437 if ( curl_easy_getinfo( _curl, CURLINFO_CONDITION_UNMET, &conditionUnmet ) == CURLE_OK && conditionUnmet )
438 {
439 WAR << "TIMECONDITION unmet - retry without." << endl;
440 curl_easy_setopt(_curl, CURLOPT_TIMECONDITION, CURL_TIMECOND_NONE);
441 curl_easy_setopt(_curl, CURLOPT_TIMEVALUE, 0L);
442 ret = executeCurl();
443 }
444 }
445 }
446#endif
447#endif
448
449
450 // apply umask
451 if ( ::chmod( destNew->c_str(), filesystem::applyUmaskTo( 0644 ) ) )
452 {
453 ERR << "Failed to chmod file " << destNew << endl;
454 }
455
456 // move the temp file into dest
457 if ( rename( destNew, dest ) != 0 ) {
458 ERR << "Rename failed" << endl;
460 }
461 destNew.resetDispose(); // no more need to unlink it
462
463 DBG << "done: " << PathInfo(dest) << endl;
464 }
465
466
467 bool MediaCurl2::tryZchunk( zyppng::NetworkRequestRef req, const OnMediaLocation &srcFile, const Pathname &target, callback::SendReport<DownloadProgressReport> &report )
468 {
469#ifdef ENABLE_ZCHUNK_COMPRESSION
470
471 // HERE add zchunk logic if required
472 if ( !srcFile.deltafile().empty()
474 && srcFile.headerSize () > 0 ) {
475
476 // first fetch the zck header
477 std::optional<zypp::Digest> digest;
478 UByteArray sum;
479
480 const auto &headerSum = srcFile.headerChecksum();
481 if ( !headerSum.empty () ) {
482 digest = zypp::Digest();
483 if ( !digest->create( headerSum.type() ) ) {
484 ERR << "Unknown header checksum type " << headerSum.type() << std::endl;
485 return false;
486 }
487 sum = zypp::Digest::hexStringToUByteArray( headerSum.checksum() );
488 }
489
490 req->addRequestRange( 0, srcFile.headerSize(), std::move(digest), sum );
491 executeRequest ( req, nullptr );
492
493 req->resetRequestRanges();
494
495 auto res = zyppng::ZckHelper::prepareZck( srcFile.deltafile(), target, srcFile.downloadSize() );
496 switch(res._code) {
498 ERR << "Failed to setup zchunk because of: " << res._message << std::endl;
499 return false;
500 }
502 return true; // already done
504 ZYPP_THROW( MediaFileSizeExceededException( req->url(), srcFile.downloadSize(), res._message ));
506 break;
507 }
508
509 for ( const auto &block : res._blocks ) {
510 if ( block._checksum.size() && block._chksumtype.size() ) {
511 std::optional<zypp::Digest> dig = zypp::Digest();
512 if ( !dig->create( block._chksumtype ) ) {
513 WAR_MEDIA << "Trying to create Digest with chksum type " << block._chksumtype << " failed " << std::endl;
514 return false;
515 }
516
518 DBG_MEDIA << "Starting block " << block._start << " with checksum " << zypp::Digest::digestVectorToString( block._checksum ) << "." << std::endl;
519 req->addRequestRange( block._start, block._len, std::move(dig), block._checksum, {}, block._relevantDigestLen, block._chksumPad );
520 }
521 };
522
523 executeRequest ( req, &report );
524
525 //we might have the file ready
526 std::string err;
528 ERR << "ZCK failed with error: " << err << std::endl;
529 return false;
530 }
531 return true;
532 }
533#endif
534 return false;
535 }
536
537
538
540
541 void MediaCurl2::getDir( const Pathname & dirname, bool recurse_r ) const
542 {
544 getDirInfo( content, dirname, /*dots*/false );
545
546 for ( filesystem::DirContent::const_iterator it = content.begin(); it != content.end(); ++it ) {
547 Pathname filename = dirname + it->name;
548 int res = 0;
549
550 switch ( it->type ) {
551 case filesystem::FT_NOT_AVAIL: // old directory.yast contains no typeinfo at all
553 getFile( OnMediaLocation( filename ) );
554 break;
555 case filesystem::FT_DIR: // newer directory.yast contain at least directory info
556 if ( recurse_r ) {
557 getDir( filename, recurse_r );
558 } else {
559 res = assert_dir( localPath( filename ) );
560 if ( res ) {
561 WAR << "Ignore error (" << res << ") on creating local directory '" << localPath( filename ) << "'" << endl;
562 }
563 }
564 break;
565 default:
566 // don't provide devices, sockets, etc.
567 break;
568 }
569 }
570 }
571
573
574 void MediaCurl2::getDirInfo( std::list<std::string> & retlist,
575 const Pathname & dirname, bool dots ) const
576 {
577 getDirectoryYast( retlist, dirname, dots );
578 }
579
581
583 const Pathname & dirname, bool dots ) const
584 {
585 getDirectoryYast( retlist, dirname, dots );
586 }
587
588 void MediaCurl2::executeRequest( zyppng::NetworkRequestRef req , callback::SendReport<DownloadProgressReport> *report )
589 {
590 auto loop = zyppng::EventLoop::create();
591
592 _nwDispatcher->run();
593
594 bool firstAuth = true;
595 bool retry = true;
596 int maxTries = _effectiveSettings.maxSilentTries();
597
598 while ( retry ) {
599 std::optional<internal::ProgressTracker> progTracker;
600
601 std::vector<zyppng::connection> signalConnections {
602 req->sigStarted().connect( [&]( zyppng::NetworkRequest &req ){
603 if ( !report) return;
604 (*report)->start( req.url(), req.targetFilePath() );
605 }),
606 req->sigProgress().connect( [&]( zyppng::NetworkRequest &req, off_t dlTotal, off_t dlNow, off_t, off_t ){
607 if ( !report || !progTracker )
608 return;
609
610 progTracker->updateStats( dlTotal, dlNow );
611 if ( !(*report)->progress( progTracker->_dnlPercent, req.url(), progTracker-> _drateTotal, progTracker->_drateLast ) )
612 _nwDispatcher->cancel ( req );
613
614 }),
615 req->sigFinished().connect( [&]( zyppng::NetworkRequest &req, const zyppng::NetworkRequestError &err ) {
616 loop->quit();
617 })
618 };
619
620 // clean up slots for every loop
621 zypp_defer {
622 std::for_each( signalConnections.begin(), signalConnections.end(), []( auto &conn ) { conn.disconnect(); });
623 signalConnections.clear();
624 };
625
626 if ( report ) {
627 progTracker = internal::ProgressTracker();
628 }
629
630 maxTries--;
631 retry = false; // normally we don't retry
632 req->transferSettings() = _effectiveSettings; // use settings from MediaCurl
633 _nwDispatcher->enqueue ( req );
634 loop->run();
635
636 // once the request is done there should be nothing there anymore
637 if ( _nwDispatcher->count () != 0 ) {
638 ZYPP_THROW( zypp::Exception("Unexpected request count after finishing MediaCurl2 request!") );
639 }
640
641 if ( req->hasError() ) {
643 std::exception_ptr excp;
644 const auto &error = req->error();
645 switch ( error.type() ) {
655 excp = ZYPP_EXCPT_PTR( zypp::media::MediaCurlException( req->url(), error.toString(), error.nativeErrorString() ) );
656 break;
657 }
660 break;
661 }
663 excp = ZYPP_EXCPT_PTR( zypp::media::MediaFileSizeExceededException( req->url(), req->expectedFileSize() ) );
664 break;
665 }
667 excp = ZYPP_EXCPT_PTR( zypp::media::MediaTemporaryProblemException( req->url(), error.toString() ) );
668 break;
669 }
671 excp = ZYPP_EXCPT_PTR( zypp::media::MediaTimeoutException( req->url(), error.toString() ) );
672 break;
673 }
675 excp = ZYPP_EXCPT_PTR( zypp::media::MediaForbiddenException( req->url(), error.toString() ) );
676 break;
677 }
680
681 //@BUG using getPathName() can result in wrong error messages
682 excp = ZYPP_EXCPT_PTR( zypp::media::MediaFileNotFoundException( _url, req->url().getPathName() ) );
683 break;
684 }
687
688 //in case we got a auth hint from the server the error object will contain it
689 std::string authHint = error.extraInfoValue("authHint", std::string());
690 if ( authenticate( authHint, firstAuth ) ) {
691 firstAuth = false;
692 retry = true;
693 continue;
694 }
695
697 excp = ZYPP_EXCPT_PTR( zypp::media::MediaUnauthorizedException( req->url(), error.toString(), error.nativeErrorString(), "" ) );
698 break;
699 }
701 // should never happen
702 DBG << "BUG: Download error flag is set , but Error code is NoError" << std::endl;
703 break;
706 excp = ZYPP_EXCPT_PTR( zypp::media::MediaCurlException( req->url(), error.toString(), error.nativeErrorString() ) );
707 break;
708 }
709 }
710
711 if ( excp ) {
712 if ( maxTries > 0 ) {
713 retry = true;
714 continue;
715 }
716
717 if ( report ) (*report)->finish( req->url(), errCode, error.toString() );
718 std::rethrow_exception( excp );
719 }
720 }
721
722 }
723
724 if ( report ) (*report)->finish( req->url(), zypp::media::DownloadProgressReport::NO_ERROR, "" );
725 }
726
728
729 bool MediaCurl2::authenticate(const std::string & availAuthTypes, bool firstTry)
730 {
733 CurlAuthData_Ptr credentials;
734
735 // get stored credentials
736 AuthData_Ptr cmcred = cm.getCred(_url);
737
738 if (cmcred && firstTry)
739 {
740 credentials.reset(new CurlAuthData(*cmcred));
741 DBG << "got stored credentials:" << endl << *credentials << endl;
742 }
743 // if not found, ask user
744 else
745 {
746
747 CurlAuthData_Ptr curlcred;
748 curlcred.reset(new CurlAuthData());
750
751 // preset the username if present in current url
752 if (!_url.getUsername().empty() && firstTry)
753 curlcred->setUsername(_url.getUsername());
754 // if CM has found some credentials, preset the username from there
755 else if (cmcred)
756 curlcred->setUsername(cmcred->username());
757
758 // indicate we have no good credentials from CM
759 cmcred.reset();
760
761 std::string prompt_msg = str::Format(_("Authentication required for '%s'")) % _url.asString();
762
763 // set available authentication types from the exception
764 // might be needed in prompt
765 curlcred->setAuthType(availAuthTypes);
766
767 // ask user
768 if (auth_report->prompt(_url, prompt_msg, *curlcred))
769 {
770 DBG << "callback answer: retry" << endl
771 << "CurlAuthData: " << *curlcred << endl;
772
773 if (curlcred->valid())
774 {
775 credentials = curlcred;
776 // if (credentials->username() != _url.getUsername())
777 // _url.setUsername(credentials->username());
785 }
786 }
787 else
788 {
789 DBG << "callback answer: cancel" << endl;
790 }
791 }
792
793 // set username and password
794 if (credentials)
795 {
796 _effectiveSettings.setUsername(credentials->username());
797 _effectiveSettings.setPassword(credentials->password());
798
799 // set available authentication types from the exception
800 if (credentials->authType() == CURLAUTH_NONE)
801 credentials->setAuthType(availAuthTypes);
802
803 // set auth type (seems this must be set _after_ setting the userpwd)
804 if (credentials->authType() != CURLAUTH_NONE) {
805 _effectiveSettings.setAuthType(credentials->authTypeAsString());
806 }
807
808 if (!cmcred)
809 {
810 credentials->setUrl(_url);
811 cm.addCred(*credentials);
812 cm.save();
813 }
814
815 return true;
816 }
817
818 return false;
819 }
820
821 } // namespace media
822} // namespace zypp
823//
Compute Message Digests (MD5, SHA1 etc)
Definition Digest.h:38
static std::string digestVectorToString(const UByteArray &vec)
get hex string representation of the digest vector given as parameter
Definition Digest.cc:243
Base class for Exception.
Definition Exception.h:147
std::string asUserHistory() const
A single (multiline) string composed of asUserString and historyAsString.
Definition Exception.cc:127
Describes a resource file located on a medium.
bool optional() const
Whether this is an optional resource.
const ByteCount & downloadSize() const
The size of the resource on the server.
const Pathname & filename() const
The path to the resource on the medium.
const Pathname & deltafile() const
The existing deltafile that can be used to reduce download size ( zchunk or metalink )
const ByteCount & headerSize() const
The size of the header prepending the resource (e.g.
const CheckSum & headerChecksum() const
The checksum of the header prepending the resource (e.g.
Url manipulation class.
Definition Url.h:93
std::string getScheme() const
Returns the scheme name of the URL.
Definition Url.cc:551
static ZConfig & instance()
Singleton ctor.
Definition ZConfig.cc:935
Wrapper class for stat/lstat.
Definition PathInfo.h:226
const Pathname & path() const
Return current Pathname.
Definition PathInfo.h:251
Pathname dirname() const
Return all but the last component od this path.
Definition Pathname.h:126
const std::string & asString() const
String representation.
Definition Pathname.h:93
bool empty() const
Test for an empty path.
Definition Pathname.h:116
Pathname absolutename() const
Return this path, adding a leading '/' if relative.
Definition Pathname.h:141
void save()
Saves any unsaved credentials added via addUserCred() or addGlobalCred() methods.
AuthData_Ptr getCred(const Url &url)
Get credentials for the specified url.
void addCred(const AuthData &cred)
Add new credentials with user callbacks.
Curl HTTP authentication data.
void releaseFrom(const std::string &ejectDev) override
Call concrete handler to release the media.
void disconnectFrom() override
bool tryZchunk(zyppng::NetworkRequestRef req, const OnMediaLocation &srcFile, const Pathname &target, callback::SendReport< DownloadProgressReport > &report)
void getFile(const OnMediaLocation &file) const override
Call concrete handler to provide file below attach point.
void getFileCopy(const OnMediaLocation &srcFile, const Pathname &targetFilename) const override
void getDir(const Pathname &dirname, bool recurse_r) const override
Call concrete handler to provide directory content (not recursive!) below attach point.
void attachTo(bool next=false) override
Call concrete handler to attach the media.
void getDirInfo(std::list< std::string > &retlist, const Pathname &dirname, bool dots=true) const override
Call concrete handler to provide a content list of directory on media via retlist.
zyppng::EventDispatcherRef _evDispatcher
Definition MediaCurl2.h:128
bool getDoesFileExist(const Pathname &filename) const override
Repeatedly calls doGetDoesFileExist() until it successfully returns, fails unexpectedly,...
@ OPTION_NO_IFMODSINCE
to not add a IFMODSINCE header if target exists
Definition MediaCurl2.h:50
Url clearQueryString(const Url &url) const
void executeRequest(zyppng::NetworkRequestRef req, callback::SendReport< DownloadProgressReport > *report=nullptr)
virtual void doGetFileCopy(const OnMediaLocation &srcFile, const Pathname &targetFilename, callback::SendReport< DownloadProgressReport > &_report, RequestOptions options=OPTION_NONE) const
void checkProtocol(const Url &url) const
check the url is supported by the curl library
bool checkAttachPoint(const Pathname &apoint) const override
Verify if the specified directory as attach point (root) as requires by the particular media handler ...
void setupEasy()
initializes the curl easy handle with the data from the url
zyppng::NetworkRequestDispatcherRef _nwDispatcher
Definition MediaCurl2.h:129
TransferSettings _effectiveSettings
Definition MediaCurl2.h:130
MediaCurl2(const Url &url_r, const Pathname &attach_point_hint_r)
bool authenticate(const std::string &availAuthTypes, bool firstTry)
Just inherits Exception to separate media exceptions.
bool isUseableAttachPoint(const Pathname &path, bool mtab=true) const
Ask media manager, if the specified path is already used as attach point or if there are another atta...
Url url() const
Url used.
virtual bool checkAttachPoint(const Pathname &apoint) const
Verify if the specified directory as attach point (root) as requires by the particular media handler ...
void disconnect()
Use concrete handler to isconnect media.
Pathname createAttachPoint() const
Try to create a default / temporary attach point.
void setMediaSource(const MediaSourceRef &ref)
Set new media source reference.
Pathname localPath(const Pathname &pathname) const
Files provided will be available at 'localPath(filename)'.
const Url _url
Url to handle.
void getDirectoryYast(std::list< std::string > &retlist, const Pathname &dirname, bool dots=true) const
Retrieve and if available scan dirname/directory.yast.
void setAttachPoint(const Pathname &path, bool temp)
Set a new attach point.
Pathname attachPoint() const
Return the currently used attach point.
Url getFileUrl(const Pathname &filename) const
concatenate the attach url and the filename to a complete download url
MediaNetworkCommonHandler(const Url &url_r, const Pathname &attach_point_r, const Pathname &urlpath_below_attachpoint_r, const bool does_download_r)
Media source internally used by MediaManager and MediaHandler.
Definition MediaSource.h:38
static Ptr create()
The NetworkRequestError class Represents a error that occured in.
const zypp::Pathname & targetFilePath() const
Returns the target filename path.
Definition request.cc:919
SignalProxy< void(NetworkRequest &req, const NetworkRequestError &err)> sigFinished()
Signals that the download finished.
Definition request.cc:1066
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.
Definition request.cc:1061
static bool validateZckFile(const zypp::Pathname &file, std::string &error)
Definition zckhelper.cc:169
static bool isZchunkFile(const zypp::Pathname &file)
Definition zckhelper.cc:21
static PrepareResult prepareZck(const zypp::Pathname &delta, const zypp::Pathname &target, const zypp::ByteCount &expectedFileSize)
Definition zckhelper.cc:34
#define WAR_MEDIA
#define DBG_MEDIA
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.
Url clearQueryString(const Url &url)
Definition Arch.h:364
const long & ZYPP_MEDIA_CURL_DEBUG()
const long& for setting CURLOPT_DEBUGDATA Returns a reference to a static variable,...
Definition curlhelper.cc:36
mode_t applyUmaskTo(mode_t mode_r)
Modify mode_r according to the current umask ( mode_r & ~getUmask() ).
Definition PathInfo.h:805
std::list< DirEntry > DirContent
Returned by readdir.
Definition PathInfo.h:526
int unlink(const Pathname &path)
Like 'unlink'.
Definition PathInfo.cc:705
shared_ptr< AuthData > AuthData_Ptr
Definition authdata.h:81
zypp::RW_pointer< MediaSource > MediaSourceRef
shared_ptr< CurlAuthData > CurlAuthData_Ptr
const std::string & asString(const std::string &t)
Global asString() that works with std::string too.
Definition String.h:139
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.
Definition ManagedFile.h:27
Bottleneck filtering all DownloadProgressReport issued from Media[Muli]Curl.
double _drateLast
Download rate in last period.
Definition MediaCurl2.cc:84
double _drateTotal
Download rate so far.
Definition MediaCurl2.cc:83
void updateStats(double dltotal=0.0, double dlnow=0.0)
Definition MediaCurl2.cc:86
double _dnlTotal
Bytes to download or 0 if unknown.
Definition MediaCurl2.cc:77
double _dnlLast
Bytes downloaded at period start.
Definition MediaCurl2.cc:78
std::chrono::steady_clock clock
Definition MediaCurl2.cc:72
double _dnlNow
Bytes downloaded now.
Definition MediaCurl2.cc:79
int _dnlPercent
Percent completed or 0 if _dnlTotal is unknown.
Definition MediaCurl2.cc:81
std::optional< clock::time_point > _timeStart
Start total stats.
Definition MediaCurl2.cc:74
std::optional< clock::time_point > _timeLast
Start last period(~1sec)
Definition MediaCurl2.cc:75
AutoDispose<int> calling ::close
Convenient building of std::string with boost::format.
Definition String.h:253
#define zypp_defer
#define ZYPP_RETHROW(EXCPT)
Drops a logline and rethrows, updating the CodeLocation.
Definition Exception.h:444
#define ZYPP_EXCPT_PTR(EXCPT)
Drops a logline and returns Exception as a std::exception_ptr.
Definition Exception.h:428
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition Exception.h:424
#define _(MSG)
Definition Gettext.h:39
#define DBG
Definition Logger.h:99
#define MIL
Definition Logger.h:100
#define ERR
Definition Logger.h:102
#define WAR
Definition Logger.h:101
Interface to gettext.