KiCad PCB EDA Suite
KICAD_CURL_EASY Class Reference

#include <kicad_curl_easy.h>

Public Member Functions

 KICAD_CURL_EASY ()
 
 ~KICAD_CURL_EASY ()
 
int Perform ()
 Equivalent to curl_easy_perform. More...
 
void SetHeader (const std::string &aName, const std::string &aValue)
 Set an arbitrary header for the HTTP(s) request. More...
 
bool SetUserAgent (const std::string &aAgent)
 Set the request user agent. More...
 
bool SetURL (const std::string &aURL)
 Set the request URL. More...
 
bool SetFollowRedirects (bool aFollow)
 Enable the following of HTTP(s) and other redirects, by default curl does not follow redirects. More...
 
const std::string GetErrorText (int aCode)
 Fetch CURL's "friendly" error string for a given error code. More...
 
int GetTransferTotal (uint64_t &aDownloadedBytes) const
 
const std::string & GetBuffer ()
 Return a reference to the received data buffer. More...
 
std::string Escape (const std::string &aUrl)
 Escapes a string for use as a URL. More...
 
bool SetTransferCallback (const TRANSFER_CALLBACK &aCallback, size_t aInterval)
 
bool SetOutputStream (const std::ostream *aOutput)
 
CURLGetCurl ()
 

Private Member Functions

template<typename T >
int setOption (int aOption, T aArg)
 Set a curl option, only supports single parameter curl options. More...
 

Private Attributes

CURLm_CURL
 
curl_slist * m_headers
 
std::string m_buffer
 
std::unique_ptr< CURL_PROGRESSprogress
 

Detailed Description

Definition at line 66 of file kicad_curl_easy.h.

Constructor & Destructor Documentation

◆ KICAD_CURL_EASY()

KICAD_CURL_EASY::KICAD_CURL_EASY ( )

Definition at line 107 of file kicad_curl_easy.cpp.

107  : m_headers( nullptr )
108 {
109  // Call KICAD_CURL::Init() from in here every time, but only the first time
110  // will incur any overhead. This strategy ensures that libcurl is never loaded
111  // unless it is needed.
112 
114 
115  m_CURL = curl_easy_init();
116 
117  if( !m_CURL )
118  {
119  THROW_IO_ERROR( wxT( "Unable to initialize CURL session" ) );
120  }
121 
122  curl_easy_setopt( m_CURL, CURLOPT_WRITEFUNCTION, write_callback );
123  curl_easy_setopt( m_CURL, CURLOPT_WRITEDATA, (void*) &m_buffer );
124 
125  // Only allow HTTP and HTTPS protocols
126  curl_easy_setopt( m_CURL, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS );
127 
128  #ifdef _WIN32
129  // We need to this to allow using the Windows Certificate store
130  curl_easy_setopt( m_CURL, CURLOPT_SSL_OPTIONS, CURLSSLOPT_NATIVE_CA );
131  #endif
132 
133  wxPlatformInfo platformInfo;
134  wxString application( Pgm().App().GetAppName() );
135  wxString version( GetBuildVersion() );
136  wxString platform = wxT( "(" ) + wxGetOsDescription() + wxT( ";" ) + GetPlatformGetBitnessName();
137 
138 #if defined( KICAD_BUILD_ARCH_X64 )
139  platform << wxT( ";64-bit" );
140 #elif defined( KICAD_BUILD_ARCH_X86 )
141  platform << wxT( ";32-bit" );
142 #elif defined( KICAD_BUILD_ARCH_ARM )
143  platform << wxT( ";ARM 32-bit" );
144 #elif defined( KICAD_BUILD_ARCH_ARM64 )
145  platform << wxT( ";ARM 64-bit" );
146 #endif
147 
148  platform << wxT( ")" );
149 
150  wxString user_agent = wxT( "KiCad/" ) + version + wxT( " " ) + platform + wxT( " " ) + application;
151 
152  user_agent << wxT( "/" ) << GetBuildDate();
153  setOption<const char*>( CURLOPT_USERAGENT, user_agent.ToStdString().c_str() );
154  setOption( CURLOPT_ACCEPT_ENCODING, "gzip,deflate" );
155 }
static size_t write_callback(void *contents, size_t size, size_t nmemb, void *userp)
static void Init()
Call curl_global_init for the application.
Definition: kicad_curl.cpp:50
int setOption(int aOption, T aArg)
Set a curl option, only supports single parameter curl options.
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:106
curl_slist * m_headers
wxString GetBuildVersion()
Get the full KiCad version string.
wxString GetPlatformGetBitnessName()
std::string m_buffer
wxString GetBuildDate()
Get the build date as a string.
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38

References GetBuildDate(), GetBuildVersion(), GetPlatformGetBitnessName(), KICAD_CURL::Init(), m_buffer, m_CURL, Pgm(), setOption(), THROW_IO_ERROR, and write_callback().

◆ ~KICAD_CURL_EASY()

KICAD_CURL_EASY::~KICAD_CURL_EASY ( )

Definition at line 158 of file kicad_curl_easy.cpp.

