libzypp 17.37.10

MediaNetworkRequestExecutor.cc
Go to the documentation of this file.
1#include "MediaNetworkRequestExecutor.h"
2#include "DownloadProgressTracker.h"
3
4#include <zypp-core/AutoDispose.h>
5#include <zypp-core/zyppng/base/eventloop.h>
6#include <zypp-core/zyppng/base/private/threaddata_p.h>
7#include <zypp-curl/ng/network/networkrequestdispatcher.h>
8#include <zypp-curl/ng/network/request.h>
9#include <zypp-media/mediaexception.h>
10
11 namespace zypp::internal {
12
13 MediaNetworkRequestExecutor::MediaNetworkRequestExecutor()
14 : _evDispatcher( zyppng::ThreadData::current().ensureDispatcher() )
15 , _nwDispatcher( std::make_shared<zyppng::NetworkRequestDispatcher>() )
16 {
17
18 }
19
20 void MediaNetworkRequestExecutor::executeRequest( zyppng::NetworkRequestRef &req, callback::SendReport<media::DownloadProgressReport> *report )
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() ) {
72 auto errCode = zypp::media::DownloadProgressReport::ERROR;
73 std::exception_ptr excp;
74 const auto &error = req->error();
75 switch ( error.type() ) {
76 case zyppng::NetworkRequestError::InternalError:
77 case zyppng::NetworkRequestError::InvalidChecksum:
78 case zyppng::NetworkRequestError::UnsupportedProtocol:
79 case zyppng::NetworkRequestError::MalformedURL:
80 case zyppng::NetworkRequestError::PeerCertificateInvalid:
81 case zyppng::NetworkRequestError::ConnectionFailed:
82 case zyppng::NetworkRequestError::ServerReturnedError:
83 case zyppng::NetworkRequestError::MissingData:
84 case zyppng::NetworkRequestError::RangeFail: {
85 excp = ZYPP_EXCPT_PTR( zypp::media::MediaCurlException( req->url(), error.toString(), error.nativeErrorString() ) );
86 break;
87 }
88 case zyppng::NetworkRequestError::Cancelled: {
89 excp = ZYPP_EXCPT_PTR( zypp::media::MediaRequestCancelledException( error.toString() ) );
90 break;
91 }
92 case zyppng::NetworkRequestError::ExceededMaxLen: {
93 excp = ZYPP_EXCPT_PTR( zypp::media::MediaFileSizeExceededException( req->url(), req->expectedFileSize() ) );
94 break;
95 }
96 case zyppng::NetworkRequestError::TemporaryProblem: {
97 excp = ZYPP_EXCPT_PTR( zypp::media::MediaTemporaryProblemException( req->url(), error.toString() ) );
98 break;
99 }
100 case zyppng::NetworkRequestError::Timeout: {
101 excp = ZYPP_EXCPT_PTR( zypp::media::MediaTimeoutException( req->url(), error.toString() ) );
102 break;
103 }
104 case zyppng::NetworkRequestError::Forbidden: {
105 excp = ZYPP_EXCPT_PTR( zypp::media::MediaForbiddenException( req->url(), error.toString() ) );
106 break;
107 }
108 case zyppng::NetworkRequestError::NotFound: {
109 errCode = zypp::media::DownloadProgressReport::NOT_FOUND;
110 excp = ZYPP_EXCPT_PTR( zypp::media::MediaFileNotFoundException( req->url() ) );
111 break;
112 }
113 case zyppng::NetworkRequestError::Unauthorized:
114 case zyppng::NetworkRequestError::AuthFailed: {
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
127 errCode = zypp::media::DownloadProgressReport::ACCESS_DENIED;
128 excp = ZYPP_EXCPT_PTR( zypp::media::MediaUnauthorizedException( req->url(), error.toString(), error.nativeErrorString(), "" ) );
129 break;
130 }
131 case zyppng::NetworkRequestError::NoError:
132 // should never happen
133 DBG << "BUG: Download error flag is set , but Error code is NoError" << std::endl;
134 break;
135 case zyppng::NetworkRequestError::Http2Error:
136 case zyppng::NetworkRequestError::Http2StreamError: {
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}
DownloadProgressTracker.h
MediaNetworkRequestExecutor.h
zypp::Exception
Base class for Exception.
Definition Exception.h:153
zypp::internal::MediaNetworkRequestExecutor::MediaNetworkRequestExecutor
MediaNetworkRequestExecutor()
Definition MediaNetworkRequestExecutor.cc:13
zypp::internal::MediaNetworkRequestExecutor::executeRequest
void executeRequest(zyppng::NetworkRequestRef &req, callback::SendReport< media::DownloadProgressReport > *report=nullptr)
Definition MediaNetworkRequestExecutor.cc:20
zypp::internal::MediaNetworkRequestExecutor::_nwDispatcher
zyppng::NetworkRequestDispatcherRef _nwDispatcher
Definition MediaNetworkRequestExecutor.h:49
zypp::internal::MediaNetworkRequestExecutor::_sigAuthRequired
zyppng::Signal< void(const zypp::Url &url, media::TransferSettings &settings, const std::string &availAuthTypes, bool firstTry, bool &canContinue)> _sigAuthRequired
Definition MediaNetworkRequestExecutor.h:47
zypp::internal::MediaNetworkRequestExecutor::_evDispatcher
zyppng::EventDispatcherRef _evDispatcher
Definition MediaNetworkRequestExecutor.h:48
zypp::media::MediaCurlException
Definition mediaexception.h:365
zypp::media::MediaFileNotFoundException
Definition mediaexception.h:164
zypp::media::MediaFileSizeExceededException
Definition mediaexception.h:513
zypp::media::MediaForbiddenException
Definition mediaexception.h:485
zypp::media::MediaRequestCancelledException
Definition mediaexception.h:568
zypp::media::MediaTemporaryProblemException
For HTTP 503 and similar.
Definition mediaexception.h:531
zypp::media::MediaTimeoutException
Definition mediaexception.h:499
zypp::media::MediaUnauthorizedException
Definition mediaexception.h:450
zyppng::EventLoop::create
static Ptr create()
Definition eventloop_glib.cc:24
zyppng::NetworkRequestError
The NetworkRequestError class Represents a error that occured in.
Definition networkrequesterror.h:24
zyppng::NetworkRequestError::ServerReturnedError
@ ServerReturnedError
Definition networkrequesterror.h:42
zyppng::NetworkRequestError::Forbidden
@ Forbidden
Definition networkrequesterror.h:38
zyppng::NetworkRequestError::PeerCertificateInvalid
@ PeerCertificateInvalid
Definition networkrequesterror.h:30
zyppng::NetworkRequestError::UnsupportedProtocol
@ UnsupportedProtocol
Definition networkrequesterror.h:34
zyppng::NetworkRequestError::InternalError
@ InternalError
Definition networkrequesterror.h:28
zyppng::NetworkRequestError::ExceededMaxLen
@ ExceededMaxLen
Definition networkrequesterror.h:32
zyppng::NetworkRequestError::Unauthorized
@ Unauthorized
Definition networkrequesterror.h:40
zyppng::NetworkRequestError::MalformedURL
@ MalformedURL
Definition networkrequesterror.h:35
zyppng::NetworkRequestError::ConnectionFailed
@ ConnectionFailed
Definition networkrequesterror.h:31
zyppng::NetworkRequestError::RangeFail
@ RangeFail
Definition networkrequesterror.h:44
zyppng::NetworkRequestError::AuthFailed
@ AuthFailed
Definition networkrequesterror.h:41
zyppng::NetworkRequestError::Timeout
@ Timeout
Definition networkrequesterror.h:37
zyppng::NetworkRequestError::Http2Error
@ Http2Error
Definition networkrequesterror.h:45
zyppng::NetworkRequestError::MissingData
@ MissingData
Definition networkrequesterror.h:43
zyppng::NetworkRequestError::NoError
@ NoError
Definition networkrequesterror.h:27
zyppng::NetworkRequestError::NotFound
@ NotFound
Definition networkrequesterror.h:39
zyppng::NetworkRequestError::Cancelled
@ Cancelled
Definition networkrequesterror.h:29
zyppng::NetworkRequestError::Http2StreamError
@ Http2StreamError
Definition networkrequesterror.h:46
zyppng::NetworkRequestError::TemporaryProblem
@ TemporaryProblem
Definition networkrequesterror.h:36
zyppng::NetworkRequestError::InvalidChecksum
@ InvalidChecksum
Definition networkrequesterror.h:33
zyppng::NetworkRequest
Definition request.h:43
zyppng::NetworkRequest::targetFilePath
const zypp::Pathname & targetFilePath() const
Returns the target filename path.
Definition request.cc:930
zyppng::NetworkRequest::url
Url url() const
Definition request.cc:916
zyppng::NetworkRequest::sigFinished
SignalProxy< void(NetworkRequest &req, const NetworkRequestError &err)> sigFinished()
Signals that the download finished.
Definition request.cc:1077
zyppng::NetworkRequest::sigProgress
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
eventloop.h
mediaexception.h
std
Definition Arch.h:364
zypp::internal
Definition DownloadProgressTracker.cc:13
zyppng
Definition MediaNetworkRequestExecutor.h:16
networkrequestdispatcher.h
request.h
zypp::callback::SendReport
Definition Callback.h:237
zypp::internal::ProgressTracker
Definition DownloadProgressTracker.h:17
zypp::media::DownloadProgressReport::NO_ERROR
@ NO_ERROR
Definition ZYppCallbacks.h:371
zypp::media::DownloadProgressReport::ACCESS_DENIED
@ ACCESS_DENIED
Definition ZYppCallbacks.h:374
zypp::media::DownloadProgressReport::ERROR
@ ERROR
Definition ZYppCallbacks.h:375
zypp::media::DownloadProgressReport::NOT_FOUND
@ NOT_FOUND
Definition ZYppCallbacks.h:372
threaddata_p.h
AutoDispose.h
zypp_defer
#define zypp_defer
Definition AutoDispose.h:293
ZYPP_EXCPT_PTR
#define ZYPP_EXCPT_PTR(EXCPT)
Drops a logline and returns Exception as a std::exception_ptr.
Definition Exception.h:463
ZYPP_THROW
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition Exception.h:459
DBG
#define DBG
Definition Logger.h:99