22#include <zypp-core/parser/Sysconfig>
28#include <zypp-curl/ProxyInfo>
29#include <zypp-curl/auth/CurlAuthData>
30#include <zypp-media/auth/CredentialManager>
31#include <zypp-curl/CurlConfig>
55 using TimePoint = std::chrono::steady_clock::time_point;
69 Distributor::instance().setReceiver(*
_oldRec);
71 Distributor::instance().noReceiver();
106 static constexpr std::chrono::milliseconds
maxfequency { 100 };
107 TimePoint now { TimePoint::clock::now() };
202 , _url(
std::move( url ))
203 , _timeout( timeout )
204 , _timeoutReached(
false )
205 , _fileSizeExceeded (
false )
272 "X-ZYpp-AnonymousId: %s",
286 "X-ZYpp-DistributionFlavor: %s",
314 const std::string &
err_r,
315 const std::string &
msg_r )
336#define SET_OPTION(opt,val) do { \
337 ret = curl_easy_setopt ( _curl, opt, val ); \
339 ZYPP_THROW(MediaCurlSetOptException(_url, _curlError)); \
343#define SET_OPTION_OFFT(opt,val) SET_OPTION(opt,(curl_off_t)val)
344#define SET_OPTION_LONG(opt,val) SET_OPTION(opt,(long)val)
345#define SET_OPTION_VOID(opt,val) SET_OPTION(opt,(void*)val)
370 WAR <<
"attach point " <<
ainfo.path()
371 <<
" is not useable for " <<
url_r.getScheme() << endl;
401 const char *
const *proto =
nullptr;
406 if( scheme == std::string((
const char *)*proto))
411 std::string msg(
"Unsupported protocol '");
510#ifdef CURLSSLOPT_ALLOW_BEAST
562 DBG <<
"Enabling HTTP authentication methods: " <<
use_auth
563 <<
" (CURLOPT_HTTPAUTH=" <<
auth <<
")" << std::endl;
582 if ( proxyuserpwd.empty() )
586 if (
curlconf.proxyuserpwd.empty() )
587 DBG <<
"Proxy: ~/.curlrc does not contain the proxy-user option" << endl;
590 proxyuserpwd =
curlconf.proxyuserpwd;
591 DBG <<
"Proxy: using proxy-user from ~/.curlrc" << endl;
599 if ( ! proxyuserpwd.empty() )
604#if CURLVERSION_AT_LEAST(7,19,4)
609 DBG <<
"Proxy: explicitly NOPROXY" << endl;
615 DBG <<
"Proxy: not explicitly set" << endl;
616 DBG <<
"Proxy: libcurl may look into the environment" << endl;
627#if CURLVERSION_AT_LEAST(7,15,5)
643 MIL <<
"No cookies requested" << endl;
648#if CURLVERSION_AT_LEAST(7,18,0)
745 const auto &filename =
srcFile.filename();
842 if (filename.
empty())
852 err =
" Unsupported protocol";
855 err +=
" or redirect (";
883 DBG << msg <<
" Login failed (URL: " <<
url.
asString() <<
")" << std::endl;
884 DBG <<
"MediaUnauthorizedException auth hint: '" <<
auth_hint <<
"'" << std::endl;
899 if (
url.
getHost().find(
".suse.com") != std::string::npos )
900 msg403 =
_(
"Visit the SUSE Customer Center to check whether your registration is valid and has not expired.");
901 else if (
url.
asString().find(
"novell.com") != std::string::npos)
902 msg403 =
_(
"Visit the Novell Customer Center to check whether your registration is valid and has not expired.");
915 std::string msg =
"Unable to retrieve HTTP response:";
922#if CURLVERSION_AT_LEAST(7,16,0)
927 err =
"File not found";
932 err =
"Login failed";
938 err =
"Connection failed";
950 err =
"Timeout reached";
1053 ERR <<
"fopen failed for /dev/null" << endl;
1088 if( assert_dir(
dest.dirname() ) )
1090 DBG <<
"assert_dir " <<
dest.dirname() <<
" failed" << endl;
1100 ERR <<
"out of memory for temp file name" << endl;
1107 ERR <<
"mkstemp failed for file '" <<
destNew <<
"'" << endl;
1115 ERR <<
"fopen failed for file '" <<
destNew <<
"'" << endl;
1121 DBG <<
"dest: " <<
dest << endl;
1157 DBG <<
" Not modified.";
1164 WAR <<
"Could not get the response code." << endl;
1172 ERR <<
"Failed to chmod file " <<
destNew << endl;
1178 ERR <<
"Fclose failed for file '" <<
destNew <<
"'" << endl;
1184 ERR <<
"Rename failed" << endl;
1197 DBG <<
srcFile.filename().asString() << endl;
1240 WAR <<
"Can't set CURLOPT_PROGRESSDATA: " <<
_curlError << endl;;
1244#if CURLVERSION_AT_LEAST(7,19,4)
1249 if (
ftell(file) == 0 &&
ret == 0 )
1257 WAR <<
"TIMECONDITION unmet - retry without." << endl;
1267 WAR <<
"Can't unset CURLOPT_PROGRESSDATA: " <<
_curlError << endl;;
1273 <<
", temp file size " <<
ftell(file)
1274 <<
" bytes." << endl;
1300 for ( filesystem::DirContent::const_iterator
it = content.begin();
it != content.end(); ++
it ) {
1304 switch (
it->type ) {
1315 WAR <<
"Ignore error (" <<
res <<
") on creating local directory '" <<
localPath( filename ) <<
"'" << endl;
1353 return pdata->reportProgress();
1369 return pdata->reportProgress();
1465 if ( msg->easy_handle !=
_curl )
continue;
1467 return msg->data.result;
1487 DBG <<
"got stored credentials:" << endl << *
credentials << endl;
1516 DBG <<
"callback answer: retry" << endl
1517 <<
"CurlAuthData: " << *
curlcred << endl;
1535 DBG <<
"callback answer: cancel" << endl;
Reference counted access to a Tp object calling a custom Dispose function when the last AutoDispose h...
reference value() const
Reference to the Tp object.
void resetDispose()
Set no dispose function.
void reset()
Reset to default Ctor values.
Store and operate with byte count.
Base class for Exception.
const char * c_str() const
ProgressData()
Ctor no range [0,0](0).
std::string distributionFlavor() const
This is flavor attribute of the installed base product but does not require the target to be loaded a...
std::string anonymousUniqueId() const
anonymous unique id
std::string targetDistribution() const
This is register.target attribute of the installed base product.
std::string getScheme() const
Returns the scheme name of the URL.
std::string asString() const
Returns a default string representation of the Url object.
std::string getUsername(EEncoding eflag=zypp::url::E_DECODED) const
Returns the username from the URL authority.
std::string getQueryParam(const std::string ¶m, EEncoding eflag=zypp::url::E_DECODED) const
Return the value for the specified query parameter.
std::string getHost(EEncoding eflag=zypp::url::E_DECODED) const
Returns the hostname or IP from the URL authority.
bool isValid() const
Verifies the Url.
static ZConfig & instance()
Singleton ctor.
Typesafe passing of user data via callbacks.
Wrapper class for stat/lstat.
Pathname extend(const std::string &r) const
Append string r to the last component of the path.
const char * c_str() const
String representation.
const std::string & asString() const
String representation.
bool empty() const
Test for an empty path.
Pathname absolutename() const
Return this path, adding a leading '/' if relative.
#define EXPLICITLY_NO_PROXY
zypp::callback::SendReport< zypp::KeyRingReport > _report
void fillSettingsFromUrl(const Url &url, media::TransferSettings &s)
Fills the settings structure using options passed on the url for example ?timeout=x&proxy=foo.
size_t log_redirects_curl(char *ptr, size_t size, size_t nmemb, void *userdata)
const char * anonymousIdHeader()
void globalInitCurlOnce()
const char * distributionFlavorHeader()
std::string curlUnEscape(const std::string &text_r)
void setupZYPP_MEDIA_CURL_DEBUG(CURL *curl)
Setup CURLOPT_VERBOSE and CURLOPT_DEBUGFUNCTION according to env::ZYPP_MEDIA_CURL_DEBUG.
CURLcode setCurlRedirProtocols(CURL *curl)
const char * agentString()
void fillSettingsSystemProxy(const Url &url, media::TransferSettings &s)
Reads the system proxy configuration and fills the settings structure proxy information.
Url clearQueryString(const Url &url)
int ZYPP_MEDIA_CURL_IPRESOLVE()
4/6 to force IPv4/v6
mode_t applyUmaskTo(mode_t mode_r)
Modify mode_r according to the current umask ( mode_r & ~getUmask() ).
int unlink(const Pathname &path)
Like 'unlink'.
std::list< DirEntry > DirContent
Returned by readdir.
int assert_file_mode(const Pathname &path, unsigned mode)
Like assert_file but enforce mode even if the file already exists.
std::string numstring(char n, int w=0)
std::string form(const char *format,...) __attribute__((format(printf
Printf style construction of std::string.
bool strToBool(const C_Str &str, bool default_r)
Parse str into a bool depending on the default value.
std::string trim(const std::string &s, const Trim trim_r)
int zypp_poll(std::vector< GPollFD > &fds, int timeout)
Small wrapper around g_poll that additionally listens to the shutdown FD returned by ZYpp::shutdownSi...
Easy-to use interface to the ZYPP dependency resolver.
AutoDispose< const Pathname > ManagedFile
A Pathname plus associated cleanup code to be executed when path is no longer needed.
Bottleneck filtering all DownloadProgressReport issued from Media[Muli]Curl.
~OptionalDownloadProgressReport() override
void report(const UserData &userData_r=UserData()) override
The most generic way of sending/receiving data.
void reportbegin() override
void reportend() override
Action problem(const Url &file_r, Error error_r, const std::string &description_r) override
OptionalDownloadProgressReport & operator=(const OptionalDownloadProgressReport &)=delete
OptionalDownloadProgressReport(bool isOptional=false)
std::chrono::steady_clock::time_point TimePoint
OptionalDownloadProgressReport(OptionalDownloadProgressReport &&)=delete
void finish(const Url &file_r, Error error_r, const std::string &reason_r) override
TimePoint _lastProgressSent
bool progress(int value_r, const Url &file_r, double dbps_avg_r=-1, double dbps_current_r=-1) override
Download progress.
OptionalDownloadProgressReport(const OptionalDownloadProgressReport &)=delete
void start(const Url &file_r, Pathname localfile_r) override
ByteCount _expectedFileSize
curl_off_t _dnlNow
Bytes downloaded now.
int _dnlPercent
Percent completed or 0 if _dnlTotal is unknown.
time_t _timeRcv
Start of no-data timeout.
ByteCount expectedFileSize() const
time_t _timeLast
Start last period(~1sec)
int reportProgress() const
double _drateLast
Download rate in last period.
bool timeoutReached() const
void expectedFileSize(ByteCount newval_r)
curl_off_t _dnlLast
Bytes downloaded at period start.
bool fileSizeExceeded() const
void updateStats(curl_off_t dltotal=0.0, curl_off_t dlnow=0.0)
double _drateTotal
Download rate so far.
zypp::callback::SendReport< zypp::media::DownloadProgressReport > * report
curl_off_t _dnlTotal
Bytes to download or 0 if unknown.
time_t _timeStart
Start total stats.
ProgressData(CURL *curl, time_t timeout=0, zypp::Url url=zypp::Url(), zypp::ByteCount expectedFileSize_r=0, zypp::callback::SendReport< zypp::media::DownloadProgressReport > *_report=nullptr)
AutoDispose<int> calling ::close
AutoDispose<FILE*> calling ::fclose
virtual void reportbegin()
virtual void report(const UserData &userData_r=UserData())
The most generic way of sending/receiving data.
callback::UserData UserData
#define ZYPP_RETHROW(EXCPT)
Drops a logline and rethrows, updating the CodeLocation.
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.