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,
114 return xferinfo( aProgress,
static_cast<curl_off_t
>( aDLtotal ),
115 static_cast<curl_off_t
>( aDLnow ),
static_cast<curl_off_t
>( aULtotal ),
116 static_cast<curl_off_t
>( aULnow ) );
123 m_headers( nullptr ),
126 m_CURL = curl_easy_init();
132 curl_easy_setopt(
m_CURL, CURLOPT_WRITEDATA,
static_cast<void*
>( &
m_buffer ) );
135#if LIBCURL_VERSION_NUM >= 0x075500
136 curl_easy_setopt(
m_CURL, CURLOPT_PROTOCOLS_STR,
"http,https");
138 curl_easy_setopt(
m_CURL, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS );
142 long sslOpts = CURLSSLOPT_NATIVE_CA;
147 if( policyState == POLICY_CURL_SSL_REVOKE::BEST_EFFORT )
149 sslOpts |= CURLSSLOPT_REVOKE_BEST_EFFORT;
151 else if( policyState == POLICY_CURL_SSL_REVOKE::NONE )
153 sslOpts |= CURLSSLOPT_NO_REVOKE;
157 curl_easy_setopt(
m_CURL, CURLOPT_SSL_OPTIONS, sslOpts );
160 if( wxGetEnv( wxT(
"KICAD_CURL_VERBOSE" ),
nullptr ) )
163 curl_easy_setopt(
m_CURL, CURLOPT_VERBOSE, 1L );
166 wxPlatformInfo platformInfo;
167 wxString application( wxS(
"KiCad" ) );
169 wxString platform = wxS(
"(" ) + wxGetOsDescription() + wxS(
";" ) +
172#if defined( KICAD_BUILD_ARCH_X64 )
173 platform << wxS(
";64-bit" );
174#elif defined( KICAD_BUILD_ARCH_X86 )
175 platform << wxS(
";32-bit" );
176#elif defined( KICAD_BUILD_ARCH_ARM )
177 platform << wxS(
";ARM 32-bit" );
178#elif defined( KICAD_BUILD_ARCH_ARM64 )
179 platform << wxS(
";ARM 64-bit" );
182 platform << wxS(
")" );
184 wxString user_agent = wxS(
"KiCad/" ) + version + wxS(
" " ) + platform + wxS(
" " ) +
188 setOption<const char*>( CURLOPT_USERAGENT, user_agent.ToStdString().c_str() );
189 setOption( CURLOPT_ACCEPT_ENCODING,
"gzip,deflate" );
198 curl_easy_cleanup(
m_CURL );
210 return curl_easy_perform(
m_CURL );
216 std::string header = aName +
':' + aValue;
224 return curl_easy_setopt(
m_CURL,
static_cast<CURLoption
>( aOption ), aArg );
230 return curl_easy_strerror(
static_cast<CURLcode
>( aCode ) );
236 if( setOption<const char*>( CURLOPT_USERAGENT, aAgent.c_str() ) == CURLE_OK )
244 const std::vector<std::pair<std::string, std::string>>& aFields )
246 std::string postfields;
248 for(
size_t i = 0; i < aFields.size(); i++ )
253 postfields +=
Escape( aFields[i].first );
255 postfields +=
Escape( aFields[i].second );
258 if( setOption<const char*>( CURLOPT_COPYPOSTFIELDS, postfields.c_str() ) != CURLE_OK )
267 if( setOption<const char*>( CURLOPT_COPYPOSTFIELDS, aField.c_str() ) != CURLE_OK )
276 if( setOption<const char*>( CURLOPT_URL, aURL.c_str() ) == CURLE_OK )
284 curl_easy_setopt(
m_CURL, CURLOPT_PROXY,
static_cast<const char*
>( cfg.
host.c_str() ) );
288 curl_easy_setopt(
m_CURL, CURLOPT_PROXYUSERNAME,
289 static_cast<const char*
>( cfg.
username.c_str() ) );
294 curl_easy_setopt(
m_CURL, CURLOPT_PROXYPASSWORD,
295 static_cast<const char*
>( cfg.
password.c_str() ) );
308 if( setOption<long>( CURLOPT_FOLLOWLOCATION, ( aFollow ? 1 : 0 ) ) == CURLE_OK )
317 char* escaped = curl_easy_escape(
m_CURL, aUrl.c_str(), aUrl.length() );
319 std::string ret( escaped );
320 curl_free( escaped );
328 progress = std::make_unique<CURL_PROGRESS>(
this, aCallback,
329 static_cast<curl_off_t
>( aInterval ) );
330#if LIBCURL_VERSION_NUM >= 0x072000
331 setOption( CURLOPT_XFERINFOFUNCTION, xferinfo );
346 curl_easy_setopt(
m_CURL, CURLOPT_WRITEDATA,
reinterpret_cast<const void*
>( aOutput ) );
353#if LIBCURL_VERSION_NUM >= 0x073700
355 int result = curl_easy_getinfo(
m_CURL, CURLINFO_SIZE_DOWNLOAD_T, &dl );
356 aDownloadedBytes =
static_cast<uint64_t
>( dl );
359 int result = curl_easy_getinfo(
m_CURL, CURLINFO_SIZE_DOWNLOAD, &dl );
360 aDownloadedBytes =
static_cast<uint64_t
>( dl );
370 curl_easy_getinfo(
m_CURL, CURLINFO_RESPONSE_CODE, &http_code );
372 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.
Simple wrapper class to call curl_global_init and curl_global_cleanup for KiCad.
static bool IsShuttingDown()
Returns true if all curl operations should terminate.
#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