2 * @brief HTTPHelper class implementation. This class represents a Helper to perform HTTP operations easily.
6 * @copyright Intra2net AG
10 #include "httphelper.hpp"
11 #include "version_info.h"
17 * Default Constructor.
19 HTTPHelper::HTTPHelper()
23 , CurlInitError(CURLE_OK)
25 CurlEasyHandle = init_curl(CurlWritedataBuff, CurlErrBuff);
30 * Constructor. Use this constructor if HTTP AUTH should be used. Username and password will then be set as HTTP auth options.
31 * @param _log Logger Object
32 * @param _proxy Proxy to use
33 * @param _proxy_port Proxy Port
34 * @param _username Username
35 * @param _password Password
37 HTTPHelper::HTTPHelper(Logger::Ptr _log, const string& _proxy, const int _proxy_port, const string& _username, const string& _password)
40 , ProxyPort(_proxy_port)
42 , CurlInitError(CURLE_OK)
46 CurlEasyHandle = init_curl(CurlWritedataBuff, CurlErrBuff);
47 if ( CurlEasyHandle != NULL )
49 if ( (CurlInitError = set_curl_auth(Username,Password)) != CURLE_OK )
51 curl_easy_cleanup(CurlEasyHandle);
52 CurlEasyHandle = NULL;
59 * Constructor. Use this constructor if you have to encode the username and password into the url
60 * @param _log Logger Object
61 * @param _proxy Proxy to use
62 * @param _proxy_port Proxy Port
64 HTTPHelper::HTTPHelper(Logger::Ptr _log, const string& _proxy, const int _proxy_port)
67 , ProxyPort(_proxy_port)
69 , CurlInitError(CURLE_OK)
71 CurlEasyHandle = init_curl(CurlWritedataBuff, CurlErrBuff);
78 HTTPHelper::~HTTPHelper()
81 if ( CurlEasyHandle != NULL )
83 curl_easy_cleanup(CurlEasyHandle);
84 CurlEasyHandle = NULL;
91 void HTTPHelper::re_initialize()
93 CurlEasyHandle = init_curl(CurlWritedataBuff, CurlErrBuff);
94 if ( (CurlEasyHandle != NULL) && !(Username.empty()) && !(Password.empty()) )
96 if ( (CurlInitError = set_curl_auth(Username,Password)) != CURLE_OK )
98 curl_easy_cleanup(CurlEasyHandle);
99 CurlEasyHandle = NULL;
106 * Perform a HTTP GET operation
107 * @param url URL for HTTP GET operation
108 * @return The status code from the http operation or -1 if an curl error occurs
110 long HTTPHelper::http_get(const string& url)
113 CurlError = CURLE_OK;
115 if ( CurlEasyHandle != NULL )
117 if ( (CurlInitError = set_curl_url(url)) != CURLE_OK )
119 Log->print_curl_error(url,CurlInitError,CurlErrBuff);
120 CurlWritedataBuff.clear();
123 if ( (CurlError = curl_easy_perform(CurlEasyHandle) ) != CURLE_OK )
125 Log->print_curl_error(url,CurlError,CurlErrBuff);
126 CurlWritedataBuff.clear();
129 if ( (CurlError = curl_easy_getinfo(CurlEasyHandle,CURLINFO_RESPONSE_CODE,&curl_info)) != CURLE_OK )
131 Log->print_curl_error(url,CurlError);
132 CurlWritedataBuff.clear();
136 Log->print_curl_data(CurlWritedataBuff);
138 // Copy the received data received via curl from the curl data buffer member to the received data member. This is needed because curl appends data to the buffer rather than overrites it.
139 ReceivedCurlData = CurlWritedataBuff;
140 CurlWritedataBuff.clear();
142 // Operation performed without any problems so we can return the curl_info
150 * Getter for member CurlWritedataBuff
151 * @return CurlWritedataBuff
153 string HTTPHelper::get_curl_data() const
155 return ReceivedCurlData;
160 * Initialized curl easy handle with a few options.
161 * @param curl_writedata_buff Reference to a string wich will be filled with the curl result
162 * @param curl_err_buff A pointer to an char array which will be filled with error message.
163 * @return A pointer to the easy curl handle or NULL if something went wrong.
165 CURL* HTTPHelper::init_curl(string& curl_writedata_buff,char* curl_err_buff)
167 CurlInitError = CURLE_OK;
168 ostringstream user_agent_stream;
169 user_agent_stream << "Intra2net AG - Bullet Proof DYNDNS Daemon - " << MAJOR_VERSION << "." << MINOR_VERSION;
170 string user_agent = user_agent_stream.str();
172 CURL *curl_easy_handle = curl_easy_init();
173 if ( curl_easy_handle == NULL )
175 // something went wrong.
176 CurlInitError = CURLE_FAILED_INIT;
177 Log->print_curl_error_init("Could not initialize CURL object.",CURLE_FAILED_INIT);
181 CurlInitError = curl_easy_setopt(curl_easy_handle,CURLOPT_NOPROGRESS,1);
182 if ( CurlInitError == CURLE_OK)
183 CurlInitError = curl_easy_setopt(curl_easy_handle,CURLOPT_CONNECTTIMEOUT,5);
184 if ( CurlInitError == CURLE_OK)
185 CurlInitError = curl_easy_setopt(curl_easy_handle,CURLOPT_TIMEOUT,10);
186 if ( CurlInitError == CURLE_OK)
187 CurlInitError = curl_easy_setopt(curl_easy_handle,CURLOPT_BUFFERSIZE,1024);
188 if ( CurlInitError == CURLE_OK)
189 CurlInitError = curl_easy_setopt(curl_easy_handle,CURLOPT_ERRORBUFFER,curl_err_buff);
190 if ( CurlInitError == CURLE_OK)
191 CurlInitError = curl_easy_setopt(curl_easy_handle,CURLOPT_WRITEFUNCTION,http_receive);
192 if ( CurlInitError == CURLE_OK)
193 CurlInitError = curl_easy_setopt(curl_easy_handle,CURLOPT_WRITEDATA,&curl_writedata_buff);
194 if ( CurlInitError == CURLE_OK)
195 CurlInitError = curl_easy_setopt(curl_easy_handle,CURLOPT_USERAGENT,user_agent.c_str());
196 if ( CurlInitError == CURLE_OK)
197 CurlInitError = curl_easy_setopt(curl_easy_handle,CURLOPT_SSL_VERIFYHOST,0);
198 if ( CurlInitError == CURLE_OK)
199 CurlInitError = curl_easy_setopt(curl_easy_handle,CURLOPT_SSL_VERIFYPEER,0);
201 if ( !Proxy.empty() )
203 if ( CurlInitError == CURLE_OK)
204 CurlInitError = curl_easy_setopt(curl_easy_handle,CURLOPT_PROXY,Proxy.c_str());
205 if ( CurlInitError == CURLE_OK)
206 CurlInitError = curl_easy_setopt(curl_easy_handle,CURLOPT_PROXYPORT,ProxyPort);
209 if ( CurlInitError != CURLE_OK )
211 // Some options could not be set, so destroy the CURL handle.
212 Log->print_curl_error_init("Could not set CURL options properly.",CurlInitError);
213 curl_easy_cleanup(curl_easy_handle);
214 curl_easy_handle = NULL;
217 return curl_easy_handle;
222 * Test if the curl handle is initialized correctly.
223 * @return True if correctly initialized, false if something went wrong during initialization.
225 bool HTTPHelper::is_initialized() const
227 if ( (CurlInitError == CURLE_OK) && (CurlEasyHandle != NULL) )
236 * Sets a url to the easy curl handle
237 * @param url The url to set.
238 * @return CURLcode CURLE_OK if everything is right.
240 CURLcode HTTPHelper::set_curl_url(const string& url)
242 CURLcode curlError = CURLE_OK;
243 if ( (CurlEasyHandle != NULL) && (CurlInitError == CURLE_OK) )
245 curlError = curl_easy_setopt(CurlEasyHandle,CURLOPT_URL,url.c_str());
246 if ( curlError != CURLE_OK )
248 // Some options could not be set, so destroy the CURL handle.
249 Log->print_curl_error_init("Could not set CURL URL properly.",curlError);
250 curl_easy_cleanup(CurlEasyHandle);
251 CurlEasyHandle = NULL;
256 return CURLE_FAILED_INIT;
263 * Sets HTTP AUTH parameters
264 * @param username The username for HTTP AUTH
265 * @param password The password for HTTP AUTH
266 * @return CURLcode CURLE_OK if everything is right.
268 CURLcode HTTPHelper::set_curl_auth(const string& username, const string& password)
270 CURLcode curlError = CURLE_OK;
271 if ( (CurlEasyHandle != NULL) && (CurlInitError == CURLE_OK) )
273 curlError = curl_easy_setopt(CurlEasyHandle,CURLOPT_USERNAME,username.c_str());
274 if ( curlError != CURLE_OK )
275 Log->print_curl_error_init("Could not set CURL username properly.",curlError);
276 curlError = curl_easy_setopt(CurlEasyHandle,CURLOPT_PASSWORD,password.c_str());
277 if ( curlError != CURLE_OK )
278 Log->print_curl_error_init("Could not set CURL password properly.",curlError);
282 return CURLE_FAILED_INIT;
289 * Callback Function is called every time CURL is receiving data from HTTPS-Server and will copy all received Data to the given stream pointer
290 * @param inBuffer Pointer to input.
291 * @param size How many mem blocks are received
292 * @param nmemb size of each memblock
293 * @param outBuffer Pointer to output stream.
294 * @return The size received.
296 size_t HTTPHelper::http_receive( void *inBuffer, size_t size, size_t nmemb, string *outBuffer )
298 outBuffer->append(static_cast<char *>(inBuffer), size*nmemb);