Skip to content

Instantly share code, notes, and snippets.

@opsJson
Last active June 23, 2022 01:59
Show Gist options
  • Select an option

  • Save opsJson/6200d1fe4666b6bfa6919677a05428b0 to your computer and use it in GitHub Desktop.

Select an option

Save opsJson/6200d1fe4666b6bfa6919677a05428b0 to your computer and use it in GitHub Desktop.
Easy cURL interface
#include <curl/curl.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
typedef struct EasyCurlString {
int size;
char **str;
} EasyCurlString;
static size_t counter(char *str)
{
size_t commas = 0;
int string = 0;
if (strcmp(str, "\"\"") == 0) return 0;
if (strcmp(str, "NULL") == 0) return 0;
if (*str == '0') return 0;
while (*str) {
if (*str == '"' && *(str - 1) != '\\') string = !string;
if (string == 0)
if (*str == ',') commas++;
str++;
}
return commas + 1;
}
static size_t _easycurl_callback(char *ptr, size_t size, size_t nitems, void *user_data)
{
EasyCurlString *r = (EasyCurlString*)user_data;
if (r->str == NULL) return size * nitems;
if (r->size == 0)
{
r->size = nitems * size;
*r->str = (char*)malloc(r->size + 1);
**r->str = 0;
}
else
{
int len = size * nitems + r->size;
char *aux = (char*)malloc(len + 1);
*aux = 0;
strcpy(aux, *r->str);
free(*r->str);
*r->str = aux;
r->size = len;
}
strcat(*r->str, ptr);
return size * nitems;
}
void GO(char *method, char *url, char *data, char **response, char **header, int *code, unsigned int count, ...)
{
unsigned int i;
va_list args;
CURL *curl;
CURLcode res;
struct curl_slist *chunk = NULL;
EasyCurlString r = {0}, h = {0};
curl_global_init(CURL_GLOBAL_ALL);
if ((curl = curl_easy_init()) == NULL)
{
fprintf(stderr, "CURL ERROR: curl_easy_init() failed.\n");
return;
}
va_start(args, count);
for (i=0; i<count; i++)
{
chunk = curl_slist_append(chunk, va_arg(args, char*));
}
if (data)
{
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
}
if (response)
{
r.str = response;
}
if (header)
{
h.str = header;
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, _easycurl_callback);
curl_easy_setopt(curl, CURLOPT_HEADERDATA, &h);
}
if (count)
{
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
}
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, method);
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_CAINFO , "cacert.pem");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, _easycurl_callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &r);
if ((res = curl_easy_perform(curl)) != CURLE_OK)
{
fprintf(stderr, "CURL ERROR: %s\n", curl_easy_strerror(res));
}
if (chunk) curl_slist_free_all(chunk);
if (code) curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, code);
curl_easy_cleanup(curl);
curl_global_cleanup();
}
#define GO(method, url, data, response_ptr, header_ptr, code_ptr, ...) \
GO(method, url, data, response_ptr, header_ptr, code_ptr, counter(#__VA_ARGS__), __VA_ARGS__)
/*///////////////////////////////////
Testing:
///////////////////////////////////*/
int main(void) {
int code;
char *body = NULL;
char *header = NULL;
GO("GET", "https://github.com", "", &body, &header, &code, "");
printf("code: %i\n\n", code);
if (header)
{
printf("%s\n", header);
free(header);
}
if (body)
{
printf("%s\n", body);
free(body);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment