18 std::vector<char>
peek_data_fd( FILE *fd, off_t offset,
size_t count )
25 std::vector<char> data( count + 1 ,
'\0' );
28 while ((l = pread( fileno( fd ), data.data(), count, offset ) ) == -1 && errno == EINTR)
38 , _targetFile (
std::move( targetFile) )
39 , _start (
std::move(start) )
40 , _len (
std::move(len) )
41 , _fMode (
std::move(fMode) )
42 , _activityTimer (
Timer::create() )
43 , _headers(
std::unique_ptr< curl_slist, decltype (&curl_slist_free_all) >(
nullptr, &curl_slist_free_all ) )
97 std::string rangeDesc;
104 if (
setCurlOption( CURLOPT_RANGE, rangeDesc.c_str() ), CURLE_OK ) {
105 strncpy(
_errorBuf.data(),
"curl_easy_setopt range failed", CURL_ERROR_SIZE);
132 char *ptr = getenv(
"ZYPP_MEDIA_CURL_DEBUG");
133 _curlDebug = (ptr && *ptr) ? zypp::str::strtonum<long>( ptr) : 0L;
145 case 4:
setCurlOption( CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4 );
break;
146 case 6:
setCurlOption( CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V6 );
break;
167 #if CURLVERSION_AT_LEAST(7,19,4) 172 #if CURLVERSION_AT_LEAST(7,60,0) // SLE15+ 173 setCurlOption( CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2TLS );
191 #ifdef CURLSSLOPT_ALLOW_BEAST 193 setCurlOption( CURLOPT_SSL_OPTIONS, CURLSSLOPT_ALLOW_BEAST );
220 if (use_auth.empty())
221 use_auth =
"digest,basic";
223 if( auth != CURLAUTH_NONE)
225 DBG <<
"Enabling HTTP authentication methods: " << use_auth
226 <<
" (CURLOPT_HTTPAUTH=" << auth <<
")" << std::endl;
233 DBG <<
"Proxy: '" << locSet.
proxy() <<
"'" << std::endl;
235 setCurlOption(CURLOPT_PROXYAUTH, CURLAUTH_BASIC|CURLAUTH_DIGEST|CURLAUTH_NTLM );
246 if ( proxyuserpwd.empty() )
251 DBG <<
"Proxy: ~/.curlrc does not contain the proxy-user option" << std::endl;
255 DBG <<
"Proxy: using proxy-user from ~/.curlrc" << std::endl;
263 if ( ! proxyuserpwd.empty() )
268 #if CURLVERSION_AT_LEAST(7,19,4) 273 DBG <<
"Proxy: explicitly NOPROXY" << std::endl;
280 DBG <<
"Proxy: not explicitly set" << std::endl;
281 DBG <<
"Proxy: libcurl may look into the environment" << std::endl;
292 #if CURLVERSION_AT_LEAST(7,15,5) 300 MIL <<
"No cookies requested" << std::endl;
303 #if CURLVERSION_AT_LEAST(7,18,0) 309 for ( TransferSettings::Headers::const_iterator it = locSet.
headersBegin();
312 if ( !z_func()->addRequestHeader( it->c_str() ) )
355 auto hexToStr = [](
const std::vector<u_char> &hex ) {
391 std::map<std::string, boost::any> extraInfo;
392 extraInfo.insert( {
"requestUrl",
_url } );
414 if ( that->
_len > 0 && that->
_len < dlnow ) {
419 that->
_sigProgress.emit( *that->z_func(), dltotal, dlnow, ultotal, ulnow );
429 if ( size * nmemb == 0)
436 return ( size * nmemb );
442 (void)curl_easy_getinfo( that->
_easyHandle, CURLINFO_EFFECTIVE_URL, &effurl);
443 if (effurl && !strncasecmp(effurl,
"http", 4))
446 (void)curl_easy_getinfo( that->
_easyHandle, CURLINFO_RESPONSE_CODE, &statuscode);
447 if (statuscode != 206) {
448 strncpy( that->
_errorBuf.data(),
"Expected range status code 206, but got none.", CURL_ERROR_SIZE);
455 std::string openMode =
"w+b";
467 strncpy( that->
_errorBuf.data(),
"Unable to open target file.", CURL_ERROR_SIZE);
473 strncpy( that->
_errorBuf.data(),
"Unable to set output file pointer.", CURL_ERROR_SIZE);
478 size_t written = fwrite( ptr, size, nmemb, that->
_outFile );
480 that->
_digest->update( ptr, written );
495 if ( d->_dispatcher )
496 d->_dispatcher->cancel( *
this,
"Request destroyed while still running" );
499 fclose( d->_outFile );
504 d_func()->_priority = prio;
509 return d_func()->_priority;
514 d_func()->_options = opt;
519 return d_func()->_options;
533 return d_func()->_lastRedirect;
538 return d_func()->_easyHandle;
549 return d_func()->_url;
563 return d_func()->_targetFile;
569 if ( curl_easy_getinfo( d_func()->_easyHandle, CURLINFO_CONTENT_TYPE, &ptr ) == CURLE_OK && ptr )
570 return std::string(ptr);
571 return std::string();
576 return d_func()->_start;
581 return d_func()->_reportedSize;
586 return d_func()->_len;
592 if ( d->_downloaded == -1 )
594 return d->_downloaded;
599 d_func()->_digest = dig;
604 d_func()->_expectedChecksum = std::move(
checksum);
609 return d_func()->_settings;
614 return d_func()->_digest;
619 return d_func()->_state;
624 return d_func()->_result;
631 return std::string();
633 return d->_result.nativeErrorString();
645 curl_slist *res = curl_slist_append( d->_headers ? d->_headers.get() :
nullptr, header.c_str() );
650 d->_headers = std::unique_ptr< curl_slist, decltype (&curl_slist_free_all) >( res, &curl_slist_free_all );
657 return d_func()->_sigStarted;
662 return d_func()->_sigProgress;
667 return d_func()->_sigFinished;
std::string getScheme() const
Returns the scheme name of the URL.
bool isError() const
isError Will return true if this is a actual error
void setCurlOption(CURLoption opt, T data)
void * nativeHandle() const
const NetworkRequestError & error() const
Returns the last set Error.
std::array< char, CURL_ERROR_SIZE+1 > _errorBuf
size_t log_redirects_curl(char *ptr, size_t size, size_t nmemb, void *userdata)
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
static ZConfig & instance()
Singleton ctor.
const char * anonymousIdHeader()
initialized only once, this gets the anonymous id from the target, which we pass in the http header ...
NetworkRequest::FileMode _fMode
const std::string & lastRedirectInfo() const
signal< void(NetworkRequest &req, off_t dltotal, off_t dlnow, off_t ultotal, off_t ulnow)> _sigProgress
static size_t writeCallback(char *ptr, size_t size, size_t nmemb, void *userdata)
NetworkRequest::Options _options
std::shared_ptr< zypp::Digest > digest() const
Returns the currently used.
const char * c_str() const
String representation.
NetworkRequest::State _state
NetworkRequestPrivate(Url &&url, zypp::Pathname &&targetFile, off_t &&start, off_t &&len, NetworkRequest::FileMode fMode)
signal< void(NetworkRequest &req)> _sigStarted
off_t expectedByteCount() const
Returns the expected byte count that was passed to the constructor, zero if none was given...
void setOptions(Options opt)
std::string form(const char *format,...) __attribute__((format(printf
Printf style construction of std::string.
TransferSettings & transferSettings()
const char * distributionFlavorHeader()
initialized only once, this gets the distribution flavor from the target, which we pass in the http h...
bool hasError() const
Checks if there was a error with the request.
void onActivityTimeout(Timer &)
zypp::Pathname _targetFile
virtual ~NetworkRequestPrivate()
std::vector< unsigned char > _expectedChecksum
bool empty() const
Test for an empty path.
void setUrl(const Url &url)
This will change the URL of the request.
std::string asString() const
Returns a default string representation of the Url object.
void setDigest(std::shared_ptr< zypp::Digest > dig)
Set a.
std::string getQueryParam(const std::string ¶m, EEncoding eflag=zypp::url::E_DECODED) const
Return the value for the specified query parameter.
bool addRequestHeader(const std::string &header)
const std::string & asString() const
String representation.
std::string asString() const
Error message provided by dumpOn as string.
bool initialize(std::string &errBuf)
The NetworkRequestError class Represents a error that occured in.
The Timer class provides repetitive and single-shot timers.
std::vector< char > peekData(off_t offset, size_t count) const
std::string extendedErrorString() const
In some cases curl can provide extended error informations collected at runtime.
Priority priority() const
std::shared_ptr< zypp::Digest > _digest
const zypp::Pathname & targetFilePath() const
Returns the target filename path.
std::unique_ptr< curl_slist, decltype(&curl_slist_free_all) > _headers
std::vector< char > peek_data_fd(FILE *fd, off_t offset, size_t count)
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
static int curlProgressCallback(void *clientp, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow)
std::string contentType() const
Returns the content type as reported from the server.
NetworkRequestError _result
Base class for Exception.
std::string _lastRedirect
to log/report redirections
std::string checksum(const Pathname &file, const std::string &algorithm)
Compute a files checksum.
std::string curlUnEscape(std::string text_r)
std::string getHost(EEncoding eflag=zypp::url::E_DECODED) const
Returns the hostname or IP from the URL authority.
signal< void(NetworkRequest &req, const NetworkRequestError &err)> _sigFinished
State state() const
Returns the current state the HttpDownloadRequest is in.
TransferSettings _settings
NetworkRequestDispatcher * _dispatcher
bool strToBool(const C_Str &str, bool default_r)
Parse str into a bool depending on the default value.
virtual ~NetworkRequest()
off_t downloadOffset() const
Returns the requested start offset.
const char * agentString()
initialized only once, this gets the agent string which also includes the curl version ...
SignalProxy< void(NetworkRequest &req, const NetworkRequestError &err)> sigFinished()
Signals that the download finished.
std::string _currentCookieFile
void setPriority(Priority prio)
Type type() const
type Returns the type of the error
SignalProxy< void(NetworkRequest &req)> sigStarted()
Signals that the dispatcher dequeued the request and actually starts downloading data.
void setExpectedChecksum(std::vector< unsigned char > checksum)
Enables automated checking of downloaded contents against a checksum.
off_t downloadedByteCount() const
Returns the number of already downloaded bytes as reported by the backend.
int log_curl(CURL *curl, curl_infotype info, char *ptr, size_t len, void *max_lvl)
void setResult(NetworkRequestError &&err)
static zyppng::NetworkRequestError customError(NetworkRequestError::Type t, std::string &&errorMsg="", std::map< std::string, boost::any > &&extraInfo={})
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.
off_t reportedByteCount() const
Returns the number of bytes that are reported from the backend as the full download size...
#define EXPLICITLY_NO_PROXY
int ZYPP_MEDIA_CURL_IPRESOLVE()
Timer::Ptr _activityTimer
void setRequestRange(off_t start=-1, off_t len=0)
NetworkRequest(Url url, zypp::Pathname targetFile, off_t start=-1, off_t len=0, FileMode fMode=WriteExclusive)