17#include <zypp/base/Logger.h>
18#include <zypp/ExternalProgram.h>
19#include <zypp/base/String.h>
20#include <zypp/base/Gettext.h>
22#include <zypp-core/parser/Sysconfig>
23#include <zypp/base/Gettext.h>
26#include <zypp-core/zyppng/base/private/linuxhelpers_p.h>
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";
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;
#define LIBZYPP_VERSION_STRING
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.
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.