diff options
-rw-r--r-- | include/api.h | 35 | ||||
-rw-r--r-- | net/api.c | 81 | ||||
-rw-r--r-- | net/net.c | 4 |
3 files changed, 99 insertions, 21 deletions
diff --git a/include/api.h b/include/api.h new file mode 100644 index 0000000..a70d447 --- /dev/null +++ b/include/api.h @@ -0,0 +1,35 @@ +#ifndef __API_H +#define __API_H +#define _Nullable + +typedef enum { + HTTP_GET, + HTTP_POST, + HTTP_PUT, + HTTP_DELETE, + HTTP_PATCH +} HTTPMethod; + +#ifndef __API_INTERNAL + +int http_request(HTTPMethod method, char *url, + struct curl_slist *_Nullable headers, char *writebuf, size_t bufsiz); + +int api_request(HTTPMethod method, char * url, + struct curl_slist *_Nullable headers, char *writebuf, size_t bufsiz); + +#endif + +#define http_get(...) http_request(HTTP_GET, __VA_ARGS__) +#define http_post(...) http_request(HTTP_POST, __VA_ARGS__) +#define http_put(...) http_request(HTTP_PUT, __VA_ARGS__) +#define http_delete(...) http_request(HTTP_DELETE, __VA_ARGS__) +#define http_patch(...) http_request(HTTP_PATCH, __VA_ARGS__) + +#define api_get(...) api_request(HTTP_GET, __VA_ARGS__) +#define api_post(...) api_request(HTTP_POST, __VA_ARGS__) +#define api_put(...) api_request(HTTP_PUT, __VA_ARGS__) +#define api_delete(...) api_request(HTTP_DELETE, __VA_ARGS__) +#define api_patch(...) api_request(HTTP_PATCH, __VA_ARGS__) + +#endif @@ -5,40 +5,83 @@ #include <curl/curl.h> +#define __API_INTERNAL +#include <api.h> +#include <log.h> + extern char *token; -int http_get(char *url) +int http_request(HTTPMethod method, char *url, + struct curl_slist *_Nullable headers, char *writebuf, size_t bufsiz) { - int pipefd[2]; - if(pipe(pipefd) < 0) - return -errno; + int inputpipe[2]; + int outputpipe[2]; + + if(pipe(inputpipe) < 0) + return -(errno << 8); + if(pipe(outputpipe) < 0) + return -(errno << 8); + + if(writebuf && bufsiz > 0) + write(inputpipe[1], writebuf, bufsiz); + close(inputpipe[1]); - FILE *write_end = fdopen(pipefd[1], "w"); + FILE *input_read = fdopen(inputpipe[0], "r"); + FILE *output_write = fdopen(outputpipe[1], "w"); - int ret = pipefd[0]; + int ret = outputpipe[0]; CURL *job = curl_easy_init(); - if(job == 0) { - close(pipefd[0]); - ret = -1; - goto close_writepipe; - } + if(job == NULL) + panic("api: curl_easy_init failed"); curl_easy_setopt(job, CURLOPT_URL, url); - curl_easy_setopt(job, CURLOPT_WRITEDATA, write_end); - curl_easy_setopt(job, CURLOPT_HTTPHEADER, - curl_slist_append(NULL, token)); + curl_easy_setopt(job, CURLOPT_READDATA, input_read); + curl_easy_setopt(job, CURLOPT_WRITEDATA, output_write); + char *requestmethod = "GET"; + switch(method) { + case HTTP_PATCH: + requestmethod = "PATCH"; + break; + case HTTP_DELETE: + requestmethod = "DELETE"; + break; + case HTTP_PUT: + requestmethod = "PUT"; + break; + case HTTP_POST: + requestmethod = "POST"; + break; + case HTTP_GET: /* fallthrough */ + default: + break; + } + curl_easy_setopt(job, CURLOPT_CUSTOMREQUEST, requestmethod); + if(headers) + curl_easy_setopt(job, CURLOPT_HTTPHEADER, headers); CURLcode res = curl_easy_perform(job); if(res > 0) { + close(outputpipe[0]); ret = -res; - close(pipefd[0]); - goto cleanup; } -cleanup: curl_easy_cleanup(job); -close_writepipe: - fclose(write_end); + fclose(input_read); + fclose(output_write); + return ret; +} + +int api_request(HTTPMethod method, char *url, + struct curl_slist *_Nullable headers, char *writebuf, size_t bufsiz) +{ + char *new_url = calloc((strlen("https://discord.com/api") + strlen(url) + 1), + sizeof(char)); + strcpy(new_url, "https://discord.com/api"); + strcat(new_url, url); + struct curl_slist *headers_auth = curl_slist_append(headers, token); + int ret = http_request(method, new_url, headers_auth, writebuf, bufsiz); + free(new_url); + curl_slist_free_all(headers_auth); return ret; } @@ -11,11 +11,11 @@ #include <cJSON.h> #include <curl/curl.h> +#include <api.h> #include <init.h> #include <log.h> #include <subsys.h> -extern int http_get(char *url); extern void ws_handle_event(cJSON *event); extern void ws_send_heartbeat(); CURL *ws_handle; @@ -149,7 +149,7 @@ void net_get_gateway_url() panic("net: wss not supported by libcurl"); /* fetch preferred url from discord */ - int fd = http_get("https://discord.com/api/gateway/bot"); + int fd = api_get("/gateway/bot", NULL, NULL, 0); if(fd < 0) { print(LOG_ERR "net: cannot get gateway url: %s", curl_easy_strerror(-fd)); goto assume; |