libzypp  17.37.5
MediaNetworkRequestExecutor.cc
Go to the documentation of this file.
3 
10 
11 namespace zypp::internal {
12 
14  : _evDispatcher( zyppng::ThreadData::current().ensureDispatcher() )
15  , _nwDispatcher( std::make_shared<zyppng::NetworkRequestDispatcher>() )
16  {
17 
18  }
19 
21  {
22  auto loop = zyppng::EventLoop::create();
23 
24  _nwDispatcher->run();
25 
26  bool firstAuth = true;
27  bool retry = true;
28  int maxTries = req->transferSettings().maxSilentTries();
29 
30  while ( retry ) {
31  std::optional<internal::ProgressTracker> progTracker;
32 
33  std::vector<zyppng::connection> signalConnections {
34  req->sigStarted().connect( [&]( zyppng::NetworkRequest &req ){
35  if ( !report) return;
36  (*report)->start( req.url(), req.targetFilePath() );
37  }),
38  req->sigProgress().connect( [&]( zyppng::NetworkRequest &req, off_t dlTotal, off_t dlNow, off_t, off_t ){
39  if ( !report || !progTracker )
40  return;
41 
42  progTracker->updateStats( dlTotal, dlNow );
43  if ( !(*report)->progress( progTracker->_dnlPercent, req.url(), progTracker-> _drateTotal, progTracker->_drateLast ) )
44  _nwDispatcher->cancel ( req );
45 
46  }),
47  req->sigFinished().connect( [&]( zyppng::NetworkRequest &req, const zyppng::NetworkRequestError &err ) {
48  loop->quit();
49  })
50  };
51 
52  // clean up slots for every loop
53  zypp_defer {
54  std::for_each( signalConnections.begin(), signalConnections.end(), []( auto &conn ) { conn.disconnect(); });
55  signalConnections.clear();
56  };
57 
58  if ( report ) {
59  progTracker = internal::ProgressTracker();
60  }
61 
62  retry = false; // normally we don't retry
63  _nwDispatcher->enqueue ( req );
64  loop->run();
65 
66  // once the request is done there should be nothing there anymore
67  if ( _nwDispatcher->count () != 0 ) {
68  ZYPP_THROW( zypp::Exception("Unexpected request count after finishing MediaCurl2 request!") );
69  }
70 
71  if ( req->hasError() ) {
73  std::exception_ptr excp;
74  const auto &error = req->error();
75  switch ( error.type() ) {
85  excp = ZYPP_EXCPT_PTR( zypp::media::MediaCurlException( req->url(), error.toString(), error.nativeErrorString() ) );
86  break;
87  }
89  excp = ZYPP_EXCPT_PTR( zypp::media::MediaRequestCancelledException( error.toString() ) );
90  break;
91  }
93  excp = ZYPP_EXCPT_PTR( zypp::media::MediaFileSizeExceededException( req->url(), req->expectedFileSize() ) );
94  break;
95  }
97  excp = ZYPP_EXCPT_PTR( zypp::media::MediaTemporaryProblemException( req->url(), error.toString() ) );
98  break;
99  }
101  excp = ZYPP_EXCPT_PTR( zypp::media::MediaTimeoutException( req->url(), error.toString() ) );
102  break;
103  }
105  excp = ZYPP_EXCPT_PTR( zypp::media::MediaForbiddenException( req->url(), error.toString() ) );
106  break;
107  }
111  break;
112  }
115 
116  //in case we got a auth hint from the server the error object will contain it
117  std::string authHint = error.extraInfoValue("authHint", std::string());
118 
119  bool canContinue = false;
120  _sigAuthRequired.emit( req->url(), req->transferSettings(), authHint, firstAuth, canContinue );
121  if ( canContinue ) {
122  firstAuth = false;
123  retry = true;
124  continue;
125  }
126 
128  excp = ZYPP_EXCPT_PTR( zypp::media::MediaUnauthorizedException( req->url(), error.toString(), error.nativeErrorString(), "" ) );
129  break;
130  }
132  // should never happen
133  DBG << "BUG: Download error flag is set , but Error code is NoError" << std::endl;
134  break;
137  excp = ZYPP_EXCPT_PTR( zypp::media::MediaCurlException( req->url(), error.toString(), error.nativeErrorString() ) );
138  break;
139  }
140  }
141 
142  if ( excp ) {
143  if ( !retry && ( maxTries - 1 ) > 0 ) {
144  maxTries--;
145  retry = true;
146  continue;
147  }
148 
149  if ( report ) (*report)->finish( req->url(), errCode, error.toString() );
150  std::rethrow_exception( excp );
151  }
152  }
153 
154  }
155 
156  if ( report ) (*report)->finish( req->url(), zypp::media::DownloadProgressReport::NO_ERROR, "" );
157  }
158 }
zyppng::Signal< void(const zypp::Url &url, media::TransferSettings &settings, const std::string &availAuthTypes, bool firstTry, bool &canContinue)> _sigAuthRequired
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition: Exception.h:459
Definition: Arch.h:363
#define ZYPP_EXCPT_PTR(EXCPT)
Drops a logline and returns Exception as a std::exception_ptr.
Definition: Exception.h:463
#define zypp_defer
Definition: AutoDispose.h:293
The NetworkRequestError class Represents a error that occured in.
void executeRequest(zyppng::NetworkRequestRef &req, callback::SendReport< media::DownloadProgressReport > *report=nullptr)
static Ptr create()
const zypp::Pathname & targetFilePath() const
Returns the target filename path.
Definition: request.cc:930
zyppng::NetworkRequestDispatcherRef _nwDispatcher
Base class for Exception.
Definition: Exception.h:152
SignalProxy< void(NetworkRequest &req, const NetworkRequestError &err)> sigFinished()
Signals that the download finished.
Definition: request.cc:1077
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:1072
#define DBG
Definition: Logger.h:99