libzypp: zypp-curl/ng/network/networkrequestdispatcher.cc Source File

libzypp 17.36.6

networkrequestdispatcher.cc
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8----------------------------------------------------------------------*/
9#include <zypp-core/Globals.h>
10#include <zypp-curl/ng/network/private/networkrequestdispatcher_p.h>
11#include <zypp-curl/ng/network/private/networkrequesterror_p.h>
12#include <zypp-curl/ng/network/private/request_p.h>
13#include <zypp-curl/ng/network/private/mediadebug_p.h>
14#include <zypp-core/zyppng/base/Timer>
15#include <zypp-core/zyppng/base/SocketNotifier>
16#include <zypp-core/zyppng/base/EventDispatcher>
17#include <zypp-curl/private/curlhelper_p.h>
18#include <assert.h>
19
20#include <zypp/base/Logger.h>
21#include <zypp/base/String.h>
22#include <zypp-core/base/DtorReset>
23
24using namespace boost;
25
26 L_ENV_CONSTR_DEFINE_FUNC(ZYPP_MEDIA_CURL_DEBUG)
27
28
29namespace zyppng {
30
31 static const std::string & defaultAgentString()
32{
33 // we need to add the release and identifier to the
34 // agent string.
35 // The target could be not initialized, and then this information
36 // is guessed.
37 static const std::string _value(
38 zypp::str::form(
39 "ZYpp " LIBZYPP_VERSION_STRING " (curl %s)"
40 , curl_version_info(CURLVERSION_NOW)->version
41 )
42 );
43 return _value;
44}
45
46
47NetworkRequestDispatcherPrivate::NetworkRequestDispatcherPrivate( NetworkRequestDispatcher &p )
48 : BasePrivate( p )
49 , _timer( Timer::create() )
50 , _multi ( curl_multi_init() )
51 , _userAgent( defaultAgentString() )
52{
53 ::internal::globalInitCurlOnce();
54
55 curl_multi_setopt( _multi, CURLMOPT_TIMERFUNCTION, NetworkRequestDispatcherPrivate::multi_timer_cb );
56 curl_multi_setopt( _multi, CURLMOPT_TIMERDATA, reinterpret_cast<void *>( this ) );
57 curl_multi_setopt( _multi, CURLMOPT_SOCKETFUNCTION, NetworkRequestDispatcherPrivate::static_socket_callback );
58 curl_multi_setopt( _multi, CURLMOPT_SOCKETDATA, reinterpret_cast<void *>( this ) );
59
60 // disabled explicit pipelining since it breaks our tests on releases < 15.2
61 // we could consider enabling it starting with a specific CURL version
62 // curl_multi_setopt( _multi, CURLMOPT_PIPELINING, CURLPIPE_MULTIPLEX|CURLPIPE_HTTP1 );
63
64 _timer->setSingleShot( true );
65 _timer->connect( &Timer::sigExpired, *this, &NetworkRequestDispatcherPrivate::multiTimerTimout );
66}
67
68NetworkRequestDispatcherPrivate::~NetworkRequestDispatcherPrivate()
69{
70 cancelAll( NetworkRequestErrorPrivate::customError( NetworkRequestError::Cancelled, "Dispatcher shutdown" ) );
71 curl_multi_cleanup( _multi );
72}
73
74//called by curl to setup a timer
75 int NetworkRequestDispatcherPrivate::multi_timer_cb( CURLM *, long timeout_ms, void *thatPtr )
76{
77 NetworkRequestDispatcherPrivate *that = reinterpret_cast<NetworkRequestDispatcherPrivate *>( thatPtr );
78 assert( that != nullptr );
79
80 if ( timeout_ms >= 0 ) {
81 that->_timer->start( static_cast<uint64_t>(timeout_ms) );
82 } else {
83 //cancel the timer
84 that->_timer->stop();
85 }
86 return 0;
87}
88
89 void NetworkRequestDispatcherPrivate::multiTimerTimout(const Timer &)
90{
91 handleMultiSocketAction( CURL_SOCKET_TIMEOUT, 0 );
92}
93
94 int NetworkRequestDispatcherPrivate::static_socket_callback(CURL * easy, curl_socket_t s, int what, void *userp, SocketNotifier *socketp )
95{
96 NetworkRequestDispatcherPrivate *that = reinterpret_cast<NetworkRequestDispatcherPrivate *>( userp );
97 assert( that != nullptr );
98 return that->socketCallback( easy, s, what, socketp );
99}
100
101 int NetworkRequestDispatcherPrivate::socketCallback(CURL *easy, curl_socket_t s, int what, void * )
102{
103 std::shared_ptr<SocketNotifier> socketp;
104
105 if ( _socketHandler.count( s ) == 0 ) {
106 if ( what == CURL_POLL_REMOVE || what == CURL_POLL_NONE )
107 return 0;
108
109 socketp = SocketNotifier::create( s, SocketNotifier::Read, false );
110 _socketHandler.insert( std::make_pair( s, socketp ) );
111
112 socketp->connect( &SocketNotifier::sigActivated, *this, &NetworkRequestDispatcherPrivate::onSocketActivated );
113 } else {
114 socketp = _socketHandler[s];
115 }
116
117 //should never happen
118 if ( !socketp ) {
119 if ( what == CURL_POLL_REMOVE || what == CURL_POLL_NONE )
120 return 0;
121
122 if ( _socketHandler.count( s ) > 0 )
123 _socketHandler.erase( s );
124
125 void *privatePtr = nullptr;
126 if ( curl_easy_getinfo( easy, CURLINFO_PRIVATE, &privatePtr ) != CURLE_OK ) {
127 privatePtr = nullptr; //make sure this was not filled with bad info
128 }
129
130 if ( privatePtr ) {
131 NetworkRequestPrivate *request = reinterpret_cast<NetworkRequestPrivate *>( privatePtr );
132 //we stop the download, if we can not listen for socket changes we can not correctly do anything
133 setFinished( *request->z_func(), NetworkRequestErrorPrivate::customError( NetworkRequestError::InternalError, "Unable to assign socket listener." ) );
134 return 0;
135 } else {
136 //a broken handle without anything assigned, also should never happen but make sure and clean it up
137 WAR << "Cleaning up unassigned easy handle" << std::endl;
138 curl_multi_remove_handle( _multi, easy );
139 curl_easy_cleanup( easy );
140 return 0;
141 }
142 }
143
144 //remove the socket
145 if ( what == CURL_POLL_REMOVE ) {
146 socketp->setEnabled( false );
147 _socketHandler.erase( s );
148 return 0;
149 }
150
151 if ( what == CURL_POLL_IN ) {
152 socketp->setMode( SocketNotifier::Read );
153 } else if ( what == CURL_POLL_OUT ) {
154 socketp->setMode( SocketNotifier::Write );
155 } else if ( what == CURL_POLL_INOUT ) {
156 socketp->setMode( SocketNotifier::Read | SocketNotifier::Write );
157 }
158
159 socketp->setEnabled();
160 return 0;
161}
162
163 void NetworkRequestDispatcherPrivate::onSocketActivated( const SocketNotifier &listener, int events )
164{
165 int evBitmask = 0;
166 if ( (events & SocketNotifier::Read) == SocketNotifier::Read )
167 evBitmask |= CURL_CSELECT_IN;
168 if ( (events & SocketNotifier::Write) == SocketNotifier::Write )
169 evBitmask |= CURL_CSELECT_OUT;
170 if ( (events & SocketNotifier::Error) == SocketNotifier::Error )
171 evBitmask |= CURL_CSELECT_ERR;
172
173 handleMultiSocketAction( listener.socket(), evBitmask );
174}
175
176 void NetworkRequestDispatcherPrivate::handleMultiSocketAction(curl_socket_t nativeSocket, int evBitmask)
177{
178 int running = 0;
179
180 // when inside a curl callback we can not call another multi curl API,
181 // for now just lock the thing, but we should consider rewriting this
182 // to post events instead of doing direct calls simply to decouple from
183 // that limitation
184 CURLMcode rc = CURLM_OK;
185 {
186 zypp::DtorReset lockSet( _locked );
187 _locked = true;
188 rc = curl_multi_socket_action( _multi, nativeSocket, evBitmask, &running );
189 }
190 if (rc != 0) {
191 //we can not recover from a error like that, cancel all and stop
192 NetworkRequestError err = NetworkRequestErrorPrivate::fromCurlMError( rc );
193 cancelAll( err );
194 //emit error
195 _lastError = err;
196 _sigError.emit( *z_func() );
197 return;
198 }
199
200 // make sure we dequeue pending requests ( in case a call to dequeue was blocked during the API call )
201 zypp::OnScopeExit scopeFinally([this](){
202 this->dequeuePending();
203 });
204
205 int msgs_left = 0;
206 CURLMsg *msg = nullptr;
207 while( (msg = curl_multi_info_read( _multi, &msgs_left )) ) {
208 if(msg->msg == CURLMSG_DONE) {
209 CURL *easy = msg->easy_handle;
210 CURLcode res = msg->data.result;
211
212 void *privatePtr = nullptr;
213 if ( curl_easy_getinfo( easy, CURLINFO_PRIVATE, &privatePtr ) != CURLE_OK ) {
214 WAR << "Unable to get CURLINFO_PRIVATE" << std::endl;
215 continue;
216 }
217
218 if ( !privatePtr ) {
219 //broken easy handle not associated, should never happen but clean it up
220 WAR << "Cleaning up unassigned easy handle" << std::endl;
221 curl_multi_remove_handle( _multi, easy );
222 curl_easy_cleanup( easy );
223 continue;
224 }
225
226 NetworkRequestPrivate *request = reinterpret_cast<NetworkRequestPrivate *>( privatePtr );
227 request->dequeueNotify();
228
229 if ( request->hasMoreWork() && ( res == CURLE_OK || request->canRecover() ) ) {
230 std::string errBuf = "Broken easy handle in request";
231 if ( !request->_easyHandle ) {
232 NetworkRequestError e = NetworkRequestErrorPrivate::customError ( NetworkRequestError::InternalError, std::move(errBuf) );
233 setFinished( *request->z_func(), e );
234 continue;
235 }
236
237 // remove the handle from multi to change options
238 curl_multi_remove_handle( _multi, request->_easyHandle );
239
240 errBuf = "Failed to reinitialize the request";
241 if ( !request->prepareToContinue ( errBuf ) ) {
242 NetworkRequestError e = NetworkRequestErrorPrivate::customError ( NetworkRequestError::InternalError, std::move(errBuf) );
243 setFinished( *request->z_func(), e );
244 } else {
245 // add the request back to the multi handle, it is not done
246 if ( !addRequestToMultiHandle( *request->z_func() ) )
247 continue;
248
249 request->aboutToStart( );
250 }
251 } else {
252 // trigger notification about file downloaded
253 // we create a error from the CURL code, there might be a already cached Result which will be used instead
254 // in cases like a RangeFail where we could not recover but there also is no real error code
255 NetworkRequestError e = NetworkRequestErrorPrivate::fromCurlError( *request->z_func(), res, request->errorMessage() );
256 setFinished( *request->z_func(), e );
257 }
258 //attention request could be deleted from here on
259 }
260 }
261}
262
263 void NetworkRequestDispatcherPrivate::cancelAll( const NetworkRequestError& result )
264{
265 //prevent dequeuePending from filling up the runningDownloads again
266 zypp::DtorReset lockReset( _locked );
267 _locked = true;
268
269 while ( _runningDownloads.size() ) {
270 std::shared_ptr<NetworkRequest> &req = _runningDownloads.back();
271 setFinished(*req, result );
272 }
273 while ( _pendingDownloads.size() ) {
274 std::shared_ptr<NetworkRequest> &req = _pendingDownloads.back();
275 setFinished(*req, result );
276 }
277}
278
279 void NetworkRequestDispatcherPrivate::setFinished( NetworkRequest &req, NetworkRequestError result )
280{
281 auto delReq = []( auto &list, NetworkRequest &req ) -> std::shared_ptr<NetworkRequest> {
282 auto it = std::find_if( list.begin(), list.end(), [ &req ]( const std::shared_ptr<NetworkRequest> &r ) {
283 return req.d_func() == r->d_func();
284 } );
285 if ( it != list.end() ) {
286 auto ptr = *it;
287 list.erase( it );
288 return ptr;
289 }
290 return nullptr;
291 };
292
293 // We have a tricky situation if a network request is called when inside a callback. In those cases, it is
294 // not allowed to call curl_multi_remove_handle. We need to tell the callback to fail, so the download
295 // is cancelled by curl itself. We also need to store the current result for later
296 auto rmode = std::get_if<NetworkRequestPrivate::running_t>( &req.d_func()->_runningMode );
297 if ( rmode ) {
298 if ( rmode->_isInCallback ) {
299 // the first cached result wins)
300 if ( !rmode->_cachedResult )
301 rmode->_cachedResult = result;
302 return;
303 } else if ( rmode->_cachedResult ) {
304 result = rmode->_cachedResult.value();
305 }
306 }
307
308 auto rLocked = delReq( _runningDownloads, req );
309 if ( !rLocked )
310 rLocked = delReq( _pendingDownloads, req );
311
312 void *easyHandle = req.d_func()->_easyHandle;
313 if ( easyHandle )
314 curl_multi_remove_handle( _multi, easyHandle );
315
316 req.d_func()->_dispatcher = nullptr;
317
318 //first set the result, the Request might have a checksum to check as well so a currently
319 //successful request could fail later on
320 req.d_func()->setResult( std::move(result) );
321 _sigDownloadFinished.emit( *z_func(), req );
322
323 //we got a open slot, try to dequeue or send the finished signals if all queues are empty
324 dequeuePending();
325}
326
327 bool NetworkRequestDispatcherPrivate::addRequestToMultiHandle(NetworkRequest &req)
328{
329 CURLMcode rc = curl_multi_add_handle( _multi, req.d_func()->_easyHandle );
330 if ( rc != 0 ) {
331 setFinished( req, NetworkRequestErrorPrivate::fromCurlMError( rc ) );
332 return false;
333 }
334
335 // make sure to wake up once to register what we have now
336 _timer->start(0);
337 return true;
338}
339
340 void NetworkRequestDispatcherPrivate::dequeuePending()
341{
342 if ( !_isRunning || _locked )
343 return;
344
345 while ( _maxConnections == -1 || ( (std::size_t)_maxConnections > _runningDownloads.size() ) ) {
346 if ( !_pendingDownloads.size() )
347 break;
348
349 std::shared_ptr<NetworkRequest> req = std::move( _pendingDownloads.front() );
350 _pendingDownloads.pop_front();
351
352 std::string errBuf = "Failed to initialize easy handle";
353 if ( !req->d_func()->initialize( errBuf ) ) {
354 //@TODO store the CURL error in the errors extra info
355 setFinished( *req, NetworkRequestErrorPrivate::customError( NetworkRequestError::InternalError, std::move(errBuf) ) );
356 continue;
357 }
358
359 if ( !addRequestToMultiHandle( *req ) )
360 continue;
361
362 req->d_func()->aboutToStart();
363 _sigDownloadStarted.emit( *z_func(), *req );
364
365 _runningDownloads.push_back( std::move(req) );
366 }
367
368 //check for empty queues
369 if ( _pendingDownloads.size() == 0 && _runningDownloads.size() == 0 ) {
370 //once we finished all requests, cancel the timer too, so curl is not called without requests
371 _timer->stop();
372 _sigQueueFinished.emit( *z_func() );
373 }
374}
375
376 ZYPP_IMPL_PRIVATE(NetworkRequestDispatcher)
377
378NetworkRequestDispatcher::NetworkRequestDispatcher( )
379 : Base( * new NetworkRequestDispatcherPrivate ( *this ) )
380{
381
382}
383
384bool NetworkRequestDispatcher::supportsProtocol( const Url &url )
385{
386 curl_version_info_data *curl_info = nullptr;
387 curl_info = curl_version_info(CURLVERSION_NOW);
388 // curl_info does not need any free (is static)
389 if (curl_info->protocols)
390 {
391 const char * const *proto = nullptr;
392 std::string scheme( url.getScheme() );
393 bool found = false;
394 for(proto=curl_info->protocols; !found && *proto; ++proto) {
395 if( scheme == std::string((const char *)*proto))
396 found = true;
397 }
398 return found;
399 }
400 return true;
401}
402
403void NetworkRequestDispatcher::setMaximumConcurrentConnections( const int maxConn )
404{
405 d_func()->_maxConnections = maxConn;
406}
407
408int NetworkRequestDispatcher::maximumConcurrentConnections () const
409{
410 return d_func()->_maxConnections;
411}
412
413void NetworkRequestDispatcher::enqueue(const std::shared_ptr<NetworkRequest> &req )
414{
415 if ( !req )
416 return;
417 Z_D();
418
419 if ( std::find( d->_runningDownloads.begin(), d->_runningDownloads.end(), req ) != d->_runningDownloads.end() ) {
420 WAR << "Ignoring request to enqueue download " << req->url().asString() << " request is already running " << std::endl;
421 return;
422 }
423
424 if ( std::find( d->_pendingDownloads.begin(), d->_pendingDownloads.end(), req ) != d->_pendingDownloads.end() ) {
425 WAR << "Ignoring request to enqueue download " << req->url().asString() << " request is already enqueued " << std::endl;
426 return;
427 }
428
429 req->d_func()->_dispatcher = this;
430 if ( req->priority() == NetworkRequest::Normal )
431 d->_pendingDownloads.push_back( req );
432 else {
433 auto it = std::find_if( d->_pendingDownloads.begin(), d->_pendingDownloads.end(), [ prio = req->priority() ]( const auto &pendingReq ){
434 return pendingReq->priority() < prio;
435 });
436
437 //if we have a valid iterator, decrement we found a pending download request with lower prio, insert before that
438 if ( it != d->_pendingDownloads.end() && it != d->_pendingDownloads.begin() )
439 it--;
440 d->_pendingDownloads.insert( it, req );
441 }
442
443 //dequeue if running and we have capacity
444 d->dequeuePending();
445}
446
447void NetworkRequestDispatcher::setAgentString( const std::string &agent )
448{
449 Z_D();
450 if ( agent.empty() )
451 d->_userAgent = defaultAgentString();
452 else
453 d->_userAgent = agent;
454}
455
456const std::string &NetworkRequestDispatcher::agentString() const
457{
458 return d_func()->_userAgent;
459}
460
461void NetworkRequestDispatcher::setHostSpecificHeader( const std::string &host, const std::string &headerName, const std::string &value )
462{
463 Z_D();
464 if ( value.empty() ) {
465 if ( auto i = d->_customHeaders.find( host ); i != d->_customHeaders.end() ) {
466 if ( auto v = i->second.find( headerName ); v != i->second.end() ) {
467 i->second.erase (v);
468 }
469 if ( i->second.empty() )
470 d->_customHeaders.erase(i);
471 }
472 return;
473 }
474 d->_customHeaders[host][headerName] = value;
475}
476
477const NetworkRequestDispatcher::SpecificHeaderMap &NetworkRequestDispatcher::hostSpecificHeaders() const
478{
479 return d_func()->_customHeaders;
480}
481
482void NetworkRequestDispatcher::cancel( NetworkRequest &req, std::string reason )
483{
484 cancel( req, NetworkRequestErrorPrivate::customError( NetworkRequestError::Cancelled, reason.size() ? std::move(reason) : "Request explicitly cancelled" ) );
485}
486
487void NetworkRequestDispatcher::cancel(NetworkRequest &req, const NetworkRequestError &err)
488{
489 Z_D();
490
491 if ( req.d_func()->_dispatcher != this ) {
492 //TODO throw exception
493 return;
494 }
495
496 d->setFinished( req, err );
497}
498
499void NetworkRequestDispatcher::cancelAll(std::string reason)
500{
501 cancelAll( NetworkRequestErrorPrivate::customError( NetworkRequestError::Cancelled, reason.size() ? std::move(reason) : "Request explicitly cancelled" ) );
502}
503
504void NetworkRequestDispatcher::cancelAll(const NetworkRequestError &err)
505{
506 d_func()->cancelAll ( err );
507}
508
509void NetworkRequestDispatcher::run()
510{
511 Z_D();
512 d->_isRunning = true;
513
514 if ( d->_pendingDownloads.size() )
515 d->dequeuePending();
516}
517
518void NetworkRequestDispatcher::reschedule()
519{
520 Z_D();
521 if ( !d->_pendingDownloads.size() )
522 return;
523
524 std::stable_sort( d->_pendingDownloads.begin(), d->_pendingDownloads.end(), []( const auto &a, const auto &b ){
525 return a->priority() < b->priority();
526 });
527
528 d->dequeuePending();
529}
530
531size_t NetworkRequestDispatcher::count()
532{
533 Z_D();
534 return d->_pendingDownloads.size() + d->_runningDownloads.size();
535}
536
537const zyppng::NetworkRequestError &NetworkRequestDispatcher::lastError() const
538{
539 return d_func()->_lastError;
540}
541
542 SignalProxy<void (NetworkRequestDispatcher &, NetworkRequest &)> NetworkRequestDispatcher::sigDownloadStarted()
543{
544 return d_func()->_sigDownloadStarted;
545}
546
547 SignalProxy<void (NetworkRequestDispatcher &, NetworkRequest &)> NetworkRequestDispatcher::sigDownloadFinished()
548{
549 return d_func()->_sigDownloadFinished;
550}
551
552 SignalProxy<void ( NetworkRequestDispatcher &)> NetworkRequestDispatcher::sigQueueFinished()
553{
554 return d_func()->_sigQueueFinished;
555}
556
557 SignalProxy<void ( NetworkRequestDispatcher &)> NetworkRequestDispatcher::sigError()
558{
559 return d_func()->_sigError;
560}
561
562}
zypp::DtorReset
Assign a vaiable a certain value when going out of scope.
Definition dtorreset.h:50
zyppng::AbstractEventSource::Error
@ Error
Definition abstracteventsource.h:50
zyppng::AbstractEventSource::Read
@ Read
Definition abstracteventsource.h:47
zyppng::AbstractEventSource::Write
@ Write
Definition abstracteventsource.h:48
zyppng::BasePrivate::BasePrivate
BasePrivate(Base &b)
Definition base_p.h:17
zyppng::Base
Definition base.h:60
zyppng::NetworkRequestDispatcherPrivate
Definition networkrequestdispatcher_p.h:30
zyppng::NetworkRequestDispatcherPrivate::NetworkRequestDispatcherPrivate
NetworkRequestDispatcherPrivate(NetworkRequestDispatcher &p)
Definition networkrequestdispatcher.cc:47
zyppng::NetworkRequestDispatcherPrivate::static_socket_callback
static int static_socket_callback(CURL *easy, curl_socket_t s, int what, void *userp, SocketNotifier *socketp)
Definition networkrequestdispatcher.cc:94
zyppng::NetworkRequestDispatcherPrivate::socketCallback
int socketCallback(CURL *easy, curl_socket_t s, int what, void *)
Definition networkrequestdispatcher.cc:101
zyppng::NetworkRequestDispatcherPrivate::_sigError
Signal< void(NetworkRequestDispatcher &)> _sigError
Definition networkrequestdispatcher_p.h:57
zyppng::NetworkRequestDispatcherPrivate::_sigQueueFinished
Signal< void(NetworkRequestDispatcher &)> _sigQueueFinished
Definition networkrequestdispatcher_p.h:56
zyppng::NetworkRequestDispatcherPrivate::dequeuePending
void dequeuePending()
Definition networkrequestdispatcher.cc:340
zyppng::NetworkRequestDispatcherPrivate::setFinished
void setFinished(NetworkRequest &req, NetworkRequestError result)
Definition networkrequestdispatcher.cc:279
zyppng::NetworkRequestDispatcherPrivate::_isRunning
bool _isRunning
Definition networkrequestdispatcher_p.h:44
zyppng::NetworkRequestDispatcherPrivate::multiTimerTimout
void multiTimerTimout(const Timer &t)
Definition networkrequestdispatcher.cc:89
zyppng::NetworkRequestDispatcherPrivate::_lastError
NetworkRequestError _lastError
Definition networkrequestdispatcher_p.h:48
zyppng::NetworkRequestDispatcherPrivate::handleMultiSocketAction
void handleMultiSocketAction(curl_socket_t nativeSocket, int evBitmask)
Definition networkrequestdispatcher.cc:176
zyppng::NetworkRequestDispatcherPrivate::_multi
CURLM * _multi
Definition networkrequestdispatcher_p.h:46
zyppng::NetworkRequestDispatcherPrivate::~NetworkRequestDispatcherPrivate
~NetworkRequestDispatcherPrivate() override
Definition networkrequestdispatcher.cc:68
zyppng::NetworkRequestDispatcherPrivate::_sigDownloadFinished
Signal< void(NetworkRequestDispatcher &, NetworkRequest &)> _sigDownloadFinished
Definition networkrequestdispatcher_p.h:55
zyppng::NetworkRequestDispatcherPrivate::_timer
std::shared_ptr< Timer > _timer
Definition networkrequestdispatcher_p.h:41
zyppng::NetworkRequestDispatcherPrivate::_maxConnections
int _maxConnections
Definition networkrequestdispatcher_p.h:36
zyppng::NetworkRequestDispatcherPrivate::_socketHandler
std::map< curl_socket_t, std::shared_ptr< SocketNotifier > > _socketHandler
Definition networkrequestdispatcher_p.h:42
zyppng::NetworkRequestDispatcherPrivate::addRequestToMultiHandle
bool addRequestToMultiHandle(NetworkRequest &req)
Definition networkrequestdispatcher.cc:327
zyppng::NetworkRequestDispatcherPrivate::_userAgent
std::string _userAgent
Definition networkrequestdispatcher_p.h:50
zyppng::NetworkRequestDispatcherPrivate::onSocketActivated
void onSocketActivated(const SocketNotifier &listener, int events)
Definition networkrequestdispatcher.cc:163
zyppng::NetworkRequestDispatcherPrivate::_sigDownloadStarted
Signal< void(NetworkRequestDispatcher &, NetworkRequest &)> _sigDownloadStarted
Definition networkrequestdispatcher_p.h:54
zyppng::NetworkRequestDispatcherPrivate::_pendingDownloads
std::deque< std::shared_ptr< NetworkRequest > > _pendingDownloads
Definition networkrequestdispatcher_p.h:38
zyppng::NetworkRequestDispatcherPrivate::multi_timer_cb
static int multi_timer_cb(CURLM *multi, long timeout_ms, void *g)
Definition networkrequestdispatcher.cc:75
zyppng::NetworkRequestDispatcherPrivate::_locked
bool _locked
Definition networkrequestdispatcher_p.h:45
zyppng::NetworkRequestDispatcherPrivate::cancelAll
void cancelAll(const NetworkRequestError &result)
Definition networkrequestdispatcher.cc:263
zyppng::NetworkRequestDispatcherPrivate::_runningDownloads
std::vector< std::shared_ptr< NetworkRequest > > _runningDownloads
Definition networkrequestdispatcher_p.h:39
zyppng::NetworkRequestErrorPrivate::fromCurlMError
static zyppng::NetworkRequestError fromCurlMError(int nativeCode)
Definition networkrequesterror.cc:206
zyppng::NetworkRequestErrorPrivate::fromCurlError
static zyppng::NetworkRequestError fromCurlError(NetworkRequest &req, int nativeCode, const std::string &nativeError)
Definition networkrequesterror.cc:39
zyppng::NetworkRequestErrorPrivate::customError
static zyppng::NetworkRequestError customError(NetworkRequestError::Type t, std::string &&errorMsg="", std::map< std::string, boost::any > &&extraInfo={})
Definition networkrequesterror.cc:34
zyppng::NetworkRequestError
The NetworkRequestError class Represents a error that occured in.
Definition networkrequesterror.h:24
zyppng::NetworkRequestError::InternalError
@ InternalError
Definition networkrequesterror.h:28
zyppng::NetworkRequestError::Cancelled
@ Cancelled
Definition networkrequesterror.h:29
zyppng::NetworkRequestPrivate
Definition request_p.h:35
zyppng::NetworkRequestPrivate::_easyHandle
void * _easyHandle
Definition request_p.h:125
zyppng::NetworkRequestPrivate::errorMessage
std::string errorMessage() const
Definition request.cc:565
zyppng::NetworkRequestPrivate::dequeueNotify
void dequeueNotify()
Definition request.cc:478
zyppng::NetworkRequestPrivate::prepareToContinue
bool prepareToContinue(std::string &errBuf)
Definition request.cc:411
zyppng::NetworkRequestPrivate::canRecover
bool canRecover() const
Definition request.cc:403
zyppng::NetworkRequestPrivate::hasMoreWork
bool hasMoreWork() const
Definition request.cc:450
zyppng::NetworkRequestPrivate::aboutToStart
void aboutToStart()
Definition request.cc:456
zyppng::NetworkRequest
Definition request.h:43
zyppng::NetworkRequest::Normal
@ Normal
Definition request.h:59
zyppng::SignalProxy
Definition signals.h:325
zyppng::SocketNotifier
Definition socketnotifier.h:69
zyppng::SocketNotifier::create
static Ptr create(int socket, int evTypes, bool enable=true)
Definition socketnotifier.cc:33
zyppng::SocketNotifier::socket
int socket() const
Definition socketnotifier.cc:71
zyppng::SocketNotifier::sigActivated
SignalProxy< void(const SocketNotifier &sock, int evTypes)> sigActivated()
Definition socketnotifier.cc:76
zyppng::Timer
The Timer class provides repetitive and single-shot timers.
Definition timer.h:45
zyppng::Timer::sigExpired
SignalProxy< void(Timer &t)> sigExpired()
This signal is always emitted when the timer expires.
Definition timer.cc:120
curlhelper_p.h
a
unsigned short a
Definition mediablocklist.cc:0
b
unsigned short b
Definition mediablocklist.cc:1
mediadebug_p.h
boost
Definition String.h:29
internal::globalInitCurlOnce
void globalInitCurlOnce()
Definition curlhelper.cc:64
zypp::str::form
std::string form(const char *format,...) __attribute__((format(printf
Printf style construction of std::string.
Definition String.cc:37
zypp::OnScopeExit
AutoDispose< void > OnScopeExit
Definition AutoDispose.h:276
zyppng
Definition MediaCurl2.h:22
zyppng::Url
zypp::Url Url
Definition url.h:15
zyppng::defaultAgentString
static const std::string & defaultAgentString()
Definition networkrequestdispatcher.cc:31
networkrequestdispatcher_p.h
networkrequesterror_p.h
request_p.h
Globals.h
Provides API related macros.
WAR
#define WAR
Definition Logger.h:101
L_ENV_CONSTR_DEFINE_FUNC
#define L_ENV_CONSTR_DEFINE_FUNC(ENV)
Definition Logger.h:117
Logger.h
String.h
ZYPP_IMPL_PRIVATE
#define ZYPP_IMPL_PRIVATE(Class)
Definition zyppglobal.h:92
Z_D
#define Z_D()
Definition zyppglobal.h:105