Added linter settings.
[bpdyndnsd] / src / httphelper.cpp
CommitLineData
efbde536
BS
1/** @file
2 * @brief HTTPHelper class implementation. This class represents a Helper to perform HTTP operations easily.
3 *
4 *
5 *
6 * @copyright Intra2net AG
7 * @license GPLv2
8*/
9
10#include "httphelper.h"
11
ca5d6889 12using namespace std;
d5a516ba 13
31af6a2e
BS
14
15/**
16 * Default Constructor.
17 */
18HTTPHelper::HTTPHelper()
19 : Log(new Logger)
20 , ProxyPort(0)
21 , CurlError(CURLE_OK)
31af6a2e 22{
c730deea 23 CurlEasyHandle = init_curl(CurlWritedataBuff, CurlErrBuff);
31af6a2e
BS
24}
25
26
d5a516ba 27/**
7de01277 28 * Constructor. Use this constructor if HTTP AUTH should be used. Username and password will then be set as HTTP auth options.
d5a516ba
BS
29 * @param _log Logger Object
30 * @param _proxy Proxy to use
31 * @param _proxy_port Proxy Port
32 * @param _username Username
33 * @param _password Password
34 */
2dd2db3e 35HTTPHelper::HTTPHelper(Logger::Ptr _log, const string& _proxy, const int _proxy_port, const string& _username, const string& _password)
6ec86aff
TJ
36 : Log(_log)
37 , Proxy(_proxy)
38 , ProxyPort(_proxy_port)
31af6a2e 39 , CurlError(CURLE_OK)
efbde536 40{
efbde536 41 CurlEasyHandle = init_curl(CurlWritedataBuff, CurlErrBuff);
31af6a2e
BS
42 if ( CurlEasyHandle != NULL )
43 {
c730deea
BS
44 if ( set_curl_auth(_username,_password) != CURLE_OK )
45 {
46 curl_easy_cleanup(CurlEasyHandle);
47 CurlEasyHandle = NULL;
48 }
31af6a2e 49 }
efbde536
BS
50}
51
52
d5a516ba 53/**
7de01277
BS
54 * Constructor. Use this constructor if you have to encode the username and password into the url
55 * @param _log Logger Object
56 * @param _proxy Proxy to use
57 * @param _proxy_port Proxy Port
58 */
59HTTPHelper::HTTPHelper(Logger::Ptr _log, const string& _proxy, const int _proxy_port)
6ec86aff
TJ
60 : Log(_log)
61 , Proxy(_proxy)
62 , ProxyPort(_proxy_port)
31af6a2e 63 , CurlError(CURLE_OK)
7de01277 64{
7de01277
BS
65 CurlEasyHandle = init_curl(CurlWritedataBuff, CurlErrBuff);
66}
67
68
69/**
d5a516ba
BS
70 * Destructor
71 */
efbde536
BS
72HTTPHelper::~HTTPHelper()
73{
891ae3b9 74 // Free memory
31af6a2e
BS
75 if ( CurlEasyHandle != NULL )
76 {
77 curl_easy_cleanup(CurlEasyHandle);
78 CurlEasyHandle = NULL;
79 }
efbde536
BS
80}
81
82
efbde536
BS
83/**
84 * Perform a HTTP GET operation
85 * @param url URL for HTTP GET operation
d5a516ba 86 * @return The status code from the http operation or -1 if an curl error occurs
efbde536 87 */
d5a516ba 88long HTTPHelper::http_get(const string& url)
efbde536 89{
d5a516ba 90 long curl_info;
efbde536 91
31af6a2e 92 if ( CurlEasyHandle != NULL )
efbde536 93 {
c730deea
BS
94 if ( (CurlError = set_curl_url(url)) != CURLE_OK )
95 {
96 Log->print_curl_error(url,CurlError,CurlErrBuff);
97 CurlWritedataBuff.clear();
98 return -1;
99 }
100 if ( (CurlError = curl_easy_perform(CurlEasyHandle) ) != CURLE_OK )
31af6a2e 101 {
c730deea 102 Log->print_curl_error(url,CurlError,CurlErrBuff);
31af6a2e
BS
103 CurlWritedataBuff.clear();
104 return -1;
105 }
c730deea 106 if ( (CurlError = curl_easy_getinfo(CurlEasyHandle,CURLINFO_RESPONSE_CODE,&curl_info)) != CURLE_OK )
31af6a2e 107 {
c730deea 108 Log->print_curl_error(url,CurlError);
31af6a2e
BS
109 CurlWritedataBuff.clear();
110 return -1;
111 }
112
113 Log->print_curl_data(CurlWritedataBuff);
114
115 // 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.
116 ReceivedCurlData = CurlWritedataBuff;
1fda5599 117 CurlWritedataBuff.clear();
1fda5599 118
31af6a2e
BS
119 // Operation performed without any problems so we can return the curl_info
120 return curl_info;
121 }
122 return -1;
efbde536
BS
123}
124
125
126/**
b6228761
BS
127 * Getter for member CurlWritedataBuff
128 * @return CurlWritedataBuff
129 */
130string HTTPHelper::get_curl_data() const
131{
1fda5599 132 return ReceivedCurlData;
b6228761
BS
133}
134
135
136/**
efbde536
BS
137 * Initialized curl easy handle with a few options.
138 * @param curl_writedata_buff Reference to a string wich will be filled with the curl result
139 * @param curl_err_buff A pointer to an char array which will be filled with error message.
c730deea 140 * @return A pointer to the easy curl handle or NULL if something went wrong.
efbde536 141 */
31af6a2e 142CURL* HTTPHelper::init_curl(string& curl_writedata_buff,char* curl_err_buff)
efbde536 143{
e8787e2e 144 string user_agent = "Bullet Proof DYNDNS Daemon 0.1.1 - Intra2net AG 2010";
b6228761 145
efbde536 146 CURL *curl_easy_handle = curl_easy_init();
31af6a2e
BS
147 if ( curl_easy_handle == NULL )
148 {
149 // something went wrong.
150 CurlError = CURLE_FAILED_INIT;
151 Log->print_curl_error_init("Could not initialize CURL object.",CURLE_FAILED_INIT);
152 return NULL;
153 }
efbde536 154
31af6a2e
BS
155 if ( CurlError == CURLE_OK )
156 CurlError = curl_easy_setopt(curl_easy_handle,CURLOPT_NOPROGRESS,1);
157 if ( CurlError == CURLE_OK)
158 CurlError = curl_easy_setopt(curl_easy_handle,CURLOPT_CONNECTTIMEOUT,5);
159 if ( CurlError == CURLE_OK)
160 CurlError = curl_easy_setopt(curl_easy_handle,CURLOPT_TIMEOUT,10);
161 if ( CurlError == CURLE_OK)
162 CurlError = curl_easy_setopt(curl_easy_handle,CURLOPT_BUFFERSIZE,1024);
163 if ( CurlError == CURLE_OK)
164 CurlError = curl_easy_setopt(curl_easy_handle,CURLOPT_ERRORBUFFER,curl_err_buff);
165 if ( CurlError == CURLE_OK)
166 CurlError = curl_easy_setopt(curl_easy_handle,CURLOPT_WRITEFUNCTION,http_receive);
167 if ( CurlError == CURLE_OK)
168 CurlError = curl_easy_setopt(curl_easy_handle,CURLOPT_WRITEDATA,&curl_writedata_buff);
169 if ( CurlError == CURLE_OK)
170 CurlError = curl_easy_setopt(curl_easy_handle,CURLOPT_USERAGENT,&user_agent);
efbde536
BS
171
172 if ( !Proxy.empty() )
173 {
31af6a2e
BS
174 if ( CurlError == CURLE_OK)
175 CurlError = curl_easy_setopt(curl_easy_handle,CURLOPT_PROXY,Proxy.c_str());
176 if ( CurlError == CURLE_OK)
177 CurlError = curl_easy_setopt(curl_easy_handle,CURLOPT_PROXYPORT,ProxyPort);
178 }
179
180 if ( CurlError != CURLE_OK )
181 {
182 // Some options could not be set, so destroy the CURL handle.
183 Log->print_curl_error_init("Could not set CURL options properly.",CurlError);
ce70569b 184 curl_easy_cleanup(curl_easy_handle);
31af6a2e 185 curl_easy_handle = NULL;
efbde536
BS
186 }
187
188 return curl_easy_handle;
189}
190
191
192/**
31af6a2e
BS
193 * Test if the curl handle is initialized correctly.
194 * @return True if correctly initialized, false if something went wrong during initialization.
195 */
08a5a621 196bool HTTPHelper::is_initialized() const
31af6a2e
BS
197{
198 if ( (CurlError == CURLE_OK) && (CurlEasyHandle != NULL) )
199 {
200 return true;
201 }
202 return false;
203}
204
205
206/**
efbde536
BS
207 * Sets a url to the easy curl handle
208 * @param url The url to set.
c730deea 209 * @return CURLcode CURLE_OK if everything is right.
efbde536 210 */
c730deea 211CURLcode HTTPHelper::set_curl_url(const string& url)
efbde536 212{
c730deea 213 if ( (CurlEasyHandle != NULL) && (CurlError == CURLE_OK) )
31af6a2e 214 {
c730deea
BS
215 CurlError = curl_easy_setopt(CurlEasyHandle,CURLOPT_URL,url.c_str());
216 if ( CurlError != CURLE_OK )
217 {
218 // Some options could not be set, so destroy the CURL handle.
219 Log->print_curl_error_init("Could not set CURL URL properly.",CurlError);
220 curl_easy_cleanup(CurlEasyHandle);
221 CurlEasyHandle = NULL;
222 }
31af6a2e 223 }
c730deea 224 return CurlError;
efbde536
BS
225}
226
227
228/**
2dd2db3e
BS
229 * Sets HTTP AUTH parameters
230 * @param username The username for HTTP AUTH
231 * @param password The password for HTTP AUTH
c730deea 232 * @return CURLcode CURLE_OK if everything is right.
2dd2db3e 233 */
c730deea 234CURLcode HTTPHelper::set_curl_auth(const string& username, const string& password)
2dd2db3e 235{
c730deea 236 if ( (CurlEasyHandle != NULL) && (CurlError == CURLE_OK) )
31af6a2e 237 {
c730deea
BS
238 CurlError = curl_easy_setopt(CurlEasyHandle,CURLOPT_USERNAME,username.c_str());
239 if ( CurlError != CURLE_OK )
240 Log->print_curl_error_init("Could not set CURL username properly.",CurlError);
241 CurlError = curl_easy_setopt(CurlEasyHandle,CURLOPT_PASSWORD,password.c_str());
242 if ( CurlError != CURLE_OK )
243 Log->print_curl_error_init("Could not set CURL password properly.",CurlError);
31af6a2e 244 }
c730deea 245 return CurlError;
2dd2db3e
BS
246}
247
248
249/**
efbde536
BS
250 * Callback Function is called every time CURL is receiving data from HTTPS-Server and will copy all received Data to the given stream pointer
251 * @param inBuffer Pointer to input.
252 * @param size How many mem blocks are received
253 * @param nmemb size of each memblock
254 * @param outBuffer Pointer to output stream.
255 * @return The size received.
256 */
ce70569b 257size_t HTTPHelper::http_receive( const char *inBuffer, size_t size, size_t nmemb, string *outBuffer )
efbde536
BS
258{
259 outBuffer->append(inBuffer);
260 return (size*nmemb);
261}
262