36#include <shared_mutex>
64static size_t write_callback(
void* aContents,
size_t aSize,
size_t aNmemb,
void* aUserp )
66 size_t realsize = aSize * aNmemb;
68 std::string* p =
static_cast<std::string*
>( aUserp );
70 p->append(
static_cast<const char*
>( aContents ), realsize );
78 size_t realsize = aSize * aNmemb;
80 std::ostream* p =
static_cast<std::ostream*
>( aUserp );
82 p->write(
static_cast<const char*
>( aContents ), realsize );
87#if LIBCURL_VERSION_NUM >= 0x072000
89static int xferinfo(
void* aProgress, curl_off_t aDLtotal, curl_off_t aDLnow, curl_off_t aULtotal,
96 curl_off_t curtime = 0;
98 curl_easy_getinfo( progress->
m_Curl->
GetCurl(), CURLINFO_TOTAL_TIME, &curtime );
103 return progress->
m_Callback( aDLtotal, aDLnow, aULtotal, aULnow );
111static int progressinfo(
void* aProgress,
double aDLtotal,
double aDLnow,
double aULtotal,
double aULnow )
113 return xferinfo( aProgress,
static_cast<curl_off_t
>( aDLtotal ),
static_cast<curl_off_t
>( aDLnow ),
114 static_cast<curl_off_t
>( aULtotal ),
static_cast<curl_off_t
>( aULnow ) );
123 m_CURL = curl_easy_init();
129 curl_easy_setopt(
m_CURL, CURLOPT_WRITEDATA,
static_cast<void*
>( &
m_buffer ) );
132#if LIBCURL_VERSION_NUM >= 0x075500
133 curl_easy_setopt(
m_CURL, CURLOPT_PROTOCOLS_STR,
"http,https");
135 curl_easy_setopt(
m_CURL, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS );
139 long sslOpts = CURLSSLOPT_NATIVE_CA;
142 if( policyState == POLICY_CURL_SSL_REVOKE::BEST_EFFORT )
144 sslOpts |= CURLSSLOPT_REVOKE_BEST_EFFORT;
146 else if( policyState == POLICY_CURL_SSL_REVOKE::NONE )
148 sslOpts |= CURLSSLOPT_NO_REVOKE;
152 curl_easy_setopt(
m_CURL, CURLOPT_SSL_OPTIONS, sslOpts );
155 if( wxGetEnv( wxT(
"KICAD_CURL_VERBOSE" ),
nullptr ) )
158 curl_easy_setopt(
m_CURL, CURLOPT_VERBOSE, 1L );
161 wxPlatformInfo platformInfo;
162 wxString application( wxS(
"KiCad" ) );
166#if defined( KICAD_BUILD_ARCH_X64 )
167 platform << wxS(
";64-bit" );
168#elif defined( KICAD_BUILD_ARCH_X86 )
169 platform << wxS(
";32-bit" );
170#elif defined( KICAD_BUILD_ARCH_ARM )
171 platform << wxS(
";ARM 32-bit" );
172#elif defined( KICAD_BUILD_ARCH_ARM64 )
173 platform << wxS(
";ARM 64-bit" );
176 platform << wxS(
")" );
178 wxString user_agent = wxS(
"KiCad/" ) + version + wxS(
" " ) + platform + wxS(
" " ) + application;
181 setOption<const char*>( CURLOPT_USERAGENT, user_agent.ToStdString().c_str() );
182 setOption( CURLOPT_ACCEPT_ENCODING,
"gzip,deflate" );
191 curl_easy_cleanup(
m_CURL );
201 return CURLE_ABORTED_BY_CALLBACK;
209 return curl_easy_perform(
m_CURL );
215 std::string header = aName +
':' + aValue;
223 return curl_easy_setopt(
m_CURL,
static_cast<CURLoption
>( aOption ), aArg );
229 return curl_easy_strerror(
static_cast<CURLcode
>( aCode ) );
235 if( setOption<const char*>( CURLOPT_USERAGENT, aAgent.c_str() ) == CURLE_OK )
243 const std::vector<std::pair<std::string, std::string>>& aFields )
245 std::string postfields;
247 for(
size_t i = 0; i < aFields.size(); i++ )
252 postfields +=
Escape( aFields[i].first );
254 postfields +=
Escape( aFields[i].second );
257 if( setOption<const char*>( CURLOPT_COPYPOSTFIELDS, postfields.c_str() ) != CURLE_OK )
266 if( setOption<const char*>( CURLOPT_COPYPOSTFIELDS, aField.c_str() ) != CURLE_OK )
275 if( setOption<const char*>( CURLOPT_URL, aURL.c_str() ) == CURLE_OK )
283 curl_easy_setopt(
m_CURL, CURLOPT_PROXY,
static_cast<const char*
>( cfg.
host.c_str() ) );
287 curl_easy_setopt(
m_CURL, CURLOPT_PROXYUSERNAME,
288 static_cast<const char*
>( cfg.
username.c_str() ) );
293 curl_easy_setopt(
m_CURL, CURLOPT_PROXYPASSWORD,
294 static_cast<const char*
>( cfg.
password.c_str() ) );
307 if( setOption<long>( CURLOPT_FOLLOWLOCATION, ( aFollow ? 1 : 0 ) ) == CURLE_OK )
316 char* escaped = curl_easy_escape(
m_CURL, aUrl.c_str(), aUrl.length() );
318 std::string ret( escaped );
319 curl_free( escaped );
327 progress = std::make_unique<CURL_PROGRESS>(
this, aCallback,
328 static_cast<curl_off_t
>( aInterval ) );
329#if LIBCURL_VERSION_NUM >= 0x072000
330 setOption( CURLOPT_XFERINFOFUNCTION, xferinfo );
344 curl_easy_setopt(
m_CURL, CURLOPT_WRITEDATA,
reinterpret_cast<const void*
>( aOutput ) );
351#if LIBCURL_VERSION_NUM >= 0x073700
353 int result = curl_easy_getinfo(
m_CURL, CURLINFO_SIZE_DOWNLOAD_T, &dl );
354 aDownloadedBytes =
static_cast<uint64_t
>( dl );
357 int result = curl_easy_getinfo(
m_CURL, CURLINFO_SIZE_DOWNLOAD, &dl );
358 aDownloadedBytes =
static_cast<uint64_t
>( dl );
367 curl_easy_getinfo(
m_CURL, CURLINFO_RESPONSE_CODE, &http_code );
369 return static_cast<int>( http_code );
wxString GetBuildVersion()
Get the full KiCad version string.
wxString GetPlatformGetBitnessName()
wxString GetBuildDate()
Get the build date as a string.
int Perform()
Equivalent to curl_easy_perform.
bool SetPostFields(const std::vector< std::pair< std::string, std::string > > &aFields)
Set fields for application/x-www-form-urlencoded POST request.
std::unique_ptr< CURL_PROGRESS > progress
std::string Escape(const std::string &aUrl)
Escapes a string for use as a URL.
bool SetUserAgent(const std::string &aAgent)
Set the request user agent.
int GetResponseStatusCode()
void SetHeader(const std::string &aName, const std::string &aValue)
Set an arbitrary header for the HTTP(s) request.
bool SetTransferCallback(const TRANSFER_CALLBACK &aCallback, size_t aInterval)
bool SetURL(const std::string &aURL)
Set the request URL.
bool SetFollowRedirects(bool aFollow)
Enable the following of HTTP(s) and other redirects, by default curl does not follow redirects.
int GetTransferTotal(uint64_t &aDownloadedBytes) const
int setOption(int aOption, T aArg)
Set a curl option, only supports single parameter curl options.
bool SetOutputStream(const std::ostream *aOutput)
const std::string GetErrorText(int aCode)
Fetch CURL's "friendly" error string for a given error code.
static bool IsShuttingDown()
Returns true if all curl operations should terminate.
static std::shared_mutex & Mutex()
Returns the mutex for shared locking when performing curl operations.
#define THROW_IO_ERROR(msg)
static int progressinfo(void *aProgress, double aDLtotal, double aDLnow, double aULtotal, double aULnow)
static size_t write_callback(void *aContents, size_t aSize, size_t aNmemb, void *aUserp)
static size_t stream_write_callback(void *aContents, size_t aSize, size_t aNmemb, void *aUserp)
std::function< int(size_t, size_t, size_t, size_t)> TRANSFER_CALLBACK
Wrapper interface around the curl_easy API/.
#define POLICY_KEY_REQUESTS_CURL_REVOKE
CURL_PROGRESS(KICAD_CURL_EASY *aCURL, TRANSFER_CALLBACK aCallback, curl_off_t aInterval)
TRANSFER_CALLBACK m_Callback
curl_off_t m_Last_run_time