1 /*************************************************************************
3 * Copyright 2020 highstreet technologies GmbH and others
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 ***************************************************************************/
20 #include "http_client.h"
21 #include "utils/log_utils.h"
22 #include "utils/sys_utils.h"
28 #include <curl/curl.h>
35 static size_t curl_write_cb(void *data, size_t size, size_t nmemb, void *userp);
37 int http_request(const char *url, const char *username, const char* password, const char *method, const char *send_data, int *response_code, char **recv_data) {
41 const char *send_data_good = send_data;
46 CURL *curl = curl_easy_init();
48 log_error("could not initialize cURL\n");
49 return NTS_ERR_FAILED;
53 struct curl_slist *header = 0;
54 header = curl_slist_append(header, "Content-Type: application/json");
56 log_error("curl_slist_append failed\n");
57 curl_easy_cleanup(curl);
58 return NTS_ERR_FAILED;
61 header = curl_slist_append(header, "Accept: application/json");
63 log_error("curl_slist_append failed\n");
64 curl_easy_cleanup(curl);
65 return NTS_ERR_FAILED;
68 curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header);
69 curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 1L); //seconds timeout for a connection
70 curl_easy_setopt(curl, CURLOPT_TIMEOUT, 1L); //seconds timeout for an operation
71 curl_easy_setopt(curl, CURLOPT_FRESH_CONNECT, 1L);
72 curl_easy_setopt(curl, CURLOPT_VERBOSE, 0L);
74 // disable SSL verifications
75 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
76 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
77 curl_easy_setopt(curl, CURLOPT_PROXY_SSL_VERIFYPEER, 0L);
78 curl_easy_setopt(curl, CURLOPT_PROXY_SSL_VERIFYHOST, 0L);
80 curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, method);
81 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, send_data_good);
82 curl_easy_setopt(curl, CURLOPT_URL, url);
84 if((username) && (password)) {
85 char *credentials = 0;
86 asprintf(&credentials, "%s:%s", username, password);
87 if(credentials == 0) {
88 log_error("asprintf failed\n");
89 curl_slist_free_all(header);
90 curl_easy_cleanup(curl);
91 return NTS_ERR_FAILED;
93 curl_easy_setopt(curl, CURLOPT_USERPWD, credentials);
97 struct memory response_data = {0};
99 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_write_cb);
100 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&response_data);
103 log_add_verbose(2, "%s-ing cURL to url=\"%s\" with body=\"%s\"... ", method, url, send_data_good);
104 CURLcode res = curl_easy_perform(curl);
105 curl_slist_free_all(header);
107 if(res != CURLE_OK) {
108 log_add(2, "failed with error: %s\n", curl_easy_strerror(res));
109 curl_easy_cleanup(curl);
110 return NTS_ERR_FAILED;
113 log_add(2, "success\n");
118 curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_rc);
119 *response_code = http_rc;
123 *recv_data = response_data.response;
126 curl_easy_cleanup(curl);
130 int http_socket_request(const char *url, const char *sock_fname, const char *method, const char *send_data, int *response_code, char **recv_data) {
135 const char *send_data_good = send_data;
136 if(!send_data_good) {
140 CURL *curl = curl_easy_init();
142 log_error("could not initialize cURL\n");
143 return NTS_ERR_FAILED;
147 struct curl_slist *header = 0;
148 header = curl_slist_append(header, "Content-Type: application/json");
150 log_error("curl_slist_append failed\n");
151 curl_easy_cleanup(curl);
152 return NTS_ERR_FAILED;
155 header = curl_slist_append(header, "Accept: application/json");
157 log_error("curl_slist_append failed\n");
158 curl_easy_cleanup(curl);
159 return NTS_ERR_FAILED;
162 curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header);
163 curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30L); //seconds timeout for a connection
164 curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30L); //seconds timeout for an operation
165 curl_easy_setopt(curl, CURLOPT_FRESH_CONNECT, 1L);
166 curl_easy_setopt(curl, CURLOPT_VERBOSE, 0L);
168 curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, method);
169 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, send_data_good);
170 curl_easy_setopt(curl, CURLOPT_URL, url);
171 curl_easy_setopt(curl, CURLOPT_UNIX_SOCKET_PATH, sock_fname);
173 struct memory response_data = {0};
175 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_write_cb);
176 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&response_data);
179 log_add_verbose(2, "%s-ing cURL to url=\"%s\" with body=\"%s\"\n", method, url, send_data_good);
180 CURLcode res = curl_easy_perform(curl);
181 curl_slist_free_all(header);
183 if(res != CURLE_OK) {
184 log_add(2, "failed with error %s\n", curl_easy_strerror(res));
185 curl_easy_cleanup(curl);
186 return NTS_ERR_FAILED;
189 log_add(2, "success\n");
194 curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_rc);
195 *response_code = http_rc;
199 *recv_data = response_data.response;
202 curl_easy_cleanup(curl);
206 static size_t curl_write_cb(void *data, size_t size, size_t nmemb, void *userp) {
207 size_t realsize = size * nmemb;
208 struct memory *mem = (struct memory *)userp;
210 char *ptr = realloc(mem->response, mem->size + realsize + 1);
212 log_error("realloc failed\n");
213 return 0; /* out of memory! */
217 memcpy(&(mem->response[mem->size]), data, realsize);
218 mem->size += realsize;
219 mem->response[mem->size] = 0;