libzypp 17.38.17
MediaNetworkRequestExecutor.cc
Go to the documentation of this file.
3
10
11namespace 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
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 // The request might already be finished at this point, e.g. if setting up the
65 // curl handle failed. Calling loop->quit() before loop->run() has no effect,
66 // so only run the loop if the request is still pending or running.
67 if ( _nwDispatcher->count () != 0 )
68 loop->run();
69
70 // once the request is done there should be nothing there anymore
71 if ( _nwDispatcher->count () != 0 ) {
72 ZYPP_THROW( zypp::Exception("Unexpected request count after finishing MediaCurl2 request!") );
73 }
74
75 if ( req->hasError() ) {
77 std::exception_ptr excp;
78 const auto &error = req->error();
79 switch ( error.type() ) {
89 excp = ZYPP_EXCPT_PTR( zypp::media::MediaCurlException( req->url(), error.toString(), error.nativeErrorString() ) );
90 break;
91 }
94 break;
95 }
97 excp = ZYPP_EXCPT_PTR( zypp::media::MediaFileSizeExceededException( req->url(), req->expectedFileSize() ) );
98 break;
99 }
101 excp = ZYPP_EXCPT_PTR( zypp::media::MediaTemporaryProblemException( req->url(), error.toString() ) );
102 break;
103 }
105 excp = ZYPP_EXCPT_PTR( zypp::media::MediaTimeoutException( req->url(), error.toString() ) );
106 break;
107 }
109 excp = ZYPP_EXCPT_PTR( zypp::media::MediaForbiddenException( req->url(), error.toString() ) );
110 break;
111 }
115 break;
116 }
119
120 //in case we got a auth hint from the server the error object will contain it
121 std::string authHint = error.extraInfoValue("authHint", std::string());
122
123 bool canContinue = false;
124 _sigAuthRequired.emit( req->url(), req->transferSettings(), authHint, firstAuth, canContinue );
125 if ( canContinue ) {
126 firstAuth = false;
127 retry = true;
128 continue;
129 }
130
132 excp = ZYPP_EXCPT_PTR( zypp::media::MediaUnauthorizedException( req->url(), error.toString(), error.nativeErrorString(), "" ) );
133 break;
134 }
136 // should never happen
137 DBG << "BUG: Download error flag is set , but Error code is NoError" << std::endl;
138 break;
141 excp = ZYPP_EXCPT_PTR( zypp::media::MediaCurlException( req->url(), error.toString(), error.nativeErrorString() ) );
142 break;
143 }
144 }
145
146 if ( excp ) {
147 if ( !retry && ( maxTries - 1 ) > 0 ) {
148 maxTries--;
149 retry = true;
150 continue;
151 }
152
153 if ( report ) (*report)->finish( req->url(), errCode, error.toString() );
154 std::rethrow_exception( excp );
155 }
156 }
157
158 }
159
160 if ( report ) (*report)->finish( req->url(), zypp::media::DownloadProgressReport::NO_ERROR, "" );
161 }
162}
#define zypp_defer
#define ZYPP_EXCPT_PTR(EXCPT)
Drops a logline and returns Exception as a std::exception_ptr.
Definition Exception.h:463
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition Exception.h:459
#define DBG
Definition Logger.h:129
Base class for Exception.
Definition Exception.h:153
void executeRequest(zyppng::NetworkRequestRef &req, callback::SendReport< media::DownloadProgressReport > *report=nullptr)
zyppng::NetworkRequestDispatcherRef _nwDispatcher
zyppng::Signal< void(const zypp::Url &url, media::TransferSettings &settings, const std::string &availAuthTypes, bool firstTry, bool &canContinue)> _sigAuthRequired
static Ptr create(GMainContext *ctx=nullptr)
The NetworkRequestError class Represents a error that occured in.
const zypp::Pathname & targetFilePath() const
Returns the target filename path.
Definition request.cc:929
SignalProxy< void(NetworkRequest &req, const NetworkRequestError &err)> sigFinished()
Signals that the download finished.
Definition request.cc:1076
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:1071
Definition ansi.h:855