159 {
160  if( m_headers )
161  curl_slist_free_all( m_headers );
162 
163  curl_easy_cleanup( m_CURL );
164 }
curl_slist * m_headers

References m_CURL, and m_headers.

Member Function Documentation

◆ Escape()

std::string KICAD_CURL_EASY::Escape ( const std::string &  aUrl)

Escapes a string for use as a URL.

Definition at line 256 of file kicad_curl_easy.cpp.

257 {
258  char* escaped = curl_easy_escape( m_CURL, aUrl.c_str(), aUrl.length() );
259 
260  std::string ret( escaped );
261  curl_free( escaped );
262 
263  return ret;
264 }

References m_CURL.

Referenced by COMMON_CONTROL::ReportBug().

◆ GetBuffer()

const std::string& KICAD_CURL_EASY::GetBuffer ( )
inline

Return a reference to the received data buffer.

Definition at line 123 of file kicad_curl_easy.h.

123 { return m_buffer; }
std::string m_buffer

References m_buffer.

◆ GetCurl()

CURL* KICAD_CURL_EASY::GetCurl ( )
inline

Definition at line 132 of file kicad_curl_easy.h.

132 { return m_CURL; }

References m_CURL.

Referenced by xferinfo().

◆ GetErrorText()

const std::string KICAD_CURL_EASY::GetErrorText ( int  aCode)

Fetch CURL's "friendly" error string for a given error code.

Parameters
aCodeis CURL error code.
Returns
The corresponding error string for the given code.

Definition at line 197 of file kicad_curl_easy.cpp.

198 {
199  return curl_easy_strerror( static_cast<CURLcode>( aCode ) );
200 }

Referenced by PLUGIN_CONTENT_MANAGER::DownloadToStream().

◆ GetTransferTotal()

int KICAD_CURL_EASY::GetTransferTotal ( uint64_t &  aDownloadedBytes) const

Definition at line 291 of file kicad_curl_easy.cpp.

292 {
293 #ifdef CURLINFO_SIZE_DOWNLOAD_T
294  curl_off_t dl;
295  int result = curl_easy_getinfo( m_CURL, CURLINFO_SIZE_DOWNLOAD_T, &dl );
296  aDownloadedBytes = static_cast<uint64_t>( dl );
297 #else
298  double dl;
299  int result = curl_easy_getinfo( m_CURL, CURLINFO_SIZE_DOWNLOAD, &dl );
300  aDownloadedBytes = static_cast<uint64_t>( dl );
301 #endif
302  return result;
303 }

References m_CURL.

◆ Perform()

int KICAD_CURL_EASY::Perform ( )

Equivalent to curl_easy_perform.

Executes the request that was previously setup.

Definition at line 167 of file kicad_curl_easy.cpp.

168 {
169  if( m_headers )
170  {
171  curl_easy_setopt( m_CURL, CURLOPT_HTTPHEADER, m_headers );
172  }
173 
174  // bonus: retain worst case memory allocation, should re-use occur
175  m_buffer.clear();
176 
177  CURLcode res = curl_easy_perform( m_CURL );
178 
179  return res;
180 }
curl_slist * m_headers
std::string m_buffer

References m_buffer, m_CURL, and m_headers.

Referenced by PLUGIN_CONTENT_MANAGER::DownloadToStream().

◆ SetFollowRedirects()

bool KICAD_CURL_EASY::SetFollowRedirects ( bool  aFollow)

Enable the following of HTTP(s) and other redirects, by default curl does not follow redirects.

Parameters
aFollowis a boolean where true will enable following redirects.
Returns
True if successful, false if not.

Definition at line 245 of file kicad_curl_easy.cpp.

246 {
247  if( setOption<long>( CURLOPT_FOLLOWLOCATION, ( aFollow ? 1 : 0 ) ) == CURLE_OK )
248  {
249  return true;
250  }
251 
252  return false;
253 }

Referenced by PLUGIN_CONTENT_MANAGER::DownloadToStream().

◆ SetHeader()

void KICAD_CURL_EASY::SetHeader ( const std::string &  aName,
const std::string &  aValue 
)

Set an arbitrary header for the HTTP(s) request.

Parameters
aNameis the left hand side of the header, i.e. Accept without the colon.
aValueis the right hand side of the header, i.e. application/json.

Definition at line 183 of file kicad_curl_easy.cpp.

184 {
185  std::string header = aName + ':' + aValue;
186  m_headers = curl_slist_append( m_headers, header.c_str() );
187 }
curl_slist * m_headers

References m_headers.

◆ setOption()

template<typename T >
int KICAD_CURL_EASY::setOption ( int  aOption,
aArg 
)
private

Set a curl option, only supports single parameter curl options.

Parameters
aOptionis CURL option, see CURL manual for options.
aArgis the argument being passed to CURL, ensure it is the right type per manual.
Returns
A CURL error code, will return CURLE_OK unless a problem was encountered.

Definition at line 191 of file kicad_curl_easy.cpp.

192 {
193  return curl_easy_setopt( m_CURL, static_cast<CURLoption>( aOption ), aArg );
194 }

References m_CURL.

Referenced by KICAD_CURL_EASY(), and SetTransferCallback().

