KiCad PCB EDA Suite
kicad_curl_easy.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2015 Mark Roszko <mark.roszko@gmail.com>
5  * Copyright (C) 2015 KiCad Developers, see CHANGELOG.TXT for contributors.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 3
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, you may find one here:
19  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20  * or you may search the http://www.gnu.org website for the version 2 license,
21  * or you may write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23  */
24 
25 #include <kicad_curl/kicad_curl.h>
27 
28 #include <cstddef>
29 #include <exception>
30 #include <stdarg.h>
31 #include <sstream>
32 #include <ki_exception.h> // THROW_IO_ERROR
33 
34 
35 static size_t write_callback( void* contents, size_t size, size_t nmemb, void* userp )
36 {
37  size_t realsize = size * nmemb;
38 
39  std::string* p = (std::string*) userp;
40 
41  p->append( (const char*) contents, realsize );
42 
43  return realsize;
44 }
45 
46 
48  m_headers( NULL )
49 {
50  // Call KICAD_CURL::Init() from in here everytime, but only the first time
51  // will incur any overhead. This strategy ensures that libcurl is never loaded
52  // unless it is needed.
53 
55 
56  m_CURL = curl_easy_init();
57 
58  if( !m_CURL )
59  {
60  THROW_IO_ERROR( "Unable to initialize CURL session" );
61  }
62 
63  curl_easy_setopt( m_CURL, CURLOPT_WRITEFUNCTION, write_callback );
64  curl_easy_setopt( m_CURL, CURLOPT_WRITEDATA, (void*) &m_buffer );
65 }
66 
67 
69 {
70  if( m_headers )
71  curl_slist_free_all( m_headers );
72 
73  curl_easy_cleanup( m_CURL );
74 }
75 
76 
78 {
79  if( m_headers )
80  {
81  curl_easy_setopt( m_CURL, CURLOPT_HTTPHEADER, m_headers );
82  }
83 
84  // bonus: retain worst case memory allocation, should re-use occur
85  m_buffer.clear();
86 
87  CURLcode res = curl_easy_perform( m_CURL );
88 
89  if( res != CURLE_OK )
90  {
91  std::string msg = "curl_easy_perform()=";
92  msg += (int)res; msg += " "; msg += GetErrorText( res ).c_str();
93  THROW_IO_ERROR( msg );
94  }
95 }
96 
97 
98 void KICAD_CURL_EASY::SetHeader( const std::string& aName, const std::string& aValue )
99 {
100  std::string header = aName + ':' + aValue;
101  m_headers = curl_slist_append( m_headers, header.c_str() );
102 }
103 
104 
105 template <typename T> int KICAD_CURL_EASY::setOption( int aOption, T aArg )
106 {
107  return curl_easy_setopt( m_CURL, (CURLoption)aOption, aArg );
108 }
109 
110 
111 const std::string KICAD_CURL_EASY::GetErrorText( int aCode )
112 {
113  return curl_easy_strerror( (CURLcode)aCode );
114 }
115 
116 
117 bool KICAD_CURL_EASY::SetUserAgent( const std::string& aAgent )
118 {
119  if( setOption<const char*>( CURLOPT_USERAGENT, aAgent.c_str() ) == CURLE_OK )
120  {
121  return true;
122  }
123  return false;
124 }
125 
126 
127 bool KICAD_CURL_EASY::SetURL( const std::string& aURL )
128 {
129  if( setOption<const char *>( CURLOPT_URL, aURL.c_str() ) == CURLE_OK )
130  {
131  return true;
132  }
133  return false;
134 }
135 
136 
138 {
139  if( setOption<long>( CURLOPT_FOLLOWLOCATION , (aFollow ? 1 : 0) ) == CURLE_OK )
140  {
141  return true;
142  }
143  return false;
144 }
bool SetUserAgent(const std::string &aAgent)
Function SetUserAgent sets the request user agent.
static size_t write_callback(void *contents, size_t size, size_t nmemb, void *userp)
void Perform()
Function perform equivalent to curl_easy_perform.
bool SetFollowRedirects(bool aFollow)
Function SetFollowRedirects enables the following of HTTP(s) and other redirects, by default curl doe...
T
enum T contains all this lexer's tokens.
static void Init()
Function Init calls curl_global_init for the application.
Definition: kicad_curl.cpp:128
int setOption(int aOption, T aArg)
Function setOption sets a curl option, only supports single parameter curl options.
curl_slist * m_headers
const std::string GetErrorText(int aCode)
Function GetErrorText fetches CURL's "friendly" error string for a given error code.
bool SetURL(const std::string &aURL)
Function SetURL sets the request URL.
std::string m_buffer
void SetHeader(const std::string &aName, const std::string &aValue)
Function SetHeader sets an arbitrary header for the HTTP(s) request.
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38