16#include <zypp-media/MediaException> 
   17#include <zypp-core/base/UserRequestException> 
   21using namespace std::literals;
 
   40    for ( 
auto i = cHeaders.beginList (); i != cHeaders.endList(); i++) {
 
   41      for ( 
const auto &val : i->second )
 
   42        m.addValue( i->first, val );
 
 
   58    if ( !destFile.empty() )
 
   60    if ( !deltaFile.empty() )
 
   67    for ( 
auto i = cHeaders.beginList (); i != cHeaders.endList(); i++) {
 
   68      for ( 
const auto &val : i->second )
 
   69        m.addValue( i->first, val );
 
 
   92    return d_func()->_parent;
 
 
  107    startedReq->_pastRedirects.push_back ( 
url );
 
 
  113    if ( !startedReq->_pastRedirects.size() )
 
  116    if ( std::find( startedReq->_pastRedirects.begin(), startedReq->_pastRedirects.end(), 
url ) != startedReq->_pastRedirects.end() )
 
 
  124    return d_func()->_currStats;
 
 
  129    return d_func()->_prevStats;
 
 
  134      return d_func()->_itemStarted;
 
 
  138      return d_func()->_itemFinished;
 
 
  145      d->_prevStats = d->_currStats;
 
  151      d->_currStats->_pulseTime = d->_itemFinished;
 
  162      ._pulseTime = std::chrono::steady_clock::now(),
 
  163      ._runningRequests = 
_runningReq ? (uint)1 : (uint)0
 
 
  170      WAR << 
"Received event for unknown request, ignoring" << std::endl;
 
  174    if ( msg.
code() == ProvideMessage::Code::ProvideStarted ) {
 
  175      MIL << 
"Request: "<< req->url() << 
" was started" << std::endl;
 
 
  183      WAR << 
"Received event for unknown request, ignoring" << std::endl;
 
  187    MIL << 
"Request: "<< req->url() << 
" CACHE MISS, request will be restarted by queue." << std::endl;
 
 
  193      WAR << 
"Received event for unknown request, ignoring" << std::endl;
 
  200    const auto code = msg.
code();
 
  201    if ( code == ProvideMessage::Code::Redirect ) {
 
  208        MIL << 
"Request finished with redirect." << std::endl;
 
  216        MIL << 
"Request redirected to: " << newUrl << std::endl;
 
  220        finishedReq->setUrl( newUrl );
 
  231    } 
else if ( code == ProvideMessage::Code::Metalink ) {
 
  236      MIL << 
"Request finished with mirrorlist from server." << std::endl;
 
  241      std::vector<zypp::Url> urls;
 
  243      for( 
auto i = mirrors.cbegin(); i != mirrors.cend(); i++ ) {
 
  248          urls.push_back ( newUrl );
 
  251            WAR << 
"Received invalid URL from worker: " << i->asString() << 
" ignoring!" << std::endl;
 
  253            WAR << 
"Received invalid value for newUrl from worker ignoring!" << std::endl;
 
  257      if ( urls.size () == 0 ) {
 
  262      MIL << 
"Found usable nr of mirrors: " << urls.size () << std::endl;
 
  263      finishedReq->setUrls( urls );
 
  274      MIL << 
"End of mirrorlist handling"<< std::endl;
 
  277    } 
else if ( code >= ProvideMessage::Code::FirstClientErrCode && code <= ProvideMessage::Code::LastSrvErrCode ) {
 
  282      std::exception_ptr errPtr;
 
  284        const auto reqUrl = finishedReq->activeUrl().value();
 
  287          case ProvideMessage::Code::BadRequest:
 
  290          case ProvideMessage::Code::PeerCertificateInvalid:
 
  293          case ProvideMessage::Code::ConnectionFailed:
 
  296          case ProvideMessage::Code::ExpectedSizeExceeded: {
 
  298            std::optional<int64_t> filesize;
 
  299            const auto &hdrs = finishedReq->provideMessage ().headers ();
 
  303                filesize = val.asInt64();
 
  313          case ProvideMessage::Code::Cancelled:
 
  316          case ProvideMessage::Code::InvalidChecksum:
 
  319          case ProvideMessage::Code::Timeout:
 
  322          case ProvideMessage::Code::NotFound:
 
  325          case ProvideMessage::Code::Forbidden:
 
  326          case ProvideMessage::Code::Unauthorized: {
 
  328            const auto &hintVal = msg.
value( 
"authHint"sv );
 
  330            if ( hintVal.valid() && hintVal.isString() ) {
 
  331              hint = hintVal.asString();
 
  338              reqUrl, reason, 
"", hint
 
  343          case ProvideMessage::Code::MountFailed:
 
  346          case ProvideMessage::Code::Jammed:
 
  349          case ProvideMessage::Code::MediaChangeSkip:
 
  350            errPtr = 
ZYPP_EXCPT_PTR( zypp::SkipRequestException ( 
zypp::str::Str() << 
"User-requested skipping for URL: " << reqUrl << 
" " << reason ) );
 
  352          case ProvideMessage::Code::MediaChangeAbort:
 
  353            errPtr = 
ZYPP_EXCPT_PTR( zypp::AbortRequestException( 
zypp::str::Str() <<
"Aborting requested by user for URL: " << reqUrl << 
" " << reason ) );
 
  355          case ProvideMessage::Code::InternalError:
 
  358          case ProvideMessage::Code::NotAFile:
 
  361          case ProvideMessage::Code::MediumNotDesired:
 
 
  386      WAR << 
"Received event for unknown request, ignoring" << std::endl;
 
  392      if ( 
log ) 
log->requestFailed( *
this, finishedReq->provideMessage().requestId(), excpt );
 
 
 
  403      WAR << 
"Received authenticationRequired for unknown request, rejecting" << std::endl;
 
  410      MIL << 
"Looking for existing auth data for " << effectiveUrl << 
"more recent then " << lastTimestamp << std::endl;
 
  412      auto credPtr = mgr.
getCred( effectiveUrl );
 
  413      if ( credPtr && credPtr->lastDatabaseUpdate() > lastTimestamp ) {
 
  414        MIL << 
"Found existing auth data for " << effectiveUrl << 
"ts: " <<  credPtr->lastDatabaseUpdate() << std::endl;
 
  418      if ( credPtr ) 
MIL << 
"Found existing auth data for " << effectiveUrl << 
"but too old ts: " <<  credPtr->lastDatabaseUpdate() << std::endl;
 
  420      std::string username;
 
  422        username = i->second;
 
  426      MIL << 
"NO Auth data found, asking user. Last tried username was: " << username << std::endl;
 
  429      if ( !userAuth || !userAuth->valid() ) {
 
  430        MIL << 
"User rejected to give auth" << std::endl;
 
 
  455    return d_func()->_parent.queueRequest( request );
 
 
  461    if ( d->_itemState != newState ) {
 
  466      const auto oldState = d->_itemState;
 
  467      d->_itemState = newState;
 
  468      d->_sigStateChanged( *
this, oldState, d->_itemState );
 
  471        d->_itemStarted = std::chrono::steady_clock::now();
 
  473        if ( 
log ) 
log->itemStart( *
this );
 
  477        d->_itemFinished = std::chrono::steady_clock::now();
 
  479        if ( 
log) 
log->itemDone( *
this );
 
  480        d->_parent.dequeueItem(
this);
 
 
  491    MIL << 
"Item Cleanup due to released Promise in state:" << 
state() << std::endl;
 
 
  497    return d_func()->_itemState;
 
 
  514      case ProvideMessage::Code::Attach:
 
  517      case ProvideMessage::Code::Detach:
 
  520      case ProvideMessage::Code::Prov:
 
  525        throw std::logic_error(
"Invalid message type in ProvideRequest");
 
  527    if ( !
url.valid() ) {
 
 
  544      case ProvideMessage::Code::Attach:
 
  547      case ProvideMessage::Code::Detach:
 
  550      case ProvideMessage::Code::Prov:
 
  555        throw std::logic_error(
"Invalid message type in ProvideRequest");
 
 
  573      WAR << 
"Double init of ProvideFileItem!" << std::endl;
 
 
  616      WAR << 
"Received event for unknown request, ignoring" << std::endl;
 
  620    if ( msg.
code() == ProvideMessage::Code::ProvideStarted ) {
 
  621      MIL << 
"Provide File Request: "<< req->url() << 
" was started" << std::endl;
 
  625      if ( !locPath.empty() )
 
  629      if ( !locPath.empty() )
 
  633        auto effUrl = req->activeUrl().value_or( 
zypp::Url() );
 
 
  650    if ( finishedReq != _runningReq ) {
 
  651      WAR << 
"Received event for unknown request, ignoring" << std::endl;
 
  655    if ( msg.
code () == ProvideMessage::Code::ProvideFinished ) {
 
  657      auto log = provider().log();
 
  660        m[
"spec"] = _initialSpec;
 
  661        if ( log ) log->requestDone( *
this, msg.
requestId(), m );
 
  664      MIL << 
"Request was successfully finished!" << std::endl;
 
  668      std::optional<zypp::ManagedFile> resFile;
 
  675        const bool checkExistsOnly  = _initialSpec.checkExistsOnly();
 
  679        if ( doesDownload && !checkExistsOnly ) {
 
  681          resFile = provider().addToFileCache ( locFilename );
 
  684              MIL << 
"CACHE MISS, file " << locFilename << 
" was already removed, queueing again" << std::endl;
 
  685              cacheMiss ( finishedReq );
 
  686              finishedReq->clearForRestart();
 
  687              enqueueRequest( finishedReq );
 
  700          if ( fileNeedsCleanup && !checkExistsOnly )
 
  703            resFile->resetDispose();
 
  706        _targetFile = locFilename;
 
  710        cancelWithError( std::current_exception() );
 
  711      } 
catch ( 
const std::exception &e ) {
 
  713        cancelWithError( std::current_exception() );
 
  715        cancelWithError( std::current_exception() );
 
  719      auto resObj = std::make_shared<ProvideResourceData>();
 
  720      resObj->_mediaHandle     = this->_handleRef;
 
  721      resObj->_myFile          = *resFile;
 
  722      resObj->_resourceUrl     = *(finishedReq->activeUrl());
 
  723      resObj->_responseHeaders = msg.
headers();
 
  726      std::exception_ptr excpt;
 
  732          ERR << 
"Caught unhandled pipline exception:" << e << std::endl;
 
  734          excpt = std::current_exception ();
 
  735        } 
catch ( 
const std::exception &e ) {
 
  736          ERR << 
"Caught unhandled pipline exception:" << e.what() << std::endl;
 
  738          excpt = std::current_exception ();
 
  740          ERR << 
"Caught unhandled unknown exception:"  << std::endl;
 
  741          excpt = std::current_exception ();
 
  745      updateState( Finished );
 
  748        ERR << 
"Rethrowing pipeline exception, this is a BUG!" << std::endl;
 
  749        std::rethrow_exception ( excpt );
 
  761      auto weakThis = weak_from_this ();
 
  763      if ( weakThis.expired () )
 
 
  787      if ( std::find( attachedMedia.begin(), attachedMedia.end(), 
_handleRef.mediaInfo() ) == attachedMedia.end() )
 
  789      urlToUse = 
_handleRef.mediaInfo()->_attachedUrl;
 
 
  798    bool checkStaging = 
false;
 
  815    baseStats._bytesProvided = providedByNow;
 
 
  832    MIL << 
"Killing the AttachMediaItem" << std::endl;
 
 
  849      WAR << 
"Double init of AttachMediaItem!" << std::endl;
 
  863    std::vector<zypp::Url> usableMirrs;
 
  864    std::optional<ProvideQueue::Config> scheme;
 
  867      const auto &s = prov.schemeConfig( prov.effectiveScheme( mirrIt->getScheme() ) );
 
  869        WAR << 
"URL: " << *mirrIt << 
" is not supported, ignoring!" << std::endl;
 
  874        usableMirrs.push_back ( *mirrIt );
 
  876        if ( scheme->worker_type () == s->worker_type () ) {
 
  877          usableMirrs.push_back( *mirrIt );
 
  879          WAR << 
"URL: " << *mirrIt << 
" has different worker type than the primary URL: "<< usableMirrs.front() <<
", ignoring!" << std::endl;
 
  901    auto &attachedMedia = prov.attachedMediaInfos ();
 
  903    for ( 
auto &medium : attachedMedia ) {
 
  910    for ( 
auto &otherItem : prov.items() ) {
 
  911      auto attachIt = std::dynamic_pointer_cast<AttachMediaItem>(otherItem);
 
  913           || attachIt.get()     == 
this             
  920      const auto sameMedium = attachIt->_initialSpec.isSameMedium( 
_initialSpec);
 
  921      if ( zypp::indeterminate(sameMedium) ) {
 
  923        if ( attachIt->_mirrorList.front() != 
_mirrorList.front() )
 
  926      else if ( !(
bool)sameMedium )
 
  929      MIL << 
"Found item providing the same medium, attaching to finished signal and waiting for it to be finished" << std::endl;
 
  950        if ( !smvDataLocal ) {
 
  955        if ( !smvDataLocal->load( 
_initialSpec.mediaFile() ) ) {
 
  962        std::vector<zypp::Url> urls;
 
  999          ERR << 
"Failed to queue request" << std::endl;
 
 
 1034    }  
catch ( 
const std::exception &e ) {
 
 1035      ERR << 
"WTF " << e.what () << std::endl;
 
 1037      ERR << 
"WTF " << std::endl;
 
 1045    MIL << 
"Before setFinished" << std::endl;
 
 
 1052    MIL << 
"Cancelling Item with error" << std::endl;
 
 1060      auto weakThis = weak_from_this ();
 
 1062      if ( weakThis.expired () )
 
 
 1090        std::rethrow_exception ( result.
error() );
 
 1095        MIL_PRV << 
"Master item was cancelled, reverting to Uninitialized state and waiting for scheduler to run again" << std::endl;
 
 
 1118      WAR << 
"Received event for unknown request, ignoring" << std::endl;
 
 1124      if ( msg.
code() == ProvideMessage::Code::ProvideFinished ) {
 
 1128        zypp::Url baseUrl = *finishedReq->activeUrl();
 
 1134        if ( !smvDataRemote ) {
 
 1143        if ( !smvDataRemote->valid () ) {
 
 1148        if (! 
_verifier->matches( smvDataRemote ) ) {
 
 1150          DBG << 
"remote: " << smvDataRemote  << std::endl;
 
 1158      } 
else if ( msg.
code() == ProvideMessage::Code::NotFound ) {
 
 1175      if ( msg.
code() == ProvideMessage::Code::AttachFinished ) {
 
 1177        std::optional<zypp::Pathname> mntPoint;
 
 1179        if ( mountPtVal.valid() && mountPtVal.isString() ) {
 
 1188          , *finishedReq->activeUrl()
 
 
 
Store and operate with byte count.
Base class for Exception.
std::string asCompleteString() const
Returns a complete string representation of the Url object.
std::string getPathName(EEncoding eflag=zypp::url::E_DECODED) const
Returns the path name from the URL.
void setPathName(const std::string &path, EEncoding eflag=zypp::url::E_DECODED)
Set the path name.
Wrapper class for stat/lstat.
bool isExist() const
Return whether valid stat info exists.
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.
std::shared_ptr< T > shared_this() const
static auto connect(typename internal::MemberFunction< SenderFunc >::ClassType &s, SenderFunc &&sFun, typename internal::MemberFunction< ReceiverFunc >::ClassType &recv, ReceiverFunc &&rFunc)
std::weak_ptr< T > weak_this() const
expected< zypp::media::AuthData > authenticationRequired(ProvideQueue &queue, ProvideRequestRef req, const zypp::Url &effectiveUrl, int64_t lastTimestamp, const std::map< std::string, std::string > &extraFields) override
zypp::Pathname _stagingFile
void cancelWithError(std::exception_ptr error) override
zypp::ByteCount bytesExpected() const override
void setMediaRef(Provide::MediaHandle &&hdl)
Provide::MediaHandle & mediaRef()
Provide::MediaHandle _handleRef
void initialize() override
static ProvideFileItemRef create(const std::vector< zypp::Url > &urls, const ProvideFileSpec &request, ProvidePrivate &parent)
ProvideFileItem(const std::vector< zypp::Url > &urls, const ProvideFileSpec &request, ProvidePrivate &parent)
ProvideFileSpec _initialSpec
ProvidePromiseRef< ProvideRes > promise()
std::vector< zypp::Url > _mirrorList
zypp::ByteCount _expectedBytes
zypp::Pathname _targetFile
ItemStats makeStats() override
void informalMessage(ProvideQueue &, ProvideRequestRef req, const ProvideMessage &msg) override
ProvidePromiseWeakRef< ProvideRes > _promise
HeaderValueMap & customHeaders()
const zypp::Pathname & destFilenameHint() const
const zypp::ByteCount & downloadSize() const
The size of the resource on the server.
const zypp::Pathname & deltafile() const
The existing deltafile that can be used to reduce download size ( zchunk or metalink )
bool checkExistsOnly() const
bool safeRedirectTo(ProvideRequestRef startedReq, const zypp::Url &url)
virtual std::chrono::steady_clock::time_point startTime() const
virtual void cacheMiss(ProvideRequestRef req)
ProvideItem(ProvidePrivate &parent)
ProvidePrivate & provider()
virtual expected< zypp::media::AuthData > authenticationRequired(ProvideQueue &queue, ProvideRequestRef req, const zypp::Url &effectiveUrl, int64_t lastTimestamp, const std::map< std::string, std::string > &extraFields)
virtual ItemStats makeStats()
virtual bool canRedirectTo(ProvideRequestRef startedReq, const zypp::Url &url)
virtual std::chrono::steady_clock::time_point finishedTime() const
virtual zypp::ByteCount bytesExpected() const
ProvideRequestRef _runningReq
void redirectTo(ProvideRequestRef startedReq, const zypp::Url &url)
virtual void informalMessage(ProvideQueue &, ProvideRequestRef req, const ProvideMessage &msg)
const std::optional< ItemStats > & previousStats() const
friend class ProvidePrivate
virtual void finishReq(ProvideQueue &queue, ProvideRequestRef finishedReq, const ProvideMessage &msg)
virtual void cancelWithError(std::exception_ptr error)=0
const std::optional< ItemStats > & currentStats() const
void updateState(const State newState)
friend class ProvideQueue
virtual bool enqueueRequest(ProvideRequestRef request)
const HeaderValueMap & headers() const
FieldVal value(const std::string_view &str, const FieldVal &defaultVal=FieldVal()) const
const std::vector< ProvideMessage::FieldVal > & values(const std::string_view &str) const
static ProvideMessage createProvide(const uint32_t reqId, const zypp::Url &url, const std::optional< std::string > &filename={}, const std::optional< std::string > &deltaFile={}, const std::optional< int64_t > &expFilesize={}, bool checkExistOnly=false)
static ProvideMessage createDetach(const uint32_t reqId, const zypp::Url &attachUrl)
static ProvideMessage createAttach(const uint32_t reqId, const zypp::Url &url, const std::string attachId, const std::string &label, const std::optional< std::string > &verifyType={}, const std::optional< std::string > &verifyData={}, const std::optional< int32_t > &mediaNr={})
bool dequeueRequest(ProvideRequestRef req, std::exception_ptr error)
std::string nextMediaId() const
Signal< std::optional< zypp::media::AuthData >(const zypp::Url &reqUrl, const std::string &triedUsername, const std::map< std::string, std::string > &extraValues) > _sigAuthRequired
std::vector< AttachedMediaInfo_Ptr > & attachedMediaInfos()
void schedule(ScheduleReason reason)
const Config & workerConfig() const
static constexpr uint32_t InvalidId
void setActiveUrl(const zypp::Url &urlToUse)
ProvideQueueWeakRef _myQueue
const std::vector< zypp::Url > & urls() const
static expected< ProvideRequestRef > createDetach(const zypp::Url &url)
static expected< ProvideRequestRef > create(ProvideItem &owner, const std::vector< zypp::Url > &urls, const std::string &id, ProvideMediaSpec &spec)
void setCurrentQueue(ProvideQueueRef ref)
ProvideQueueRef currentQueue()
const std::optional< zypp::Url > activeUrl() const
ProvideRequest(ProvideItem *owner, const std::vector< zypp::Url > &urls, ProvideMessage &&msg)
A ProvideRes object is a reference counted ownership of a resource in the cache provided by a Provide...
ProvideMediaHandle MediaHandle
WorkerType worker_type() const
static expected success(ConsParams &&...params)
static expected error(ConsParams &&...params)
int unlink(const Pathname &path)
Like 'unlink'.
AutoDispose< const Pathname > ManagedFile
A Pathname plus associated cleanup code to be executed when path is no longer needed.
intrusive_ptr< T > make_intrusive(Args &&... __args)
constexpr std::string_view LocalMountPoint("local_mountpoint")
constexpr std::string_view AttachId("attach_id")
constexpr std::string_view VerifyData("verify_data")
constexpr std::string_view VerifyType("verify_type")
constexpr std::string_view MediaNr("media_nr")
constexpr std::string_view Url("url")
constexpr std::string_view LastUser("username")
constexpr std::string_view Url("url")
constexpr std::string_view Reason("reason")
constexpr std::string_view LocalFilename("local_filename")
constexpr std::string_view CacheHit("cacheHit")
constexpr std::string_view Url("url")
constexpr std::string_view MetalinkEnabled("metalink_enabled")
constexpr std::string_view ExpectedFilesize("expected_filesize")
constexpr std::string_view DeltaFile("delta_file")
constexpr std::string_view CheckExistOnly("check_existance_only")
constexpr std::string_view Filename("filename")
constexpr std::string_view StagingFilename("staging_filename")
constexpr std::string_view Url("url")
constexpr std::string_view LocalFilename("local_filename")
constexpr std::string_view NewUrl("new_url")
constexpr std::string_view NETWORK_METALINK_ENABLED("zypp-nw-metalink-enabled")
static constexpr std::string_view DEFAULT_MEDIA_VERIFIER("SuseMediaV1")
std::shared_ptr< ProvidePromise< T > > ProvidePromiseRef
std::unordered_map< std::string, boost::any > AnyMap
Convenient building of std::string via std::ostringstream Basically a std::ostringstream autoconverti...
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
#define ZYPP_EXCPT_PTR(EXCPT)
Drops a logline and returns Exception as a std::exception_ptr.
#define ZYPP_FWD_CURRENT_EXCPT()
Drops a logline and returns the current Exception as a std::exception_ptr.
#define ZYPP_IMPL_PRIVATE(Class)