◆ SetOutputStream()

bool KICAD_CURL_EASY::SetOutputStream ( const std::ostream *  aOutput)

Definition at line 283 of file kicad_curl_easy.cpp.

284 {
285  curl_easy_setopt( m_CURL, CURLOPT_WRITEFUNCTION, stream_write_callback );
286  curl_easy_setopt( m_CURL, CURLOPT_WRITEDATA, reinterpret_cast<const void*>( aOutput ) );
287  return true;
288 }
static size_t stream_write_callback(void *contents, size_t size, size_t nmemb, void *userp)

References m_CURL, and stream_write_callback().

Referenced by PCM_TASK_MANAGER::downloadFile(), and PLUGIN_CONTENT_MANAGER::DownloadToStream().

◆ SetTransferCallback()

bool KICAD_CURL_EASY::SetTransferCallback ( const TRANSFER_CALLBACK aCallback,
size_t  aInterval 
)

Definition at line 267 of file kicad_curl_easy.cpp.

268 {
269  progress = std::make_unique<CURL_PROGRESS>( this, aCallback,
270  static_cast<curl_off_t>( aInterval ) );
271 #ifdef CURLOPT_XFERINFOFUNCTION
272  setOption( CURLOPT_XFERINFOFUNCTION, xferinfo );
273  setOption( CURLOPT_XFERINFODATA, progress.get() );
274 #else
275  setOption( CURLOPT_PROGRESSFUNCTION, progressinfo );
276  setOption( CURLOPT_PROGRESSDATA, progress.get() );
277 #endif
278  setOption( CURLOPT_NOPROGRESS, 0L );
279  return true;
280 }
static int progressinfo(void *p, double dltotal, double dlnow, double ultotal, double ulnow)
int setOption(int aOption, T aArg)
Set a curl option, only supports single parameter curl options.
std::unique_ptr< CURL_PROGRESS > progress
static int xferinfo(void *p, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow)

References progress, progressinfo(), setOption(), and xferinfo().

Referenced by PLUGIN_CONTENT_MANAGER::DownloadToStream().

◆ SetURL()

bool KICAD_CURL_EASY::SetURL ( const std::string &  aURL)

Set the request URL.

Parameters
aURLis the URL.
Returns
True if successful, false if not.

Definition at line 214 of file kicad_curl_easy.cpp.

215 {
216  if( setOption<const char*>( CURLOPT_URL, aURL.c_str() ) == CURLE_OK )
217  {
219 
220  // Unforunately on Windows land, proxies can be configured depending on destination url
221  // So we also check and set any proxy config here
222  if( KIPLATFORM::ENV::GetSystemProxyConfig( aURL, cfg ) )
223  {
224  curl_easy_setopt( m_CURL, CURLOPT_PROXY, static_cast<const char*>( cfg.host.c_str() ) );
225  if( !cfg.username.empty() )
226  {
227  curl_easy_setopt( m_CURL, CURLOPT_PROXYUSERNAME,
228  static_cast<const char*>( cfg.username.c_str() ) );
229  }
230 
231  if( !cfg.password.empty() )
232  {
233  curl_easy_setopt( m_CURL, CURLOPT_PROXYPASSWORD,
234  static_cast<const char*>( cfg.password.c_str() ) );
235  }
236  }
237 
238  return true;
239  }
240 
241  return false;
242 }
bool GetSystemProxyConfig(const wxString &aURL, PROXY_CONFIG &aCfg)
Retrieves platform level proxying requirements to reach the given url.

References KIPLATFORM::ENV::GetSystemProxyConfig(), KIPLATFORM::ENV::PROXY_CONFIG::host, m_CURL, KIPLATFORM::ENV::PROXY_CONFIG::password, and KIPLATFORM::ENV::PROXY_CONFIG::username.

Referenced by PLUGIN_CONTENT_MANAGER::DownloadToStream().

◆ SetUserAgent()

bool KICAD_CURL_EASY::SetUserAgent ( const std::string &  aAgent)

Set the request user agent.

Parameters
aAgentis the string to set for the user agent.
Returns
True if successful, false if not.

Definition at line 203 of file kicad_curl_easy.cpp.

204 {
205  if( setOption<const char*>( CURLOPT_USERAGENT, aAgent.c_str() ) == CURLE_OK )
206  {
207  return true;
208  }
209 
210  return false;
211 }

Member Data Documentation

◆ m_buffer

std::string KICAD_CURL_EASY::m_buffer
private

Definition at line 148 of file kicad_curl_easy.h.

Referenced by GetBuffer(), KICAD_CURL_EASY(), and Perform().

◆ m_CURL

CURL* KICAD_CURL_EASY::m_CURL
private

◆ m_headers

curl_slist* KICAD_CURL_EASY::m_headers
private

Definition at line 147 of file kicad_curl_easy.h.

Referenced by Perform(), SetHeader(), and ~KICAD_CURL_EASY().

◆ progress

std::unique_ptr<CURL_PROGRESS> KICAD_CURL_EASY::progress
private

Definition at line 149 of file kicad_curl_easy.h.

Referenced by SetTransferCallback().


The documentation for this class was generated from the following files: