summaryrefslogtreecommitdiff
path: root/src/http.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/http.c')
-rw-r--r--src/http.c117
1 files changed, 110 insertions, 7 deletions
diff --git a/src/http.c b/src/http.c
index 35130af..a865f96 100644
--- a/src/http.c
+++ b/src/http.c
@@ -1,6 +1,8 @@
#define _POSIX_C_SOURCE 200809L
#include <stdlib.h>
#include <string.h>
+#include <pthread.h>
+#include <err.h>
#include <curl/curl.h>
#include "string-util.h"
#include "auth.h"
@@ -41,6 +43,7 @@ static size_t write_response(void *ptr, size_t size, size_t nmemb, void *stream)
char *get_request(const char *url)
{
+
CURL *curl = NULL;
CURLcode status;
struct curl_slist *headers = NULL;
@@ -58,8 +61,10 @@ char *get_request(const char *url)
struct write_result write_result = {.data = data, .pos = 0};
if (auth_token) {
- char *auth_header_val = malloc(strlen(AUTH_HEADER_STR_PREFIX) + strlen(auth_token) + 1);
- strlcpy(auth_header_val, AUTH_HEADER_STR_PREFIX, sizeof(auth_header_val));
+ char *auth_header_val =
+ malloc(strlen(AUTH_HEADER_STR_PREFIX) + strlen(auth_token) + 1);
+ strlcpy(auth_header_val, AUTH_HEADER_STR_PREFIX,
+ sizeof(auth_header_val));
strlcat(auth_header_val, auth_token, sizeof(auth_header_val));
headers = curl_slist_append(headers, auth_header_val);
}
@@ -71,7 +76,8 @@ char *get_request(const char *url)
status = curl_easy_perform(curl);
if (status != 0) {
- fprintf(stderr, "get_request(): unable to request data from %s: %s\n", url, curl_easy_strerror(status));
+ fprintf(stderr, "get_request(): unable to request data from %s: %s\n",
+ url, curl_easy_strerror(status));
goto error;
}
@@ -105,7 +111,6 @@ char *post_request(const char *url, char *post_data)
char *data = NULL;
long code;
-
curl = curl_easy_init();
if (!curl)
goto error;
@@ -117,8 +122,10 @@ char *post_request(const char *url, char *post_data)
struct write_result write_result = {.data = data, .pos = 0};
if (auth_token) {
- char *auth_header_val = malloc(strlen(AUTH_HEADER_STR_PREFIX) + strlen(auth_token) + 1);
- strlcpy(auth_header_val, AUTH_HEADER_STR_PREFIX, sizeof(auth_header_val));
+ char *auth_header_val =
+ malloc(strlen(AUTH_HEADER_STR_PREFIX) + strlen(auth_token) + 1);
+ strlcpy(auth_header_val, AUTH_HEADER_STR_PREFIX,
+ sizeof(auth_header_val));
strlcat(auth_header_val, auth_token, sizeof(auth_header_val));
headers = curl_slist_append(headers, auth_header_val);
}
@@ -135,7 +142,8 @@ char *post_request(const char *url, char *post_data)
status = curl_easy_perform(curl);
if (status != 0) {
- fprintf(stderr, "post_request(): unable to request data from %s: %s\n", url, curl_easy_strerror(status));
+ fprintf(stderr, "post_request(): unable to request data from %s: %s\n",
+ url, curl_easy_strerror(status));
goto error;
}
@@ -160,3 +168,98 @@ error:
curl_easy_cleanup(curl);
return NULL;
}
+
+struct post_request_arg {
+ char *url;
+ char *post_data;
+ void (*callback)(char *);
+};
+
+void *post_one_url(void *arg)
+{
+
+ struct post_request_arg *req_args = (struct post_request_arg *)arg;
+ CURL *curl = NULL;
+ CURLcode status;
+ struct curl_slist *headers = NULL;
+ char *data = NULL;
+ long code;
+
+ curl = curl_easy_init();
+ if (!curl)
+ goto error;
+
+ data = malloc(BUFFER_SIZE);
+ if (!data)
+ goto error;
+
+ struct write_result write_result = {.data = data, .pos = 0};
+
+ if (auth_token) {
+ char *auth_header_val =
+ malloc(strlen(AUTH_HEADER_STR_PREFIX) + strlen(auth_token) + 1);
+ strlcpy(auth_header_val, AUTH_HEADER_STR_PREFIX,
+ sizeof(auth_header_val));
+ strlcat(auth_header_val, auth_token, sizeof(auth_header_val));
+ headers = curl_slist_append(headers, auth_header_val);
+ }
+ if (req_args->post_data) {
+ char *content_type_header_val = "Content-Type: application/json";
+ headers = curl_slist_append(headers, content_type_header_val);
+ }
+
+ curl_easy_setopt(curl, CURLOPT_URL, req_args->url);
+ curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_response);
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, &write_result);
+ curl_easy_setopt(curl, CURLOPT_POSTFIELDS, req_args->post_data);
+
+ status = curl_easy_perform(curl);
+ if (status != 0) {
+ fprintf(stderr, "post_request(): unable to request data from %s: %s\n",
+ req_args->url, curl_easy_strerror(status));
+ goto error;
+ }
+
+ curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code);
+ if (code != 200) {
+ fprintf(stderr, "post_request(): server responded with code %ld\n", code);
+ goto error;
+ }
+
+ data[write_result.pos] = '\0';
+
+ curl_slist_free_all(headers);
+ curl_easy_cleanup(curl);
+
+ (*(req_args->callback))(data);
+ return NULL;
+
+error:
+ if (data)
+ free(data);
+ if (headers)
+ curl_slist_free_all(headers);
+ if (curl)
+ curl_easy_cleanup(curl);
+
+ (*(req_args->callback))(NULL);
+ return NULL;
+}
+
+int http_post_async(char *url, char *post_data, void (*callback)(char *))
+{
+ struct post_request_arg *arg;
+ pthread_t t;
+
+ arg = calloc(1, sizeof(struct post_request_arg));
+ if (!arg) {
+ err(1, "http_post_async(): calloc failed");
+ return -1;
+ }
+ arg->url = url;
+ arg->post_data = post_data;
+ arg->callback = callback;
+
+ return pthread_create(&t, NULL, post_one_url, arg);
+}