#include #include #include #include #include "curl_utils.h" struct curl_buffer { char *data; size_t size; }; struct curl_slist *MakeHeaders(e6_auth_t auth) { struct curl_slist *headers = NULL; char auth_buf[256]; char base64_buf[128]; snprintf(auth_buf, sizeof(auth_buf), "%s:%s", auth.username, auth.api_key); EVP_EncodeBlock((unsigned char*)base64_buf, (unsigned char*)auth_buf, strlen(auth_buf)); memset(auth_buf, 0, sizeof(auth_buf)); snprintf(auth_buf, sizeof(base64_buf), "Authorization: Basic %s", base64_buf); headers = curl_slist_append(headers, auth_buf); char user_agent_buf[256]; snprintf(user_agent_buf, sizeof(user_agent_buf), "User-Agent: %s/%f (by %s on e621)", auth.project_name, auth.project_ver, auth.username); headers = curl_slist_append(headers, user_agent_buf); return headers; } static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userdata) { size_t total = size * nmemb; struct curl_buffer *mem = (struct curl_buffer *)userdata; char *ptr = realloc(mem->data, mem->size + total + 1); if (!ptr) return 0; mem->data = ptr; memcpy(&(mem->data[mem->size]), contents, total); mem->size += total; mem->data[mem->size] = '\0'; return total; } char *MakeUrl(char *path, curl_url_peram_t *perams, int peram_count) { char *url = (char *)malloc(E621_URL_BUF_SIZE); strncpy(url, E621_HOST, E621_URL_BUF_SIZE); strncat(url, path, strlen(path)); strcat(url, "?"); for (int i=0; i < peram_count; i++){ strncat(url, perams[i].key, strlen(perams[i].key)); strcat(url, "="); for (int j = 0; j < perams[i].count; j++) { strncat(url, perams[i].value[j], strlen(perams[i].value[j])); if (j != perams[i].count - 1) { strcat(url, "+"); } } if(i < peram_count-1){ strcat(url, "&"); } } return url; } char *CurlGet(char *path, curl_url_peram_t *perams, int peram_count, e6_auth_t auth) { CURL *curl = curl_easy_init(); CURLcode result; struct curl_buffer buffer; buffer.data = malloc(1); buffer.size = 0; if(!curl){ fprintf(stderr, "Failed to initialize CURL"); exit(EXIT_FAILURE); } char *url = MakeUrl(path, perams, peram_count); struct curl_slist *headers = MakeHeaders(auth); curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&buffer); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); result = curl_easy_perform(curl); if (result != CURLE_OK) { fprintf(stderr, "CURL error: %s", curl_easy_strerror(result)); return NULL; } return buffer.data; }