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;
408 const char *
const *proto =
nullptr;
413 if( scheme == std::string((
const char *)*proto))
418 std::string msg(
"Unsupported protocol '");
517#ifdef CURLSSLOPT_ALLOW_BEAST
569 DBG <<
"Enabling HTTP authentication methods: " <<
use_auth
570 <<
" (CURLOPT_HTTPAUTH=" <<
auth <<
")" << std::endl;
589 if ( proxyuserpwd.empty() )
593 if (
curlconf.proxyuserpwd.empty() )
594 DBG <<
"Proxy: ~/.curlrc does not contain the proxy-user option" << endl;
597 proxyuserpwd =
curlconf.proxyuserpwd;
598 DBG <<
"Proxy: using proxy-user from ~/.curlrc" << endl;
606 if ( ! proxyuserpwd.empty() )
611#if CURLVERSION_AT_LEAST(7,19,4)
616 DBG <<
"Proxy: explicitly NOPROXY" << endl;
622 DBG <<
"Proxy: not explicitly set" << endl;
623 DBG <<
"Proxy: libcurl may look into the environment" << endl;
634#if CURLVERSION_AT_LEAST(7,15,5)
650 MIL <<
"No cookies requested" << endl;
655#if CURLVERSION_AT_LEAST(7,18,0)
752 const auto &filename =
srcFile.filename();
849 if (filename.
empty())
859 err =
" Unsupported protocol";
862 err +=
" or redirect (";
890 DBG << msg <<
" Login failed (URL: " <<
url.
asString() <<
")" << std::endl;
891 DBG <<
"MediaUnauthorizedException auth hint: '" <<
auth_hint <<
"'" << std::endl;
906 if (
url.
getHost().find(
".suse.com") != std::string::npos )
907 msg403 =
_(
"Visit the SUSE Customer Center to check whether your registration is valid and has not expired.");
908 else if (
url.
asString().find(
"novell.com") != std::string::npos)
909 msg403 =
_(
"Visit the Novell Customer Center to check whether your registration is valid and has not expired.");
922 std::string msg =
"Unable to retrieve HTTP response:";
929#if CURLVERSION_AT_LEAST(7,16,0)
934 err =
"File not found";
939 err =
"Login failed";
945 err =
"Connection failed";
957 err =
"Timeout reached";
1060 ERR <<
"fopen failed for /dev/null" << endl;
1095 if( assert_dir(
dest.dirname() ) )
1097 DBG <<
"assert_dir " <<
dest.dirname() <<
" failed" << endl;
1107 ERR <<
"out of memory for temp file name" << endl;
1114 ERR <<
"mkstemp failed for file '" <<
destNew <<
"'" << endl;
1122 ERR <<
"fopen failed for file '" <<
destNew <<
"'" << endl;
1128 DBG <<
"dest: " <<
dest << endl;
1164 DBG <<
" Not modified.";
1171 WAR <<
"Could not get the response code." << endl;
1179 ERR <<
"Failed to chmod file " <<
destNew << endl;
1185 ERR <<
"Fclose failed for file '" <<
destNew <<
"'" << endl;
1191 ERR <<
"Rename failed" << endl;
1204 DBG <<
srcFile.filename().asString() << endl;
1247 WAR <<
"Can't set CURLOPT_PROGRESSDATA: " <<
_curlError << endl;;
1251#if CURLVERSION_AT_LEAST(7,19,4)
1256 if (
ftell(file) == 0 &&
ret == 0 )
1264 WAR <<
"TIMECONDITION unmet - retry without." << endl;
1274 WAR <<
"Can't unset CURLOPT_PROGRESSDATA: " <<
_curlError << endl;;
1280 <<
", temp file size " <<
ftell(file)
1281 <<
" bytes." << endl;
1307 for ( filesystem::DirContent::const_iterator
it = content.begin();
it != content.end(); ++
it ) {
1311 switch (
it->type ) {
1322 WAR <<
"Ignore error (" <<
res <<
") on creating local directory '" <<
localPath( filename ) <<
"'" << endl;
1360 return pdata->reportProgress();
1376 return pdata->reportProgress();
1472 if ( msg->easy_handle !=
_curl )
continue;
1474 return msg->data.result;
1494 DBG <<
"got stored credentials:" << endl << *
credentials << endl;
1523 DBG <<
"callback answer: retry" << endl
1524 <<
"CurlAuthData: " << *
curlcred << endl;
1542 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() ).
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.
int unlink(const Pathname &path)
Like 'unlink'.
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.