permanent-satori-hole/src/curl_helper.c
2023-12-27 01:35:22 +01:00

164 lines
4.5 KiB
C

#include "curl_helper.h"
sat_curl_string_ptr sat_curl_string_alloc(void) {
sat_curl_string_ptr str = malloc(sizeof(sat_curl_string));
sat_curl_string_init(str);
return str;
}
void sat_curl_string_free(sat_curl_string_ptr str, bool freeArg) {
if(str == NULL) return;
if(str->str)
free(str->str);
if(freeArg)
free(str);
}
void sat_curl_string_init(sat_curl_string_ptr str) {
str->length = 0;
str->str = malloc(sizeof(char));
str->str[0] = '\0';
}
size_t sat_curl_string_write(char *ptr, size_t width, size_t count, sat_curl_string_ptr str) {
size_t newLength = width * count;
size_t totalLength = str->length + newLength;
str->str = realloc(str->str, totalLength + 1);
memcpy(str->str + str->length, ptr, newLength);
str->str[totalLength] = '\0';
str->length = totalLength;
return newLength;
}
#define SAT_CURL_URL_SCHEME_FREE (0x01)
#define SAT_CURL_URL_SCHEME_CURLFREE (0x02)
#define SAT_CURL_URL_HOST_FREE (0x04)
#define SAT_CURL_URL_HOST_CURLFREE (0x08)
#define SAT_CURL_URL_PORT_FREE (0x10)
#define SAT_CURL_URL_PORT_CURLFREE (0x20)
#define SAT_CURL_URL_PATH_FREE (0x40)
#define SAT_CURL_URL_PATH_CURLFREE (0x80)
sat_curl_url_ptr sat_curl_url_alloc(void) {
sat_curl_url_ptr url = malloc(sizeof(sat_curl_url));
memset(url, 0, sizeof(sat_curl_url));
return url;
}
void sat_curl_url_free(sat_curl_url_ptr url, bool freeArg) {
if(url == NULL) return;
if(url->scheme) {
if(url->flags & SAT_CURL_URL_SCHEME_CURLFREE)
curl_free(url->scheme);
else if(url->flags & SAT_CURL_URL_SCHEME_FREE)
free(url->scheme);
}
if(url->host) {
if(url->flags & SAT_CURL_URL_HOST_CURLFREE)
curl_free(url->host);
else if(url->flags & SAT_CURL_URL_HOST_FREE)
free(url->host);
}
if(url->port) {
if(url->flags & SAT_CURL_URL_PORT_CURLFREE)
curl_free(url->port);
else if(url->flags & SAT_CURL_URL_PORT_FREE)
free(url->port);
}
if(url->path) {
if(url->flags & SAT_CURL_URL_PATH_CURLFREE)
curl_free(url->path);
else if(url->flags & SAT_CURL_URL_PATH_FREE)
free(url->path);
}
if(freeArg)
free(url);
}
// winapi eat your heart out
int sat_curl_url_parse(sat_curl_url_ptr url, char *str, char *scheme, char *host, char *port, char *path, bool supplyDefaults) {
if(str == NULL) return -1;
if(strlen(str) < 3) return -2;
CURLU *curl = curl_url();
if(!curl) return -3;
bool skipScheme = false;
CURLUcode err = curl_url_set(curl, CURLUPART_URL, str, CURLU_NON_SUPPORT_SCHEME);
if(err == CURLUE_BAD_SCHEME) {
// compensating for browsers interpreting //host as no scheme but curl not
if(str[0] == '/' && str[1] == '/') {
str += 2;
skipScheme = true;
} else return err;
err = curl_url_set(curl, CURLUPART_URL, str, CURLU_DEFAULT_SCHEME | CURLU_NON_SUPPORT_SCHEME);
}
if(err)
return err;
if(skipScheme || curl_url_get(curl, CURLUPART_SCHEME, &url->scheme, 0))
url->scheme = scheme;
else
url->flags |= SAT_CURL_URL_SCHEME_CURLFREE;
if(curl_url_get(curl, CURLUPART_HOST, &url->host, 0))
url->host = host;
else
url->flags |= SAT_CURL_URL_HOST_CURLFREE;
if(curl_url_get(curl, CURLUPART_PORT, &url->port, 0))
url->port = port;
else
url->flags |= SAT_CURL_URL_PORT_CURLFREE;
if(curl_url_get(curl, CURLUPART_PATH, &url->path, 0))
path = path;
else
url->flags |= SAT_CURL_URL_PATH_CURLFREE;
curl_url_cleanup(curl);
if(supplyDefaults) {
if(url->port == NULL && url->scheme != NULL) {
if(!strcmp(url->scheme, "https") || !strcmp(url->scheme, "wss"))
url->port = "443";
else if(!strcmp(url->scheme, "http") || !strcmp(url->scheme, "ws"))
url->port = "80";
}
}
return 0;
}
void sat_curl_url_owns_scheme(sat_curl_url_ptr url) {
if(!(url->flags & SAT_CURL_URL_SCHEME_CURLFREE))
url->flags |= SAT_CURL_URL_SCHEME_FREE;
}
void sat_curl_url_owns_host(sat_curl_url_ptr url) {
if(!(url->flags & SAT_CURL_URL_HOST_CURLFREE))
url->flags |= SAT_CURL_URL_HOST_FREE;
}
void sat_curl_url_owns_port(sat_curl_url_ptr url) {
if(!(url->flags & SAT_CURL_URL_PORT_CURLFREE))
url->flags |= SAT_CURL_URL_PORT_FREE;
}
void sat_curl_url_owns_path(sat_curl_url_ptr url) {
if(!(url->flags & SAT_CURL_URL_PATH_CURLFREE))
url->flags |= SAT_CURL_URL_PATH_FREE;
}