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");
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");
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");
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");
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_message(2, "%s-ing cURL to url=\"%s\" with body=\"%s\"\n", 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_message(2, "--> could not send cURL to url=%s, with error: %s\n", url, curl_easy_strerror(res));
109 curl_easy_cleanup(curl);
110 return NTS_ERR_FAILED;
115 curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_rc);
116 *response_code = http_rc;
120 *recv_data = response_data.response;
123 curl_easy_cleanup(curl);
127 int http_socket_request(const char *url, const char *sock_fname, const char *method, const char *send_data, int *response_code, char **recv_data) {
132 const char *send_data_good = send_data;
133 if(!send_data_good) {
137 CURL *curl = curl_easy_init();
139 log_error("could not initialize cURL");
140 return NTS_ERR_FAILED;
144 struct curl_slist *header = 0;
145 header = curl_slist_append(header, "Content-Type: application/json");
147 log_error("curl_slist_append failed");
148 curl_easy_cleanup(curl);
149 return NTS_ERR_FAILED;
152 header = curl_slist_append(header, "Accept: application/json");
154 log_error("curl_slist_append failed");
155 curl_easy_cleanup(curl);
156 return NTS_ERR_FAILED;
159 curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header);
160 curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 1L); //seconds timeout for a connection
161 curl_easy_setopt(curl, CURLOPT_TIMEOUT, 2L); //seconds timeout for an operation
162 curl_easy_setopt(curl, CURLOPT_FRESH_CONNECT, 1L);
163 curl_easy_setopt(curl, CURLOPT_VERBOSE, 0L);
165 curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, method);
166 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, send_data_good);
167 curl_easy_setopt(curl, CURLOPT_URL, url);
168 curl_easy_setopt(curl, CURLOPT_UNIX_SOCKET_PATH, sock_fname);
170 struct memory response_data = {0};
172 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_write_cb);
173 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&response_data);
176 log_message(2, "%s-ing cURL to url=\"%s\" with body=\"%s\"\n", method, url, send_data_good);
177 CURLcode res = curl_easy_perform(curl);
178 curl_slist_free_all(header);
180 if(res != CURLE_OK) {
181 log_message(2, "--> could not send cURL to url=%s, with error: %s\n", url, curl_easy_strerror(res));
182 curl_easy_cleanup(curl);
183 return NTS_ERR_FAILED;
188 curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_rc);
189 *response_code = http_rc;
193 *recv_data = response_data.response;
196 curl_easy_cleanup(curl);
200 static size_t curl_write_cb(void *data, size_t size, size_t nmemb, void *userp) {
201 size_t realsize = size * nmemb;
202 struct memory *mem = (struct memory *)userp;
204 char *ptr = realloc(mem->response, mem->size + realsize + 1);
206 log_error("realloc failed");
207 return 0; /* out of memory! */
211 memcpy(&(mem->response[mem->size]), data, realsize);
212 mem->size += realsize;
213 mem->response[mem->size] = 0;