diff --git a/Makefile b/Makefile index daf6743..9288dcc 100644 --- a/Makefile +++ b/Makefile @@ -46,10 +46,10 @@ httpd.o: httpd.c xs.h xs_io.h xs_json.h xs_socket.h xs_httpd.h xs_mime.h \ xs_time.h xs_openssl.h snac.h main.o: main.c xs.h xs_io.h xs_json.h snac.h mastoapi.o: mastoapi.c xs.h xs_openssl.h xs_json.h xs_io.h xs_time.h \ - xs_glob.h xs_set.h xs_random.h xs_httpd.h xs_mime.h snac.h + xs_glob.h xs_set.h xs_random.h xs_url.h xs_mime.h snac.h snac.o: snac.c xs.h xs_io.h xs_unicode.h xs_json.h xs_curl.h xs_openssl.h \ - xs_socket.h xs_httpd.h xs_mime.h xs_regex.h xs_set.h xs_time.h xs_glob.h \ - xs_random.h xs_match.h snac.h + xs_socket.h xs_url.h xs_httpd.h xs_mime.h xs_regex.h xs_set.h xs_time.h \ + xs_glob.h xs_random.h xs_match.h snac.h upgrade.o: upgrade.c xs.h xs_io.h xs_json.h xs_glob.h snac.h utils.o: utils.c xs.h xs_io.h xs_json.h xs_time.h xs_openssl.h \ xs_random.h snac.h diff --git a/mastoapi.c b/mastoapi.c index fbb6843..40ad12b 100644 --- a/mastoapi.c +++ b/mastoapi.c @@ -11,7 +11,7 @@ #include "xs_glob.h" #include "xs_set.h" #include "xs_random.h" -#include "xs_httpd.h" +#include "xs_url.h" #include "xs_mime.h" #include "snac.h" diff --git a/snac.c b/snac.c index 3f6d747..e396135 100644 --- a/snac.c +++ b/snac.c @@ -10,6 +10,7 @@ #include "xs_curl.h" #include "xs_openssl.h" #include "xs_socket.h" +#include "xs_url.h" #include "xs_httpd.h" #include "xs_mime.h" #include "xs_regex.h" diff --git a/xs_httpd.h b/xs_httpd.h index 0e60b64..644b3ed 100644 --- a/xs_httpd.h +++ b/xs_httpd.h @@ -4,200 +4,12 @@ #define _XS_HTTPD_H -xs_str *xs_url_dec(const char *str); -xs_dict *xs_url_vars(const char *str); xs_dict *xs_httpd_request(FILE *f, xs_str **payload, int *p_size); void xs_httpd_response(FILE *f, int status, xs_dict *headers, xs_str *body, int b_size); #ifdef XS_IMPLEMENTATION -xs_str *xs_url_dec(const char *str) -/* decodes an URL */ -{ - xs_str *s = xs_str_new(NULL); - - while (*str) { - if (*str == '%') { - int i; - - if (sscanf(str + 1, "%02x", &i) == 1) { - unsigned char uc = i; - - s = xs_append_m(s, (char *)&uc, 1); - str += 2; - } - } - else - if (*str == '+') - s = xs_append_m(s, " ", 1); - else - s = xs_append_m(s, str, 1); - - str++; - } - - return s; -} - - -xs_dict *xs_url_vars(const char *str) -/* parse url variables */ -{ - xs_dict *vars; - - vars = xs_dict_new(); - - if (str != NULL) { - /* split by arguments */ - xs *args = xs_split(str, "&"); - - xs_list *l; - xs_val *v; - - l = args; - while (xs_list_iter(&l, &v)) { - xs *kv = xs_split_n(v, "=", 2); - - if (xs_list_len(kv) == 2) { - const char *key = xs_list_get(kv, 0); - const char *pv = xs_dict_get(vars, key); - - if (!xs_is_null(pv)) { - /* there is a previous value: convert to a list and append */ - xs *vlist = NULL; - if (xs_type(pv) == XSTYPE_LIST) - vlist = xs_dup(pv); - else { - vlist = xs_list_new(); - vlist = xs_list_append(vlist, pv); - } - - vlist = xs_list_append(vlist, xs_list_get(kv, 1)); - vars = xs_dict_set(vars, key, vlist); - } - else { - /* ends with []? force to always be a list */ - if (xs_endswith(key, "[]")) { - xs *vlist = xs_list_new(); - vlist = xs_list_append(vlist, xs_list_get(kv, 1)); - vars = xs_dict_append(vars, key, vlist); - } - else - vars = xs_dict_append(vars, key, xs_list_get(kv, 1)); - } - } - } - } - - return vars; -} - - -xs_dict *_xs_multipart_form_data(xs_str *payload, int p_size, char *header) -/* parses a multipart/form-data payload */ -{ - xs *boundary = NULL; - int offset = 0; - int bsz; - char *p; - - /* build the boundary string */ - { - xs *l1 = xs_split(header, "="); - - if (xs_list_len(l1) != 2) - return NULL; - - boundary = xs_fmt("--%s", xs_list_get(l1, 1)); - } - - bsz = strlen(boundary); - - xs_dict *p_vars = xs_dict_new(); - - /* iterate searching the boundaries */ - while ((p = xs_memmem(payload + offset, p_size - offset, boundary, bsz)) != NULL) { - xs *s1 = NULL; - xs *l1 = NULL; - char *vn = NULL; - char *fn = NULL; - char *q; - int po, ps; - - /* final boundary? */ - p += bsz; - - if (p[0] == '-' && p[1] == '-') - break; - - /* skip the \r\n */ - p += 2; - - /* now on a Content-Disposition... line; get it */ - q = strchr(p, '\r'); - s1 = xs_realloc(NULL, q - p + 1); - memcpy(s1, p, q - p); - s1[q - p] = '\0'; - - /* move on (over a \r\n) */ - p = q; - - /* split by " like a primitive man */ - l1 = xs_split(s1, "\""); - - /* get the variable name */ - vn = xs_list_get(l1, 1); - - /* is it an attached file? */ - if (xs_list_len(l1) >= 4 && strcmp(xs_list_get(l1, 2), "; filename=") == 0) { - /* get the file name */ - fn = xs_list_get(l1, 3); - } - - /* find the start of the part content */ - if ((p = xs_memmem(p, p_size - (p - payload), "\r\n\r\n", 4)) == NULL) - break; - - p += 4; - - /* find the next boundary */ - if ((q = xs_memmem(p, p_size - (p - payload), boundary, bsz)) == NULL) - break; - - po = p - payload; - ps = q - p - 2; /* - 2 because the final \r\n */ - - /* is it a filename? */ - if (fn != NULL) { - /* p_var value is a list */ - xs *l1 = xs_list_new(); - xs *vpo = xs_number_new(po); - xs *vps = xs_number_new(ps); - - l1 = xs_list_append(l1, fn); - l1 = xs_list_append(l1, vpo); - l1 = xs_list_append(l1, vps); - - p_vars = xs_dict_append(p_vars, vn, l1); - } - else { - /* regular variable; just copy */ - xs *vc = xs_realloc(NULL, ps + 1); - memcpy(vc, payload + po, ps); - vc[ps] = '\0'; - - p_vars = xs_dict_append(p_vars, vn, vc); - } - - /* move on */ - offset = q - payload; - } - - return p_vars; -} - - xs_dict *xs_httpd_request(FILE *f, xs_str **payload, int *p_size) /* processes an httpd connection */ { @@ -267,7 +79,7 @@ xs_dict *xs_httpd_request(FILE *f, xs_str **payload, int *p_size) } else if (*payload && v && xs_startswith(v, "multipart/form-data")) { - p_vars = _xs_multipart_form_data(*payload, *p_size, v); + p_vars = xs_multipart_form_data(*payload, *p_size, v); } else p_vars = xs_dict_new(); diff --git a/xs_version.h b/xs_version.h index d0c2fb5..f5836c7 100644 --- a/xs_version.h +++ b/xs_version.h @@ -1 +1 @@ -/* b5831045cfd18e95352e5108cd47386510bf060d */ +/* 0b8d1591403ac07d83de975db6afa27e353f958c */