libzypp  17.37.10
provideitem.cc
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
9 
10 #include "private/providedbg_p.h"
11 #include "private/provideitem_p.h"
12 #include "private/provide_p.h"
14 #include "private/provideres_p.h"
15 #include "provide-configvars.h"
16 #include <zypp-media/MediaException>
17 #include <zypp-core/base/UserRequestException>
18 #include "mediaverifier.h"
19 #include <zypp-core/fs/PathInfo.h>
20 
21 using namespace std::literals;
22 
23 namespace zyppng {
24 
25  static constexpr std::string_view DEFAULT_MEDIA_VERIFIER("SuseMediaV1");
26 
27  expected<ProvideRequestRef> ProvideRequest::create(ProvideItem &owner, const zypp::MirroredOrigin &origin, const std::string &id, ProvideMediaSpec &spec )
28  {
29  if ( !origin.isValid () )
30  return expected<ProvideRequestRef>::error( ZYPP_EXCPT_PTR ( zypp::media::MediaException("Origin config must be valid") ) );
31 
32  auto m = ProvideMessage::createAttach( ProvideQueue::InvalidId, origin.authority().url(), id, spec.label() );
33  if ( !spec.mediaFile().empty() ) {
34  m.setValue( AttachMsgFields::VerifyType, std::string(DEFAULT_MEDIA_VERIFIER.data()) );
35  m.setValue( AttachMsgFields::VerifyData, spec.mediaFile().asString() );
36  m.setValue( AttachMsgFields::MediaNr, int32_t(spec.medianr()) );
37  }
38 
39  const auto &cHeaders = spec.customHeaders();
40  for ( auto i = cHeaders.beginList (); i != cHeaders.endList(); i++) {
41  for ( const auto &val : i->second )
42  m.addValue( i->first, val );
43  }
44 
45  return expected<ProvideRequestRef>::success( ProvideRequestRef( new ProvideRequest(&owner, origin, std::move(m))) );
46  }
47 
48  expected<ProvideRequestRef> ProvideRequest::create(ProvideItem &owner, const zypp::MirroredOrigin &origin, ProvideFileSpec &spec )
49  {
50  if ( !origin.isValid () )
51  return expected<ProvideRequestRef>::error( ZYPP_EXCPT_PTR ( zypp::media::MediaException("Origin config must be valid") ) );
52 
53  auto m = ProvideMessage::createProvide ( ProvideQueue::InvalidId, origin.authority().url() );
54  const auto &destFile = spec.destFilenameHint();
55  const auto &deltaFile = spec.deltafile();
56  const int64_t fSize = spec.downloadSize();;
57 
58  if ( !destFile.empty() )
59  m.setValue( ProvideMsgFields::Filename, destFile.asString() );
60  if ( !deltaFile.empty() )
61  m.setValue( ProvideMsgFields::DeltaFile, deltaFile.asString() );
62  if ( fSize )
63  m.setValue( ProvideMsgFields::ExpectedFilesize, fSize );
65 
66  const auto &cHeaders = spec.customHeaders();
67  for ( auto i = cHeaders.beginList (); i != cHeaders.endList(); i++) {
68  for ( const auto &val : i->second )
69  m.addValue( i->first, val );
70  }
71 
72  return expected<ProvideRequestRef>::success( ProvideRequestRef( new ProvideRequest(&owner, origin, std::move(m)) ) );
73  }
74 
75  expected<ProvideRequestRef> ProvideRequest::createDetach( const zypp::Url &url )
76  {
77  auto m = ProvideMessage::createDetach ( ProvideQueue::InvalidId , url );
78  return expected<ProvideRequestRef>::success( ProvideRequestRef( new ProvideRequest( nullptr, { url }, std::move(m) ) ) );
79  }
80 
82 
83  ProvideItem::ProvideItem( ProvidePrivate &parent )
84  : Base( *new ProvideItemPrivate( parent, *this ) )
85  { }
86 
88  { }
89 
91  {
92  return d_func()->_parent;
93  }
94 
95  bool ProvideItem::safeRedirectTo( ProvideRequestRef startedReq, const zypp::Url &url )
96  {
97  if ( !canRedirectTo( startedReq, url ) )
98  return false;
99 
100  redirectTo( startedReq, url );
101  return true;
102  }
103 
104  void ProvideItem::redirectTo( ProvideRequestRef startedReq, const zypp::Url &url )
105  {
106  //@TODO strip irrelevant stuff from URL
107  startedReq->_pastRedirects.push_back ( url );
108  }
109 
110  bool ProvideItem::canRedirectTo( ProvideRequestRef startedReq, const zypp::Url &url )
111  {
112  // make sure there is no redirect loop
113  if ( !startedReq->_pastRedirects.size() )
114  return true;
115 
116  if ( std::find( startedReq->_pastRedirects.begin(), startedReq->_pastRedirects.end(), url ) != startedReq->_pastRedirects.end() )
117  return false;
118 
119  return true;
120  }
121 
122  const std::optional<ProvideItem::ItemStats> &ProvideItem::currentStats() const
123  {
124  return d_func()->_currStats;
125  }
126 
127  const std::optional<ProvideItem::ItemStats> &ProvideItem::previousStats() const
128  {
129  return d_func()->_prevStats;
130  }
131 
132  std::chrono::steady_clock::time_point ProvideItem::startTime() const
133  {
134  return d_func()->_itemStarted;
135  }
136 
137  std::chrono::steady_clock::time_point ProvideItem::finishedTime() const {
138  return d_func()->_itemFinished;
139  }
140 
142  {
143  Z_D();
144  if ( d->_currStats )
145  d->_prevStats = d->_currStats;
146 
147  d->_currStats = makeStats();
148 
149  // once the item is finished the pulse time is always the finish time
150  if ( d->_itemState == Finished )
151  d->_currStats->_pulseTime = d->_itemFinished;
152  }
153 
155  {
156  return 0;
157  }
158 
160  {
161  return ItemStats {
162  ._pulseTime = std::chrono::steady_clock::now(),
163  ._runningRequests = _runningReq ? (uint)1 : (uint)0
164  };
165  }
166 
167  void ProvideItem::informalMessage ( ProvideQueue &, ProvideRequestRef req, const ProvideMessage &msg )
168  {
169  if ( req != _runningReq ) {
170  WAR << "Received event for unknown request, ignoring" << std::endl;
171  return;
172  }
173 
175  MIL << "Request: "<< req->url() << " was started" << std::endl;
176  }
177 
178  }
179 
180  void ProvideItem::cacheMiss( ProvideRequestRef req )
181  {
182  if ( req != _runningReq ) {
183  WAR << "Received event for unknown request, ignoring" << std::endl;
184  return;
185  }
186 
187  MIL << "Request: "<< req->url() << " CACHE MISS, request will be restarted by queue." << std::endl;
188  }
189 
190  void ProvideItem::finishReq(ProvideQueue &, ProvideRequestRef finishedReq, const ProvideMessage &msg )
191  {
192  if ( finishedReq != _runningReq ) {
193  WAR << "Received event for unknown request, ignoring" << std::endl;
194  return;
195  }
196 
197  auto log = provider().log();
198 
199  // explicitely handled codes
200  const auto code = msg.code();
201  if ( code == ProvideMessage::Code::Redirect ) {
202 
203  // remove the old request
204  _runningReq.reset();
205 
206  try {
207 
208  MIL << "Request finished with redirect." << std::endl;
209 
211  if ( !safeRedirectTo( finishedReq, newUrl ) ) {
213  return;
214  }
215 
216  MIL << "Request redirected to: " << newUrl << std::endl;
217 
218  if ( log ) log->requestRedirect( *this, msg.requestId(), newUrl );
219 
220  finishedReq->setUrl( newUrl );
221 
222  if ( !enqueueRequest( finishedReq ) ) {
223  cancelWithError( ZYPP_EXCPT_PTR(zypp::media::MediaException("Failed to queue request")) );
224  }
225  } catch ( ... ) {
226  cancelWithError( std::current_exception() );
227  return;
228  }
229  return;
230 
231  } else if ( code == ProvideMessage::Code::Metalink ) {
232 
233  // remove the old request
234  _runningReq.reset();
235 
236  MIL << "Request finished with mirrorlist from server." << std::endl;
237 
238  //@TODO get rid of metalink inside the provider and handle it just in legacy mode:
239  // code requests the metalist in RepoInfo and the provider already gets a clean MirroredOrigin config
240 
241  zypp::MirroredOrigin newOrigin;
242  const auto &mirrors = msg.values( MetalinkRedirectMsgFields::NewUrl );
243  for( auto i = mirrors.cbegin(); i != mirrors.cend(); i++ ) {
244  try {
245  zypp::Url newUrl( i->asString() );
246  if ( !canRedirectTo( finishedReq, newUrl ) )
247  continue;
248  if ( !newOrigin.isValid () )
249  newOrigin.setAuthority (newUrl);
250  else
251  newOrigin.addMirror(newUrl);
252  } catch ( ... ) {
253  if ( i->isString() )
254  WAR << "Received invalid URL from worker: " << i->asString() << " ignoring!" << std::endl;
255  else
256  WAR << "Received invalid value for newUrl from worker ignoring!" << std::endl;
257  }
258  }
259 
260  if ( newOrigin.endpointCount() == 0 ) {
261  cancelWithError( ZYPP_EXCPT_PTR ( zypp::media::MediaException("No mirrors left to redirect to.")) );
262  return;
263  }
264 
265  MIL << "Found usable nr of mirrors: " << newOrigin.endpointCount() << std::endl;
266  finishedReq->setOrigin( std::move(newOrigin) );
267 
268  // disable metalink
269  finishedReq->provideMessage().setValue( ProvideMsgFields::MetalinkEnabled, false );
270 
271  if ( log ) log->requestDone( *this, msg.requestId() );
272 
273  if ( !enqueueRequest( finishedReq ) ) {
274  cancelWithError( ZYPP_EXCPT_PTR(zypp::media::MediaException("Failed to queue request")) );
275  }
276 
277  MIL << "End of mirrorlist handling"<< std::endl;
278  return;
279 
281 
282  // remove the old request
283  _runningReq.reset();
284 
285  std::exception_ptr errPtr;
286  try {
287  const auto reqUrl = finishedReq->activeUrl().value();
288  const auto reason = msg.value( ErrMsgFields::Reason ).asString();
289  switch ( code ) {
291  errPtr = ZYPP_EXCPT_PTR( zypp::media::MediaException (zypp::str::Str() << "Bad request for URL: " << reqUrl << " " << reason ) );
292  break;
294  errPtr = ZYPP_EXCPT_PTR( zypp::media::MediaException(zypp::str::Str() << "PeerCertificateInvalid Error for URL: " << reqUrl << " " << reason) );
295  break;
297  errPtr = ZYPP_EXCPT_PTR( zypp::media::MediaException(zypp::str::Str() << "ConnectionFailed Error for URL: " << reqUrl << " " << reason ) );
298  break;
300 
301  std::optional<int64_t> filesize;
302  const auto &hdrs = finishedReq->provideMessage ().headers ();
303  if ( hdrs.contains( ProvideMsgFields::ExpectedFilesize ) ) {
304  const auto &val = hdrs.value ( ProvideMsgFields::ExpectedFilesize );
305  if ( val.valid() )
306  filesize = val.asInt64();
307  }
308 
309  if ( !filesize ) {
310  errPtr = ZYPP_EXCPT_PTR( zypp::media::MediaException( zypp::str::Str() << "ExceededExpectedSize Error for URL: " << reqUrl << " " << reason ) );
311  } else {
312  errPtr = ZYPP_EXCPT_PTR( zypp::media::MediaFileSizeExceededException(reqUrl, *filesize ) );
313  }
314  break;
315  }
317  errPtr = ZYPP_EXCPT_PTR( zypp::media::MediaException( zypp::str::Str() << "Request was cancelled: " << reqUrl << " " << reason ) );
318  break;
320  errPtr = ZYPP_EXCPT_PTR( zypp::media::MediaException( zypp::str::Str() << "InvalidChecksum Error for URL: " << reqUrl << " " << reason ) );
321  break;
324  break;
327  break;
330 
331  const auto &hintVal = msg.value( "authHint"sv );
332  std::string hint;
333  if ( hintVal.valid() && hintVal.isString() ) {
334  hint = hintVal.asString();
335  }
336 
337  //@TODO retry here with timestamp from cred store check
338  // we let the request fail after it checked the store
339 
341  reqUrl, reason, "", hint
342  ));
343  break;
344 
345  }
347  errPtr = ZYPP_EXCPT_PTR( zypp::media::MediaException( zypp::str::Str() << "MountFailed Error for URL: " << reqUrl << " " << reason ) );
348  break;
351  break;
353  errPtr = ZYPP_EXCPT_PTR( zypp::SkipRequestException ( zypp::str::Str() << "User-requested skipping for URL: " << reqUrl << " " << reason ) );
354  break;
356  errPtr = ZYPP_EXCPT_PTR( zypp::AbortRequestException( zypp::str::Str() <<"Aborting requested by user for URL: " << reqUrl << " " << reason ) );
357  break;
359  errPtr = ZYPP_EXCPT_PTR( zypp::media::MediaException( zypp::str::Str() << "WorkerSpecific Error for URL: " << reqUrl << " " << reason ) );
360  break;
362  errPtr = ZYPP_EXCPT_PTR( zypp::media::MediaNotAFileException(reqUrl, "") );
363  break;
366  break;
367  default:
368  errPtr = ZYPP_EXCPT_PTR( zypp::media::MediaException( zypp::str::Str() << "Unknown Error for URL: " << reqUrl << " " << reason ) );
369  break;
370  }
371  } catch (...) {
372  errPtr = ZYPP_EXCPT_PTR( zypp::media::MediaException( zypp::str::Str() << "Invalid error message received for URL: " << *finishedReq->activeUrl() << " code: " << code ) );
373  }
374 
375  if ( log ) log->requestFailed( *this, msg.requestId(), errPtr );
376  // finish the request
377  cancelWithError( errPtr );
378  return;
379  }
380 
381  // if we reach here we don't know how to handle the message
382  _runningReq.reset();
383  cancelWithError( ZYPP_EXCPT_PTR (zypp::media::MediaException("Unhandled message received for ProvideFileItem")) );
384  }
385 
386  void ProvideItem::finishReq(ProvideQueue *, ProvideRequestRef finishedReq , const std::exception_ptr excpt)
387  {
388  if ( finishedReq != _runningReq ) {
389  WAR << "Received event for unknown request, ignoring" << std::endl;
390  return;
391  }
392 
393  if ( _runningReq ) {
394  auto log = provider().log();
395  if ( log ) log->requestFailed( *this, finishedReq->provideMessage().requestId(), excpt );
396  }
397 
398  _runningReq.reset();
399  cancelWithError(excpt);
400  }
401 
402  expected<zypp::media::AuthData> ProvideItem::authenticationRequired ( ProvideQueue &queue, ProvideRequestRef req, const zypp::Url &effectiveUrl, int64_t lastTimestamp, const std::map<std::string, std::string> &extraFields )
403  {
404 
405  if ( req != _runningReq ) {
406  WAR << "Received authenticationRequired for unknown request, rejecting" << std::endl;
407  return expected<zypp::media::AuthData>::error( ZYPP_EXCPT_PTR( zypp::media::MediaException("Unknown request in authenticationRequired, this is a bug.") ) );
408  }
409 
410  try {
411  zypp::media::CredentialManager mgr ( provider().credManagerOptions() );
412 
413  MIL << "Looking for existing auth data for " << effectiveUrl << "more recent then " << lastTimestamp << std::endl;
414 
415  auto credPtr = mgr.getCred( effectiveUrl );
416  if ( credPtr && credPtr->lastDatabaseUpdate() > lastTimestamp ) {
417  MIL << "Found existing auth data for " << effectiveUrl << "ts: " << credPtr->lastDatabaseUpdate() << std::endl;
418  return expected<zypp::media::AuthData>::success( *credPtr );
419  }
420 
421  if ( credPtr ) MIL << "Found existing auth data for " << effectiveUrl << "but too old ts: " << credPtr->lastDatabaseUpdate() << std::endl;
422 
423  std::string username;
424  if ( auto i = extraFields.find( std::string(AuthDataRequestMsgFields::LastUser) ); i != extraFields.end() ) {
425  username = i->second;
426  }
427 
428 
429  MIL << "NO Auth data found, asking user. Last tried username was: " << username << std::endl;
430 
431  auto userAuth = provider()._sigAuthRequired.emit( effectiveUrl, username, extraFields );
432  if ( !userAuth || !userAuth->valid() ) {
433  MIL << "User rejected to give auth" << std::endl;
435  }
436 
437  mgr.addCred( *userAuth );
438  mgr.save();
439 
440  // rather ugly, but update the timestamp to the last mtime of the cred database our URL belongs to
441  // otherwise we'd need to reload the cred database
442  userAuth->setLastDatabaseUpdate( mgr.timestampForCredDatabase( effectiveUrl ) );
443 
445  } catch ( const zypp::Exception &e ) {
446  ZYPP_CAUGHT(e);
448  }
449  }
450 
451  bool ProvideItem::enqueueRequest( ProvideRequestRef request )
452  {
453  // base item just supports one running request at a time
454  if ( _runningReq )
455  return ( _runningReq == request );
456 
457  _runningReq = request;
458  return d_func()->_parent.queueRequest( request );
459  }
460 
461  void ProvideItem::updateState( const State newState )
462  {
463  Z_D();
464  if ( d->_itemState != newState ) {
465 
466  bool started = ( d->_itemState == Uninitialized && ( newState != Finished ));
467  auto log = provider().log();
468 
469  const auto oldState = d->_itemState;
470  d->_itemState = newState;
471  d->_sigStateChanged( *this, oldState, d->_itemState );
472 
473  if ( started ) {
474  d->_itemStarted = std::chrono::steady_clock::now();
475  pulse();
476  if ( log ) log->itemStart( *this );
477  }
478 
479  if ( newState == Finished ) {
480  d->_itemFinished = std::chrono::steady_clock::now();
481  pulse();
482  if ( log) log->itemDone( *this );
483  d->_parent.dequeueItem(this);
484  }
485  // CAREFUL, 'this' might be invalid from here on
486  }
487  }
488 
490  {
491  if ( state() == Finished || state() == Finalizing )
492  return;
493 
494  MIL << "Item Cleanup due to released Promise in state:" << state() << std::endl;
496  }
497 
499  {
500  return d_func()->_itemState;
501  }
502 
503  void ProvideRequest::setCurrentQueue( ProvideQueueRef ref )
504  {
505  _myQueue = ref;
506  }
507 
509  {
510  return _myQueue.lock();
511  }
512 
513  const std::optional<zypp::Url> ProvideRequest::activeUrl() const
514  {
516  switch ( this->_message.code () ) {
519  break;
522  break;
525  break;
526  default:
527  // should never happen because we guard the constructor
528  throw std::logic_error("Invalid message type in ProvideRequest");
529  }
530  if ( !url.valid() ) {
531  return {};
532  }
533 
534  try {
535  auto u = zypp::Url( url.asString() );
536  return u;
537  } catch ( const zypp::Exception &e ) {
538  ZYPP_CAUGHT(e);
539  }
540 
541  return {};
542  }
543 
544  void ProvideRequest::setActiveUrl(const zypp::Url &urlToUse) {
545 
546  switch ( this->_message.code () ) {
549  break;
552  break;
555  break;
556  default:
557  // should never happen because we guard the constructor
558  throw std::logic_error("Invalid message type in ProvideRequest");
559  }
560  }
561 
563  : ProvideItem( parent )
564  , _origin ( std::move(origin) )
565  , _initialSpec ( request )
566  { }
567 
568  ProvideFileItemRef ProvideFileItem::create( zypp::MirroredOrigin origin, const ProvideFileSpec &request, ProvidePrivate &parent )
569  {
570  return ProvideFileItemRef( new ProvideFileItem( std::move(origin), request, parent ) );
571  }
572 
574  {
575  if ( state() != Uninitialized || _runningReq ) {
576  WAR << "Double init of ProvideFileItem!" << std::endl;
577  return;
578  }
579 
580  auto req = ProvideRequest::create( *this, _origin, _initialSpec );
581  if ( !req ){
582  cancelWithError( req.error() );
583  return ;
584  }
585 
586  if ( enqueueRequest( *req ) ) {
588  updateState( Pending );
589  } else {
590  cancelWithError( ZYPP_EXCPT_PTR(zypp::media::MediaException("Failed to queue request")) );
591  return ;
592  }
593  }
594 
596  {
597  if ( !_promiseCreated ) {
598  _promiseCreated = true;
599  auto promiseRef = std::make_shared<ProvidePromise<ProvideRes>>( shared_this<ProvideItem>() );
600  _promise = promiseRef;
601  return promiseRef;
602  }
603  return _promise.lock();
604  }
605 
607  {
608  _handleRef = std::move(hdl);
609  }
610 
612  {
613  return _handleRef;
614  }
615 
616  void ProvideFileItem::informalMessage ( ProvideQueue &, ProvideRequestRef req, const ProvideMessage &msg )
617  {
618  if ( req != _runningReq ) {
619  WAR << "Received event for unknown request, ignoring" << std::endl;
620  return;
621  }
622 
624  MIL << "Provide File Request: "<< req->url() << " was started" << std::endl;
625  auto log = provider().log();
626 
627  auto locPath = msg.value( ProvideStartedMsgFields::LocalFilename, std::string() ).asString();
628  if ( !locPath.empty() )
629  _targetFile = zypp::Pathname(locPath);
630 
631  locPath = msg.value( ProvideStartedMsgFields::StagingFilename, std::string() ).asString();
632  if ( !locPath.empty() )
633  _stagingFile = zypp::Pathname(locPath);
634 
635  if ( log ) {
636  auto effUrl = req->activeUrl().value_or( zypp::Url() );
637  try {
639  } catch( const zypp::Exception &e ) {
640  ZYPP_CAUGHT(e);
641  }
642 
643  AnyMap m;
644  m["spec"] = _initialSpec;
645  if ( log ) log->requestStart( *this, msg.requestId(), effUrl, m );
647  }
648  }
649  }
650 
651  void zyppng::ProvideFileItem::ProvideFileItem::finishReq( zyppng::ProvideQueue &queue, ProvideRequestRef finishedReq, const ProvideMessage &msg )
652  {
653  if ( finishedReq != _runningReq ) {
654  WAR << "Received event for unknown request, ignoring" << std::endl;
655  return;
656  }
657 
659 
660  auto log = provider().log();
661  if ( log ) {
662  AnyMap m;
663  m["spec"] = _initialSpec;
664  if ( log ) log->requestDone( *this, msg.requestId(), m );
665  }
666 
667  MIL << "Request was successfully finished!" << std::endl;
668  // request is def done
669  _runningReq.reset();
670 
671  std::optional<zypp::ManagedFile> resFile;
672 
673  try {
674  const auto locFilename = msg.value( ProvideFinishedMsgFields::LocalFilename ).asString();
675  const auto cacheHit = msg.value( ProvideFinishedMsgFields::CacheHit ).asBool();
676  const auto &wConf = queue.workerConfig();
677 
678  const bool checkExistsOnly = _initialSpec.checkExistsOnly();
679  const bool doesDownload = wConf.worker_type() == ProvideQueue::Config::Downloading;
680  const bool fileNeedsCleanup = doesDownload || ( wConf.worker_type() == ProvideQueue::Config::CPUBound && wConf.cfg_flags() & ProvideQueue::Config::FileArtifacts );
681 
682  if ( doesDownload && !checkExistsOnly ) {
683 
684  resFile = provider().addToFileCache ( locFilename );
685  if ( !resFile ) {
686  if ( cacheHit ) {
687  MIL << "CACHE MISS, file " << locFilename << " was already removed, queueing again" << std::endl;
688  cacheMiss ( finishedReq );
689  finishedReq->clearForRestart();
690  enqueueRequest( finishedReq );
691  return;
692  } else {
693  // if we reach here it seems that a new file, that was not in cache before, vanished between
694  // providing it and receiving the finished message.
695  // unlikely this can happen but better be safe than sorry
696  cancelWithError( ZYPP_EXCPT_PTR( zypp::media::MediaException("File vanished between downloading and adding it to cache.")) );
697  return;
698  }
699  }
700 
701  } else {
702  resFile = zypp::ManagedFile( zypp::filesystem::Pathname(locFilename) );
703  if ( fileNeedsCleanup && !checkExistsOnly )
704  resFile->setDispose( zypp::filesystem::unlink );
705  else
706  resFile->resetDispose();
707  }
708 
709  _targetFile = locFilename;
710 
711  } catch ( const zypp::Exception &e ) {
712  ZYPP_CAUGHT(e);
713  cancelWithError( std::current_exception() );
714  } catch ( const std::exception &e ) {
715  ZYPP_CAUGHT(e);
716  cancelWithError( std::current_exception() );
717  } catch ( ...) {
718  cancelWithError( std::current_exception() );
719  }
720 
721  // keep the media handle around as long as the file is used by the code
722  auto resObj = std::make_shared<ProvideResourceData>();
723  resObj->_mediaHandle = this->_handleRef;
724  resObj->_myFile = *resFile;
725  resObj->_resourceUrl = *(finishedReq->activeUrl());
726  resObj->_responseHeaders = msg.headers();
727 
728  // if there is a exception escaping the pipeline we need to rethrow it after cleaning up
729  std::exception_ptr excpt;
730  auto p = promise();
731  if ( p ) {
732  try {
733  p->setReady( expected<ProvideRes>::success( ProvideRes( resObj )) );
734  } catch( const zypp::Exception &e ) {
735  ERR << "Caught unhandled pipline exception:" << e << std::endl;
736  ZYPP_CAUGHT(e);
737  excpt = std::current_exception ();
738  } catch ( const std::exception &e ) {
739  ERR << "Caught unhandled pipline exception:" << e.what() << std::endl;
740  ZYPP_CAUGHT(e);
741  excpt = std::current_exception ();
742  } catch ( ...) {
743  ERR << "Caught unhandled unknown exception:" << std::endl;
744  excpt = std::current_exception ();
745  }
746  }
747 
748  updateState( Finished );
749 
750  if ( excpt ) {
751  ERR << "Rethrowing pipeline exception, this is a BUG!" << std::endl;
752  std::rethrow_exception ( excpt );
753  }
754 
755  } else {
756  // on errors we could recover from if we have mirrors we try to redirect
757  switch( msg.code() ) {
759  case NotFound:
760  case ConnectionFailed:
761  //case Timeout:
762  case InvalidChecksum: {
763  auto log = provider().log();
764  MIL << "Request failed trying to recover." << std::endl;
765 
766  bool canRedirect = false;
767  for ( const auto &ep : _origin ) {
768  if ( canRedirectTo ( finishedReq, ep.url() ) ) {
769  canRedirect = true;
770  break;
771  }
772  }
773 
774  if ( canRedirect ) {
775  MIL << "Trying to recover by redirecting to a mirror" << std::endl;
776  if ( enqueueRequest( finishedReq ) )
777  return;
778  }
779 
780  MIL << "No mirror found or no mirror usable, giving up" << std::endl;
781  break;
782  }
783  default:
784  //all other codes handled by default code
785  break;
786  }
787  ProvideItem::finishReq ( queue, finishedReq, msg );
788  }
789  }
790 
791 
792  void zyppng::ProvideFileItem::cancelWithError( std::exception_ptr error )
793  {
794  if ( _runningReq ) {
795  auto weakThis = weak_from_this ();
796  provider().dequeueRequest ( _runningReq, error );
797  if ( weakThis.expired () )
798  return;
799  }
800 
801  // if we reach this place for some reason finishReq was not called, lets clean up manually
802  _runningReq.reset();
803  auto p = promise();
804  if ( p ) {
805  try {
806  p->setReady( expected<ProvideRes>::error( error ) );
807  } catch( const zypp::Exception &e ) {
808  ZYPP_CAUGHT(e);
809  }
810  }
811  updateState( Finished );
812  }
813 
814  expected<zypp::media::AuthData> ProvideFileItem::authenticationRequired ( ProvideQueue &queue, ProvideRequestRef req, const zypp::Url &effectiveUrl, int64_t lastTimestamp, const std::map<std::string, std::string> &extraFields )
815  {
816  zypp::Url urlToUse = effectiveUrl;
817  if ( _handleRef.isValid() ) {
818  // if we have a attached medium this overrules the URL we are going to ask the user about... this is how the old media backend did handle this
819  // i guess there were never password protected repositories that have different credentials on the redirection targets
820  auto &attachedMedia = provider().attachedMediaInfos();
821  if ( std::find( attachedMedia.begin(), attachedMedia.end(), _handleRef.mediaInfo() ) == attachedMedia.end() )
822  return expected<zypp::media::AuthData>::error( ZYPP_EXCPT_PTR( zypp::media::MediaException("Attachment handle vanished during request.") ) );
823  urlToUse = _handleRef.mediaInfo()->attachedUrl();
824  }
825  return ProvideItem::authenticationRequired( queue, req, urlToUse, lastTimestamp, extraFields );
826  }
827 
829  {
830  zypp::ByteCount providedByNow;
831 
832  bool checkStaging = false;
833  if ( !_targetFile.empty() ) {
835  if ( inf.isExist() && inf.isFile() )
836  providedByNow = zypp::ByteCount( inf.size() );
837  else
838  checkStaging = true;
839  }
840 
841  if ( checkStaging && !_stagingFile.empty() ) {
843  if ( inf.isExist() && inf.isFile() )
844  providedByNow = zypp::ByteCount( inf.size() );
845  }
846 
847  auto baseStats = ProvideItem::makeStats();
848  baseStats._bytesExpected = bytesExpected();
849  baseStats._bytesProvided = providedByNow;
850  return baseStats;
851  }
852 
854  {
856  }
857 
859  : ProvideItem ( parent )
860  , _origin ( origin )
861  , _initialSpec ( request )
862  { }
863 
865  {
866  MIL << "Killing the AttachMediaItem" << std::endl;
867  }
868 
870  {
871  if ( !_promiseCreated ) {
872  _promiseCreated = true;
873  auto promiseRef = std::make_shared<ProvidePromise<Provide::MediaHandle>>( shared_this<ProvideItem>() );
874  _promise = promiseRef;
875  return promiseRef;
876  }
877  return _promise.lock();
878  }
879 
881  {
882  if ( state() != Uninitialized ) {
883  WAR << "Double init of AttachMediaItem!" << std::endl;
884  return;
885  }
887 
888  if ( !_origin.isValid() ) {
889  cancelWithError( ZYPP_EXCPT_PTR( zypp::media::MediaException("No usable origin config.")) );
890  return;
891  }
892 
893  // shortcut to the provider instance
894  auto &prov= provider();
895 
896  // authority mandates the scheme
897  expected<ProvideQueue::Config> scheme = prov.schemeConfig( prov.effectiveScheme( _origin.authority().scheme() ) );
898 
899  if ( !scheme || !_origin.isValid() ) {
900  auto prom = promise();
901  if ( prom ) {
902  try {
903  if ( !scheme )
904  prom->setReady( expected<Provide::MediaHandle>::error( scheme.error() ) );
905  else
906  prom->setReady( expected<Provide::MediaHandle>::error( ZYPP_EXCPT_PTR ( zypp::media::MediaException("No valid mirrors available") )) );
907  } catch( const zypp::Exception &e ) {
908  ZYPP_CAUGHT(e);
909  }
910  }
912  return;
913  }
914 
915  // first check if there is a already attached medium we can use as well
916  auto &attachedMedia = prov.attachedMediaInfos ();
917 
918  // @TODO should we extend the mirrors here if some are not in the mirror list?
919  for ( auto &medium : attachedMedia ) {
920  if ( medium->isSameMedium ( _origin, _initialSpec ) ) {
921  finishWithSuccess ( medium );
922  return;
923  }
924  }
925 
926  for ( auto &otherItem : prov.items() ) {
927  auto attachIt = std::dynamic_pointer_cast<AttachMediaItem>(otherItem);
928  if ( !attachIt // not the right type
929  || attachIt.get() == this // do not attach to ourselves
930  || attachIt->state () == Uninitialized // item was not initialized
931  || attachIt->state () == Finalizing // item cleaning up
932  || attachIt->state () == Finished ) // item done
933  continue;
934 
935  // does this Item attach the same medium?
936  const bool sameMedium = AttachedMediaInfo::isSameMedium( attachIt->_origin, attachIt->_initialSpec, _origin, _initialSpec );
937  if ( !sameMedium )
938  continue;
939 
940  MIL << "Found item providing the same medium, attaching to finished signal and waiting for it to be finished" << std::endl;
941 
942  // it does, connect to its ready signal and just wait
944  return;
945  }
946 
947  _workerType = scheme->worker_type();
948 
949  switch( _workerType ) {
951 
952  // if the media file is empty in the spec we can not do anything
953  // simply pretend attach worked
954  if( _initialSpec.mediaFile().empty() ) {
955  finishWithSuccess( prov.addMedium( zypp::make_intrusive<AttachedMediaInfo>( provider().nextMediaId(), _workerType, _origin, _initialSpec ) ) );
956  return;
957  }
958 
959  // prepare the verifier with the data
960  auto smvDataLocal = MediaDataVerifier::createVerifier("SuseMediaV1");
961  if ( !smvDataLocal ) {
962  cancelWithError( ZYPP_EXCPT_PTR( zypp::media::MediaException("Unable to verify the medium, no verifier instance was returned.")) );
963  return;
964  }
965 
966  if ( !smvDataLocal->load( _initialSpec.mediaFile() ) ) {
967  cancelWithError( ZYPP_EXCPT_PTR( zypp::media::MediaException("Unable to verify the medium, unable to load local verify data.")) );
968  return;
969  }
970 
971  _verifier = smvDataLocal;
972 
973  zypp::MirroredOrigin fileOrigin = _origin;
974  for ( auto &ep : fileOrigin ) {
975  ep.url().appendPathName ( ( zypp::str::Format("/media.%d/media") % _initialSpec.medianr() ).asString() );
976  }
977 
978  // for downloading schemes we ask for the /media.x/media file and check the data manually
979  ProvideFileSpec spec;
981 
982  // disable metalink
983  spec.customHeaders().set( std::string(NETWORK_METALINK_ENABLED), false );
984 
985  auto req = ProvideRequest::create( *this, fileOrigin, spec );
986  if ( !req ) {
987  cancelWithError( req.error() );
988  return;
989  }
990  if ( !enqueueRequest( *req ) ) {
991  cancelWithError( ZYPP_EXCPT_PTR(zypp::media::MediaException("Failed to queue request")) );
992  return;
993  }
995  break;
996  }
999 
1000  const auto &newId = provider().nextMediaId();
1001  auto req = ProvideRequest::create( *this, _origin, newId, _initialSpec );
1002  if ( !req ) {
1003  cancelWithError( req.error() );
1004  return;
1005  }
1006  if ( !enqueueRequest( *req ) ) {
1007  ERR << "Failed to queue request" << std::endl;
1008  cancelWithError( ZYPP_EXCPT_PTR(zypp::media::MediaException("Failed to queue request")) );
1009  return;
1010  }
1011  break;
1012  }
1013  default: {
1014  auto prom = promise();
1015  if ( prom ) {
1016  try {
1017  prom->setReady( expected<Provide::MediaHandle>::error( ZYPP_EXCPT_PTR ( zypp::media::MediaException("URL scheme does not support attaching.") )) );
1018  } catch( const zypp::Exception &e ) {
1019  ZYPP_CAUGHT(e);
1020  }
1021  }
1022  updateState( Finished );
1023  return;
1024  }
1025  }
1026  }
1027 
1028  void AttachMediaItem::finishWithSuccess( AttachedMediaInfo_Ptr medium )
1029  {
1030 
1032 
1033  auto prom = promise();
1034  try {
1035  if ( prom ) {
1036  try {
1037  prom->setReady( expected<Provide::MediaHandle>::success( Provide::MediaHandle( *static_cast<Provide*>( provider().z_func() ), medium ) ) );
1038  } catch( const zypp::Exception &e ) {
1039  ZYPP_CAUGHT(e);
1040  }
1041  }
1042  } catch ( const std::exception &e ) {
1043  ERR << "WTF " << e.what () << std::endl;
1044  } catch ( ... ) {
1045  ERR << "WTF " << std::endl;
1046  }
1047 
1048  // tell others as well
1050 
1051  prom->isReady ();
1052 
1053  MIL << "Before setFinished" << std::endl;
1054  updateState( Finished );
1055  return;
1056  }
1057 
1058  void AttachMediaItem::cancelWithError( std::exception_ptr error )
1059  {
1060  MIL << "Cancelling Item with error" << std::endl;
1062 
1063  // tell children
1065 
1066  if ( _runningReq ) {
1067  // we might get deleted when calling dequeueRequest
1068  auto weakThis = weak_from_this ();
1069  provider().dequeueRequest ( _runningReq, error );
1070  if ( weakThis.expired () )
1071  return;
1072  }
1073 
1074  // if we reach this place we had no runningReq, clean up manually
1075  _runningReq.reset();
1076  _masterItemConn.disconnect();
1077 
1078  auto p = promise();
1079  if ( p ) {
1080  try {
1081  p->setReady( expected<zyppng::Provide::MediaHandle>::error( error ) );
1082  } catch( const zypp::Exception &e ) {
1083  ZYPP_CAUGHT(e);
1084  }
1085  }
1086  updateState( Finished );
1087  }
1088 
1090  {
1091 
1092  _masterItemConn.disconnect();
1093 
1094  if ( result ) {
1095  finishWithSuccess( AttachedMediaInfo_Ptr(result.get()) );
1096  } else {
1097  try {
1098  std::rethrow_exception ( result.error() );
1099  } catch ( const zypp::media::MediaRequestCancelledException & e) {
1100  // in case a item was cancelled, we revert to Pending state and trigger the scheduler.
1101  // This will make sure that all our sibilings that also depend on the master
1102  // can revert to pending state and we only get one new master in the next schedule run
1103  MIL_PRV << "Master item was cancelled, reverting to Uninitialized state and waiting for scheduler to run again" << std::endl;
1106 
1107  } catch ( ... ) {
1108  cancelWithError( std::current_exception() );
1109  }
1110  }
1111  }
1112 
1113  AttachMediaItemRef AttachMediaItem::create( const zypp::MirroredOrigin &origin, const ProvideMediaSpec &request, ProvidePrivate &parent )
1114  {
1115  return AttachMediaItemRef( new AttachMediaItem(origin, request, parent) );
1116  }
1117 
1119  {
1120  return _sigReady;
1121  }
1122 
1123  void AttachMediaItem::finishReq ( ProvideQueue &queue, ProvideRequestRef finishedReq, const ProvideMessage &msg )
1124  {
1125  if ( finishedReq != _runningReq ) {
1126  WAR << "Received event for unknown request, ignoring" << std::endl;
1127  return;
1128  }
1129 
1131  // success
1133 
1135 
1136  zypp::Url baseUrl = *finishedReq->activeUrl();
1137  // remove /media.n/media
1138  baseUrl.setPathName( zypp::Pathname(baseUrl.getPathName()).dirname().dirname() );
1139 
1140  // we got the file, lets parse it
1141  auto smvDataRemote = MediaDataVerifier::createVerifier("SuseMediaV1");
1142  if ( !smvDataRemote ) {
1143  return cancelWithError( ZYPP_EXCPT_PTR( zypp::media::MediaException("Unable to verify the medium, no verifier instance was returned.")) );
1144  }
1145 
1146  if ( !smvDataRemote->load( msg.value( ProvideFinishedMsgFields::LocalFilename ).asString() ) ) {
1147  return cancelWithError( ZYPP_EXCPT_PTR( zypp::media::MediaException("Unable to verify the medium, unable to load remote verify data.")) );
1148  }
1149 
1150  // check if we got a valid media file
1151  if ( !smvDataRemote->valid () ) {
1152  return cancelWithError( ZYPP_EXCPT_PTR( zypp::media::MediaException("Unable to verify the medium, unable to load local verify data.")) );
1153  }
1154 
1155  // check if the received file matches with the one we have in the spec
1156  if (! _verifier->matches( smvDataRemote ) ) {
1157  DBG << "expect: " << _verifier << " medium " << _initialSpec.medianr() << std::endl;
1158  DBG << "remote: " << smvDataRemote << std::endl;
1159  return cancelWithError( ZYPP_EXCPT_PTR( zypp::media::MediaNotDesiredException( *finishedReq->activeUrl() ) ) );
1160  }
1161 
1162  // all good, register the medium and tell all child items
1163  _runningReq.reset();
1164 
1165  return finishWithSuccess( provider().addMedium( zypp::make_intrusive<AttachedMediaInfo>( provider().nextMediaId(), _workerType, _origin, _initialSpec) ) );
1166 
1167  } else if ( msg.code() == ProvideMessage::Code::NotFound ) {
1168 
1169  // simple downloading attachment we need to check the media file contents
1170  // in case of a error we might tolerate a file not found error in certain situations
1171  if ( _verifier->totalMedia () == 1 ) {
1172  // relaxed , tolerate a vanished media file
1173  _runningReq.reset();
1174 
1175  return finishWithSuccess( provider().addMedium( zypp::make_intrusive<AttachedMediaInfo>( provider().nextMediaId(), _workerType, _origin, _initialSpec ) ) );
1176  }
1177  }
1178  } else {
1179  // real device attach
1180  if ( msg.code() == ProvideMessage::Code::AttachFinished ) {
1181 
1182  std::optional<zypp::Pathname> mntPoint;
1184  if ( mountPtVal.valid() && mountPtVal.isString() ) {
1185  mntPoint = zypp::Pathname(mountPtVal.asString());
1186  }
1187 
1188  _runningReq.reset();
1189  return finishWithSuccess( provider().addMedium( zypp::make_intrusive<AttachedMediaInfo>(
1190  finishedReq->provideMessage().value( AttachMsgFields::AttachId ).asString()
1191  , queue.weak_this<ProvideQueue>()
1192  , _workerType
1193  , zypp::MirroredOrigin(*finishedReq->activeUrl()) // no mirrors
1194  , _initialSpec
1195  , mntPoint ) ) );
1196  }
1197  }
1198 
1199  // unhandled message , let the base impl do it
1200  return ProvideItem::finishReq ( queue, finishedReq, msg );
1201  }
1202 
1203  expected<zypp::media::AuthData> AttachMediaItem::authenticationRequired ( ProvideQueue &queue, ProvideRequestRef req, const zypp::Url &effectiveUrl, int64_t lastTimestamp, const std::map<std::string, std::string> &extraFields )
1204  {
1205  zypp::Url baseUrl = effectiveUrl;
1207  // remove /media.n/media
1208  baseUrl.setPathName( zypp::Pathname(baseUrl.getPathName()).dirname().dirname() );
1209  }
1210  return ProvideItem::authenticationRequired( queue, req, baseUrl, lastTimestamp, extraFields );
1211  }
1212 
1213 }
static AttachMediaItemRef create(const zypp::MirroredOrigin &origin, const ProvideMediaSpec &request, ProvidePrivate &parent)
bool safeRedirectTo(ProvideRequestRef startedReq, const zypp::Url &url)
Definition: provideitem.cc:95
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
static expected< ProvideRequestRef > create(ProvideItem &owner, const zypp::MirroredOrigin &origin, const std::string &id, ProvideMediaSpec &spec)
Definition: provideitem.cc:27
#define MIL
Definition: Logger.h:100
virtual bool enqueueRequest(ProvideRequestRef request)
Definition: provideitem.cc:451
constexpr std::string_view Url("url")
constexpr std::string_view LocalFilename("local_filename")
const std::string & asString() const
constexpr std::string_view AttachId("attach_id")
ProvideQueue::Config::WorkerType _workerType
ProvidePromiseWeakRef< Provide::MediaHandle > _promise
static constexpr std::string_view DEFAULT_MEDIA_VERIFIER("SuseMediaV1")
constexpr std::string_view NETWORK_METALINK_ENABLED("zypp-nw-metalink-enabled")
constexpr std::string_view VerifyData("verify_data")
void finishWithSuccess(AttachedMediaInfo_Ptr medium)
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
Definition: provideitem.cc:814
ProvideQueueWeakRef _myQueue
Definition: provideitem_p.h:91
constexpr std::string_view Filename("filename")
Signal< std::optional< zypp::media::AuthData > const zypp::Url &reqUrl, const std::string &triedUsername, const std::map< std::string, std::string > &extraValues) > _sigAuthRequired
Definition: provide_p.h:97
Store and operate with byte count.
Definition: ByteCount.h:31
#define ZYPP_IMPL_PRIVATE(Class)
Definition: zyppglobal.h:92
virtual void cacheMiss(ProvideRequestRef req)
Definition: provideitem.cc:180
ProvidePromiseRef< ProvideRes > promise()
Definition: provideitem.cc:595
void initialize() override
Definition: provideitem.cc:880
void save()
Saves any unsaved credentials added via addUserCred() or addGlobalCred() methods. ...
std::string nextMediaId() const
Definition: provide.cc:798
MediaDataVerifierRef _verifier
virtual void finishReq(ProvideQueue &queue, ProvideRequestRef finishedReq, const ProvideMessage &msg)
Definition: provideitem.cc:190
std::shared_ptr< ProvidePromise< T > > ProvidePromiseRef
Definition: providefwd_p.h:31
const zypp::Pathname & deltafile() const
The existing deltafile that can be used to reduce download size ( zchunk or metalink ) ...
Definition: providespec.cc:246
Signal< void(const zyppng::expected< AttachedMediaInfo * > &)> _sigReady
virtual ItemStats makeStats()
Definition: provideitem.cc:159
void onMasterItemReady(const zyppng::expected< AttachedMediaInfo *> &result)
Definition: Arch.h:363
const zypp::Url & url() const
AuthData_Ptr getCred(const Url &url)
Get credentials for the specified url.
zypp::MirroredOrigin _origin
AttachMediaItem(const zypp::MirroredOrigin &origin, const ProvideMediaSpec &request, ProvidePrivate &parent)
Definition: provideitem.cc:858
const std::string & label() const
Definition: providespec.cc:101
std::chrono::steady_clock::time_point _pulseTime
Definition: provideitem.h:46
Convenient building of std::string with boost::format.
Definition: String.h:253
static expected error(ConsParams &&...params)
Definition: expected.h:126
constexpr std::string_view VerifyType("verify_type")
void initialize() override
Definition: provideitem.cc:573
std::string scheme() const
#define ZYPP_EXCPT_PTR(EXCPT)
Drops a logline and returns Exception as a std::exception_ptr.
Definition: Exception.h:463
State state() const
Definition: provideitem.cc:498
zypp::MirroredOrigin _origin
ProvideMessage _message
Definition: provideitem_p.h:87
time_t timestampForCredDatabase(const zypp::Url &url)
zyppng::AttachedMediaInfo_constPtr mediaInfo() const
Definition: provide.cc:993
#define ERR
Definition: Logger.h:102
std::vector< AttachedMediaInfo_Ptr > & attachedMediaInfos()
Definition: provide.cc:734
#define Z_D()
Definition: zyppglobal.h:105
AutoDispose< const Pathname > ManagedFile
A Pathname plus associated cleanup code to be executed when path is no longer needed.
Definition: ManagedFile.h:27
const std::optional< zypp::Url > activeUrl() const
Returns the currenty active URL as set by the scheduler.
Definition: provideitem.cc:513
void updateState(const State newState)
Definition: provideitem.cc:461
constexpr std::string_view CheckExistOnly("check_existance_only")
WeakPtr parent() const
Definition: base.cc:26
std::string asString(TInt val, char zero='0', char one='1')
For printing bits.
Definition: Bit.h:57
constexpr std::string_view NewUrl("new_url")
bool empty() const
Test for an empty path.
Definition: Pathname.h:116
ProvideFileSpec _initialSpec
void setPathName(const std::string &path, EEncoding eflag=zypp::url::E_DECODED)
Set the path name.
Definition: Url.cc:782
std::string asString() const
Returns a default string representation of the Url object.
Definition: Url.cc:515
constexpr std::string_view LocalFilename("local_filename")
FieldVal value(const std::string_view &str, const FieldVal &defaultVal=FieldVal()) const
void redirectTo(ProvideRequestRef startedReq, const zypp::Url &url)
Definition: provideitem.cc:104
Convenient building of std::string via std::ostringstream Basically a std::ostringstream autoconverti...
Definition: String.h:212
unsigned medianr() const
Definition: providespec.cc:110
static auto connect(typename internal::MemberFunction< SenderFunc >::ClassType &s, SenderFunc &&sFun, typename internal::MemberFunction< ReceiverFunc >::ClassType &recv, ReceiverFunc &&rFunc)
Definition: base.h:142
Manages a data source characterized by an authoritative URL and a list of mirror URLs.
zypp::Pathname mediaFile() const
Definition: providespec.cc:119
const std::string & asString() const
String representation.
Definition: Pathname.h:93
const Config & workerConfig() const
bool isExist() const
Return whether valid stat info exists.
Definition: PathInfo.h:286
Just inherits Exception to separate media exceptions.
virtual void informalMessage(ProvideQueue &, ProvideRequestRef req, const ProvideMessage &msg)
Definition: provideitem.cc:167
Pathname dirname() const
Return all but the last component od this path.
Definition: Pathname.h:126
zypp::Url url() const
Definition: provideitem_p.h:69
#define WAR
Definition: Logger.h:101
std::string asCompleteString() const
Returns a complete string representation of the Url object.
Definition: Url.cc:523
void informalMessage(ProvideQueue &, ProvideRequestRef req, const ProvideMessage &msg) override
Definition: provideitem.cc:616
const std::optional< ItemStats > & currentStats() const
Definition: provideitem.cc:122
std::weak_ptr< T > weak_this() const
Definition: base.h:123
ProvideStatusRef log()
Definition: provide_p.h:90
void cancelWithError(std::exception_ptr error) override
Definition: provideitem.cc:792
ItemStats makeStats() override
Definition: provideitem.cc:828
void schedule(ScheduleReason reason)
Definition: provide.cc:38
WorkerType worker_type() const
zypp::ByteCount bytesExpected() const override
Definition: provideitem.cc:853
const zypp::ByteCount & downloadSize() const
The size of the resource on the server.
Definition: providespec.cc:210
constexpr std::string_view Reason("reason")
void set(const std::string &key, Value val)
void cancelWithError(std::exception_ptr error) override
SignalProxy< void(const zyppng::expected< AttachedMediaInfo * > &) > sigReady()
int unlink(const Pathname &path)
Like &#39;unlink&#39;.
Definition: PathInfo.cc:705
const zypp::Pathname & destFilenameHint() const
Definition: providespec.cc:192
ProvidePrivate & provider()
Definition: provideitem.cc:90
static expected success(ConsParams &&...params)
Definition: expected.h:115
constexpr std::string_view NewUrl("new_url")
void setCurrentQueue(ProvideQueueRef ref)
Definition: provideitem.cc:503
void setValue(const std::string &name, const FieldVal &value)
constexpr std::string_view DeltaFile("delta_file")
#define MIL_PRV
Definition: providedbg_p.h:35
static MediaDataVerifierRef createVerifier(const std::string &verifierType)
virtual bool canRedirectTo(ProvideRequestRef startedReq, const zypp::Url &url)
Definition: provideitem.cc:110
const std::vector< ProvideMessage::FieldVal > & values(const std::string_view &str) const
zypp::Pathname _targetFile
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
Definition: Exception.h:475
ProvideFileItem(zypp::MirroredOrigin origin, const ProvideFileSpec &request, ProvidePrivate &parent)
Definition: provideitem.cc:562
bool dequeueRequest(ProvideRequestRef req, std::exception_ptr error)
Definition: provide.cc:832
void finishReq(ProvideQueue &queue, ProvideRequestRef finishedReq, const ProvideMessage &msg) override
Base class for Exception.
Definition: Exception.h:152
HeaderValueMap & customHeaders()
Definition: providespec.cc:128
void setActiveUrl(const zypp::Url &urlToUse)
Definition: provideitem.cc:544
constexpr std::string_view Url("url")
constexpr std::string_view LocalMountPoint("local_mountpoint")
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)
Definition: provideitem.cc:402
std::string getPathName(EEncoding eflag=zypp::url::E_DECODED) const
Returns the path name from the URL.
Definition: Url.cc:622
constexpr std::string_view Url("url")
unsigned int MediaNr
Definition: MediaManager.h:32
ProvidePromiseRef< Provide::MediaHandle > promise()
Definition: provideitem.cc:869
zypp::ByteCount _expectedBytes
virtual void released()
Definition: provideitem.cc:489
bool addMirror(OriginEndpoint newMirror)
ProvideQueueRef currentQueue()
Definition: provideitem.cc:508
constexpr std::string_view MetalinkEnabled("metalink_enabled")
Wrapper class for ::stat/::lstat.
Definition: PathInfo.h:225
Provide::MediaHandle _handleRef
virtual void cancelWithError(std::exception_ptr error)=0
uint endpointCount() const
constexpr std::string_view StagingFilename("staging_filename")
void setAuthority(OriginEndpoint newAuthority)
Provide::MediaHandle & mediaRef()
Definition: provideitem.cc:611
constexpr std::string_view Url("url")
#define ZYPP_FWD_CURRENT_EXCPT()
Drops a logline and returns the current Exception as a std::exception_ptr.
Definition: Exception.h:471
std::unordered_map< std::string, boost::any > AnyMap
Definition: provide.h:48
const HeaderValueMap & headers() const
virtual zypp::ByteCount bytesExpected() const
Definition: provideitem.cc:154
void addCred(const AuthData &cred)
Add new credentials with user callbacks.
const OriginEndpoint & authority() const
ProvideMediaSpec _initialSpec
void setMediaRef(Provide::MediaHandle &&hdl)
Definition: provideitem.cc:606
bool isSameMedium(const zypp::MirroredOrigin &origin, const ProvideMediaSpec &spec)
static ProvideFileItemRef create(zypp::MirroredOrigin origin, const ProvideFileSpec &request, ProvidePrivate &parent)
Definition: provideitem.cc:568
const std::optional< ItemStats > & previousStats() const
Definition: provideitem.cc:127
ProvidePromiseWeakRef< ProvideRes > _promise
HeaderValueMap & customHeaders()
Definition: providespec.cc:258
constexpr std::string_view CacheHit("cacheHit")
virtual std::chrono::steady_clock::time_point startTime() const
Definition: provideitem.cc:132
constexpr std::string_view LastUser("username")
zypp::Pathname _stagingFile
Url manipulation class.
Definition: Url.h:92
virtual std::chrono::steady_clock::time_point finishedTime() const
Definition: provideitem.cc:137
bool checkExistsOnly() const
Definition: providespec.cc:198
#define DBG
Definition: Logger.h:99
ProvideRequestRef _runningReq
Definition: provideitem.h:189
constexpr std::string_view ExpectedFilesize("expected_filesize")