diff --git a/chttp.c b/chttp.c index 7c5465c..6d125db 100644 --- a/chttp.c +++ b/chttp.c @@ -3,7 +3,7 @@ // This file was generated automatically. Do not modify directly. // // Refer to the end of this file for the license -#ifndef HTTP_DONT_INCLUDE +#ifndef CHTTP_DONT_INCLUDE #include "chttp.h" #endif @@ -11,7 +11,7 @@ // src/basic.c //////////////////////////////////////////////////////////////////////////////////////// -bool http_streq(HTTP_String s1, HTTP_String s2) +bool chttp_streq(CHTTP_String s1, CHTTP_String s2) { if (s1.len != s2.len) return false; @@ -30,7 +30,7 @@ static char to_lower(char c) return c; } -bool http_streqcase(HTTP_String s1, HTTP_String s2) +bool chttp_streqcase(CHTTP_String s1, CHTTP_String s2) { if (s1.len != s2.len) return false; @@ -42,7 +42,7 @@ bool http_streqcase(HTTP_String s1, HTTP_String s2) return true; } -HTTP_String http_trim(HTTP_String s) +CHTTP_String chttp_trim(CHTTP_String s) { int i = 0; while (i < s.len && (s.ptr[i] == ' ' || s.ptr[i] == '\t')) @@ -66,7 +66,7 @@ static bool is_printable(char c) return c >= ' ' && c <= '~'; } -void print_bytes(HTTP_String prefix, HTTP_String src) +void print_bytes(CHTTP_String prefix, CHTTP_String src) { if (src.len == 0) return; @@ -107,16 +107,16 @@ void print_bytes(HTTP_String prefix, HTTP_String src) putc('\n', stream); } -char *http_strerror(int code) +char *chttp_strerror(int code) { switch (code) { - case HTTP_OK: return "No error"; - case HTTP_ERROR_UNSPECIFIED: return "Unspecified error"; - case HTTP_ERROR_OOM: return "Out of memory"; - case HTTP_ERROR_BADURL: return "Invalid URL"; - case HTTP_ERROR_REQLIMIT: return "Parallel request limit reached"; - case HTTP_ERROR_BADHANDLE: return "Invalid handle"; - case HTTP_ERROR_NOTLS: return "TLS support not built-in"; + case CHTTP_OK: return "No error"; + case CHTTP_ERROR_UNSPECIFIED: return "Unspecified error"; + case CHTTP_ERROR_OOM: return "Out of memory"; + case CHTTP_ERROR_BADURL: return "Invalid URL"; + case CHTTP_ERROR_REQLIMIT: return "Parallel request limit reached"; + case CHTTP_ERROR_BADHANDLE: return "Invalid handle"; + case CHTTP_ERROR_NOTLS: return "TLS support not built-in"; } return "???"; } @@ -254,7 +254,7 @@ consume_absolute_path(Scanner *s) // path-absolute = "/" [ segment-nz *( "/" segment ) ] // path-rootless = segment-nz *( "/" segment ) // path-empty = 0 -static int parse_path(Scanner *s, HTTP_String *path, int abempty) +static int parse_path(Scanner *s, CHTTP_String *path, int abempty) { int start = s->cur; @@ -301,7 +301,7 @@ static int parse_path(Scanner *s, HTTP_String *path, int abempty) // (do nothing) } - *path = (HTTP_String) { + *path = (CHTTP_String) { s->src + start, s->cur - start, }; @@ -341,7 +341,7 @@ static void invert_bytes(void *p, int len) } } -static int parse_ipv4(Scanner *s, HTTP_IPv4 *ipv4) +static int parse_ipv4(Scanner *s, CHTTP_IPv4 *ipv4) { unsigned int out = 0; int i = 0; @@ -415,7 +415,7 @@ static int parse_ipv6_comp(Scanner *s) return (int) buf; } -static int parse_ipv6(Scanner *s, HTTP_IPv6 *ipv6) +static int parse_ipv6(Scanner *s, CHTTP_IPv6 *ipv6) { unsigned short head[8]; unsigned short tail[8]; @@ -485,7 +485,7 @@ static int is_regname(char c) return is_unreserved(c) || is_sub_delim(c); } -static int parse_regname(Scanner *s, HTTP_String *regname) +static int parse_regname(Scanner *s, CHTTP_String *regname) { if (s->cur == s->len || !is_regname(s->src[s->cur])) return -1; @@ -498,7 +498,7 @@ static int parse_regname(Scanner *s, HTTP_String *regname) return 0; } -static int parse_host(Scanner *s, HTTP_Host *host) +static int parse_host(Scanner *s, CHTTP_Host *host) { int ret; if (s->cur < s->len && s->src[s->cur] == '[') { @@ -506,13 +506,13 @@ static int parse_host(Scanner *s, HTTP_Host *host) s->cur++; int start = s->cur; - HTTP_IPv6 ipv6; + CHTTP_IPv6 ipv6; ret = parse_ipv6(s, &ipv6); if (ret < 0) return ret; - host->mode = HTTP_HOST_MODE_IPV6; + host->mode = CHTTP_HOST_MODE_IPV6; host->ipv6 = ipv6; - host->text = (HTTP_String) { s->src + start, s->cur - start }; + host->text = (CHTTP_String) { s->src + start, s->cur - start }; if (s->cur == s->len || s->src[s->cur] != ']') return -1; @@ -521,22 +521,22 @@ static int parse_host(Scanner *s, HTTP_Host *host) } else { int start = s->cur; - HTTP_IPv4 ipv4; + CHTTP_IPv4 ipv4; ret = parse_ipv4(s, &ipv4); if (ret >= 0) { - host->mode = HTTP_HOST_MODE_IPV4; + host->mode = CHTTP_HOST_MODE_IPV4; host->ipv4 = ipv4; } else { s->cur = start; - HTTP_String regname; + CHTTP_String regname; ret = parse_regname(s, ®name); if (ret < 0) return ret; - host->mode = HTTP_HOST_MODE_NAME; + host->mode = CHTTP_HOST_MODE_NAME; host->name = regname; } - host->text = (HTTP_String) { s->src + start, s->cur - start }; + host->text = (CHTTP_String) { s->src + start, s->cur - start }; } return 0; @@ -565,16 +565,16 @@ static int is_userinfo(char c) } // authority = [ userinfo "@" ] host [ ":" port ] -static int parse_authority(Scanner *s, HTTP_Authority *authority) +static int parse_authority(Scanner *s, CHTTP_Authority *authority) { - HTTP_String userinfo; + CHTTP_String userinfo; { int start = s->cur; CONSUME_OPTIONAL_SEQUENCE(s, is_userinfo); if (s->cur < s->len && s->src[s->cur] == '@') { - userinfo = (HTTP_String) { + userinfo = (CHTTP_String) { s->src + start, s->cur - start }; @@ -582,11 +582,11 @@ static int parse_authority(Scanner *s, HTTP_Authority *authority) } else { // Rollback s->cur = start; - userinfo = (HTTP_String) {NULL, 0}; + userinfo = (CHTTP_String) {NULL, 0}; } } - HTTP_Host host; + CHTTP_Host host; { int ret = parse_host(s, &host); if (ret < 0) @@ -613,9 +613,9 @@ static int parse_authority(Scanner *s, HTTP_Authority *authority) return 0; } -static int parse_uri(Scanner *s, HTTP_URL *url, int allow_fragment) +static int parse_uri(Scanner *s, CHTTP_URL *url, int allow_fragment) { - HTTP_String scheme = {0}; + CHTTP_String scheme = {0}; { int start = s->cur; if (s->cur == s->len || !is_scheme_head(s->src[s->cur])) @@ -623,7 +623,7 @@ static int parse_uri(Scanner *s, HTTP_URL *url, int allow_fragment) do s->cur++; while (s->cur < s->len && is_scheme_body(s->src[s->cur])); - scheme = (HTTP_String) { + scheme = (CHTTP_String) { s->src + start, s->cur - start, }; @@ -634,7 +634,7 @@ static int parse_uri(Scanner *s, HTTP_URL *url, int allow_fragment) } int abempty = 0; - HTTP_Authority authority = {0}; + CHTTP_Authority authority = {0}; if (s->len - s->cur > 1 && s->src[s->cur+0] == '/' && s->src[s->cur+1] == '/') { @@ -647,29 +647,29 @@ static int parse_uri(Scanner *s, HTTP_URL *url, int allow_fragment) abempty = 1; } - HTTP_String path; + CHTTP_String path; int ret = parse_path(s, &path, abempty); if (ret < 0) return ret; - HTTP_String query = {0}; + CHTTP_String query = {0}; if (s->cur < s->len && s->src[s->cur] == '?') { int start = s->cur; do s->cur++; while (s->cur < s->len && is_query(s->src[s->cur])); - query = (HTTP_String) { + query = (CHTTP_String) { s->src + start, s->cur - start, }; } - HTTP_String fragment = {0}; + CHTTP_String fragment = {0}; if (allow_fragment && s->cur < s->len && s->src[s->cur] == '#') { int start = s->cur; do s->cur++; while (s->cur < s->len && is_fragment(s->src[s->cur])); - fragment = (HTTP_String) { + fragment = (CHTTP_String) { s->src + start, s->cur - start, }; @@ -688,7 +688,7 @@ static int parse_uri(Scanner *s, HTTP_URL *url, int allow_fragment) // host = IP-literal / IPv4address / reg-name // IP-literal = "[" ( IPv6address / IPvFuture ) "]" // reg-name = *( unreserved / pct-encoded / sub-delims ) -static int parse_authority_form(Scanner *s, HTTP_Host *host, int *port) +static int parse_authority_form(Scanner *s, CHTTP_Host *host, int *port) { int ret; @@ -717,23 +717,23 @@ static int parse_authority_form(Scanner *s, HTTP_Host *host, int *port) return 0; } -static int parse_origin_form(Scanner *s, HTTP_String *path, HTTP_String *query) +static int parse_origin_form(Scanner *s, CHTTP_String *path, CHTTP_String *query) { int ret, start; start = s->cur; ret = consume_absolute_path(s); if (ret < 0) return ret; - *path = (HTTP_String) { s->src + start, s->cur - start }; + *path = (CHTTP_String) { s->src + start, s->cur - start }; if (s->cur < s->len && s->src[s->cur] == '?') { start = s->cur; do s->cur++; while (s->cur < s->len && is_query(s->src[s->cur])); - *query = (HTTP_String) { s->src + start, s->cur - start }; + *query = (CHTTP_String) { s->src + start, s->cur - start }; } else - *query = (HTTP_String) { NULL, 0 }; + *query = (CHTTP_String) { NULL, 0 }; return 0; } @@ -748,11 +748,11 @@ static int parse_asterisk_form(Scanner *s) return 0; } -static int parse_request_target(Scanner *s, HTTP_URL *url) +static int parse_request_target(Scanner *s, CHTTP_URL *url) { int ret; - memset(url, 0, sizeof(HTTP_URL)); + memset(url, 0, sizeof(CHTTP_URL)); // asterisk-form ret = parse_asterisk_form(s); @@ -770,7 +770,7 @@ static int parse_request_target(Scanner *s, HTTP_URL *url) return -1; } -bool consume_str(Scanner *scan, HTTP_String token) +bool consume_str(Scanner *scan, CHTTP_String token) { assert(token.len > 0); @@ -790,10 +790,10 @@ static int is_header_body(char c) return is_vchar(c) || c == ' ' || c == '\t'; } -static int parse_headers(Scanner *s, HTTP_Header *headers, int max_headers) +static int parse_headers(Scanner *s, CHTTP_Header *headers, int max_headers) { int num_headers = 0; - while (!consume_str(s, HTTP_STR("\r\n"))) { + while (!consume_str(s, CHTTP_STR("\r\n"))) { // RFC 9112: // field-line = field-name ":" OWS field-value OWS @@ -813,7 +813,7 @@ static int parse_headers(Scanner *s, HTTP_Header *headers, int max_headers) do s->cur++; while (s->cur < s->len && is_tchar(s->src[s->cur])); - HTTP_String name = { s->src + start, s->cur - start }; + CHTTP_String name = { s->src + start, s->cur - start }; if (s->cur == s->len || s->src[s->cur] != ':') return -1; // ERROR @@ -821,13 +821,13 @@ static int parse_headers(Scanner *s, HTTP_Header *headers, int max_headers) start = s->cur; CONSUME_OPTIONAL_SEQUENCE(s, is_header_body); - HTTP_String body = { s->src + start, s->cur - start }; - body = http_trim(body); + CHTTP_String body = { s->src + start, s->cur - start }; + body = chttp_trim(body); if (num_headers < max_headers) - headers[num_headers++] = (HTTP_Header) { name, body }; + headers[num_headers++] = (CHTTP_Header) { name, body }; - if (!consume_str(s, HTTP_STR("\r\n"))) { + if (!consume_str(s, CHTTP_STR("\r\n"))) { return -1; } } @@ -848,7 +848,7 @@ static bool is_space(char c) } static int -parse_transfer_encoding(HTTP_String src, TransferEncodingOption *dst, int max) +parse_transfer_encoding(CHTTP_String src, TransferEncodingOption *dst, int max) { Scanner s = { src.ptr, src.len, 0 }; @@ -859,10 +859,10 @@ parse_transfer_encoding(HTTP_String src, TransferEncodingOption *dst, int max) TransferEncodingOption opt; if (0) {} - else if (consume_str(&s, HTTP_STR("chunked"))) opt = TRANSFER_ENCODING_OPTION_CHUNKED; - else if (consume_str(&s, HTTP_STR("compress"))) opt = TRANSFER_ENCODING_OPTION_COMPRESS; - else if (consume_str(&s, HTTP_STR("deflate"))) opt = TRANSFER_ENCODING_OPTION_DEFLATE; - else if (consume_str(&s, HTTP_STR("gzip"))) opt = TRANSFER_ENCODING_OPTION_GZIP; + else if (consume_str(&s, CHTTP_STR("chunked"))) opt = TRANSFER_ENCODING_OPTION_CHUNKED; + else if (consume_str(&s, CHTTP_STR("compress"))) opt = TRANSFER_ENCODING_OPTION_COMPRESS; + else if (consume_str(&s, CHTTP_STR("deflate"))) opt = TRANSFER_ENCODING_OPTION_DEFLATE; + else if (consume_str(&s, CHTTP_STR("gzip"))) opt = TRANSFER_ENCODING_OPTION_GZIP; else return -1; // Invalid option if (num == max) @@ -904,8 +904,8 @@ parse_content_length(const char *src, int len, uint64_t *out) } static int parse_body(Scanner *s, - HTTP_Header *headers, int num_headers, - HTTP_String *body, bool body_expected) + CHTTP_Header *headers, int num_headers, + CHTTP_String *body, bool body_expected) { // RFC 9112 section 6: @@ -913,7 +913,7 @@ static int parse_body(Scanner *s, // Transfer-Encoding header field. Request message framing is independent of method // semantics. - int header_index = http_find_header(headers, num_headers, HTTP_STR("Transfer-Encoding")); + int header_index = chttp_find_header(headers, num_headers, CHTTP_STR("Transfer-Encoding")); if (header_index != -1) { // RFC 9112 section 6.1: @@ -921,10 +921,10 @@ static int parse_body(Scanner *s, // or process such a request in accordance with the Transfer-Encoding alone. Regardless, // the server MUST close the connection after responding to such a request to avoid the // potential attacks. - if (http_find_header(headers, num_headers, HTTP_STR("Content-Length")) != -1) + if (chttp_find_header(headers, num_headers, CHTTP_STR("Content-Length")) != -1) return -1; - HTTP_String value = headers[header_index].value; + CHTTP_String value = headers[header_index].value; // RFC 9112 section 6.1: // If any transfer coding other than chunked is applied to a request's content, the @@ -934,14 +934,14 @@ static int parse_body(Scanner *s, // coding or terminate the message by closing the connection. TransferEncodingOption opts[8]; - int num = parse_transfer_encoding(value, opts, HTTP_COUNT(opts)); + int num = parse_transfer_encoding(value, opts, CHTTP_COUNT(opts)); if (num != 1 || opts[0] != TRANSFER_ENCODING_OPTION_CHUNKED) return -1; - HTTP_String chunks_maybe[128]; - HTTP_String *chunks = chunks_maybe; + CHTTP_String chunks_maybe[128]; + CHTTP_String *chunks = chunks_maybe; int num_chunks = 0; - int max_chunks = HTTP_COUNT(chunks_maybe); + int max_chunks = CHTTP_COUNT(chunks_maybe); #define FREE_CHUNK_LIST \ if (chunks != chunks_maybe) \ @@ -1031,7 +1031,7 @@ static int parse_body(Scanner *s, max_chunks *= 2; - HTTP_String *new_chunks = malloc(max_chunks * sizeof(HTTP_String)); + CHTTP_String *new_chunks = malloc(max_chunks * sizeof(CHTTP_String)); if (new_chunks == NULL) { if (chunks != chunks_maybe) free(chunks); @@ -1046,7 +1046,7 @@ static int parse_body(Scanner *s, chunks = new_chunks; } - chunks[num_chunks++] = (HTTP_String) { chunk_ptr, chunk_len }; + chunks[num_chunks++] = (CHTTP_String) { chunk_ptr, chunk_len }; } char *content_ptr = content_start; @@ -1055,7 +1055,7 @@ static int parse_body(Scanner *s, content_ptr += chunks[i].len; } - *body = (HTTP_String) { + *body = (CHTTP_String) { content_start, content_ptr - content_start }; @@ -1070,11 +1070,11 @@ static int parse_body(Scanner *s, // If a valid Content-Length header field is present without Transfer-Encoding, // its decimal value defines the expected message body length in octets. - header_index = http_find_header(headers, num_headers, HTTP_STR("Content-Length")); + header_index = chttp_find_header(headers, num_headers, CHTTP_STR("Content-Length")); if (header_index != -1) { // Have Content-Length - HTTP_String value = headers[header_index].value; + CHTTP_String value = headers[header_index].value; uint64_t tmp; if (parse_content_length(value.ptr, value.len, &tmp) < 0) @@ -1086,7 +1086,7 @@ static int parse_body(Scanner *s, if (len > s->len - s->cur) return 0; // Incomplete request - *body = (HTTP_String) { s->src + s->cur, len }; + *body = (CHTTP_String) { s->src + s->cur, len }; s->cur += len; return 1; @@ -1095,7 +1095,7 @@ static int parse_body(Scanner *s, // No Content-Length or Transfer-Encoding if (body_expected) return -1; - *body = (HTTP_String) { NULL, 0 }; + *body = (CHTTP_String) { NULL, 0 }; return 1; } @@ -1113,7 +1113,7 @@ static int contains_head(char *src, int len) return 0; } -static int parse_request(Scanner *s, HTTP_Request *req) +static int parse_request(Scanner *s, CHTTP_Request *req) { if (!contains_head(s->src + s->cur, s->len - s->cur)) return 0; @@ -1121,15 +1121,15 @@ static int parse_request(Scanner *s, HTTP_Request *req) req->secure = false; if (0) {} - else if (consume_str(s, HTTP_STR("GET "))) req->method = HTTP_METHOD_GET; - else if (consume_str(s, HTTP_STR("POST "))) req->method = HTTP_METHOD_POST; - else if (consume_str(s, HTTP_STR("PUT "))) req->method = HTTP_METHOD_PUT; - else if (consume_str(s, HTTP_STR("HEAD "))) req->method = HTTP_METHOD_HEAD; - else if (consume_str(s, HTTP_STR("DELETE "))) req->method = HTTP_METHOD_DELETE; - else if (consume_str(s, HTTP_STR("CONNECT "))) req->method = HTTP_METHOD_CONNECT; - else if (consume_str(s, HTTP_STR("OPTIONS "))) req->method = HTTP_METHOD_OPTIONS; - else if (consume_str(s, HTTP_STR("TRACE "))) req->method = HTTP_METHOD_TRACE; - else if (consume_str(s, HTTP_STR("PATCH "))) req->method = HTTP_METHOD_PATCH; + else if (consume_str(s, CHTTP_STR("GET "))) req->method = CHTTP_METHOD_GET; + else if (consume_str(s, CHTTP_STR("POST "))) req->method = CHTTP_METHOD_POST; + else if (consume_str(s, CHTTP_STR("PUT "))) req->method = CHTTP_METHOD_PUT; + else if (consume_str(s, CHTTP_STR("HEAD "))) req->method = CHTTP_METHOD_HEAD; + else if (consume_str(s, CHTTP_STR("DELETE "))) req->method = CHTTP_METHOD_DELETE; + else if (consume_str(s, CHTTP_STR("CONNECT "))) req->method = CHTTP_METHOD_CONNECT; + else if (consume_str(s, CHTTP_STR("OPTIONS "))) req->method = CHTTP_METHOD_OPTIONS; + else if (consume_str(s, CHTTP_STR("TRACE "))) req->method = CHTTP_METHOD_TRACE; + else if (consume_str(s, CHTTP_STR("PATCH "))) req->method = CHTTP_METHOD_PATCH; else return -1; { @@ -1147,47 +1147,47 @@ static int parse_request(Scanner *s, HTTP_Request *req) s->cur = s2.cur; } - if (consume_str(s, HTTP_STR(" HTTP/1.1\r\n"))) { + if (consume_str(s, CHTTP_STR(" HTTP/1.1\r\n"))) { req->minor = 1; - } else if (consume_str(s, HTTP_STR(" HTTP/1.0\r\n")) || consume_str(s, HTTP_STR(" HTTP/1\r\n"))) { + } else if (consume_str(s, CHTTP_STR(" HTTP/1.0\r\n")) || consume_str(s, CHTTP_STR(" HTTP/1\r\n"))) { req->minor = 0; } else { return -1; } - int num_headers = parse_headers(s, req->headers, HTTP_MAX_HEADERS); + int num_headers = parse_headers(s, req->headers, CHTTP_MAX_HEADERS); if (num_headers < 0) return num_headers; req->num_headers = num_headers; // Request methods that typically don't have a body bool body_expected = true; - if (req->method == HTTP_METHOD_GET || - req->method == HTTP_METHOD_HEAD || - req->method == HTTP_METHOD_DELETE || - req->method == HTTP_METHOD_OPTIONS || - req->method == HTTP_METHOD_TRACE) + if (req->method == CHTTP_METHOD_GET || + req->method == CHTTP_METHOD_HEAD || + req->method == CHTTP_METHOD_DELETE || + req->method == CHTTP_METHOD_OPTIONS || + req->method == CHTTP_METHOD_TRACE) body_expected = false; return parse_body(s, req->headers, req->num_headers, &req->body, body_expected); } -int http_find_header(HTTP_Header *headers, int num_headers, HTTP_String name) +int chttp_find_header(CHTTP_Header *headers, int num_headers, CHTTP_String name) { for (int i = 0; i < num_headers; i++) - if (http_streqcase(name, headers[i].name)) + if (chttp_streqcase(name, headers[i].name)) return i; return -1; } -static int parse_response(Scanner *s, HTTP_Response *res) +static int parse_response(Scanner *s, CHTTP_Response *res) { if (!contains_head(s->src + s->cur, s->len - s->cur)) return 0; - if (consume_str(s, HTTP_STR("HTTP/1.1 "))) { + if (consume_str(s, CHTTP_STR("HTTP/1.1 "))) { res->minor = 1; - } else if (consume_str(s, HTTP_STR("HTTP/1.0 ")) || consume_str(s, HTTP_STR("HTTP/1 "))) { + } else if (consume_str(s, CHTTP_STR("HTTP/1.0 ")) || consume_str(s, CHTTP_STR("HTTP/1 "))) { res->minor = 0; } else { return -1; @@ -1219,7 +1219,7 @@ static int parse_response(Scanner *s, HTTP_Response *res) return -1; s->cur += 2; - int num_headers = parse_headers(s, res->headers, HTTP_MAX_HEADERS); + int num_headers = parse_headers(s, res->headers, CHTTP_MAX_HEADERS); if (num_headers < 0) return num_headers; res->num_headers = num_headers; @@ -1239,7 +1239,7 @@ static int parse_response(Scanner *s, HTTP_Response *res) return parse_body(s, res->headers, res->num_headers, &res->body, body_expected); } -int http_parse_ipv4(char *src, int len, HTTP_IPv4 *ipv4) +int chttp_parse_ipv4(char *src, int len, CHTTP_IPv4 *ipv4) { Scanner s = {src, len, 0}; int ret = parse_ipv4(&s, ipv4); @@ -1247,7 +1247,7 @@ int http_parse_ipv4(char *src, int len, HTTP_IPv4 *ipv4) return s.cur; } -int http_parse_ipv6(char *src, int len, HTTP_IPv6 *ipv6) +int chttp_parse_ipv6(char *src, int len, CHTTP_IPv6 *ipv6) { Scanner s = {src, len, 0}; int ret = parse_ipv6(&s, ipv6); @@ -1255,7 +1255,7 @@ int http_parse_ipv6(char *src, int len, HTTP_IPv6 *ipv6) return s.cur; } -int http_parse_url(char *src, int len, HTTP_URL *url) +int chttp_parse_url(char *src, int len, CHTTP_URL *url) { Scanner s = {src, len, 0}; int ret = parse_uri(&s, url, 1); @@ -1264,7 +1264,7 @@ int http_parse_url(char *src, int len, HTTP_URL *url) return ret; } -int http_parse_request(char *src, int len, HTTP_Request *req) +int chttp_parse_request(char *src, int len, CHTTP_Request *req) { Scanner s = {src, len, 0}; int ret = parse_request(&s, req); @@ -1273,7 +1273,7 @@ int http_parse_request(char *src, int len, HTTP_Request *req) return ret; } -int http_parse_response(char *src, int len, HTTP_Response *res) +int chttp_parse_response(char *src, int len, CHTTP_Response *res) { Scanner s = {src, len, 0}; int ret = parse_response(&s, res); @@ -1282,14 +1282,14 @@ int http_parse_response(char *src, int len, HTTP_Response *res) return ret; } -HTTP_String http_get_cookie(HTTP_Request *req, HTTP_String name) +CHTTP_String chttp_get_cookie(CHTTP_Request *req, CHTTP_String name) { // Simple cookie parsing - does not handle quoted values or special characters // See RFC 6265 for full cookie specification for (int i = 0; i < req->num_headers; i++) { - if (!http_streqcase(req->headers[i].name, HTTP_STR("Cookie"))) + if (!chttp_streqcase(req->headers[i].name, CHTTP_STR("Cookie"))) continue; char *src = req->headers[i].value.ptr; @@ -1307,7 +1307,7 @@ HTTP_String http_get_cookie(HTTP_Request *req, HTTP_String name) while (cur < len && src[cur] != '=') cur++; - HTTP_String cookie_name = { src + off, cur - off }; + CHTTP_String cookie_name = { src + off, cur - off }; if (cur == len) break; @@ -1317,9 +1317,9 @@ HTTP_String http_get_cookie(HTTP_Request *req, HTTP_String name) while (cur < len && src[cur] != ';') cur++; - HTTP_String cookie_value = { src + off, cur - off }; + CHTTP_String cookie_value = { src + off, cur - off }; - if (http_streq(name, cookie_name)) + if (chttp_streq(name, cookie_name)) return cookie_value; if (cur == len) @@ -1328,10 +1328,10 @@ HTTP_String http_get_cookie(HTTP_Request *req, HTTP_String name) } } - return HTTP_STR(""); + return CHTTP_STR(""); } -HTTP_String http_get_param(HTTP_String body, HTTP_String str, char *mem, int cap) +CHTTP_String chttp_get_param(CHTTP_String body, CHTTP_String str, char *mem, int cap) { // This is just a best-effort implementation @@ -1344,29 +1344,29 @@ HTTP_String http_get_param(HTTP_String body, HTTP_String str, char *mem, int cap while (cur < len) { - HTTP_String name; + CHTTP_String name; { int off = cur; while (cur < len && src[cur] != '=' && src[cur] != '&') cur++; - name = (HTTP_String) { src + off, cur - off }; + name = (CHTTP_String) { src + off, cur - off }; } - HTTP_String body = HTTP_STR(""); + CHTTP_String body = CHTTP_STR(""); if (cur < len) { cur++; if (src[cur-1] == '=') { int off = cur; while (cur < len && src[cur] != '&') cur++; - body = (HTTP_String) { src + off, cur - off }; + body = (CHTTP_String) { src + off, cur - off }; if (cur < len) cur++; } } - if (http_streq(str, name)) { + if (chttp_streq(str, name)) { bool percent_encoded = false; for (int i = 0; i < body.len; i++) @@ -1379,9 +1379,9 @@ HTTP_String http_get_param(HTTP_String body, HTTP_String str, char *mem, int cap return body; if (body.len > cap) - return (HTTP_String) { NULL, 0 }; + return (CHTTP_String) { NULL, 0 }; - HTTP_String decoded = { mem, 0 }; + CHTTP_String decoded = { mem, 0 }; for (int i = 0; i < body.len; i++) { char c = body.ptr[i]; @@ -1392,7 +1392,7 @@ HTTP_String http_get_param(HTTP_String body, HTTP_String str, char *mem, int cap if (body.len - i < 3 || !is_hex_digit(body.ptr[i+1]) || !is_hex_digit(body.ptr[i+2])) - return (HTTP_String) { NULL, 0 }; + return (CHTTP_String) { NULL, 0 }; int h = hex_digit_to_int(body.ptr[i+1]); int l = hex_digit_to_int(body.ptr[i+2]); @@ -1409,13 +1409,13 @@ HTTP_String http_get_param(HTTP_String body, HTTP_String str, char *mem, int cap } } - return HTTP_STR(""); + return CHTTP_STR(""); } -int http_get_param_i(HTTP_String body, HTTP_String str) +int chttp_get_param_i(CHTTP_String body, CHTTP_String str) { char buf[128]; - HTTP_String out = http_get_param(body, str, buf, (int) sizeof(buf)); + CHTTP_String out = chttp_get_param(body, str, buf, (int) sizeof(buf)); if (out.len == 0 || !is_digit(out.ptr[0])) return -1; @@ -1431,38 +1431,38 @@ int http_get_param_i(HTTP_String body, HTTP_String str) return res; } -bool http_match_host(HTTP_Request *req, HTTP_String domain, int port) +bool chttp_match_host(CHTTP_Request *req, CHTTP_String domain, int port) { - int idx = http_find_header(req->headers, req->num_headers, HTTP_STR("Host")); + int idx = chttp_find_header(req->headers, req->num_headers, CHTTP_STR("Host")); assert(idx != -1); // Requests without the host header are always rejected char tmp[1<<8]; if (port > -1 && port != 80) { int ret = snprintf(tmp, sizeof(tmp), "%.*s:%d", domain.len, domain.ptr, port); assert(ret > 0); - domain = (HTTP_String) { tmp, ret }; + domain = (CHTTP_String) { tmp, ret }; } - HTTP_String host = req->headers[idx].value; - return http_streqcase(host, domain); + CHTTP_String host = req->headers[idx].value; + return chttp_streqcase(host, domain); } // , :: GMT -static int parse_date(Scanner *s, HTTP_Date *out) +static int parse_date(Scanner *s, CHTTP_Date *out) { - struct { HTTP_String str; HTTP_WeekDay val; } week_day_table[] = { - { HTTP_STR("Mon, "), HTTP_WEEKDAY_MON }, - { HTTP_STR("Tue, "), HTTP_WEEKDAY_TUE }, - { HTTP_STR("Wed, "), HTTP_WEEKDAY_WED }, - { HTTP_STR("Thu, "), HTTP_WEEKDAY_THU }, - { HTTP_STR("Fri, "), HTTP_WEEKDAY_FRI }, - { HTTP_STR("Sat, "), HTTP_WEEKDAY_SAT }, - { HTTP_STR("Sun, "), HTTP_WEEKDAY_SUN }, + struct { CHTTP_String str; CHTTP_WeekDay val; } week_day_table[] = { + { CHTTP_STR("Mon, "), CHTTP_WEEKDAY_MON }, + { CHTTP_STR("Tue, "), CHTTP_WEEKDAY_TUE }, + { CHTTP_STR("Wed, "), CHTTP_WEEKDAY_WED }, + { CHTTP_STR("Thu, "), CHTTP_WEEKDAY_THU }, + { CHTTP_STR("Fri, "), CHTTP_WEEKDAY_FRI }, + { CHTTP_STR("Sat, "), CHTTP_WEEKDAY_SAT }, + { CHTTP_STR("Sun, "), CHTTP_WEEKDAY_SUN }, }; bool found = false; - for (int i = 0; i < HTTP_COUNT(week_day_table); i++) + for (int i = 0; i < CHTTP_COUNT(week_day_table); i++) if (consume_str(s, week_day_table[i].str)) { out->week_day = week_day_table[i].val; found = true; @@ -1480,23 +1480,23 @@ static int parse_date(Scanner *s, HTTP_Date *out) + (s->src[s->cur+1] - '0') * 1; s->cur += 2; - struct { HTTP_String str; HTTP_Month val; } month_table[] = { - { HTTP_STR(" Jan "), HTTP_MONTH_JAN }, - { HTTP_STR(" Feb "), HTTP_MONTH_FEB }, - { HTTP_STR(" Mar "), HTTP_MONTH_MAR }, - { HTTP_STR(" Apr "), HTTP_MONTH_APR }, - { HTTP_STR(" May "), HTTP_MONTH_MAY }, - { HTTP_STR(" Jun "), HTTP_MONTH_JUN }, - { HTTP_STR(" Jul "), HTTP_MONTH_JUL }, - { HTTP_STR(" Aug "), HTTP_MONTH_AUG }, - { HTTP_STR(" Sep "), HTTP_MONTH_SEP }, - { HTTP_STR(" Oct "), HTTP_MONTH_OCT }, - { HTTP_STR(" Nov "), HTTP_MONTH_NOV }, - { HTTP_STR(" Dec "), HTTP_MONTH_DEC }, + struct { CHTTP_String str; CHTTP_Month val; } month_table[] = { + { CHTTP_STR(" Jan "), CHTTP_MONTH_JAN }, + { CHTTP_STR(" Feb "), CHTTP_MONTH_FEB }, + { CHTTP_STR(" Mar "), CHTTP_MONTH_MAR }, + { CHTTP_STR(" Apr "), CHTTP_MONTH_APR }, + { CHTTP_STR(" May "), CHTTP_MONTH_MAY }, + { CHTTP_STR(" Jun "), CHTTP_MONTH_JUN }, + { CHTTP_STR(" Jul "), CHTTP_MONTH_JUL }, + { CHTTP_STR(" Aug "), CHTTP_MONTH_AUG }, + { CHTTP_STR(" Sep "), CHTTP_MONTH_SEP }, + { CHTTP_STR(" Oct "), CHTTP_MONTH_OCT }, + { CHTTP_STR(" Nov "), CHTTP_MONTH_NOV }, + { CHTTP_STR(" Dec "), CHTTP_MONTH_DEC }, }; found = false; - for (int i = 0; i < HTTP_COUNT(month_table); i++) + for (int i = 0; i < CHTTP_COUNT(month_table); i++) if (consume_str(s, month_table[i].str)) { out->month = month_table[i].val; found = true; @@ -1562,7 +1562,7 @@ static bool is_cookie_octet(char c) (c >= 0x5D && c <= 0x7E); } -int http_parse_set_cookie(HTTP_String str, HTTP_SetCookie *out) +int chttp_parse_set_cookie(CHTTP_String str, CHTTP_SetCookie *out) { Scanner s = { str.ptr, str.len, 0 }; @@ -1573,7 +1573,7 @@ int http_parse_set_cookie(HTTP_String str, HTTP_SetCookie *out) do s.cur++; while (s.cur < s.len && is_tchar(s.src[s.cur])); - out->name = (HTTP_String) { s.src + off, s.cur - off }; + out->name = (CHTTP_String) { s.src + off, s.cur - off }; // cookie-pair = cookie-name "=" cookie-value if (s.cur == s.len || s.src[s.cur] != '=') @@ -1588,13 +1588,13 @@ int http_parse_set_cookie(HTTP_String str, HTTP_SetCookie *out) s.cur++; if (s.cur == s.len || s.src[s.cur] != '"') return -1; // Missing closing double quote - out->value = (HTTP_String) { s.src + off, s.cur - off }; + out->value = (CHTTP_String) { s.src + off, s.cur - off }; s.cur++; // Consume closing double quote } else { int off = s.cur; while (s.cur < s.len && is_cookie_octet(s.src[s.cur])) s.cur++; - out->value = (HTTP_String) { s.src + off, s.cur - off }; + out->value = (CHTTP_String) { s.src + off, s.cur - off }; } // *( ";" SP cookie-av ) @@ -1603,20 +1603,20 @@ int http_parse_set_cookie(HTTP_String str, HTTP_SetCookie *out) // path-av / secure-av / httponly-av / // extension-av out->secure = false; - out->http_only = false; + out->chttp_only = false; out->have_date = false; out->have_max_age = false; out->have_domain = false; out->have_path = false; - while (consume_str(&s, HTTP_STR("; "))) { - if (consume_str(&s, HTTP_STR("Expires="))) { + while (consume_str(&s, CHTTP_STR("; "))) { + if (consume_str(&s, CHTTP_STR("Expires="))) { // expires-av = "Expires=" sane-cookie-date if (parse_date(&s, &out->date) < 0) return -1; out->have_date = true; - } else if (consume_str(&s, HTTP_STR("Max-Age="))) { + } else if (consume_str(&s, CHTTP_STR("Max-Age="))) { // max-age-av = "Max-Age=" non-zero-digit *DIGIT @@ -1633,7 +1633,7 @@ int http_parse_set_cookie(HTTP_String str, HTTP_SetCookie *out) out->have_max_age = true; out->max_age = value; - } else if (consume_str(&s, HTTP_STR("Domain="))) { + } else if (consume_str(&s, CHTTP_STR("Domain="))) { // domain-av = "Domain=" domain-value // domain-value = @@ -1683,9 +1683,9 @@ int http_parse_set_cookie(HTTP_String str, HTTP_SetCookie *out) } out->have_domain = true; - out->domain = (HTTP_String) { s.src + off, s.cur - off }; + out->domain = (CHTTP_String) { s.src + off, s.cur - off }; - } else if (consume_str(&s, HTTP_STR("Path="))) { + } else if (consume_str(&s, CHTTP_STR("Path="))) { // path-av = "Path=" path-value // path-value = @@ -1695,17 +1695,17 @@ int http_parse_set_cookie(HTTP_String str, HTTP_SetCookie *out) s.cur++; out->have_path = true; - out->path = (HTTP_String) { s.src + off, s.cur - off }; + out->path = (CHTTP_String) { s.src + off, s.cur - off }; - } else if (consume_str(&s, HTTP_STR("Secure"))) { + } else if (consume_str(&s, CHTTP_STR("Secure"))) { // secure-av = "Secure" out->secure = true; - } else if (consume_str(&s, HTTP_STR("HttpOnly"))) { + } else if (consume_str(&s, CHTTP_STR("HttpOnly"))) { // httponly-av = "HttpOnly" - out->http_only = true; + out->chttp_only = true; } else { return -1; // Invalid attribute @@ -1796,7 +1796,7 @@ static int servername_callback(SSL *ssl, int *ad, void *arg) #endif int server_secure_context_init(ServerSecureContext *ctx, - HTTP_String cert_file, HTTP_String key_file) + CHTTP_String cert_file, CHTTP_String key_file) { #ifdef HTTPS_ENABLED SSL_CTX *p = SSL_CTX_new(TLS_server_method()); @@ -1865,7 +1865,7 @@ void server_secure_context_free(ServerSecureContext *ctx) } int server_secure_context_add_certificate(ServerSecureContext *ctx, - HTTP_String domain, HTTP_String cert_file, HTTP_String key_file) + CHTTP_String domain, CHTTP_String cert_file, CHTTP_String key_file) { #ifdef HTTPS_ENABLED if (ctx->num_certs == SERVER_CERTIFICATE_LIMIT) @@ -1971,7 +1971,7 @@ static int create_socket_pair(NATIVE_SOCKET *a, NATIVE_SOCKET *b, bool *global_c WSADATA wsaData; WORD wVersionRequested = MAKEWORD(2, 2); if (WSAStartup(wVersionRequested, &wsaData)) - return HTTP_ERROR_UNSPECIFIED; + return CHTTP_ERROR_UNSPECIFIED; sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (sock == INVALID_SOCKET && *global_cleanup) @@ -1981,7 +1981,7 @@ static int create_socket_pair(NATIVE_SOCKET *a, NATIVE_SOCKET *b, bool *global_c if (sock == INVALID_SOCKET) { if (*global_cleanup) WSACleanup(); - return HTTP_ERROR_UNSPECIFIED; + return CHTTP_ERROR_UNSPECIFIED; } // Bind to loopback address with port 0 (dynamic port assignment) @@ -1996,21 +1996,21 @@ static int create_socket_pair(NATIVE_SOCKET *a, NATIVE_SOCKET *b, bool *global_c closesocket(sock); if (*global_cleanup) WSACleanup(); - return HTTP_ERROR_UNSPECIFIED; + return CHTTP_ERROR_UNSPECIFIED; } if (getsockname(sock, (struct sockaddr*)&addr, &addr_len) == SOCKET_ERROR) { closesocket(sock); if (*global_cleanup) WSACleanup(); - return HTTP_ERROR_UNSPECIFIED; + return CHTTP_ERROR_UNSPECIFIED; } if (connect(sock, (struct sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR) { closesocket(sock); if (*global_cleanup) WSACleanup(); - return HTTP_ERROR_UNSPECIFIED; + return CHTTP_ERROR_UNSPECIFIED; } // Optional: Set socket to non-blocking mode @@ -2020,20 +2020,20 @@ static int create_socket_pair(NATIVE_SOCKET *a, NATIVE_SOCKET *b, bool *global_c closesocket(sock); if (*global_cleanup) WSACleanup(); - return HTTP_ERROR_UNSPECIFIED; + return CHTTP_ERROR_UNSPECIFIED; } *a = sock; *b = sock; - return HTTP_OK; + return CHTTP_OK; #else *global_cleanup = false; int fds[2]; if (pipe(fds) < 0) - return HTTP_ERROR_UNSPECIFIED; + return CHTTP_ERROR_UNSPECIFIED; *a = fds[0]; *b = fds[1]; - return HTTP_OK; + return CHTTP_OK; #endif } @@ -2042,23 +2042,23 @@ static int set_socket_blocking(NATIVE_SOCKET sock, bool value) #ifdef _WIN32 u_long mode = !value; if (ioctlsocket(sock, FIONBIO, &mode) == SOCKET_ERROR) - return HTTP_ERROR_UNSPECIFIED; - return HTTP_OK; + return CHTTP_ERROR_UNSPECIFIED; + return CHTTP_OK; #endif #ifdef __linux__ int flags = fcntl(sock, F_GETFL, 0); if (flags < 0) - return HTTP_ERROR_UNSPECIFIED; + return CHTTP_ERROR_UNSPECIFIED; if (value) flags &= ~O_NONBLOCK; else flags |= O_NONBLOCK; if (fcntl(sock, F_SETFL, flags) < 0) - return HTTP_ERROR_UNSPECIFIED; - return HTTP_OK; + return CHTTP_ERROR_UNSPECIFIED; + return CHTTP_OK; #endif } -static NATIVE_SOCKET create_listen_socket(HTTP_String addr, +static NATIVE_SOCKET create_listen_socket(CHTTP_String addr, Port port, bool reuse_addr, int backlog) { NATIVE_SOCKET sock = socket(AF_INET, SOCK_STREAM, 0); @@ -2144,7 +2144,7 @@ int socket_manager_init(SocketManager *sm, Socket *socks, socks[i].state = SOCKET_STATE_FREE; socks[i].gen = 1; } - return HTTP_OK; + return CHTTP_OK; } void socket_manager_free(SocketManager *sm) @@ -2170,57 +2170,57 @@ void socket_manager_free(SocketManager *sm) } int socket_manager_listen_tcp(SocketManager *sm, - HTTP_String addr, Port port, int backlog, + CHTTP_String addr, Port port, int backlog, bool reuse_addr) { if (sm->plain_sock != NATIVE_SOCKET_INVALID) - return HTTP_ERROR_UNSPECIFIED; + return CHTTP_ERROR_UNSPECIFIED; sm->plain_sock = create_listen_socket(addr, port, reuse_addr, backlog); if (sm->plain_sock == NATIVE_SOCKET_INVALID) - return HTTP_ERROR_UNSPECIFIED; + return CHTTP_ERROR_UNSPECIFIED; - return HTTP_OK; + return CHTTP_OK; } int socket_manager_listen_tls(SocketManager *sm, - HTTP_String addr, Port port, int backlog, - bool reuse_addr, HTTP_String cert_file, - HTTP_String key_file) + CHTTP_String addr, Port port, int backlog, + bool reuse_addr, CHTTP_String cert_file, + CHTTP_String key_file) { #ifndef HTTPS_ENABLED - return HTTP_ERROR_NOTLS; + return CHTTP_ERROR_NOTLS; #endif if (sm->secure_sock != NATIVE_SOCKET_INVALID) - return HTTP_ERROR_UNSPECIFIED; + return CHTTP_ERROR_UNSPECIFIED; sm->secure_sock = create_listen_socket(addr, port, reuse_addr, backlog); if (sm->secure_sock == NATIVE_SOCKET_INVALID) - return HTTP_ERROR_UNSPECIFIED; + return CHTTP_ERROR_UNSPECIFIED; if (server_secure_context_init(&sm->server_secure_context, cert_file, key_file) < 0) { CLOSE_NATIVE_SOCKET(sm->secure_sock); sm->secure_sock = NATIVE_SOCKET_INVALID; - return HTTP_ERROR_UNSPECIFIED; + return CHTTP_ERROR_UNSPECIFIED; } - return HTTP_OK; + return CHTTP_OK; } int socket_manager_add_certificate(SocketManager *sm, - HTTP_String domain, HTTP_String cert_file, HTTP_String key_file) + CHTTP_String domain, CHTTP_String cert_file, CHTTP_String key_file) { if (sm->secure_sock == NATIVE_SOCKET_INVALID) - return HTTP_ERROR_UNSPECIFIED; + return CHTTP_ERROR_UNSPECIFIED; int ret = server_secure_context_add_certificate( &sm->server_secure_context, domain, cert_file, key_file); if (ret < 0) return ret; - return HTTP_OK; + return CHTTP_OK; } static bool is_secure(Socket *s) @@ -2360,13 +2360,13 @@ static void socket_update(Socket *s) struct sockaddr_in buf; buf.sin_family = AF_INET; buf.sin_port = htons(addr.port); - memcpy(&buf.sin_addr, &addr.ipv4, sizeof(HTTP_IPv4)); + memcpy(&buf.sin_addr, &addr.ipv4, sizeof(CHTTP_IPv4)); ret = connect(sock, (struct sockaddr*) &buf, sizeof(buf)); } else { struct sockaddr_in6 buf; buf.sin6_family = AF_INET6; buf.sin6_port = htons(addr.port); - memcpy(&buf.sin6_addr, &addr.ipv6, sizeof(HTTP_IPv6)); + memcpy(&buf.sin6_addr, &addr.ipv6, sizeof(CHTTP_IPv6)); ret = connect(sock, (struct sockaddr*) &buf, sizeof(buf)); } @@ -2625,12 +2625,12 @@ int socket_manager_wakeup(SocketManager *sm) char byte = 1; #ifdef _WIN32 if (send(sm->signal_sock, &byte, 1, 0) < 0) - return HTTP_ERROR_UNSPECIFIED; + return CHTTP_ERROR_UNSPECIFIED; #else if (write(sm->signal_sock, &byte, 1) < 0) - return HTTP_ERROR_UNSPECIFIED; + return CHTTP_ERROR_UNSPECIFIED; #endif - return HTTP_OK; + return CHTTP_OK; } void socket_manager_register_events( @@ -2861,7 +2861,7 @@ static int resolve_connect_targets(ConnectTarget *targets, RegisteredName *name = malloc(sizeof(RegisteredName) + targets[i].name.len + 1); if (name == NULL) { free_addr_list(resolved, num_resolved); - return HTTP_ERROR_OOM; + return CHTTP_ERROR_OOM; } name->refs = 0; memcpy(name->data, targets[i].name.ptr, targets[i].name.len); @@ -2871,7 +2871,7 @@ static int resolve_connect_targets(ConnectTarget *targets, // 512 bytes is more than enough for a DNS hostname (max 253 chars) char hostname[1<<9]; if (targets[i].name.len >= (int) sizeof(hostname)) - return HTTP_ERROR_OOM; + return CHTTP_ERROR_OOM; memcpy(hostname, targets[i].name.ptr, targets[i].name.len); hostname[targets[i].name.len] = '\0'; #endif @@ -2883,12 +2883,12 @@ static int resolve_connect_targets(ConnectTarget *targets, free(name); #endif free_addr_list(resolved, num_resolved); - return HTTP_ERROR_UNSPECIFIED; + return CHTTP_ERROR_UNSPECIFIED; } for (struct addrinfo *rp = res; rp; rp = rp->ai_next) { if (rp->ai_family == AF_INET) { - HTTP_IPv4 ipv4 = *(HTTP_IPv4*) &((struct sockaddr_in*)rp->ai_addr)->sin_addr; + CHTTP_IPv4 ipv4 = *(CHTTP_IPv4*) &((struct sockaddr_in*)rp->ai_addr)->sin_addr; if (num_resolved < max_resolved) { resolved[num_resolved].is_ipv4 = true; resolved[num_resolved].ipv4 = ipv4; @@ -2900,7 +2900,7 @@ static int resolve_connect_targets(ConnectTarget *targets, num_resolved++; } } else if (rp->ai_family == AF_INET6) { - HTTP_IPv6 ipv6 = *(HTTP_IPv6*) &((struct sockaddr_in6*)rp->ai_addr)->sin6_addr; + CHTTP_IPv6 ipv6 = *(CHTTP_IPv6*) &((struct sockaddr_in6*)rp->ai_addr)->sin6_addr; if (num_resolved < max_resolved) { resolved[num_resolved].is_ipv4 = false; resolved[num_resolved].ipv6 = ipv6; @@ -2956,17 +2956,17 @@ int socket_connect(SocketManager *sm, int num_targets, void *user) { if (sm->num_used == sm->max_used) - return HTTP_ERROR_UNSPECIFIED; + return CHTTP_ERROR_UNSPECIFIED; #ifdef HTTPS_ENABLED if (!sm->at_least_one_secure_connect) { if (client_secure_context_init(&sm->client_secure_context) < 0) - return HTTP_ERROR_UNSPECIFIED; + return CHTTP_ERROR_UNSPECIFIED; sm->at_least_one_secure_connect = true; } #else if (secure) - return HTTP_ERROR_NOTLS; + return CHTTP_ERROR_NOTLS; #endif AddressAndPort resolved[MAX_CONNECT_TARGETS]; @@ -2974,7 +2974,7 @@ int socket_connect(SocketManager *sm, int num_targets, targets, num_targets, resolved, MAX_CONNECT_TARGETS); if (num_resolved <= 0) - return HTTP_ERROR_UNSPECIFIED; + return CHTTP_ERROR_UNSPECIFIED; Socket *s = sm->sockets; while (s->state != SOCKET_STATE_FREE) { @@ -2991,7 +2991,7 @@ int socket_connect(SocketManager *sm, int num_targets, s->next_addr = 0; s->addrs = malloc(num_resolved * sizeof(AddressAndPort)); if (s->addrs == NULL) - return HTTP_ERROR_OOM; + return CHTTP_ERROR_OOM; for (int i = 0; i < num_resolved; i++) s->addrs[i] = resolved[i]; } @@ -3015,7 +3015,7 @@ int socket_connect(SocketManager *sm, int num_targets, sm->num_used++; socket_update(s); - return HTTP_OK; + return CHTTP_OK; } static bool would_block(void) @@ -3527,7 +3527,7 @@ static EVP_PKEY *generate_rsa_key_pair(int key_bits) return pkey; } -static X509 *create_certificate(EVP_PKEY *pkey, HTTP_String C, HTTP_String O, HTTP_String CN, int days) +static X509 *create_certificate(EVP_PKEY *pkey, CHTTP_String C, CHTTP_String O, CHTTP_String CN, int days) { X509 *x509 = X509_new(); if (!x509) @@ -3563,7 +3563,7 @@ static X509 *create_certificate(EVP_PKEY *pkey, HTTP_String C, HTTP_String O, HT return x509; } -static int save_private_key(EVP_PKEY *pkey, HTTP_String file) +static int save_private_key(EVP_PKEY *pkey, CHTTP_String file) { char copy[1<<10]; if (file.len >= (int) sizeof(copy)) @@ -3585,7 +3585,7 @@ static int save_private_key(EVP_PKEY *pkey, HTTP_String file) return 0; } -static int save_certificate(X509 *x509, HTTP_String file) +static int save_certificate(X509 *x509, CHTTP_String file) { char copy[1<<10]; if (file.len >= (int) sizeof(copy)) @@ -3607,8 +3607,8 @@ static int save_certificate(X509 *x509, HTTP_String file) return 0; } -int http_create_test_certificate(HTTP_String C, HTTP_String O, HTTP_String CN, - HTTP_String cert_file, HTTP_String key_file) +int chttp_create_test_certificate(CHTTP_String C, CHTTP_String O, CHTTP_String CN, + CHTTP_String cert_file, CHTTP_String key_file) { EVP_PKEY *pkey = generate_rsa_key_pair(2048); if (pkey == NULL) @@ -3639,8 +3639,8 @@ int http_create_test_certificate(HTTP_String C, HTTP_String O, HTTP_String CN, #else -int http_create_test_certificate(HTTP_String C, HTTP_String O, HTTP_String CN, - HTTP_String cert_file, HTTP_String key_file) +int chttp_create_test_certificate(CHTTP_String C, CHTTP_String O, CHTTP_String CN, + CHTTP_String cert_file, CHTTP_String key_file) { (void) C; (void) O; @@ -3656,13 +3656,13 @@ int http_create_test_certificate(HTTP_String C, HTTP_String O, HTTP_String CN, // src/client.c //////////////////////////////////////////////////////////////////////////////////////// -static void http_client_conn_free(HTTP_ClientConn *conn) +static void chttp_client_conn_free(CHTTP_ClientConn *conn) { byte_queue_free(&conn->output); byte_queue_free(&conn->input); } -int http_client_init(HTTP_Client *client) +int chttp_client_init(CHTTP_Client *client) { client->input_buffer_limit = 1<<20; client->output_buffer_limit = 1<<20; @@ -3670,8 +3670,8 @@ int http_client_init(HTTP_Client *client) client->cookie_jar.count = 0; client->num_conns = 0; - for (int i = 0; i < HTTP_CLIENT_CAPACITY; i++) { - client->conns[i].state = HTTP_CLIENT_CONN_FREE; + for (int i = 0; i < CHTTP_CLIENT_CAPACITY; i++) { + client->conns[i].state = CHTTP_CLIENT_CONN_FREE; client->conns[i].gen = 0; } @@ -3679,10 +3679,10 @@ int http_client_init(HTTP_Client *client) client->ready_head = 0; return socket_manager_init(&client->sockets, - client->socket_pool, HTTP_CLIENT_CAPACITY); + client->socket_pool, CHTTP_CLIENT_CAPACITY); } -void http_client_free(HTTP_Client *client) +void chttp_client_free(CHTTP_Client *client) { socket_manager_free(&client->sockets); @@ -3690,63 +3690,63 @@ void http_client_free(HTTP_Client *client) free(client->cookie_jar.items[i].name.ptr); for (int i = 0, j = 0; j < client->num_conns; i++) { - HTTP_ClientConn *conn = &client->conns[i]; - if (conn->state == HTTP_CLIENT_CONN_FREE) + CHTTP_ClientConn *conn = &client->conns[i]; + if (conn->state == CHTTP_CLIENT_CONN_FREE) continue; j++; - http_client_conn_free(conn); + chttp_client_conn_free(conn); } } -void http_client_set_input_limit(HTTP_Client *client, uint32_t limit) +void chttp_client_set_input_limit(CHTTP_Client *client, uint32_t limit) { client->input_buffer_limit = limit; } -void http_client_set_output_limit(HTTP_Client *client, uint32_t limit) +void chttp_client_set_output_limit(CHTTP_Client *client, uint32_t limit) { client->output_buffer_limit = limit; } -int http_client_wakeup(HTTP_Client *client) +int chttp_client_wakeup(CHTTP_Client *client) { return socket_manager_wakeup(&client->sockets); } // Get a connection pointer from a request builder. // If the builder is invalid, returns NULL. -static HTTP_ClientConn* -request_builder_to_conn(HTTP_RequestBuilder builder) +static CHTTP_ClientConn* +request_builder_to_conn(CHTTP_RequestBuilder builder) { - HTTP_Client *client = builder.client; + CHTTP_Client *client = builder.client; if (client == NULL) return NULL; - if (builder.index >= HTTP_CLIENT_CAPACITY) + if (builder.index >= CHTTP_CLIENT_CAPACITY) return NULL; - HTTP_ClientConn *conn = &client->conns[builder.index]; + CHTTP_ClientConn *conn = &client->conns[builder.index]; if (builder.gen != conn->gen) return NULL; return conn; } -HTTP_RequestBuilder http_client_get_builder(HTTP_Client *client) +CHTTP_RequestBuilder chttp_client_get_builder(CHTTP_Client *client) { // Find a free connection slot - if (client->num_conns == HTTP_CLIENT_CAPACITY) - return (HTTP_RequestBuilder) { NULL, -1, -1 }; + if (client->num_conns == CHTTP_CLIENT_CAPACITY) + return (CHTTP_RequestBuilder) { NULL, -1, -1 }; int i = 0; - while (client->conns[i].state != HTTP_CLIENT_CONN_FREE) { + while (client->conns[i].state != CHTTP_CLIENT_CONN_FREE) { i++; - assert(i < HTTP_CLIENT_CAPACITY); + assert(i < CHTTP_CLIENT_CAPACITY); } client->num_conns++; - client->conns[i].state = HTTP_CLIENT_CONN_WAIT_METHOD; + client->conns[i].state = CHTTP_CLIENT_CONN_WAIT_METHOD; client->conns[i].handle = SOCKET_HANDLE_INVALID; client->conns[i].client = client; client->conns[i].user = NULL; @@ -3754,30 +3754,30 @@ HTTP_RequestBuilder http_client_get_builder(HTTP_Client *client) byte_queue_init(&client->conns[i].input, client->input_buffer_limit); byte_queue_init(&client->conns[i].output, client->output_buffer_limit); - return (HTTP_RequestBuilder) { client, i, client->conns[i].gen }; + return (CHTTP_RequestBuilder) { client, i, client->conns[i].gen }; } // TODO: test this function -static bool is_subdomain(HTTP_String domain, HTTP_String subdomain) +static bool is_subdomain(CHTTP_String domain, CHTTP_String subdomain) { - if (http_streq(domain, subdomain)) + if (chttp_streq(domain, subdomain)) return true; // Exact match if (domain.len > subdomain.len) return false; - HTTP_String subdomain_suffix = { + CHTTP_String subdomain_suffix = { subdomain.ptr + subdomain.len - domain.len, domain.len }; - if (subdomain_suffix.ptr[-1] != '.' || !http_streq(domain, subdomain_suffix)) + if (subdomain_suffix.ptr[-1] != '.' || !chttp_streq(domain, subdomain_suffix)) return false; return true; } // TODO: test this function -static bool is_subpath(HTTP_String path, HTTP_String subpath) +static bool is_subpath(CHTTP_String path, CHTTP_String subpath) { if (path.len > subpath.len) return false; @@ -3786,16 +3786,16 @@ static bool is_subpath(HTTP_String path, HTTP_String subpath) return false; subpath.len = path.len; - return http_streq(path, subpath); + return chttp_streq(path, subpath); } -static bool should_send_cookie(HTTP_CookieJarEntry entry, HTTP_URL url) +static bool should_send_cookie(CHTTP_CookieJarEntry entry, CHTTP_URL url) { // TODO: If the cookie is expired, ignore it regardless if (entry.exact_domain) { // Cookie domain and URL domain must match exactly - if (!http_streq(entry.domain, url.authority.host.text)) + if (!chttp_streq(entry.domain, url.authority.host.text)) return false; } else { // The URL's domain must match or be a subdomain of the cookie's domain @@ -3805,7 +3805,7 @@ static bool should_send_cookie(HTTP_CookieJarEntry entry, HTTP_URL url) if (entry.exact_path) { // Cookie path and URL path must match exactly - if (!http_streq(entry.path, url.path)) + if (!chttp_streq(entry.path, url.path)) return false; } else { if (!is_subpath(entry.path, url.path)) @@ -3813,41 +3813,41 @@ static bool should_send_cookie(HTTP_CookieJarEntry entry, HTTP_URL url) } if (entry.secure) { - if (!http_streq(url.scheme, HTTP_STR("https"))) + if (!chttp_streq(url.scheme, CHTTP_STR("https"))) return false; // Cookie was marked as secure but the target URL is not HTTPS } return true; } -static HTTP_String get_method_string(HTTP_Method method) +static CHTTP_String get_method_string(CHTTP_Method method) { switch (method) { - case HTTP_METHOD_GET : return HTTP_STR("GET"); - case HTTP_METHOD_HEAD : return HTTP_STR("HEAD"); - case HTTP_METHOD_POST : return HTTP_STR("POST"); - case HTTP_METHOD_PUT : return HTTP_STR("PUT"); - case HTTP_METHOD_DELETE : return HTTP_STR("DELETE"); - case HTTP_METHOD_CONNECT: return HTTP_STR("CONNECT"); - case HTTP_METHOD_OPTIONS: return HTTP_STR("OPTIONS"); - case HTTP_METHOD_TRACE : return HTTP_STR("TRACE"); - case HTTP_METHOD_PATCH : return HTTP_STR("PATCH"); + case CHTTP_METHOD_GET : return CHTTP_STR("GET"); + case CHTTP_METHOD_HEAD : return CHTTP_STR("HEAD"); + case CHTTP_METHOD_POST : return CHTTP_STR("POST"); + case CHTTP_METHOD_PUT : return CHTTP_STR("PUT"); + case CHTTP_METHOD_DELETE : return CHTTP_STR("DELETE"); + case CHTTP_METHOD_CONNECT: return CHTTP_STR("CONNECT"); + case CHTTP_METHOD_OPTIONS: return CHTTP_STR("OPTIONS"); + case CHTTP_METHOD_TRACE : return CHTTP_STR("TRACE"); + case CHTTP_METHOD_PATCH : return CHTTP_STR("PATCH"); } - return HTTP_STR("???"); + return CHTTP_STR("???"); } -void http_request_builder_set_user(HTTP_RequestBuilder builder, void *user) +void chttp_request_builder_set_user(CHTTP_RequestBuilder builder, void *user) { - HTTP_ClientConn *conn = request_builder_to_conn(builder); + CHTTP_ClientConn *conn = request_builder_to_conn(builder); if (conn == NULL) return; // Invalid builder conn->user = user; } -void http_request_builder_trace(HTTP_RequestBuilder builder, bool trace_bytes) +void chttp_request_builder_trace(CHTTP_RequestBuilder builder, bool trace_bytes) { - HTTP_ClientConn *conn = request_builder_to_conn(builder); + CHTTP_ClientConn *conn = request_builder_to_conn(builder); if (conn == NULL) return; // Invalid builder @@ -3855,47 +3855,47 @@ void http_request_builder_trace(HTTP_RequestBuilder builder, bool trace_bytes) } // TODO: comment -void http_request_builder_insecure(HTTP_RequestBuilder builder, +void chttp_request_builder_insecure(CHTTP_RequestBuilder builder, bool insecure) { - HTTP_ClientConn *conn = request_builder_to_conn(builder); + CHTTP_ClientConn *conn = request_builder_to_conn(builder); if (conn == NULL) return; // Invalid builder conn->dont_verify_cert = insecure; } -void http_request_builder_method(HTTP_RequestBuilder builder, - HTTP_Method method) +void chttp_request_builder_method(CHTTP_RequestBuilder builder, + CHTTP_Method method) { - HTTP_ClientConn *conn = request_builder_to_conn(builder); + CHTTP_ClientConn *conn = request_builder_to_conn(builder); if (conn == NULL) return; // Invalid builder - if (conn->state != HTTP_CLIENT_CONN_WAIT_METHOD) + if (conn->state != CHTTP_CLIENT_CONN_WAIT_METHOD) return; // Request line already written // Write method - HTTP_String method_str = get_method_string(method); + CHTTP_String method_str = get_method_string(method); byte_queue_write(&conn->output, method_str.ptr, method_str.len); byte_queue_write(&conn->output, " ", 1); - conn->state = HTTP_CLIENT_CONN_WAIT_URL; + conn->state = CHTTP_CLIENT_CONN_WAIT_URL; } -void http_request_builder_target(HTTP_RequestBuilder builder, - HTTP_String url) +void chttp_request_builder_target(CHTTP_RequestBuilder builder, + CHTTP_String url) { - HTTP_ClientConn *conn = request_builder_to_conn(builder); + CHTTP_ClientConn *conn = request_builder_to_conn(builder); if (conn == NULL) return; // Invalid builder - if (conn->state != HTTP_CLIENT_CONN_WAIT_URL) + if (conn->state != CHTTP_CLIENT_CONN_WAIT_URL) return; // Request line already written if (url.len == 0) { - conn->state = HTTP_CLIENT_CONN_COMPLETE; - conn->result = HTTP_ERROR_BADURL; + conn->state = CHTTP_CLIENT_CONN_COMPLETE; + conn->result = CHTTP_ERROR_BADURL; return; } @@ -3903,8 +3903,8 @@ void http_request_builder_target(HTTP_RequestBuilder builder, // URL pointers remain valid char *url_copy = malloc(url.len); if (url_copy == NULL) { - conn->state = HTTP_CLIENT_CONN_COMPLETE; - conn->result = HTTP_ERROR_OOM; + conn->state = CHTTP_CLIENT_CONN_COMPLETE; + conn->result = CHTTP_ERROR_OOM; return; } memcpy(url_copy, url.ptr, url.len); @@ -3913,16 +3913,16 @@ void http_request_builder_target(HTTP_RequestBuilder builder, conn->url_buffer.len = url.len; // Parse the copied URL (all url.* pointers will reference url_buffer) - if (http_parse_url(conn->url_buffer.ptr, conn->url_buffer.len, &conn->url) < 0) { - conn->state = HTTP_CLIENT_CONN_COMPLETE; - conn->result = HTTP_ERROR_BADURL; + if (chttp_parse_url(conn->url_buffer.ptr, conn->url_buffer.len, &conn->url) < 0) { + conn->state = CHTTP_CLIENT_CONN_COMPLETE; + conn->result = CHTTP_ERROR_BADURL; return; } - if (!http_streq(conn->url.scheme, HTTP_STR("http")) && - !http_streq(conn->url.scheme, HTTP_STR("https"))) { - conn->state = HTTP_CLIENT_CONN_COMPLETE; - conn->result = HTTP_ERROR_BADURL; + if (!chttp_streq(conn->url.scheme, CHTTP_STR("http")) && + !chttp_streq(conn->url.scheme, CHTTP_STR("https"))) { + conn->state = CHTTP_CLIENT_CONN_COMPLETE; + conn->result = CHTTP_ERROR_BADURL; return; } @@ -3935,13 +3935,13 @@ void http_request_builder_target(HTTP_RequestBuilder builder, conn->url.path.len); // Write query string - HTTP_String query = conn->url.query; + CHTTP_String query = conn->url.query; if (query.len > 0) { byte_queue_write(&conn->output, "?", 1); byte_queue_write(&conn->output, query.ptr, query.len); } - HTTP_String version = HTTP_STR(" HTTP/1.1"); + CHTTP_String version = CHTTP_STR(" HTTP/1.1"); byte_queue_write(&conn->output, version.ptr, version.len); byte_queue_write(&conn->output, "\r\n", 2); @@ -3957,10 +3957,10 @@ void http_request_builder_target(HTTP_RequestBuilder builder, // Find all entries from the cookie jar that should // be sent to this server and append headers for them - HTTP_Client *client = builder.client; - HTTP_CookieJar *cookie_jar = &client->cookie_jar; + CHTTP_Client *client = builder.client; + CHTTP_CookieJar *cookie_jar = &client->cookie_jar; for (int i = 0; i < cookie_jar->count; i++) { - HTTP_CookieJarEntry entry = cookie_jar->items[i]; + CHTTP_CookieJarEntry entry = cookie_jar->items[i]; if (should_send_cookie(entry, conn->url)) { // TODO: Adding one header per cookie may cause the number of // headers to increase significantly. Should probably group @@ -3973,12 +3973,12 @@ void http_request_builder_target(HTTP_RequestBuilder builder, } } - HTTP_String s; + CHTTP_String s; - s = HTTP_STR("Connection: Close\r\n"); + s = CHTTP_STR("Connection: Close\r\n"); byte_queue_write(&conn->output, s.ptr, s.len); - s = HTTP_STR("Content-Length: "); + s = CHTTP_STR("Content-Length: "); byte_queue_write(&conn->output, s.ptr, s.len); conn->content_length_value_offset = byte_queue_offset(&conn->output); @@ -3986,20 +3986,20 @@ void http_request_builder_target(HTTP_RequestBuilder builder, #define TEN_SPACES " " _Static_assert(sizeof(TEN_SPACES) == 10+1); - s = HTTP_STR(TEN_SPACES "\r\n"); + s = CHTTP_STR(TEN_SPACES "\r\n"); byte_queue_write(&conn->output, s.ptr, s.len); - conn->state = HTTP_CLIENT_CONN_WAIT_HEADER; + conn->state = CHTTP_CLIENT_CONN_WAIT_HEADER; } -void http_request_builder_header(HTTP_RequestBuilder builder, - HTTP_String str) +void chttp_request_builder_header(CHTTP_RequestBuilder builder, + CHTTP_String str) { - HTTP_ClientConn *conn = request_builder_to_conn(builder); + CHTTP_ClientConn *conn = request_builder_to_conn(builder); if (conn == NULL) return; - if (conn->state != HTTP_CLIENT_CONN_WAIT_HEADER) + if (conn->state != CHTTP_CLIENT_CONN_WAIT_HEADER) return; // Validate header: must contain a colon and no control characters @@ -4019,33 +4019,33 @@ void http_request_builder_header(HTTP_RequestBuilder builder, byte_queue_write(&conn->output, "\r\n", 2); } -void http_request_builder_body(HTTP_RequestBuilder builder, - HTTP_String str) +void chttp_request_builder_body(CHTTP_RequestBuilder builder, + CHTTP_String str) { - HTTP_ClientConn *conn = request_builder_to_conn(builder); + CHTTP_ClientConn *conn = request_builder_to_conn(builder); if (conn == NULL) return; // Transition from WAIT_HEADER to WAIT_BODY if needed - if (conn->state == HTTP_CLIENT_CONN_WAIT_HEADER) { + if (conn->state == CHTTP_CLIENT_CONN_WAIT_HEADER) { byte_queue_write(&conn->output, "\r\n", 2); conn->content_length_offset = byte_queue_offset(&conn->output); - conn->state = HTTP_CLIENT_CONN_WAIT_BODY; + conn->state = CHTTP_CLIENT_CONN_WAIT_BODY; } - if (conn->state != HTTP_CLIENT_CONN_WAIT_BODY) + if (conn->state != CHTTP_CLIENT_CONN_WAIT_BODY) return; byte_queue_write(&conn->output, str.ptr, str.len); } -static ConnectTarget url_to_connect_target(HTTP_URL url) +static ConnectTarget url_to_connect_target(CHTTP_URL url) { - HTTP_Authority authority = url.authority; + CHTTP_Authority authority = url.authority; ConnectTarget target; if (authority.port < 1) { - if (http_streq(url.scheme, HTTP_STR("https"))) + if (chttp_streq(url.scheme, CHTTP_STR("https"))) target.port = 443; else target.port = 80; @@ -4053,42 +4053,42 @@ static ConnectTarget url_to_connect_target(HTTP_URL url) target.port = authority.port; } - if (authority.host.mode == HTTP_HOST_MODE_NAME) { + if (authority.host.mode == CHTTP_HOST_MODE_NAME) { target.type = CONNECT_TARGET_NAME; target.name = authority.host.name; - } else if (authority.host.mode == HTTP_HOST_MODE_IPV4) { + } else if (authority.host.mode == CHTTP_HOST_MODE_IPV4) { target.type = CONNECT_TARGET_IPV4; target.ipv4 = authority.host.ipv4; - } else if (authority.host.mode == HTTP_HOST_MODE_IPV6) { + } else if (authority.host.mode == CHTTP_HOST_MODE_IPV6) { target.type = CONNECT_TARGET_IPV6; target.ipv6 = authority.host.ipv6; } else { - HTTP_UNREACHABLE; + CHTTP_UNREACHABLE; } return target; } -int http_request_builder_send(HTTP_RequestBuilder builder) +int chttp_request_builder_send(CHTTP_RequestBuilder builder) { - HTTP_Client *client = builder.client; + CHTTP_Client *client = builder.client; if (client == NULL) - return HTTP_ERROR_REQLIMIT; + return CHTTP_ERROR_REQLIMIT; - HTTP_ClientConn *conn = request_builder_to_conn(builder); + CHTTP_ClientConn *conn = request_builder_to_conn(builder); if (conn == NULL) - return HTTP_ERROR_BADHANDLE; + return CHTTP_ERROR_BADHANDLE; - if (conn->state == HTTP_CLIENT_CONN_COMPLETE) + if (conn->state == CHTTP_CLIENT_CONN_COMPLETE) goto error; // Early completion due to an error - if (conn->state == HTTP_CLIENT_CONN_WAIT_HEADER) { + if (conn->state == CHTTP_CLIENT_CONN_WAIT_HEADER) { byte_queue_write(&conn->output, "\r\n", 2); conn->content_length_offset = byte_queue_offset(&conn->output); - conn->state = HTTP_CLIENT_CONN_WAIT_BODY; + conn->state = CHTTP_CLIENT_CONN_WAIT_BODY; } - if (conn->state != HTTP_CLIENT_CONN_WAIT_BODY) + if (conn->state != CHTTP_CLIENT_CONN_WAIT_BODY) goto error; if (byte_queue_error(&conn->output)) @@ -4103,16 +4103,16 @@ int http_request_builder_send(HTTP_RequestBuilder builder) byte_queue_patch(&conn->output, conn->content_length_value_offset, tmp, len); ConnectTarget target = url_to_connect_target(conn->url); - bool secure = http_streq(conn->url.scheme, HTTP_STR("https")); + bool secure = chttp_streq(conn->url.scheme, CHTTP_STR("https")); if (socket_connect(&client->sockets, 1, &target, secure, conn->dont_verify_cert, conn) < 0) goto error; - conn->state = HTTP_CLIENT_CONN_FLUSHING; + conn->state = CHTTP_CLIENT_CONN_FLUSHING; conn->gen++; - return HTTP_OK; + return CHTTP_OK; error: - conn->state = HTTP_CLIENT_CONN_FREE; + conn->state = CHTTP_CLIENT_CONN_FREE; free(conn->url_buffer.ptr); byte_queue_free(&conn->input); byte_queue_free(&conn->output); @@ -4120,17 +4120,17 @@ error: return conn->result; } -static void save_one_cookie(HTTP_CookieJar *cookie_jar, - HTTP_Header set_cookie, HTTP_String domain, HTTP_String path) +static void save_one_cookie(CHTTP_CookieJar *cookie_jar, + CHTTP_Header set_cookie, CHTTP_String domain, CHTTP_String path) { - if (cookie_jar->count == HTTP_COOKIE_JAR_CAPACITY) + if (cookie_jar->count == CHTTP_COOKIE_JAR_CAPACITY) return; // Cookie jar capacity reached - HTTP_SetCookie parsed; - if (http_parse_set_cookie(set_cookie.value, &parsed) < 0) + CHTTP_SetCookie parsed; + if (chttp_parse_set_cookie(set_cookie.value, &parsed) < 0) return; // Ignore invalid Set-Cookie headers - HTTP_CookieJarEntry entry; + CHTTP_CookieJarEntry entry; entry.name = parsed.name; entry.value = parsed.value; @@ -4179,32 +4179,32 @@ static void save_one_cookie(HTTP_CookieJar *cookie_jar, cookie_jar->items[cookie_jar->count++] = entry; } -static void save_cookies(HTTP_CookieJar *cookie_jar, - HTTP_Header *headers, int num_headers, - HTTP_String domain, HTTP_String path) +static void save_cookies(CHTTP_CookieJar *cookie_jar, + CHTTP_Header *headers, int num_headers, + CHTTP_String domain, CHTTP_String path) { // TODO: remove expired cookies for (int i = 0; i < num_headers; i++) - if (http_streqcase(headers[i].name, HTTP_STR("Set-Cookie"))) // TODO: headers are case-insensitive, right? + if (chttp_streqcase(headers[i].name, CHTTP_STR("Set-Cookie"))) // TODO: headers are case-insensitive, right? save_one_cookie(cookie_jar, headers[i], domain, path); } -void http_client_register_events(HTTP_Client *client, +void chttp_client_register_events(CHTTP_Client *client, EventRegister *reg) { socket_manager_register_events(&client->sockets, reg); } -void http_client_process_events(HTTP_Client *client, +void chttp_client_process_events(CHTTP_Client *client, EventRegister reg) { - SocketEvent events[HTTP_CLIENT_CAPACITY]; + SocketEvent events[CHTTP_CLIENT_CAPACITY]; int num_events = socket_manager_translate_events(&client->sockets, events, reg); for (int i = 0; i < num_events; i++) { - HTTP_ClientConn *conn = events[i].user; + CHTTP_ClientConn *conn = events[i].user; if (conn == NULL) continue; // If a socket is not couple to a connection, // it means the response was already returned @@ -4212,7 +4212,7 @@ void http_client_process_events(HTTP_Client *client, if (events[i].type == SOCKET_EVENT_DISCONNECT) { - conn->state = HTTP_CLIENT_CONN_COMPLETE; + conn->state = CHTTP_CLIENT_CONN_COMPLETE; conn->result = -1; } else if (events[i].type == SOCKET_EVENT_READY) { @@ -4223,7 +4223,7 @@ void http_client_process_events(HTTP_Client *client, while (socket_ready(&client->sockets, conn->handle)) { - if (conn->state == HTTP_CLIENT_CONN_FLUSHING) { + if (conn->state == CHTTP_CLIENT_CONN_FLUSHING) { ByteView src = byte_queue_read_buf(&conn->output); @@ -4232,7 +4232,7 @@ void http_client_process_events(HTTP_Client *client, num = socket_send(&client->sockets, conn->handle, src.ptr, src.len); if (conn->trace_bytes) - print_bytes(HTTP_STR("<< "), (HTTP_String){src.ptr, num}); + print_bytes(CHTTP_STR("<< "), (CHTTP_String){src.ptr, num}); byte_queue_read_ack(&conn->output, num); @@ -4243,10 +4243,10 @@ void http_client_process_events(HTTP_Client *client, // Request fully sent, now wait for response if (byte_queue_empty(&conn->output)) - conn->state = HTTP_CLIENT_CONN_BUFFERING; + conn->state = CHTTP_CLIENT_CONN_BUFFERING; } - if (conn->state == HTTP_CLIENT_CONN_BUFFERING) { + if (conn->state == CHTTP_CLIENT_CONN_BUFFERING) { // Receive response data int min_recv = 1<<10; @@ -4259,7 +4259,7 @@ void http_client_process_events(HTTP_Client *client, num = socket_recv(&client->sockets, conn->handle, dst.ptr, dst.len); if (conn->trace_bytes) - print_bytes(HTTP_STR(">> "), (HTTP_String){dst.ptr, num}); + print_bytes(CHTTP_STR(">> "), (CHTTP_String){dst.ptr, num}); byte_queue_write_ack(&conn->input, num); @@ -4269,7 +4269,7 @@ void http_client_process_events(HTTP_Client *client, } ByteView src = byte_queue_read_buf(&conn->input); - int ret = http_parse_response(src.ptr, src.len, &conn->response); + int ret = chttp_parse_response(src.ptr, src.len, &conn->response); if (ret == 0) { // Still waiting @@ -4292,7 +4292,7 @@ void http_client_process_events(HTTP_Client *client, // Ready assert(ret > 0); - conn->state = HTTP_CLIENT_CONN_COMPLETE; + conn->state = CHTTP_CLIENT_CONN_COMPLETE; conn->result = 0; conn->response.context = client; @@ -4310,36 +4310,36 @@ void http_client_process_events(HTTP_Client *client, } } - if (conn->state == HTTP_CLIENT_CONN_COMPLETE) { + if (conn->state == CHTTP_CLIENT_CONN_COMPLETE) { // Decouple from the socket socket_set_user(&client->sockets, events[i].handle, NULL); socket_close(&client->sockets, events[i].handle); // Push to the ready queue - assert(client->num_ready < HTTP_CLIENT_CAPACITY); - int tail = (client->ready_head + client->num_ready) % HTTP_CLIENT_CAPACITY; + assert(client->num_ready < CHTTP_CLIENT_CAPACITY); + int tail = (client->ready_head + client->num_ready) % CHTTP_CLIENT_CAPACITY; client->ready[tail] = conn - client->conns; client->num_ready++; } } } -bool http_client_next_response(HTTP_Client *client, - int *result, void **user, HTTP_Response **response) +bool chttp_client_next_response(CHTTP_Client *client, + int *result, void **user, CHTTP_Response **response) { if (client->num_ready == 0) return false; - HTTP_ClientConn *conn = &client->conns[client->ready[client->ready_head]]; - client->ready_head = (client->ready_head + 1) % HTTP_CLIENT_CAPACITY; + CHTTP_ClientConn *conn = &client->conns[client->ready[client->ready_head]]; + client->ready_head = (client->ready_head + 1) % CHTTP_CLIENT_CAPACITY; client->num_ready--; - assert(conn->state == HTTP_CLIENT_CONN_COMPLETE); + assert(conn->state == CHTTP_CLIENT_CONN_COMPLETE); *result = conn->result; *user = conn->user; - if (conn->result == HTTP_OK) { + if (conn->result == CHTTP_OK) { *response = &conn->response; } else { *response = NULL; @@ -4348,17 +4348,17 @@ bool http_client_next_response(HTTP_Client *client, return true; } -void http_free_response(HTTP_Response *response) +void chttp_free_response(CHTTP_Response *response) { if (response == NULL || response->context == NULL) return; - HTTP_Client *client = response->context; + CHTTP_Client *client = response->context; response->context = NULL; // TODO: I'm positive there is a better way to do this. // It should just be a bouds check + subtraction. - HTTP_ClientConn *conn = NULL; - for (int i = 0; i < HTTP_CLIENT_CAPACITY; i++) + CHTTP_ClientConn *conn = NULL; + for (int i = 0; i < CHTTP_CLIENT_CAPACITY; i++) if (&client->conns[i].response == response) { conn = &client->conns[i]; break; @@ -4366,7 +4366,7 @@ void http_free_response(HTTP_Response *response) if (conn == NULL) return; - conn->state = HTTP_CLIENT_CONN_FREE; + conn->state = CHTTP_CLIENT_CONN_FREE; free(conn->url_buffer.ptr); byte_queue_free(&conn->input); byte_queue_free(&conn->output); @@ -4379,112 +4379,112 @@ void http_free_response(HTTP_Response *response) #define POLL poll #endif -void http_client_wait_response(HTTP_Client *client, - int *result, void **user, HTTP_Response **response) +void chttp_client_wait_response(CHTTP_Client *client, + int *result, void **user, CHTTP_Response **response) { for (;;) { - void *ptrs[HTTP_CLIENT_POLL_CAPACITY]; - struct pollfd polled[HTTP_CLIENT_POLL_CAPACITY]; + void *ptrs[CHTTP_CLIENT_POLL_CAPACITY]; + struct pollfd polled[CHTTP_CLIENT_POLL_CAPACITY]; EventRegister reg = { ptrs, polled, 0 }; - http_client_register_events(client, ®); + chttp_client_register_events(client, ®); if (reg.num_polled > 0) POLL(reg.polled, reg.num_polled, -1); - http_client_process_events(client, reg); + chttp_client_process_events(client, reg); - if (http_client_next_response(client, result, user, response)) + if (chttp_client_next_response(client, result, user, response)) break; } } -static _Thread_local HTTP_Client *implicit_client; +static _Thread_local CHTTP_Client *implicit_client; -static int perform_request(HTTP_Method method, - HTTP_String url, HTTP_String *headers, - int num_headers, HTTP_String body, - HTTP_Response **response) +static int perform_request(CHTTP_Method method, + CHTTP_String url, CHTTP_String *headers, + int num_headers, CHTTP_String body, + CHTTP_Response **response) { if (implicit_client == NULL) { - implicit_client = malloc(sizeof(HTTP_Client)); + implicit_client = malloc(sizeof(CHTTP_Client)); if (implicit_client == NULL) - return HTTP_ERROR_OOM; + return CHTTP_ERROR_OOM; - int ret = http_client_init(implicit_client); + int ret = chttp_client_init(implicit_client); if (ret < 0) { free(implicit_client); implicit_client = NULL; return ret; } } - HTTP_Client *client = implicit_client; + CHTTP_Client *client = implicit_client; - HTTP_RequestBuilder builder = http_client_get_builder(client); - http_request_builder_method(builder, method); - http_request_builder_target(builder, url); + CHTTP_RequestBuilder builder = chttp_client_get_builder(client); + chttp_request_builder_method(builder, method); + chttp_request_builder_target(builder, url); for (int i = 0; i < num_headers; i++) - http_request_builder_header(builder, headers[i]); - http_request_builder_body(builder, body); - int ret = http_request_builder_send(builder); + chttp_request_builder_header(builder, headers[i]); + chttp_request_builder_body(builder, body); + int ret = chttp_request_builder_send(builder); if (ret < 0) return ret; int result; void *user; - http_client_wait_response(client, &result, &user, response); + chttp_client_wait_response(client, &result, &user, response); return result; } -int http_get(HTTP_String url, HTTP_String *headers, - int num_headers, HTTP_Response **response) +int chttp_get(CHTTP_String url, CHTTP_String *headers, + int num_headers, CHTTP_Response **response) { - return perform_request(HTTP_METHOD_GET, url, headers, num_headers, HTTP_STR(""), response); + return perform_request(CHTTP_METHOD_GET, url, headers, num_headers, CHTTP_STR(""), response); } -int http_post(HTTP_String url, HTTP_String *headers, - int num_headers, HTTP_String body, - HTTP_Response **response) +int chttp_post(CHTTP_String url, CHTTP_String *headers, + int num_headers, CHTTP_String body, + CHTTP_Response **response) { - return perform_request(HTTP_METHOD_POST, url, headers, num_headers, body, response); + return perform_request(CHTTP_METHOD_POST, url, headers, num_headers, body, response); } -int http_put(HTTP_String url, HTTP_String *headers, - int num_headers, HTTP_String body, - HTTP_Response **response) +int chttp_put(CHTTP_String url, CHTTP_String *headers, + int num_headers, CHTTP_String body, + CHTTP_Response **response) { - return perform_request(HTTP_METHOD_PUT, url, headers, num_headers, body, response); + return perform_request(CHTTP_METHOD_PUT, url, headers, num_headers, body, response); } -int http_delete(HTTP_String url, HTTP_String *headers, - int num_headers, HTTP_Response **response) +int chttp_delete(CHTTP_String url, CHTTP_String *headers, + int num_headers, CHTTP_Response **response) { - return perform_request(HTTP_METHOD_DELETE, url, headers, num_headers, HTTP_STR(""), response); + return perform_request(CHTTP_METHOD_DELETE, url, headers, num_headers, CHTTP_STR(""), response); } //////////////////////////////////////////////////////////////////////////////////////// // src/server.c //////////////////////////////////////////////////////////////////////////////////////// -static void http_server_conn_init(HTTP_ServerConn *conn, +static void chttp_server_conn_init(CHTTP_ServerConn *conn, SocketHandle handle, uint32_t input_buffer_limit, uint32_t output_buffer_limit) { - conn->state = HTTP_SERVER_CONN_BUFFERING; + conn->state = CHTTP_SERVER_CONN_BUFFERING; conn->handle = handle; conn->closing = false; byte_queue_init(&conn->input, input_buffer_limit); byte_queue_init(&conn->output, output_buffer_limit); } -static void http_server_conn_free(HTTP_ServerConn *conn) +static void chttp_server_conn_free(CHTTP_ServerConn *conn) { byte_queue_free(&conn->output); byte_queue_free(&conn->input); } -int http_server_init(HTTP_Server *server) +int chttp_server_init(CHTTP_Server *server) { server->input_buffer_limit = 1<<20; server->output_buffer_limit = 1<<20; @@ -4494,8 +4494,8 @@ int http_server_init(HTTP_Server *server) server->backlog = 32; server->num_conns = 0; - for (int i = 0; i < HTTP_SERVER_CAPACITY; i++) { - server->conns[i].state = HTTP_SERVER_CONN_FREE; + for (int i = 0; i < CHTTP_SERVER_CAPACITY; i++) { + server->conns[i].state = CHTTP_SERVER_CONN_FREE; server->conns[i].gen = 0; } @@ -4503,77 +4503,77 @@ int http_server_init(HTTP_Server *server) server->ready_head = 0; return socket_manager_init(&server->sockets, - server->socket_pool, HTTP_SERVER_CAPACITY); + server->socket_pool, CHTTP_SERVER_CAPACITY); } -void http_server_free(HTTP_Server *server) +void chttp_server_free(CHTTP_Server *server) { socket_manager_free(&server->sockets); for (int i = 0, j = 0; j < server->num_conns; i++) { - HTTP_ServerConn *conn = &server->conns[i]; - if (conn->state == HTTP_SERVER_CONN_FREE) + CHTTP_ServerConn *conn = &server->conns[i]; + if (conn->state == CHTTP_SERVER_CONN_FREE) continue; j++; - http_server_conn_free(conn); + chttp_server_conn_free(conn); } } -void http_server_set_input_limit(HTTP_Server *server, uint32_t limit) +void chttp_server_set_input_limit(CHTTP_Server *server, uint32_t limit) { server->input_buffer_limit = limit; } -void http_server_set_output_limit(HTTP_Server *server, uint32_t limit) +void chttp_server_set_output_limit(CHTTP_Server *server, uint32_t limit) { server->output_buffer_limit = limit; } -void http_server_set_trace_bytes(HTTP_Server *server, bool value) +void chttp_server_set_trace_bytes(CHTTP_Server *server, bool value) { server->trace_bytes = value; } -void http_server_set_reuse_addr(HTTP_Server *server, bool reuse) +void chttp_server_set_reuse_addr(CHTTP_Server *server, bool reuse) { server->reuse_addr = reuse; } -void http_server_set_backlog(HTTP_Server *server, int backlog) +void chttp_server_set_backlog(CHTTP_Server *server, int backlog) { server->backlog = backlog; } -int http_server_listen_tcp(HTTP_Server *server, - HTTP_String addr, Port port) +int chttp_server_listen_tcp(CHTTP_Server *server, + CHTTP_String addr, Port port) { return socket_manager_listen_tcp(&server->sockets, addr, port, server->backlog, server->reuse_addr); } -int http_server_listen_tls(HTTP_Server *server, - HTTP_String addr, Port port, HTTP_String cert_file_name, - HTTP_String key_file_name) +int chttp_server_listen_tls(CHTTP_Server *server, + CHTTP_String addr, Port port, CHTTP_String cert_file_name, + CHTTP_String key_file_name) { return socket_manager_listen_tls(&server->sockets, addr, port, server->backlog, server->reuse_addr, cert_file_name, key_file_name); } -int http_server_add_certificate(HTTP_Server *server, - HTTP_String domain, HTTP_String cert_file, HTTP_String key_file) +int chttp_server_add_certificate(CHTTP_Server *server, + CHTTP_String domain, CHTTP_String cert_file, CHTTP_String key_file) { return socket_manager_add_certificate(&server->sockets, domain, cert_file, key_file); } -int http_server_wakeup(HTTP_Server *server) +int chttp_server_wakeup(CHTTP_Server *server) { return socket_manager_wakeup(&server->sockets); } -void http_server_register_events(HTTP_Server *server, +void chttp_server_register_events(CHTTP_Server *server, EventRegister *reg) { socket_manager_register_events(&server->sockets, reg); @@ -4585,12 +4585,12 @@ void http_server_register_events(HTTP_Server *server, // to the ready queue. If the request is invalid, // close the socket. static void -check_request_buffer(HTTP_Server *server, HTTP_ServerConn *conn) +check_request_buffer(CHTTP_Server *server, CHTTP_ServerConn *conn) { - assert(conn->state == HTTP_SERVER_CONN_BUFFERING); + assert(conn->state == CHTTP_SERVER_CONN_BUFFERING); ByteView src = byte_queue_read_buf(&conn->input); - int ret = http_parse_request(src.ptr, src.len, &conn->request); + int ret = chttp_parse_request(src.ptr, src.len, &conn->request); if (ret < 0) { // Invalid request @@ -4615,22 +4615,22 @@ check_request_buffer(HTTP_Server *server, HTTP_ServerConn *conn) // Stop receiving I/O events while we are building the response socket_silent(&server->sockets, conn->handle, true); - conn->state = HTTP_SERVER_CONN_WAIT_STATUS; + conn->state = CHTTP_SERVER_CONN_WAIT_STATUS; conn->request_len = ret; conn->response_offset = byte_queue_offset(&conn->output); // Push to the ready queue - assert(server->num_ready < HTTP_SERVER_CAPACITY); - int tail = (server->ready_head + server->num_ready) % HTTP_SERVER_CAPACITY; + assert(server->num_ready < CHTTP_SERVER_CAPACITY); + int tail = (server->ready_head + server->num_ready) % CHTTP_SERVER_CAPACITY; server->ready[tail] = conn - server->conns; server->num_ready++; } } static void -http_server_conn_process_events(HTTP_Server *server, HTTP_ServerConn *conn) +chttp_server_conn_process_events(CHTTP_Server *server, CHTTP_ServerConn *conn) { - if (conn->state == HTTP_SERVER_CONN_FLUSHING) { + if (conn->state == CHTTP_SERVER_CONN_FLUSHING) { ByteView src = byte_queue_read_buf(&conn->output); @@ -4639,7 +4639,7 @@ http_server_conn_process_events(HTTP_Server *server, HTTP_ServerConn *conn) num = socket_send(&server->sockets, conn->handle, src.ptr, src.len); if (server->trace_bytes) - print_bytes(HTTP_STR("<< "), (HTTP_String) { src.ptr, num }); + print_bytes(CHTTP_STR("<< "), (CHTTP_String) { src.ptr, num }); byte_queue_read_ack(&conn->output, num); @@ -4656,11 +4656,11 @@ http_server_conn_process_events(HTTP_Server *server, HTTP_ServerConn *conn) socket_close(&server->sockets, conn->handle); return; } - conn->state = HTTP_SERVER_CONN_BUFFERING; + conn->state = CHTTP_SERVER_CONN_BUFFERING; } } - if (conn->state == HTTP_SERVER_CONN_BUFFERING) { + if (conn->state == CHTTP_SERVER_CONN_BUFFERING) { int min_recv = 1<<10; byte_queue_write_setmincap(&conn->input, min_recv); @@ -4676,7 +4676,7 @@ http_server_conn_process_events(HTTP_Server *server, HTTP_ServerConn *conn) num = socket_recv(&server->sockets, conn->handle, dst.ptr, dst.len); if (server->trace_bytes) - print_bytes(HTTP_STR(">> "), (HTTP_String) { dst.ptr, num }); + print_bytes(CHTTP_STR(">> "), (CHTTP_String) { dst.ptr, num }); byte_queue_write_ack(&conn->input, num); @@ -4688,38 +4688,38 @@ http_server_conn_process_events(HTTP_Server *server, HTTP_ServerConn *conn) } } -void http_server_process_events(HTTP_Server *server, +void chttp_server_process_events(CHTTP_Server *server, EventRegister reg) { - SocketEvent events[HTTP_SERVER_CAPACITY]; + SocketEvent events[CHTTP_SERVER_CAPACITY]; int num_events = socket_manager_translate_events(&server->sockets, events, reg); for (int i = 0; i < num_events; i++) { - HTTP_ServerConn *conn = events[i].user; + CHTTP_ServerConn *conn = events[i].user; if (events[i].type == SOCKET_EVENT_DISCONNECT) { - http_server_conn_free(conn); // TODO: what if this was in the ready queue? + chttp_server_conn_free(conn); // TODO: what if this was in the ready queue? server->num_conns--; } else if (events[i].type == SOCKET_EVENT_READY) { if (events[i].user == NULL) { - if (server->num_conns == HTTP_SERVER_CAPACITY) { + if (server->num_conns == CHTTP_SERVER_CAPACITY) { socket_close(&server->sockets, events[i].handle); continue; } int j = 0; - while (server->conns[j].state != HTTP_SERVER_CONN_FREE) { + while (server->conns[j].state != CHTTP_SERVER_CONN_FREE) { j++; - assert(i < HTTP_SERVER_CAPACITY); + assert(i < CHTTP_SERVER_CAPACITY); } conn = &server->conns[j]; - http_server_conn_init(conn, + chttp_server_conn_init(conn, events[i].handle, server->input_buffer_limit, server->output_buffer_limit); @@ -4729,44 +4729,44 @@ void http_server_process_events(HTTP_Server *server, } while (socket_ready(&server->sockets, events[i].handle) - && conn->state != HTTP_SERVER_CONN_WAIT_STATUS) - http_server_conn_process_events(server, conn); + && conn->state != CHTTP_SERVER_CONN_WAIT_STATUS) + chttp_server_conn_process_events(server, conn); } } } -bool http_server_next_request(HTTP_Server *server, - HTTP_Request **request, HTTP_ResponseBuilder *builder) +bool chttp_server_next_request(CHTTP_Server *server, + CHTTP_Request **request, CHTTP_ResponseBuilder *builder) { if (server->num_ready == 0) return false; - HTTP_ServerConn *conn = &server->conns[server->ready[server->ready_head]]; - server->ready_head = (server->ready_head + 1) % HTTP_SERVER_CAPACITY; + CHTTP_ServerConn *conn = &server->conns[server->ready[server->ready_head]]; + server->ready_head = (server->ready_head + 1) % CHTTP_SERVER_CAPACITY; server->num_ready--; - assert(conn->state == HTTP_SERVER_CONN_WAIT_STATUS); + assert(conn->state == CHTTP_SERVER_CONN_WAIT_STATUS); *request = &conn->request; - *builder = (HTTP_ResponseBuilder) { server, conn - server->conns, conn->gen }; + *builder = (CHTTP_ResponseBuilder) { server, conn - server->conns, conn->gen }; return true; } -void http_server_wait_request(HTTP_Server *server, - HTTP_Request **request, HTTP_ResponseBuilder *builder) +void chttp_server_wait_request(CHTTP_Server *server, + CHTTP_Request **request, CHTTP_ResponseBuilder *builder) { for (;;) { - void *ptrs[HTTP_SERVER_POLL_CAPACITY]; - struct pollfd polled[HTTP_SERVER_POLL_CAPACITY]; + void *ptrs[CHTTP_SERVER_POLL_CAPACITY]; + struct pollfd polled[CHTTP_SERVER_POLL_CAPACITY]; EventRegister reg = { ptrs, polled, 0 }; - http_server_register_events(server, ®); + chttp_server_register_events(server, ®); if (reg.num_polled > 0) POLL(reg.polled, reg.num_polled, -1); - http_server_process_events(server, reg); + chttp_server_process_events(server, reg); - if (http_server_next_request(server, request, builder)) + if (chttp_server_next_request(server, request, builder)) break; } } @@ -4777,17 +4777,17 @@ void http_server_wait_request(HTTP_Server *server, // can be returned, as any builder is invalidated by // incrementing the connection's generation counter // when a response is completed. -static HTTP_ServerConn* -builder_to_conn(HTTP_ResponseBuilder builder) +static CHTTP_ServerConn* +builder_to_conn(CHTTP_ResponseBuilder builder) { - HTTP_Server *server = builder.server; + CHTTP_Server *server = builder.server; if (server == NULL) return NULL; - if (builder.index > HTTP_SERVER_CAPACITY) + if (builder.index > CHTTP_SERVER_CAPACITY) return NULL; - HTTP_ServerConn *conn = &server->conns[builder.index]; + CHTTP_ServerConn *conn = &server->conns[builder.index]; if (builder.gen != conn->gen) return NULL; @@ -4862,31 +4862,31 @@ get_status_text(int code) } static void -write_status(HTTP_ServerConn *conn, int status) +write_status(CHTTP_ServerConn *conn, int status) { byte_queue_write_fmt(&conn->output, "HTTP/1.1 %d %s\r\n", status, get_status_text(status)); } -void http_response_builder_status(HTTP_ResponseBuilder builder, int status) +void chttp_response_builder_status(CHTTP_ResponseBuilder builder, int status) { - HTTP_ServerConn *conn = builder_to_conn(builder); + CHTTP_ServerConn *conn = builder_to_conn(builder); if (conn == NULL) return; - if (conn->state != HTTP_SERVER_CONN_WAIT_STATUS) { + if (conn->state != CHTTP_SERVER_CONN_WAIT_STATUS) { // Reset all response content and start from scrach. byte_queue_remove_from_offset(&conn->output, conn->response_offset); - conn->state = HTTP_SERVER_CONN_WAIT_STATUS; + conn->state = CHTTP_SERVER_CONN_WAIT_STATUS; } write_status(conn, status); - conn->state = HTTP_SERVER_CONN_WAIT_HEADER; + conn->state = CHTTP_SERVER_CONN_WAIT_HEADER; } -static bool is_header_valid(HTTP_String str) +static bool is_header_valid(CHTTP_String str) { bool has_colon = false; for (int i = 0; i < str.len; i++) { @@ -4900,13 +4900,13 @@ static bool is_header_valid(HTTP_String str) return has_colon; } -void http_response_builder_header(HTTP_ResponseBuilder builder, HTTP_String str) +void chttp_response_builder_header(CHTTP_ResponseBuilder builder, CHTTP_String str) { - HTTP_ServerConn *conn = builder_to_conn(builder); + CHTTP_ServerConn *conn = builder_to_conn(builder); if (conn == NULL) return; - if (conn->state != HTTP_SERVER_CONN_WAIT_HEADER) + if (conn->state != CHTTP_SERVER_CONN_WAIT_HEADER) return; // Header must contain a colon and no control characters @@ -4917,19 +4917,19 @@ void http_response_builder_header(HTTP_ResponseBuilder builder, HTTP_String str) byte_queue_write(&conn->output, "\r\n", 2); } -static void append_special_headers(HTTP_ServerConn *conn) +static void append_special_headers(CHTTP_ServerConn *conn) { - HTTP_String s; + CHTTP_String s; if (conn->closing) { - s = HTTP_STR("Connection: Close\r\n"); + s = CHTTP_STR("Connection: Close\r\n"); byte_queue_write(&conn->output, s.ptr, s.len); } else { - s = HTTP_STR("Connection: Keep-Alive\r\n"); + s = CHTTP_STR("Connection: Keep-Alive\r\n"); byte_queue_write(&conn->output, s.ptr, s.len); } - s = HTTP_STR("Content-Length: "); + s = CHTTP_STR("Content-Length: "); byte_queue_write(&conn->output, s.ptr, s.len); conn->content_length_value_offset = byte_queue_offset(&conn->output); @@ -4937,14 +4937,14 @@ static void append_special_headers(HTTP_ServerConn *conn) #define TEN_SPACES " " _Static_assert(sizeof(TEN_SPACES) == 10+1); - s = HTTP_STR(TEN_SPACES "\r\n"); + s = CHTTP_STR(TEN_SPACES "\r\n"); byte_queue_write(&conn->output, s.ptr, s.len); byte_queue_write(&conn->output, "\r\n", 2); conn->content_length_offset = byte_queue_offset(&conn->output); } -static void patch_special_headers(HTTP_ServerConn *conn) +static void patch_special_headers(CHTTP_ServerConn *conn) { int content_length = byte_queue_size_from_offset(&conn->output, conn->content_length_offset); @@ -4955,52 +4955,52 @@ static void patch_special_headers(HTTP_ServerConn *conn) byte_queue_patch(&conn->output, conn->content_length_value_offset, tmp, len); } -void http_response_builder_body(HTTP_ResponseBuilder builder, HTTP_String str) +void chttp_response_builder_body(CHTTP_ResponseBuilder builder, CHTTP_String str) { - HTTP_ServerConn *conn = builder_to_conn(builder); + CHTTP_ServerConn *conn = builder_to_conn(builder); if (conn == NULL) return; - if (conn->state == HTTP_SERVER_CONN_WAIT_HEADER) { + if (conn->state == CHTTP_SERVER_CONN_WAIT_HEADER) { append_special_headers(conn); - conn->state = HTTP_SERVER_CONN_WAIT_BODY; + conn->state = CHTTP_SERVER_CONN_WAIT_BODY; } - if (conn->state != HTTP_SERVER_CONN_WAIT_BODY) + if (conn->state != CHTTP_SERVER_CONN_WAIT_BODY) return; byte_queue_write(&conn->output, str.ptr, str.len); } -void http_response_builder_body_cap(HTTP_ResponseBuilder builder, int cap) +void chttp_response_builder_body_cap(CHTTP_ResponseBuilder builder, int cap) { - HTTP_ServerConn *conn = builder_to_conn(builder); + CHTTP_ServerConn *conn = builder_to_conn(builder); if (conn == NULL) return; - if (conn->state == HTTP_SERVER_CONN_WAIT_HEADER) { + if (conn->state == CHTTP_SERVER_CONN_WAIT_HEADER) { append_special_headers(conn); - conn->state = HTTP_SERVER_CONN_WAIT_BODY; + conn->state = CHTTP_SERVER_CONN_WAIT_BODY; } - if (conn->state != HTTP_SERVER_CONN_WAIT_BODY) + if (conn->state != CHTTP_SERVER_CONN_WAIT_BODY) return; byte_queue_write_setmincap(&conn->output, cap); } -char *http_response_builder_body_buf(HTTP_ResponseBuilder builder, int *cap) +char *chttp_response_builder_body_buf(CHTTP_ResponseBuilder builder, int *cap) { - HTTP_ServerConn *conn = builder_to_conn(builder); + CHTTP_ServerConn *conn = builder_to_conn(builder); if (conn == NULL) return NULL; - if (conn->state == HTTP_SERVER_CONN_WAIT_HEADER) { + if (conn->state == CHTTP_SERVER_CONN_WAIT_HEADER) { append_special_headers(conn); - conn->state = HTTP_SERVER_CONN_WAIT_BODY; + conn->state = CHTTP_SERVER_CONN_WAIT_BODY; } - if (conn->state != HTTP_SERVER_CONN_WAIT_BODY) + if (conn->state != CHTTP_SERVER_CONN_WAIT_BODY) return NULL; ByteView tmp = byte_queue_write_buf(&conn->output); @@ -5008,47 +5008,47 @@ char *http_response_builder_body_buf(HTTP_ResponseBuilder builder, int *cap) return tmp.ptr; } -void http_response_builder_body_ack(HTTP_ResponseBuilder builder, int num) +void chttp_response_builder_body_ack(CHTTP_ResponseBuilder builder, int num) { - HTTP_ServerConn *conn = builder_to_conn(builder); + CHTTP_ServerConn *conn = builder_to_conn(builder); if (conn == NULL) return; - if (conn->state != HTTP_SERVER_CONN_WAIT_BODY) + if (conn->state != CHTTP_SERVER_CONN_WAIT_BODY) return; byte_queue_write_ack(&conn->output, num); } -void http_response_builder_send(HTTP_ResponseBuilder builder) +void chttp_response_builder_send(CHTTP_ResponseBuilder builder) { - HTTP_ServerConn *conn = builder_to_conn(builder); + CHTTP_ServerConn *conn = builder_to_conn(builder); if (conn == NULL) return; - if (conn->state == HTTP_SERVER_CONN_WAIT_STATUS) { + if (conn->state == CHTTP_SERVER_CONN_WAIT_STATUS) { write_status(conn, 500); - conn->state = HTTP_SERVER_CONN_WAIT_HEADER; + conn->state = CHTTP_SERVER_CONN_WAIT_HEADER; } - if (conn->state == HTTP_SERVER_CONN_WAIT_HEADER) { + if (conn->state == CHTTP_SERVER_CONN_WAIT_HEADER) { append_special_headers(conn); - conn->state = HTTP_SERVER_CONN_WAIT_BODY; + conn->state = CHTTP_SERVER_CONN_WAIT_BODY; } - assert(conn->state == HTTP_SERVER_CONN_WAIT_BODY); + assert(conn->state == CHTTP_SERVER_CONN_WAIT_BODY); patch_special_headers(conn); // Remove the buffered request byte_queue_read_ack(&conn->input, conn->request_len); - conn->state = HTTP_SERVER_CONN_FLUSHING; + conn->state = CHTTP_SERVER_CONN_FLUSHING; conn->gen++; // Enable back I/O events socket_silent(&builder.server->sockets, conn->handle, false); - http_server_conn_process_events(builder.server, conn); + chttp_server_conn_process_events(builder.server, conn); } //////////////////////////////////////////////////////////////////////////////////////// diff --git a/chttp.h b/chttp.h index d032947..2b14cf4 100644 --- a/chttp.h +++ b/chttp.h @@ -1,5 +1,5 @@ -#ifndef HTTP_INCLUDED -#define HTTP_INCLUDED +#ifndef CHTTP_INCLUDED +#define CHTTP_INCLUDED // cHTTP, an HTTP client and server library! // // This file was generated automatically. Do not modify directly. @@ -45,56 +45,56 @@ enum { - HTTP_OK = 0, + CHTTP_OK = 0, // A generic error occurred - HTTP_ERROR_UNSPECIFIED = -1, + CHTTP_ERROR_UNSPECIFIED = -1, // Out of memory - HTTP_ERROR_OOM = -2, + CHTTP_ERROR_OOM = -2, // Invalid URL - HTTP_ERROR_BADURL = -3, + CHTTP_ERROR_BADURL = -3, // Parallel request limit reached - HTTP_ERROR_REQLIMIT = -4, + CHTTP_ERROR_REQLIMIT = -4, // Invalid handle - HTTP_ERROR_BADHANDLE = -5, + CHTTP_ERROR_BADHANDLE = -5, // TLS support not built-in - HTTP_ERROR_NOTLS = -6, + CHTTP_ERROR_NOTLS = -6, }; // String type used throughout cHTTP. typedef struct { char *ptr; int len; -} HTTP_String; +} CHTTP_String; // Compare two strings and return true iff they have // the same contents. -bool http_streq(HTTP_String s1, HTTP_String s2); +bool chttp_streq(CHTTP_String s1, CHTTP_String s2); // Compre two strings case-insensitively (uppercase and // lowercase versions of a letter are considered the same) // and return true iff they have the same contents. -bool http_streqcase(HTTP_String s1, HTTP_String s2); +bool chttp_streqcase(CHTTP_String s1, CHTTP_String s2); // Remove spaces and tabs from the start and the end of // a string. This doesn't change the original string and // the new one references the contents of the original one. -HTTP_String http_trim(HTTP_String s); +CHTTP_String chttp_trim(CHTTP_String s); // Print the contents of a byte string with the given prefix. // This is primarily used for debugging purposes. -void print_bytes(HTTP_String prefix, HTTP_String src); +void print_bytes(CHTTP_String prefix, CHTTP_String src); // TODO: comment -char *http_strerror(int code); +char *chttp_strerror(int code); // Macro to simplify converting string literals to -// HTTP_String. +// CHTTP_String. // // Instead of doing this: // @@ -102,7 +102,7 @@ char *http_strerror(int code); // // You do this: // -// HTTP_String s = HTTP_STR("some string") +// CHTTP_String s = CHTTP_STR("some string") // // This is a bit cumbersome, but better than null-terminated // strings, having a pointer and length variable pairs whenever @@ -112,177 +112,177 @@ char *http_strerror(int code); // #define S(X) ... // // But I don't want to cause collisions with user code. -#define HTTP_STR(X) ((HTTP_String) {(X), sizeof(X)-1}) +#define CHTTP_STR(X) ((CHTTP_String) {(X), sizeof(X)-1}) // Returns the number of items of a static array. -#define HTTP_COUNT(X) (int) (sizeof(X) / sizeof((X)[0])) +#define CHTTP_COUNT(X) (int) (sizeof(X) / sizeof((X)[0])) -// Macro to unpack an HTTP_String into its length and pointer components. -// Useful for passing HTTP_String to printf-style functions with "%.*s" format. -// Example: printf("%.*s", HTTP_UNPACK(str)); -#define HTTP_UNPACK(X) (X).len, (X).ptr +// Macro to unpack an CHTTP_String into its length and pointer components. +// Useful for passing CHTTP_String to printf-style functions with "%.*s" format. +// Example: printf("%.*s", CHTTP_UNPACK(str)); +#define CHTTP_UNPACK(X) (X).len, (X).ptr // TODO: comment -#define HTTP_UNREACHABLE __builtin_trap() +#define CHTTP_UNREACHABLE __builtin_trap() //////////////////////////////////////////////////////////////////////////////////////// // src/parse.h //////////////////////////////////////////////////////////////////////////////////////// -#define HTTP_MAX_HEADERS 32 +#define CHTTP_MAX_HEADERS 32 typedef struct { unsigned int data; -} HTTP_IPv4; +} CHTTP_IPv4; typedef struct { unsigned short data[8]; -} HTTP_IPv6; +} CHTTP_IPv6; typedef enum { - HTTP_HOST_MODE_VOID = 0, - HTTP_HOST_MODE_NAME, - HTTP_HOST_MODE_IPV4, - HTTP_HOST_MODE_IPV6, -} HTTP_HostMode; + CHTTP_HOST_MODE_VOID = 0, + CHTTP_HOST_MODE_NAME, + CHTTP_HOST_MODE_IPV4, + CHTTP_HOST_MODE_IPV6, +} CHTTP_HostMode; typedef struct { - HTTP_HostMode mode; - HTTP_String text; + CHTTP_HostMode mode; + CHTTP_String text; union { - HTTP_String name; - HTTP_IPv4 ipv4; - HTTP_IPv6 ipv6; + CHTTP_String name; + CHTTP_IPv4 ipv4; + CHTTP_IPv6 ipv6; }; -} HTTP_Host; +} CHTTP_Host; typedef struct { - HTTP_String userinfo; - HTTP_Host host; + CHTTP_String userinfo; + CHTTP_Host host; int port; -} HTTP_Authority; +} CHTTP_Authority; // ZII typedef struct { - HTTP_String scheme; - HTTP_Authority authority; - HTTP_String path; - HTTP_String query; - HTTP_String fragment; -} HTTP_URL; + CHTTP_String scheme; + CHTTP_Authority authority; + CHTTP_String path; + CHTTP_String query; + CHTTP_String fragment; +} CHTTP_URL; typedef enum { - HTTP_METHOD_GET, - HTTP_METHOD_HEAD, - HTTP_METHOD_POST, - HTTP_METHOD_PUT, - HTTP_METHOD_DELETE, - HTTP_METHOD_CONNECT, - HTTP_METHOD_OPTIONS, - HTTP_METHOD_TRACE, - HTTP_METHOD_PATCH, -} HTTP_Method; + CHTTP_METHOD_GET, + CHTTP_METHOD_HEAD, + CHTTP_METHOD_POST, + CHTTP_METHOD_PUT, + CHTTP_METHOD_DELETE, + CHTTP_METHOD_CONNECT, + CHTTP_METHOD_OPTIONS, + CHTTP_METHOD_TRACE, + CHTTP_METHOD_PATCH, +} CHTTP_Method; typedef struct { - HTTP_String name; - HTTP_String value; -} HTTP_Header; + CHTTP_String name; + CHTTP_String value; +} CHTTP_Header; typedef struct { bool secure; - HTTP_Method method; - HTTP_URL url; + CHTTP_Method method; + CHTTP_URL url; int minor; int num_headers; - HTTP_Header headers[HTTP_MAX_HEADERS]; - HTTP_String body; -} HTTP_Request; + CHTTP_Header headers[CHTTP_MAX_HEADERS]; + CHTTP_String body; +} CHTTP_Request; typedef struct { void* context; int minor; int status; - HTTP_String reason; + CHTTP_String reason; int num_headers; - HTTP_Header headers[HTTP_MAX_HEADERS]; - HTTP_String body; -} HTTP_Response; + CHTTP_Header headers[CHTTP_MAX_HEADERS]; + CHTTP_String body; +} CHTTP_Response; -int http_parse_ipv4 (char *src, int len, HTTP_IPv4 *ipv4); -int http_parse_ipv6 (char *src, int len, HTTP_IPv6 *ipv6); -int http_parse_url (char *src, int len, HTTP_URL *url); -int http_parse_request (char *src, int len, HTTP_Request *req); -int http_parse_response (char *src, int len, HTTP_Response *res); +int chttp_parse_ipv4 (char *src, int len, CHTTP_IPv4 *ipv4); +int chttp_parse_ipv6 (char *src, int len, CHTTP_IPv6 *ipv6); +int chttp_parse_url (char *src, int len, CHTTP_URL *url); +int chttp_parse_request (char *src, int len, CHTTP_Request *req); +int chttp_parse_response (char *src, int len, CHTTP_Response *res); -int http_find_header (HTTP_Header *headers, int num_headers, HTTP_String name); +int chttp_find_header (CHTTP_Header *headers, int num_headers, CHTTP_String name); -HTTP_String http_get_cookie (HTTP_Request *req, HTTP_String name); -HTTP_String http_get_param (HTTP_String body, HTTP_String str, char *mem, int cap); -int http_get_param_i (HTTP_String body, HTTP_String str); +CHTTP_String chttp_get_cookie (CHTTP_Request *req, CHTTP_String name); +CHTTP_String chttp_get_param (CHTTP_String body, CHTTP_String str, char *mem, int cap); +int chttp_get_param_i (CHTTP_String body, CHTTP_String str); // Checks whether the request was meant for the host with the given // domain an port. If port is -1, the default value of 80 is assumed. -bool http_match_host(HTTP_Request *req, HTTP_String domain, int port); +bool chttp_match_host(CHTTP_Request *req, CHTTP_String domain, int port); // Date and cookie types for Set-Cookie header parsing typedef enum { - HTTP_WEEKDAY_MON, - HTTP_WEEKDAY_TUE, - HTTP_WEEKDAY_WED, - HTTP_WEEKDAY_THU, - HTTP_WEEKDAY_FRI, - HTTP_WEEKDAY_SAT, - HTTP_WEEKDAY_SUN, -} HTTP_WeekDay; + CHTTP_WEEKDAY_MON, + CHTTP_WEEKDAY_TUE, + CHTTP_WEEKDAY_WED, + CHTTP_WEEKDAY_THU, + CHTTP_WEEKDAY_FRI, + CHTTP_WEEKDAY_SAT, + CHTTP_WEEKDAY_SUN, +} CHTTP_WeekDay; typedef enum { - HTTP_MONTH_JAN, - HTTP_MONTH_FEB, - HTTP_MONTH_MAR, - HTTP_MONTH_APR, - HTTP_MONTH_MAY, - HTTP_MONTH_JUN, - HTTP_MONTH_JUL, - HTTP_MONTH_AUG, - HTTP_MONTH_SEP, - HTTP_MONTH_OCT, - HTTP_MONTH_NOV, - HTTP_MONTH_DEC, -} HTTP_Month; + CHTTP_MONTH_JAN, + CHTTP_MONTH_FEB, + CHTTP_MONTH_MAR, + CHTTP_MONTH_APR, + CHTTP_MONTH_MAY, + CHTTP_MONTH_JUN, + CHTTP_MONTH_JUL, + CHTTP_MONTH_AUG, + CHTTP_MONTH_SEP, + CHTTP_MONTH_OCT, + CHTTP_MONTH_NOV, + CHTTP_MONTH_DEC, +} CHTTP_Month; typedef struct { - HTTP_WeekDay week_day; + CHTTP_WeekDay week_day; int day; - HTTP_Month month; + CHTTP_Month month; int year; int hour; int minute; int second; -} HTTP_Date; +} CHTTP_Date; typedef struct { - HTTP_String name; - HTTP_String value; + CHTTP_String name; + CHTTP_String value; bool secure; - bool http_only; + bool chttp_only; bool have_date; - HTTP_Date date; + CHTTP_Date date; bool have_max_age; uint32_t max_age; bool have_domain; - HTTP_String domain; + CHTTP_String domain; bool have_path; - HTTP_String path; -} HTTP_SetCookie; + CHTTP_String path; +} CHTTP_SetCookie; // Parses a Set-Cookie header value // Returns 0 on success, -1 on error -int http_parse_set_cookie(HTTP_String str, HTTP_SetCookie *out); +int chttp_parse_set_cookie(CHTTP_String str, CHTTP_SetCookie *out); //////////////////////////////////////////////////////////////////////////////////////// // src/secure_context.h @@ -323,10 +323,10 @@ typedef struct { } ServerSecureContext; int server_secure_context_init(ServerSecureContext *ctx, - HTTP_String cert_file, HTTP_String key_file); + CHTTP_String cert_file, CHTTP_String key_file); void server_secure_context_free(ServerSecureContext *ctx); int server_secure_context_add_certificate(ServerSecureContext *ctx, - HTTP_String domain, HTTP_String cert_file, HTTP_String key_file); + CHTTP_String domain, CHTTP_String cert_file, CHTTP_String key_file); //////////////////////////////////////////////////////////////////////////////////////// // src/socket.h @@ -456,8 +456,8 @@ typedef struct { // Internal use only typedef struct { union { - HTTP_IPv4 ipv4; - HTTP_IPv6 ipv6; + CHTTP_IPv4 ipv4; + CHTTP_IPv6 ipv6; }; bool is_ipv4; Port port; @@ -574,7 +574,7 @@ void socket_manager_free(SocketManager *sm); // can only be used once per manager. // Returns 0 on success, -1 on error. int socket_manager_listen_tcp(SocketManager *sm, - HTTP_String addr, Port port, int backlog, + CHTTP_String addr, Port port, int backlog, bool reuse_addr); // Same as the previous function, but incoming @@ -585,9 +585,9 @@ int socket_manager_listen_tcp(SocketManager *sm, // and secure connections. // Returns 0 on success, -1 on error. int socket_manager_listen_tls(SocketManager *sm, - HTTP_String addr, Port port, int backlog, - bool reuse_addr, HTTP_String cert_file, - HTTP_String key_file); + CHTTP_String addr, Port port, int backlog, + bool reuse_addr, CHTTP_String cert_file, + CHTTP_String key_file); // If the socket manager was configures to accept // TLS connections, this adds additional certificates @@ -595,7 +595,7 @@ int socket_manager_listen_tls(SocketManager *sm, // authenticity. // Returns 0 on success, -1 on error. int socket_manager_add_certificate(SocketManager *sm, - HTTP_String domain, HTTP_String cert_file, HTTP_String key_file); + CHTTP_String domain, CHTTP_String cert_file, CHTTP_String key_file); // When a thread is blocked on a poll() call for // descriptors associated to this socket manager, @@ -638,9 +638,9 @@ typedef struct { ConnectTargetType type; Port port; union { - HTTP_IPv4 ipv4; - HTTP_IPv6 ipv6; - HTTP_String name; + CHTTP_IPv4 ipv4; + CHTTP_IPv6 ipv6; + CHTTP_String name; }; } ConnectTarget; @@ -721,7 +721,7 @@ typedef uint64_t ByteQueueOffset; // Initialize the queue with a given capacity limit. // This is just a soft limit. The queue will allocate // dynamically as needed up to this limit and won't -// grow further. When the limit is reached, http_queue_full +// grow further. When the limit is reached, chttp_queue_full // returns true. void byte_queue_init(ByteQueue *queue, uint32_t limit); @@ -837,35 +837,35 @@ void byte_queue_remove_from_offset(ByteQueue *queue, ByteQueueOffset offset); // // The output is a certificate file in PEM format and a private // key file with the key used to sign the certificate. -int http_create_test_certificate(HTTP_String C, HTTP_String O, HTTP_String CN, - HTTP_String cert_file, HTTP_String key_file); +int chttp_create_test_certificate(CHTTP_String C, CHTTP_String O, CHTTP_String CN, + CHTTP_String cert_file, CHTTP_String key_file); //////////////////////////////////////////////////////////////////////////////////////// // src/client.h //////////////////////////////////////////////////////////////////////////////////////// -#ifndef HTTP_CLIENT_CAPACITY +#ifndef CHTTP_CLIENT_CAPACITY // The maximum ammount of requests that can be performed // in parallel. -#define HTTP_CLIENT_CAPACITY (1<<7) +#define CHTTP_CLIENT_CAPACITY (1<<7) #endif // Maximum number of descriptors the client will want // to wait on. It's one per connection plus the wakeup // self-pipe. -#define HTTP_CLIENT_POLL_CAPACITY (HTTP_CLIENT_CAPACITY+1) +#define CHTTP_CLIENT_POLL_CAPACITY (CHTTP_CLIENT_CAPACITY+1) -#ifndef HTTP_COOKIE_JAR_CAPACITY +#ifndef CHTTP_COOKIE_JAR_CAPACITY // Maximum number of cookies that can be associated to a // single client. -#define HTTP_COOKIE_JAR_CAPACITY 128 +#define CHTTP_COOKIE_JAR_CAPACITY 128 #endif typedef struct { // Cookie name and value - HTTP_String name; - HTTP_String value; + CHTTP_String name; + CHTTP_String value; // If the "exact_domain" is true, the cookie // can only be sent to the exact domain referred @@ -873,7 +873,7 @@ typedef struct { // "exact_domain" is false, then the cookie is // compatible with subdomains. bool exact_domain; - HTTP_String domain; + CHTTP_String domain; // If "exact_path" is set, the cookie is only // compatible with requests to paths that match @@ -881,40 +881,40 @@ typedef struct { // then any path that starts with "path" is // compatible with the cookie. bool exact_path; - HTTP_String path; + CHTTP_String path; // This cookie can only be sent over HTTPS bool secure; -} HTTP_CookieJarEntry; +} CHTTP_CookieJarEntry; typedef struct { int count; - HTTP_CookieJarEntry items[HTTP_COOKIE_JAR_CAPACITY]; -} HTTP_CookieJar; + CHTTP_CookieJarEntry items[CHTTP_COOKIE_JAR_CAPACITY]; +} CHTTP_CookieJar; typedef enum { - HTTP_CLIENT_CONN_FREE, - HTTP_CLIENT_CONN_WAIT_METHOD, - HTTP_CLIENT_CONN_WAIT_URL, - HTTP_CLIENT_CONN_WAIT_HEADER, - HTTP_CLIENT_CONN_WAIT_BODY, - HTTP_CLIENT_CONN_FLUSHING, - HTTP_CLIENT_CONN_BUFFERING, - HTTP_CLIENT_CONN_COMPLETE, -} HTTP_ClientConnState; + CHTTP_CLIENT_CONN_FREE, + CHTTP_CLIENT_CONN_WAIT_METHOD, + CHTTP_CLIENT_CONN_WAIT_URL, + CHTTP_CLIENT_CONN_WAIT_HEADER, + CHTTP_CLIENT_CONN_WAIT_BODY, + CHTTP_CLIENT_CONN_FLUSHING, + CHTTP_CLIENT_CONN_BUFFERING, + CHTTP_CLIENT_CONN_COMPLETE, +} CHTTP_ClientConnState; // Fields of this struct are private -typedef struct HTTP_Client HTTP_Client; +typedef struct CHTTP_Client CHTTP_Client; typedef struct { - HTTP_ClientConnState state; + CHTTP_ClientConnState state; // Handle to the socket SocketHandle handle; // Pointer back to the client - HTTP_Client *client; + CHTTP_Client *client; // Generation counter for request builder validation uint16_t gen; @@ -930,11 +930,11 @@ typedef struct { bool dont_verify_cert; // Allocated copy of the URL string - HTTP_String url_buffer; + CHTTP_String url_buffer; // Parsed URL for connection establishment // All url.* pointers reference into url_buffer - HTTP_URL url; + CHTTP_URL url; // Data received from the server ByteQueue input; @@ -949,7 +949,7 @@ typedef struct { int result; // Parsed response once complete - HTTP_Response response; + CHTTP_Response response; // This offset points to the first byte that comes // after the string "Content-Length: ". @@ -960,10 +960,10 @@ typedef struct { // content byte subtracting it from the offset reached // when the request is marked as done. ByteQueueOffset content_length_offset; -} HTTP_ClientConn; +} CHTTP_ClientConn; // Fields of this struct are private -struct HTTP_Client { +struct CHTTP_Client { // Size limit of the input and output buffer of each // connection. @@ -971,18 +971,18 @@ struct HTTP_Client { uint32_t output_buffer_limit; // List of cookies created during this session - HTTP_CookieJar cookie_jar; + CHTTP_CookieJar cookie_jar; // Array of connections. The counter contains the // number of structs such that state!=FREE. int num_conns; - HTTP_ClientConn conns[HTTP_CLIENT_CAPACITY]; + CHTTP_ClientConn conns[CHTTP_CLIENT_CAPACITY]; // Queue of indices referring to connections that // are in the COMPLETE state. int num_ready; int ready_head; - int ready[HTTP_CLIENT_CAPACITY]; + int ready[CHTTP_CLIENT_CAPACITY]; // Asynchronous TCP and TLS socket abstraction SocketManager sockets; @@ -992,80 +992,80 @@ struct HTTP_Client { // manager with a pointer to it. This allows // allocating the exact number of sockets we // will need. - Socket socket_pool[HTTP_CLIENT_CAPACITY]; + Socket socket_pool[CHTTP_CLIENT_CAPACITY]; }; // Initialize an HTTP client object. This allows one to // perform a number of requests in parallel. -int http_client_init(HTTP_Client *client); +int chttp_client_init(CHTTP_Client *client); // Release resources associated to a client object. -void http_client_free(HTTP_Client *client); +void chttp_client_free(CHTTP_Client *client); // Set input and output buffer size limit for any // given connection. The default value is 1MB -void http_client_set_input_limit(HTTP_Client *client, uint32_t limit); -void http_client_set_output_limit(HTTP_Client *client, uint32_t limit); +void chttp_client_set_input_limit(CHTTP_Client *client, uint32_t limit); +void chttp_client_set_output_limit(CHTTP_Client *client, uint32_t limit); // When a thread is blocked waiting for client events, // other threads can call this function to wake it up. -int http_client_wakeup(HTTP_Client *client); +int chttp_client_wakeup(CHTTP_Client *client); typedef struct { - HTTP_Client *client; + CHTTP_Client *client; uint16_t index; uint16_t gen; -} HTTP_RequestBuilder; +} CHTTP_RequestBuilder; // Create a new request builder object. -HTTP_RequestBuilder http_client_get_builder(HTTP_Client *client); +CHTTP_RequestBuilder chttp_client_get_builder(CHTTP_Client *client); // TODO: comment -void http_request_builder_set_user(HTTP_RequestBuilder builder, +void chttp_request_builder_set_user(CHTTP_RequestBuilder builder, void *user); // TODO: comment -void http_request_builder_trace(HTTP_RequestBuilder builder, +void chttp_request_builder_trace(CHTTP_RequestBuilder builder, bool trace_bytes); // TODO: comment -void http_request_builder_insecure(HTTP_RequestBuilder builder, +void chttp_request_builder_insecure(CHTTP_RequestBuilder builder, bool insecure); // Set the method of the current request. This is the first // function of the request builder that the user must call. -void http_request_builder_method(HTTP_RequestBuilder builder, - HTTP_Method method); +void chttp_request_builder_method(CHTTP_RequestBuilder builder, + CHTTP_Method method); // Set the URL of the current request. This must be set after // the method and before any header/body -void http_request_builder_target(HTTP_RequestBuilder builder, - HTTP_String url); +void chttp_request_builder_target(CHTTP_RequestBuilder builder, + CHTTP_String url); // After the URL, the user may set zero or more headers. -void http_request_builder_header(HTTP_RequestBuilder builder, - HTTP_String str); +void chttp_request_builder_header(CHTTP_RequestBuilder builder, + CHTTP_String str); // Append bytes to the request's body. You can call this // any amount of times, as long as it's after having set // the URL. -void http_request_builder_body(HTTP_RequestBuilder builder, - HTTP_String str); +void chttp_request_builder_body(CHTTP_RequestBuilder builder, + CHTTP_String str); // Mark this request as complete. This invalidates the // builder. // Returns 0 on success, -1 on error. -int http_request_builder_send(HTTP_RequestBuilder builder); +int chttp_request_builder_send(CHTTP_RequestBuilder builder); // Resets the event register with the list of descriptors // the client wants monitored. -void http_client_register_events(HTTP_Client *client, +void chttp_client_register_events(CHTTP_Client *client, EventRegister *reg); // The caller has waited for poll() to return and some // I/O events to be triggered, so now the HTTP client // can continue its buffering and flushing operations. -void http_client_process_events(HTTP_Client *client, +void chttp_client_process_events(CHTTP_Client *client, EventRegister reg); // After some I/O events were processes, some responses @@ -1073,86 +1073,86 @@ void http_client_process_events(HTTP_Client *client, // buffered responses. If a request was available, true // is returned. If no more are avaiable, false is returned. // The returned response must be freed using the -// http_free_response function. +// chttp_free_response function. // TODO: Better comment talking about output arguments -bool http_client_next_response(HTTP_Client *client, - int *result, void **user, HTTP_Response **response); +bool chttp_client_next_response(CHTTP_Client *client, + int *result, void **user, CHTTP_Response **response); // TODO: comment -void http_client_wait_response(HTTP_Client *client, - int *result, void **user, HTTP_Response **response); +void chttp_client_wait_response(CHTTP_Client *client, + int *result, void **user, CHTTP_Response **response); // Free a response object. You can't access its fields // again after this. -void http_free_response(HTTP_Response *response); +void chttp_free_response(CHTTP_Response *response); // Perform a blocking GET request -int http_get(HTTP_String url, HTTP_String *headers, - int num_headers, HTTP_Response **response); +int chttp_get(CHTTP_String url, CHTTP_String *headers, + int num_headers, CHTTP_Response **response); // Perform a blocking POST request -int http_post(HTTP_String url, HTTP_String *headers, - int num_headers, HTTP_String body, - HTTP_Response **response); +int chttp_post(CHTTP_String url, CHTTP_String *headers, + int num_headers, CHTTP_String body, + CHTTP_Response **response); // Perform a blocking PUT request -int http_put(HTTP_String url, HTTP_String *headers, - int num_headers, HTTP_String body, - HTTP_Response **response); +int chttp_put(CHTTP_String url, CHTTP_String *headers, + int num_headers, CHTTP_String body, + CHTTP_Response **response); // Perform a blocking DELETE request -int http_delete(HTTP_String url, HTTP_String *headers, - int num_headers, HTTP_Response **response); +int chttp_delete(CHTTP_String url, CHTTP_String *headers, + int num_headers, CHTTP_Response **response); //////////////////////////////////////////////////////////////////////////////////////// // src/server.h //////////////////////////////////////////////////////////////////////////////////////// -#ifndef HTTP_SERVER_CAPACITY +#ifndef CHTTP_SERVER_CAPACITY // The maximum ammount of requests that can be handled // in parallel. -#define HTTP_SERVER_CAPACITY (1<<9) +#define CHTTP_SERVER_CAPACITY (1<<9) #endif // Maximum number of descriptors the server will want // to wait on. It's one per connection plus two for the // TCP and TLS listener, plus one for the wakeup self-pipe. -#define HTTP_SERVER_POLL_CAPACITY (HTTP_SERVER_CAPACITY+3) +#define CHTTP_SERVER_POLL_CAPACITY (CHTTP_SERVER_CAPACITY+3) typedef enum { // This struct is unused - HTTP_SERVER_CONN_FREE, + CHTTP_SERVER_CONN_FREE, // No request was buffered yet. - HTTP_SERVER_CONN_BUFFERING, + CHTTP_SERVER_CONN_BUFFERING, // A request was just buffered and is waiting for // the user to build a response. To be specific, // it's waiting for the user to set a response status. - HTTP_SERVER_CONN_WAIT_STATUS, + CHTTP_SERVER_CONN_WAIT_STATUS, // A request is buffered and a status was set. Now // the user can set a header or append the first // bytes of the response body. - HTTP_SERVER_CONN_WAIT_HEADER, + CHTTP_SERVER_CONN_WAIT_HEADER, // A request is buffered and some bytes were appended // to the response. Now the user can either append more // bytes or send out the response. - HTTP_SERVER_CONN_WAIT_BODY, + CHTTP_SERVER_CONN_WAIT_BODY, // A response has been produced and it's being flushed. - HTTP_SERVER_CONN_FLUSHING, + CHTTP_SERVER_CONN_FLUSHING, -} HTTP_ServerConnState; +} CHTTP_ServerConnState; // This structure represents the HTTP connection to // a client. typedef struct { // If false, this struct is unused - HTTP_ServerConnState state; + CHTTP_ServerConnState state; // Handle to the socket SocketHandle handle; @@ -1177,7 +1177,7 @@ typedef struct { // When the state is WAIT_STATUS, WAIT_HEADER, // or WAIT_BODY, this contains the parsed version // of the buffered request. - HTTP_Request request; + CHTTP_Request request; // Length of the buffered request when the request // field is valid. @@ -1202,7 +1202,7 @@ typedef struct { // it from the offset reached when the response is marked // as done. ByteQueueOffset content_length_offset; -} HTTP_ServerConn; +} CHTTP_ServerConn; typedef struct { @@ -1218,13 +1218,13 @@ typedef struct { // Array of connections. The counter contains the // number of structs such that state=FREE. int num_conns; - HTTP_ServerConn conns[HTTP_SERVER_CAPACITY]; + CHTTP_ServerConn conns[CHTTP_SERVER_CAPACITY]; // Queue of indices referring to connections that // are in the WAIT_STATUS state. int num_ready; int ready_head; - int ready[HTTP_SERVER_CAPACITY]; + int ready[CHTTP_SERVER_CAPACITY]; // Asynchronous TCP and TLS socket abstraction SocketManager sockets; @@ -1234,74 +1234,74 @@ typedef struct { // manager with a pointer to it. This allows // allocating the exact number of sockets we // will need. - Socket socket_pool[HTTP_SERVER_CAPACITY]; + Socket socket_pool[CHTTP_SERVER_CAPACITY]; -} HTTP_Server; +} CHTTP_Server; // Initialize the HTTP server object. By default, it won't // listen for connections. You need to call // -// http_server_listen_tcp -// http_server_listen_tls +// chttp_server_listen_tcp +// chttp_server_listen_tls // // to listen for connection. Note that you can have a // single server listening for HTTP and HTTPS requests // by calling both. -int http_server_init(HTTP_Server *server); +int chttp_server_init(CHTTP_Server *server); // Release resources associated to the server. -void http_server_free(HTTP_Server *server); +void chttp_server_free(CHTTP_Server *server); // Set input and output buffer size limit for any // given connection. The default value is 1MB -void http_server_set_input_limit(HTTP_Server *server, uint32_t limit); -void http_server_set_output_limit(HTTP_Server *server, uint32_t limit); +void chttp_server_set_input_limit(CHTTP_Server *server, uint32_t limit); +void chttp_server_set_output_limit(CHTTP_Server *server, uint32_t limit); // TODO: Comment -void http_server_set_trace_bytes(HTTP_Server *server, bool value); +void chttp_server_set_trace_bytes(CHTTP_Server *server, bool value); // TODO: Comment -void http_server_set_reuse_addr(HTTP_Server *server, bool reuse); +void chttp_server_set_reuse_addr(CHTTP_Server *server, bool reuse); // TODO: comment -void http_server_set_backlog(HTTP_Server *server, int backlog); +void chttp_server_set_backlog(CHTTP_Server *server, int backlog); // Enable listening for plain HTTP requests at the // specified interface. -int http_server_listen_tcp(HTTP_Server *server, - HTTP_String addr, Port port); +int chttp_server_listen_tcp(CHTTP_Server *server, + CHTTP_String addr, Port port); // Enable listening for HTTPS requests at the specified // interfact, using the specified certificate and key // to verify the connection. -int http_server_listen_tls(HTTP_Server *server, HTTP_String addr, Port port, - HTTP_String cert_file_name, HTTP_String key_file_name); +int chttp_server_listen_tls(CHTTP_Server *server, CHTTP_String addr, Port port, + CHTTP_String cert_file_name, CHTTP_String key_file_name); // Add the certificate for an additional domain when // the server is listening for HTTPS requests. -int http_server_add_certificate(HTTP_Server *server, - HTTP_String domain, HTTP_String cert_file, HTTP_String key_file); +int chttp_server_add_certificate(CHTTP_Server *server, + CHTTP_String domain, CHTTP_String cert_file, CHTTP_String key_file); // When a thread is blocked waiting for server events, // other threads can call this function to wake it up. -int http_server_wakeup(HTTP_Server *server); +int chttp_server_wakeup(CHTTP_Server *server); // Resets the event register with the list of descriptors // the server wants monitored. -void http_server_register_events(HTTP_Server *server, +void chttp_server_register_events(CHTTP_Server *server, EventRegister *reg); // The caller has waited for poll() to return and some // I/O events to be triggered, so now the HTTP server // can continue its buffering and flushing operations. -void http_server_process_events(HTTP_Server *server, +void chttp_server_process_events(CHTTP_Server *server, EventRegister reg); typedef struct { - HTTP_Server *server; + CHTTP_Server *server; uint16_t index; uint16_t gen; -} HTTP_ResponseBuilder; +} CHTTP_ResponseBuilder; // After some I/O events were processes, some requests // may be availabe. This function returns one of the @@ -1311,35 +1311,35 @@ typedef struct { // respond in batches. // For each request returned by this function, the user // must build a response using the response builder API. -bool http_server_next_request(HTTP_Server *server, - HTTP_Request **request, HTTP_ResponseBuilder *builder); +bool chttp_server_next_request(CHTTP_Server *server, + CHTTP_Request **request, CHTTP_ResponseBuilder *builder); // TODO: comment -void http_server_wait_request(HTTP_Server *server, - HTTP_Request **request, HTTP_ResponseBuilder *builder); +void chttp_server_wait_request(CHTTP_Server *server, + CHTTP_Request **request, CHTTP_ResponseBuilder *builder); // This function is called to set the status code of // a request's response. If this function is called // after the other response builder functions, it will // reset the response and set a new status. -void http_response_builder_status(HTTP_ResponseBuilder builder, int status); +void chttp_response_builder_status(CHTTP_ResponseBuilder builder, int status); // Append a header to the response. This can only be // used after having set the status and before appending // to the body. -void http_response_builder_header(HTTP_ResponseBuilder builder, HTTP_String str); +void chttp_response_builder_header(CHTTP_ResponseBuilder builder, CHTTP_String str); // Append some bytes to the response's body -void http_response_builder_body(HTTP_ResponseBuilder builder, HTTP_String str); +void chttp_response_builder_body(CHTTP_ResponseBuilder builder, CHTTP_String str); // TODO: comment -void http_response_builder_body_cap(HTTP_ResponseBuilder builder, int cap); -char *http_response_builder_body_buf(HTTP_ResponseBuilder builder, int *cap); -void http_response_builder_body_ack(HTTP_ResponseBuilder builder, int num); +void chttp_response_builder_body_cap(CHTTP_ResponseBuilder builder, int cap); +char *chttp_response_builder_body_buf(CHTTP_ResponseBuilder builder, int *cap); +void chttp_response_builder_body_ack(CHTTP_ResponseBuilder builder, int num); // Mark the response as complete. This will invalidate // the response builder handle. -void http_response_builder_send(HTTP_ResponseBuilder builder); +void chttp_response_builder_send(CHTTP_ResponseBuilder builder); //////////////////////////////////////////////////////////////////////////////////////// // Copyright 2025 Francesco Cozzuto @@ -1365,4 +1365,4 @@ void http_response_builder_send(HTTP_ResponseBuilder builder); // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. //////////////////////////////////////////////////////////////////////////////////////// -#endif // HTTP_INCLUDED +#endif // CHTTP_INCLUDED diff --git a/examples/000_simple_client.c b/examples/000_simple_client.c index 14261b4..a84fd98 100644 --- a/examples/000_simple_client.c +++ b/examples/000_simple_client.c @@ -2,14 +2,14 @@ int main(void) { - HTTP_Response *response; + CHTTP_Response *response; - int ret = http_get(HTTP_STR("http://coz.is/"), NULL, 0, &response); - if (ret == HTTP_OK) { + int ret = chttp_get(CHTTP_STR("http://coz.is/"), NULL, 0, &response); + if (ret == CHTTP_OK) { printf("Received %d bytes\n", response->body.len); - http_free_response(response); + chttp_free_response(response); } else { - printf("Request failure: %s\n", http_strerror(ret)); + printf("Request failure: %s\n", chttp_strerror(ret)); } return 0; } diff --git a/examples/001_simple_server.c b/examples/001_simple_server.c index 9a34ffa..2943a8d 100644 --- a/examples/001_simple_server.c +++ b/examples/001_simple_server.c @@ -4,33 +4,33 @@ int main(void) { int ret; - HTTP_Server server; - ret = http_server_init(&server); + CHTTP_Server server; + ret = chttp_server_init(&server); if (ret < 0) { - fprintf(stderr, "Couldn't initialize server (%s)\n", http_strerror(ret)); + fprintf(stderr, "Couldn't initialize server (%s)\n", chttp_strerror(ret)); return -1; } - http_server_set_reuse_addr(&server, true); - http_server_set_trace_bytes(&server, true); + chttp_server_set_reuse_addr(&server, true); + chttp_server_set_trace_bytes(&server, true); - ret = http_server_listen_tcp(&server, HTTP_STR("127.0.0.1"), 8080); + ret = chttp_server_listen_tcp(&server, CHTTP_STR("127.0.0.1"), 8080); if (ret < 0) { - fprintf(stderr, "Couldn't start listening (%s)\n", http_strerror(ret)); + fprintf(stderr, "Couldn't start listening (%s)\n", chttp_strerror(ret)); return -1; } for (;;) { - HTTP_Request *request; - HTTP_ResponseBuilder builder; - http_server_wait_request(&server, &request, &builder); + CHTTP_Request *request; + CHTTP_ResponseBuilder builder; + chttp_server_wait_request(&server, &request, &builder); - http_response_builder_status(builder, 200); - http_response_builder_body(builder, HTTP_STR("Hello, world!")); - http_response_builder_send(builder); + chttp_response_builder_status(builder, 200); + chttp_response_builder_body(builder, CHTTP_STR("Hello, world!")); + chttp_response_builder_send(builder); } - http_server_free(&server); + chttp_server_free(&server); return 0; } diff --git a/examples/002_proxy.c b/examples/002_proxy.c index f6bde9b..c4e2535 100644 --- a/examples/002_proxy.c +++ b/examples/002_proxy.c @@ -13,41 +13,41 @@ int main() { int ret; - HTTP_String remote = HTTP_STR("http://coz.is"); + CHTTP_String remote = CHTTP_STR("http://coz.is"); - HTTP_Client client; - ret = http_client_init(&client); + CHTTP_Client client; + ret = chttp_client_init(&client); if (ret < 0) { - printf("Couldn't initialize client (%s)\n", http_strerror(ret)); + printf("Couldn't initialize client (%s)\n", chttp_strerror(ret)); return -1; } - HTTP_Server server; - ret = http_server_init(&server); + CHTTP_Server server; + ret = chttp_server_init(&server); if (ret < 0) { - fprintf(stderr, "Couldn't initialize server (%s)\n", http_strerror(ret)); + fprintf(stderr, "Couldn't initialize server (%s)\n", chttp_strerror(ret)); return -1; } - http_server_set_reuse_addr(&server, true); - http_server_set_trace_bytes(&server, true); + chttp_server_set_reuse_addr(&server, true); + chttp_server_set_trace_bytes(&server, true); - ret = http_server_listen_tcp(&server, HTTP_STR("127.0.0.1"), 8080); + ret = chttp_server_listen_tcp(&server, CHTTP_STR("127.0.0.1"), 8080); if (ret < 0) { - fprintf(stderr, "Couldn't start listening (%s)\n", http_strerror(ret)); + fprintf(stderr, "Couldn't start listening (%s)\n", chttp_strerror(ret)); return -1; } - bool used[HTTP_SERVER_CAPACITY]; - for (int i = 0; i < HTTP_SERVER_CAPACITY; i++) + bool used[CHTTP_SERVER_CAPACITY]; + for (int i = 0; i < CHTTP_SERVER_CAPACITY; i++) used[i] = false; - HTTP_ResponseBuilder pending[HTTP_SERVER_CAPACITY]; + CHTTP_ResponseBuilder pending[CHTTP_SERVER_CAPACITY]; int num_pending = 0; for (;;) { - #define POLL_CAPACITY (HTTP_CLIENT_POLL_CAPACITY + HTTP_SERVER_POLL_CAPACITY) + #define POLL_CAPACITY (CHTTP_CLIENT_POLL_CAPACITY + CHTTP_SERVER_POLL_CAPACITY) void *ptrs[POLL_CAPACITY]; struct pollfd polled[POLL_CAPACITY]; @@ -57,14 +57,14 @@ int main() polled, 0 }; - http_server_register_events(&server, &server_reg); + chttp_server_register_events(&server, &server_reg); EventRegister client_reg = { ptrs + server_reg.num_polled, polled + server_reg.num_polled, 0 }; - http_client_register_events(&client, &client_reg); + chttp_client_register_events(&client, &client_reg); if (server_reg.num_polled > 0 || client_reg.num_polled > 0) { @@ -75,62 +75,62 @@ int main() int result; void *user; - HTTP_Response *response; - http_client_process_events(&client, client_reg); - while (http_client_next_response(&client, &result, &user, &response)) { + CHTTP_Response *response; + chttp_client_process_events(&client, client_reg); + while (chttp_client_next_response(&client, &result, &user, &response)) { - HTTP_ResponseBuilder *builder = (HTTP_ResponseBuilder*) user; + CHTTP_ResponseBuilder *builder = (CHTTP_ResponseBuilder*) user; int i = builder - pending; assert(i > -1); - assert(i < HTTP_SERVER_CAPACITY); + assert(i < CHTTP_SERVER_CAPACITY); - if (result == HTTP_OK) { - http_response_builder_status(*builder, response->status); - http_response_builder_body(*builder, response->body); - http_response_builder_send(*builder); + if (result == CHTTP_OK) { + chttp_response_builder_status(*builder, response->status); + chttp_response_builder_body(*builder, response->body); + chttp_response_builder_send(*builder); } else { - http_response_builder_status(*builder, 500); - http_response_builder_send(*builder); + chttp_response_builder_status(*builder, 500); + chttp_response_builder_send(*builder); } used[i] = false; num_pending--; } - HTTP_Request *request; - HTTP_ResponseBuilder response_builder; - http_server_process_events(&server, server_reg); - while (http_server_next_request(&server, &request, &response_builder)) { + CHTTP_Request *request; + CHTTP_ResponseBuilder response_builder; + chttp_server_process_events(&server, server_reg); + while (chttp_server_next_request(&server, &request, &response_builder)) { int i = 0; while (used[i]) { i++; - assert(i < HTTP_SERVER_CAPACITY); + assert(i < CHTTP_SERVER_CAPACITY); } - HTTP_String path = request->url.path; + CHTTP_String path = request->url.path; if (path.len == 0) - path = HTTP_STR("/"); + path = CHTTP_STR("/"); char target[1<<10]; int target_len = snprintf(target, sizeof(target), - "%.*s%.*s", HTTP_UNPACK(remote), HTTP_UNPACK(path)); + "%.*s%.*s", CHTTP_UNPACK(remote), CHTTP_UNPACK(path)); if (target_len < 0 || target_len >= (int) sizeof(target)) { - http_response_builder_status(response_builder, 500); - http_response_builder_send(response_builder); + chttp_response_builder_status(response_builder, 500); + chttp_response_builder_send(response_builder); continue; } - HTTP_RequestBuilder request_builder = http_client_get_builder(&client); - http_request_builder_set_user(request_builder, &pending[i]); - http_request_builder_trace(request_builder, true); - http_request_builder_method(request_builder, request->method); - http_request_builder_target(request_builder, (HTTP_String) { target, target_len }); - ret = http_request_builder_send(request_builder); + CHTTP_RequestBuilder request_builder = chttp_client_get_builder(&client); + chttp_request_builder_set_user(request_builder, &pending[i]); + chttp_request_builder_trace(request_builder, true); + chttp_request_builder_method(request_builder, request->method); + chttp_request_builder_target(request_builder, (CHTTP_String) { target, target_len }); + ret = chttp_request_builder_send(request_builder); if (ret < 0) { - http_response_builder_status(response_builder, 500); - http_response_builder_send(response_builder); + chttp_response_builder_status(response_builder, 500); + chttp_response_builder_send(response_builder); continue; } @@ -140,7 +140,7 @@ int main() } } - http_server_free(&server); - http_client_free(&client); + chttp_server_free(&server); + chttp_client_free(&client); return 0; } diff --git a/examples/003_virtual_hosts.c b/examples/003_virtual_hosts.c index c00d7e7..ae4fefb 100644 --- a/examples/003_virtual_hosts.c +++ b/examples/003_virtual_hosts.c @@ -16,21 +16,21 @@ int main(void) int ret; - HTTP_Server server; - ret = http_server_init(&server); + CHTTP_Server server; + ret = chttp_server_init(&server); if (ret < 0) { - fprintf(stderr, "Couldn't initialize server (%s)\n", http_strerror(ret)); + fprintf(stderr, "Couldn't initialize server (%s)\n", chttp_strerror(ret)); return -1; } - http_server_set_reuse_addr(&server, true); - http_server_set_trace_bytes(&server, true); + chttp_server_set_reuse_addr(&server, true); + chttp_server_set_trace_bytes(&server, true); - HTTP_String local_addr = HTTP_STR("127.0.0.1"); + CHTTP_String local_addr = CHTTP_STR("127.0.0.1"); uint16_t local_port = 8080; - ret = http_server_listen_tcp(&server, local_addr, local_port); + ret = chttp_server_listen_tcp(&server, local_addr, local_port); if (ret < 0) { - fprintf(stderr, "Couldn't start listening (%s)\n", http_strerror(ret)); + fprintf(stderr, "Couldn't start listening (%s)\n", chttp_strerror(ret)); return -1; } @@ -48,29 +48,29 @@ int main(void) for (;;) { - HTTP_Request *req; - HTTP_ResponseBuilder builder; - http_server_wait_request(&server, &req, &builder); + CHTTP_Request *req; + CHTTP_ResponseBuilder builder; + chttp_server_wait_request(&server, &req, &builder); - if (http_match_host(req, HTTP_STR("websiteB.com"), local_port)) { + if (chttp_match_host(req, CHTTP_STR("websiteB.com"), local_port)) { // Website B - http_response_builder_status(builder, 200); - http_response_builder_body(builder, HTTP_STR("Hello from websiteB.com!")); - http_response_builder_send(builder); + chttp_response_builder_status(builder, 200); + chttp_response_builder_body(builder, CHTTP_STR("Hello from websiteB.com!")); + chttp_response_builder_send(builder); - } else if (http_match_host(req, HTTP_STR("websiteC.com"), local_port)) { + } else if (chttp_match_host(req, CHTTP_STR("websiteC.com"), local_port)) { // Website C - http_response_builder_status(builder, 200); - http_response_builder_body(builder, HTTP_STR("Hello from websiteC.com!")); - http_response_builder_send(builder); + chttp_response_builder_status(builder, 200); + chttp_response_builder_body(builder, CHTTP_STR("Hello from websiteC.com!")); + chttp_response_builder_send(builder); } else { // Serve websiteA by default - http_response_builder_status(builder, 200); - http_response_builder_body(builder, HTTP_STR("Hello from websiteA.com!")); - http_response_builder_send(builder); + chttp_response_builder_status(builder, 200); + chttp_response_builder_body(builder, CHTTP_STR("Hello from websiteA.com!")); + chttp_response_builder_send(builder); } } - http_server_free(&server); + chttp_server_free(&server); return 0; } diff --git a/examples/004_https_server.c b/examples/004_https_server.c index 351f639..5164f09 100644 --- a/examples/004_https_server.c +++ b/examples/004_https_server.c @@ -4,39 +4,39 @@ int main(void) { - HTTP_String local_addr = HTTP_STR("127.0.0.1"); + CHTTP_String local_addr = CHTTP_STR("127.0.0.1"); uint16_t local_port = 8443; - HTTP_String cert_file = HTTP_STR("websiteA_cert.pem"); - HTTP_String key_file = HTTP_STR("websiteA_key.pem"); + CHTTP_String cert_file = CHTTP_STR("websiteA_cert.pem"); + CHTTP_String key_file = CHTTP_STR("websiteA_key.pem"); - HTTP_Server server; - int ret = http_server_init(&server); + CHTTP_Server server; + int ret = chttp_server_init(&server); if (ret < 0) { - fprintf(stderr, "Couldn't initialize server (%s)\n", http_strerror(ret)); + fprintf(stderr, "Couldn't initialize server (%s)\n", chttp_strerror(ret)); return -1; } - http_server_set_reuse_addr(&server, true); - http_server_set_trace_bytes(&server, true); + chttp_server_set_reuse_addr(&server, true); + chttp_server_set_trace_bytes(&server, true); - ret = http_server_listen_tls(&server, local_addr, local_port, cert_file, key_file); + ret = chttp_server_listen_tls(&server, local_addr, local_port, cert_file, key_file); if (ret < 0) { - fprintf(stderr, "Couldn't start listening (%s)\n", http_strerror(ret)); + fprintf(stderr, "Couldn't start listening (%s)\n", chttp_strerror(ret)); return -1; } for (;;) { - HTTP_Request *req; - HTTP_ResponseBuilder builder; - http_server_wait_request(&server, &req, &builder); + CHTTP_Request *req; + CHTTP_ResponseBuilder builder; + chttp_server_wait_request(&server, &req, &builder); - http_response_builder_status(builder, 200); - http_response_builder_body(builder, HTTP_STR("Hello from websiteA.com!")); - http_response_builder_send(builder); + chttp_response_builder_status(builder, 200); + chttp_response_builder_body(builder, CHTTP_STR("Hello from websiteA.com!")); + chttp_response_builder_send(builder); } - http_server_free(&server); + chttp_server_free(&server); return 0; } diff --git a/examples/005_virtual_hosts_over_https.c b/examples/005_virtual_hosts_over_https.c index a090c61..327d131 100644 --- a/examples/005_virtual_hosts_over_https.c +++ b/examples/005_virtual_hosts_over_https.c @@ -38,47 +38,47 @@ int main(void) if (ret < 0) return -1; - HTTP_Server server; - ret = http_server_init(&server); + CHTTP_Server server; + ret = chttp_server_init(&server); if (ret < 0) { - fprintf(stderr, "Couldn't initialize server (%s)\n", http_strerror(ret)); + fprintf(stderr, "Couldn't initialize server (%s)\n", chttp_strerror(ret)); return -1; } - http_server_set_reuse_addr(&server, true); - http_server_set_trace_bytes(&server, true); + chttp_server_set_reuse_addr(&server, true); + chttp_server_set_trace_bytes(&server, true); // First, set up an HTTPS server instance with one // of the certificate. This will act as default certificate // when ecrypted connections don't target a specific domain. - HTTP_String local_addr = HTTP_STR("127.0.0.1"); + CHTTP_String local_addr = CHTTP_STR("127.0.0.1"); uint16_t local_port = 8443; - HTTP_String cert_file = HTTP_STR("websiteA_cert.pem"); - HTTP_String key_file = HTTP_STR("websiteA_key.pem"); + CHTTP_String cert_file = CHTTP_STR("websiteA_cert.pem"); + CHTTP_String key_file = CHTTP_STR("websiteA_key.pem"); - ret = http_server_listen_tls(&server, local_addr, local_port, cert_file, key_file); + ret = chttp_server_listen_tls(&server, local_addr, local_port, cert_file, key_file); if (ret < 0) { - fprintf(stderr, "Couldn't start listening (%s)\n", http_strerror(ret)); + fprintf(stderr, "Couldn't start listening (%s)\n", chttp_strerror(ret)); return -1; } // Then we can add an arbitrary number of additional // certificates using the add_website function - ret = http_server_add_certificate(&server, - HTTP_STR("websiteB.com"), - HTTP_STR("websiteB_cert.pem"), - HTTP_STR("websiteB_key.pem")); + ret = chttp_server_add_certificate(&server, + CHTTP_STR("websiteB.com"), + CHTTP_STR("websiteB_cert.pem"), + CHTTP_STR("websiteB_key.pem")); if (ret < 0) return -1; - ret = http_server_add_certificate(&server, - HTTP_STR("websiteC.com"), - HTTP_STR("websiteC_cert.pem"), - HTTP_STR("websiteC_key.pem")); + ret = chttp_server_add_certificate(&server, + CHTTP_STR("websiteC.com"), + CHTTP_STR("websiteC_cert.pem"), + CHTTP_STR("websiteC_key.pem")); if (ret < 0) return -1; @@ -109,67 +109,67 @@ int main(void) for (;;) { - HTTP_Request *req; - HTTP_ResponseBuilder builder; - http_server_wait_request(&server, &req, &builder); + CHTTP_Request *req; + CHTTP_ResponseBuilder builder; + chttp_server_wait_request(&server, &req, &builder); - if (http_match_host(req, HTTP_STR("websiteB.com"), 8080) || - http_match_host(req, HTTP_STR("websiteB.com"), 8443)) { + if (chttp_match_host(req, CHTTP_STR("websiteB.com"), 8080) || + chttp_match_host(req, CHTTP_STR("websiteB.com"), 8443)) { - http_response_builder_status(builder, 200); - http_response_builder_body(builder, HTTP_STR("Hello from websiteB.com!")); - http_response_builder_send(builder); + chttp_response_builder_status(builder, 200); + chttp_response_builder_body(builder, CHTTP_STR("Hello from websiteB.com!")); + chttp_response_builder_send(builder); - } else if (http_match_host(req, HTTP_STR("websiteC.com"), 8080) || - http_match_host(req, HTTP_STR("websiteC.com"), 8443)) { + } else if (chttp_match_host(req, CHTTP_STR("websiteC.com"), 8080) || + chttp_match_host(req, CHTTP_STR("websiteC.com"), 8443)) { - http_response_builder_status(builder, 200); - http_response_builder_body(builder, HTTP_STR("Hello from websiteC.com!")); - http_response_builder_send(builder); + chttp_response_builder_status(builder, 200); + chttp_response_builder_body(builder, CHTTP_STR("Hello from websiteC.com!")); + chttp_response_builder_send(builder); } else { // Serve websiteA.com by default to be consistent // with the certificate setup - http_response_builder_status(builder, 200); - http_response_builder_body(builder, HTTP_STR("Hello from websiteA.com!")); - http_response_builder_send(builder); + chttp_response_builder_status(builder, 200); + chttp_response_builder_body(builder, CHTTP_STR("Hello from websiteA.com!")); + chttp_response_builder_send(builder); } } - http_server_free(&server); + chttp_server_free(&server); return 0; } int setup_test_certificates(void) { - int ret = http_create_test_certificate( - HTTP_STR("IT"), - HTTP_STR("Organization A"), - HTTP_STR("websiteA.com"), - HTTP_STR("websiteA_cert.pem"), - HTTP_STR("websiteA_key.pem") + int ret = chttp_create_test_certificate( + CHTTP_STR("IT"), + CHTTP_STR("Organization A"), + CHTTP_STR("websiteA.com"), + CHTTP_STR("websiteA_cert.pem"), + CHTTP_STR("websiteA_key.pem") ); if (ret < 0) return -1; - ret = http_create_test_certificate( - HTTP_STR("IT"), - HTTP_STR("Organization B"), - HTTP_STR("websiteB.com"), - HTTP_STR("websiteB_cert.pem"), - HTTP_STR("websiteB_key.pem") + ret = chttp_create_test_certificate( + CHTTP_STR("IT"), + CHTTP_STR("Organization B"), + CHTTP_STR("websiteB.com"), + CHTTP_STR("websiteB_cert.pem"), + CHTTP_STR("websiteB_key.pem") ); if (ret < 0) return -1; - ret = http_create_test_certificate( - HTTP_STR("IT"), - HTTP_STR("Organization C"), - HTTP_STR("websiteC.com"), - HTTP_STR("websiteC_cert.pem"), - HTTP_STR("websiteC_key.pem") + ret = chttp_create_test_certificate( + CHTTP_STR("IT"), + CHTTP_STR("Organization C"), + CHTTP_STR("websiteC.com"), + CHTTP_STR("websiteC_cert.pem"), + CHTTP_STR("websiteC_key.pem") ); if (ret < 0) return -1; diff --git a/examples/006_parallel_client.c b/examples/006_parallel_client.c index 4991679..e75644d 100644 --- a/examples/006_parallel_client.c +++ b/examples/006_parallel_client.c @@ -4,37 +4,37 @@ int main(void) { int ret; - HTTP_Client client; - ret = http_client_init(&client); + CHTTP_Client client; + ret = chttp_client_init(&client); if (ret < 0) { - printf("Couldn't initialize client (%s)\n", http_strerror(ret)); + printf("Couldn't initialize client (%s)\n", chttp_strerror(ret)); return -1; } - HTTP_RequestBuilder builder = http_client_get_builder(&client); + CHTTP_RequestBuilder builder = chttp_client_get_builder(&client); - http_request_builder_method(builder, HTTP_METHOD_GET); - http_request_builder_target(builder, HTTP_STR("http://coz.is")); - http_request_builder_header(builder, HTTP_STR("Greeting: Hello from the cHTTP example!")); + chttp_request_builder_method(builder, CHTTP_METHOD_GET); + chttp_request_builder_target(builder, CHTTP_STR("http://coz.is")); + chttp_request_builder_header(builder, CHTTP_STR("Greeting: Hello from the cHTTP example!")); - ret = http_request_builder_send(builder); + ret = chttp_request_builder_send(builder); if (ret < 0) { - printf("Couldn't build request (%s)\n", http_strerror(ret)); + printf("Couldn't build request (%s)\n", chttp_strerror(ret)); return -1; } int result; void *user; - HTTP_Response *response; - http_client_wait_response(&client, &result, &user, &response); + CHTTP_Response *response; + chttp_client_wait_response(&client, &result, &user, &response); - if (result == HTTP_OK) { + if (result == CHTTP_OK) { printf("Received %d bytes\n", response->body.len); } else { - printf("Couldn't receive response (%s)\n", http_strerror(result)); + printf("Couldn't receive response (%s)\n", chttp_strerror(result)); } - http_free_response(response); - http_client_free(&client); + chttp_free_response(response); + chttp_client_free(&client); return 0; } diff --git a/misc/amalg.py b/misc/amalg.py index ddedf2d..ae7af48 100644 --- a/misc/amalg.py +++ b/misc/amalg.py @@ -53,8 +53,8 @@ license = """ """ header = Amalgamator() -header.append_text("#ifndef HTTP_INCLUDED\n") -header.append_text("#define HTTP_INCLUDED\n") +header.append_text("#ifndef CHTTP_INCLUDED\n") +header.append_text("#define CHTTP_INCLUDED\n") header.append_text(desc) header.append_file("src/includes.h") header.append_file("src/basic.h") @@ -66,13 +66,13 @@ header.append_file("src/cert.h") header.append_file("src/client.h") header.append_file("src/server.h") header.append_text(license) -header.append_text("#endif // HTTP_INCLUDED\n") +header.append_text("#endif // CHTTP_INCLUDED\n") header.save("chttp.h") source = Amalgamator() source.append_text(desc) source.append_text("\n") -source.append_text("#ifndef HTTP_DONT_INCLUDE\n") +source.append_text("#ifndef CHTTP_DONT_INCLUDE\n") source.append_text('#include "chttp.h"\n') source.append_text("#endif\n") source.append_file("src/basic.c") diff --git a/src/basic.c b/src/basic.c index 560aefa..ba8ebb1 100644 --- a/src/basic.c +++ b/src/basic.c @@ -1,5 +1,5 @@ -bool http_streq(HTTP_String s1, HTTP_String s2) +bool chttp_streq(CHTTP_String s1, CHTTP_String s2) { if (s1.len != s2.len) return false; @@ -18,7 +18,7 @@ static char to_lower(char c) return c; } -bool http_streqcase(HTTP_String s1, HTTP_String s2) +bool chttp_streqcase(CHTTP_String s1, CHTTP_String s2) { if (s1.len != s2.len) return false; @@ -30,7 +30,7 @@ bool http_streqcase(HTTP_String s1, HTTP_String s2) return true; } -HTTP_String http_trim(HTTP_String s) +CHTTP_String chttp_trim(CHTTP_String s) { int i = 0; while (i < s.len && (s.ptr[i] == ' ' || s.ptr[i] == '\t')) @@ -54,7 +54,7 @@ static bool is_printable(char c) return c >= ' ' && c <= '~'; } -void print_bytes(HTTP_String prefix, HTTP_String src) +void print_bytes(CHTTP_String prefix, CHTTP_String src) { if (src.len == 0) return; @@ -95,16 +95,16 @@ void print_bytes(HTTP_String prefix, HTTP_String src) putc('\n', stream); } -char *http_strerror(int code) +char *chttp_strerror(int code) { switch (code) { - case HTTP_OK: return "No error"; - case HTTP_ERROR_UNSPECIFIED: return "Unspecified error"; - case HTTP_ERROR_OOM: return "Out of memory"; - case HTTP_ERROR_BADURL: return "Invalid URL"; - case HTTP_ERROR_REQLIMIT: return "Parallel request limit reached"; - case HTTP_ERROR_BADHANDLE: return "Invalid handle"; - case HTTP_ERROR_NOTLS: return "TLS support not built-in"; + case CHTTP_OK: return "No error"; + case CHTTP_ERROR_UNSPECIFIED: return "Unspecified error"; + case CHTTP_ERROR_OOM: return "Out of memory"; + case CHTTP_ERROR_BADURL: return "Invalid URL"; + case CHTTP_ERROR_REQLIMIT: return "Parallel request limit reached"; + case CHTTP_ERROR_BADHANDLE: return "Invalid handle"; + case CHTTP_ERROR_NOTLS: return "TLS support not built-in"; } return "???"; } diff --git a/src/basic.h b/src/basic.h index 066bbda..a229dc4 100644 --- a/src/basic.h +++ b/src/basic.h @@ -1,56 +1,56 @@ enum { - HTTP_OK = 0, + CHTTP_OK = 0, // A generic error occurred - HTTP_ERROR_UNSPECIFIED = -1, + CHTTP_ERROR_UNSPECIFIED = -1, // Out of memory - HTTP_ERROR_OOM = -2, + CHTTP_ERROR_OOM = -2, // Invalid URL - HTTP_ERROR_BADURL = -3, + CHTTP_ERROR_BADURL = -3, // Parallel request limit reached - HTTP_ERROR_REQLIMIT = -4, + CHTTP_ERROR_REQLIMIT = -4, // Invalid handle - HTTP_ERROR_BADHANDLE = -5, + CHTTP_ERROR_BADHANDLE = -5, // TLS support not built-in - HTTP_ERROR_NOTLS = -6, + CHTTP_ERROR_NOTLS = -6, }; // String type used throughout cHTTP. typedef struct { char *ptr; int len; -} HTTP_String; +} CHTTP_String; // Compare two strings and return true iff they have // the same contents. -bool http_streq(HTTP_String s1, HTTP_String s2); +bool chttp_streq(CHTTP_String s1, CHTTP_String s2); // Compre two strings case-insensitively (uppercase and // lowercase versions of a letter are considered the same) // and return true iff they have the same contents. -bool http_streqcase(HTTP_String s1, HTTP_String s2); +bool chttp_streqcase(CHTTP_String s1, CHTTP_String s2); // Remove spaces and tabs from the start and the end of // a string. This doesn't change the original string and // the new one references the contents of the original one. -HTTP_String http_trim(HTTP_String s); +CHTTP_String chttp_trim(CHTTP_String s); // Print the contents of a byte string with the given prefix. // This is primarily used for debugging purposes. -void print_bytes(HTTP_String prefix, HTTP_String src); +void print_bytes(CHTTP_String prefix, CHTTP_String src); // TODO: comment -char *http_strerror(int code); +char *chttp_strerror(int code); // Macro to simplify converting string literals to -// HTTP_String. +// CHTTP_String. // // Instead of doing this: // @@ -58,7 +58,7 @@ char *http_strerror(int code); // // You do this: // -// HTTP_String s = HTTP_STR("some string") +// CHTTP_String s = CHTTP_STR("some string") // // This is a bit cumbersome, but better than null-terminated // strings, having a pointer and length variable pairs whenever @@ -68,15 +68,15 @@ char *http_strerror(int code); // #define S(X) ... // // But I don't want to cause collisions with user code. -#define HTTP_STR(X) ((HTTP_String) {(X), sizeof(X)-1}) +#define CHTTP_STR(X) ((CHTTP_String) {(X), sizeof(X)-1}) // Returns the number of items of a static array. -#define HTTP_COUNT(X) (int) (sizeof(X) / sizeof((X)[0])) +#define CHTTP_COUNT(X) (int) (sizeof(X) / sizeof((X)[0])) -// Macro to unpack an HTTP_String into its length and pointer components. -// Useful for passing HTTP_String to printf-style functions with "%.*s" format. -// Example: printf("%.*s", HTTP_UNPACK(str)); -#define HTTP_UNPACK(X) (X).len, (X).ptr +// Macro to unpack an CHTTP_String into its length and pointer components. +// Useful for passing CHTTP_String to printf-style functions with "%.*s" format. +// Example: printf("%.*s", CHTTP_UNPACK(str)); +#define CHTTP_UNPACK(X) (X).len, (X).ptr // TODO: comment -#define HTTP_UNREACHABLE __builtin_trap() +#define CHTTP_UNREACHABLE __builtin_trap() diff --git a/src/byte_queue.h b/src/byte_queue.h index 7b66f20..933983e 100644 --- a/src/byte_queue.h +++ b/src/byte_queue.h @@ -41,7 +41,7 @@ typedef uint64_t ByteQueueOffset; // Initialize the queue with a given capacity limit. // This is just a soft limit. The queue will allocate // dynamically as needed up to this limit and won't -// grow further. When the limit is reached, http_queue_full +// grow further. When the limit is reached, chttp_queue_full // returns true. void byte_queue_init(ByteQueue *queue, uint32_t limit); diff --git a/src/cert.c b/src/cert.c index 67bc005..5b44640 100644 --- a/src/cert.c +++ b/src/cert.c @@ -27,7 +27,7 @@ static EVP_PKEY *generate_rsa_key_pair(int key_bits) return pkey; } -static X509 *create_certificate(EVP_PKEY *pkey, HTTP_String C, HTTP_String O, HTTP_String CN, int days) +static X509 *create_certificate(EVP_PKEY *pkey, CHTTP_String C, CHTTP_String O, CHTTP_String CN, int days) { X509 *x509 = X509_new(); if (!x509) @@ -63,7 +63,7 @@ static X509 *create_certificate(EVP_PKEY *pkey, HTTP_String C, HTTP_String O, HT return x509; } -static int save_private_key(EVP_PKEY *pkey, HTTP_String file) +static int save_private_key(EVP_PKEY *pkey, CHTTP_String file) { char copy[1<<10]; if (file.len >= (int) sizeof(copy)) @@ -85,7 +85,7 @@ static int save_private_key(EVP_PKEY *pkey, HTTP_String file) return 0; } -static int save_certificate(X509 *x509, HTTP_String file) +static int save_certificate(X509 *x509, CHTTP_String file) { char copy[1<<10]; if (file.len >= (int) sizeof(copy)) @@ -107,8 +107,8 @@ static int save_certificate(X509 *x509, HTTP_String file) return 0; } -int http_create_test_certificate(HTTP_String C, HTTP_String O, HTTP_String CN, - HTTP_String cert_file, HTTP_String key_file) +int chttp_create_test_certificate(CHTTP_String C, CHTTP_String O, CHTTP_String CN, + CHTTP_String cert_file, CHTTP_String key_file) { EVP_PKEY *pkey = generate_rsa_key_pair(2048); if (pkey == NULL) @@ -139,8 +139,8 @@ int http_create_test_certificate(HTTP_String C, HTTP_String O, HTTP_String CN, #else -int http_create_test_certificate(HTTP_String C, HTTP_String O, HTTP_String CN, - HTTP_String cert_file, HTTP_String key_file) +int chttp_create_test_certificate(CHTTP_String C, CHTTP_String O, CHTTP_String CN, + CHTTP_String cert_file, CHTTP_String key_file) { (void) C; (void) O; diff --git a/src/cert.h b/src/cert.h index b56b4ae..59184be 100644 --- a/src/cert.h +++ b/src/cert.h @@ -12,5 +12,5 @@ // // The output is a certificate file in PEM format and a private // key file with the key used to sign the certificate. -int http_create_test_certificate(HTTP_String C, HTTP_String O, HTTP_String CN, - HTTP_String cert_file, HTTP_String key_file); +int chttp_create_test_certificate(CHTTP_String C, CHTTP_String O, CHTTP_String CN, + CHTTP_String cert_file, CHTTP_String key_file); diff --git a/src/client.c b/src/client.c index 9513f4e..a57ddda 100644 --- a/src/client.c +++ b/src/client.c @@ -1,11 +1,11 @@ -static void http_client_conn_free(HTTP_ClientConn *conn) +static void chttp_client_conn_free(CHTTP_ClientConn *conn) { byte_queue_free(&conn->output); byte_queue_free(&conn->input); } -int http_client_init(HTTP_Client *client) +int chttp_client_init(CHTTP_Client *client) { client->input_buffer_limit = 1<<20; client->output_buffer_limit = 1<<20; @@ -13,8 +13,8 @@ int http_client_init(HTTP_Client *client) client->cookie_jar.count = 0; client->num_conns = 0; - for (int i = 0; i < HTTP_CLIENT_CAPACITY; i++) { - client->conns[i].state = HTTP_CLIENT_CONN_FREE; + for (int i = 0; i < CHTTP_CLIENT_CAPACITY; i++) { + client->conns[i].state = CHTTP_CLIENT_CONN_FREE; client->conns[i].gen = 0; } @@ -22,10 +22,10 @@ int http_client_init(HTTP_Client *client) client->ready_head = 0; return socket_manager_init(&client->sockets, - client->socket_pool, HTTP_CLIENT_CAPACITY); + client->socket_pool, CHTTP_CLIENT_CAPACITY); } -void http_client_free(HTTP_Client *client) +void chttp_client_free(CHTTP_Client *client) { socket_manager_free(&client->sockets); @@ -33,63 +33,63 @@ void http_client_free(HTTP_Client *client) free(client->cookie_jar.items[i].name.ptr); for (int i = 0, j = 0; j < client->num_conns; i++) { - HTTP_ClientConn *conn = &client->conns[i]; - if (conn->state == HTTP_CLIENT_CONN_FREE) + CHTTP_ClientConn *conn = &client->conns[i]; + if (conn->state == CHTTP_CLIENT_CONN_FREE) continue; j++; - http_client_conn_free(conn); + chttp_client_conn_free(conn); } } -void http_client_set_input_limit(HTTP_Client *client, uint32_t limit) +void chttp_client_set_input_limit(CHTTP_Client *client, uint32_t limit) { client->input_buffer_limit = limit; } -void http_client_set_output_limit(HTTP_Client *client, uint32_t limit) +void chttp_client_set_output_limit(CHTTP_Client *client, uint32_t limit) { client->output_buffer_limit = limit; } -int http_client_wakeup(HTTP_Client *client) +int chttp_client_wakeup(CHTTP_Client *client) { return socket_manager_wakeup(&client->sockets); } // Get a connection pointer from a request builder. // If the builder is invalid, returns NULL. -static HTTP_ClientConn* -request_builder_to_conn(HTTP_RequestBuilder builder) +static CHTTP_ClientConn* +request_builder_to_conn(CHTTP_RequestBuilder builder) { - HTTP_Client *client = builder.client; + CHTTP_Client *client = builder.client; if (client == NULL) return NULL; - if (builder.index >= HTTP_CLIENT_CAPACITY) + if (builder.index >= CHTTP_CLIENT_CAPACITY) return NULL; - HTTP_ClientConn *conn = &client->conns[builder.index]; + CHTTP_ClientConn *conn = &client->conns[builder.index]; if (builder.gen != conn->gen) return NULL; return conn; } -HTTP_RequestBuilder http_client_get_builder(HTTP_Client *client) +CHTTP_RequestBuilder chttp_client_get_builder(CHTTP_Client *client) { // Find a free connection slot - if (client->num_conns == HTTP_CLIENT_CAPACITY) - return (HTTP_RequestBuilder) { NULL, -1, -1 }; + if (client->num_conns == CHTTP_CLIENT_CAPACITY) + return (CHTTP_RequestBuilder) { NULL, -1, -1 }; int i = 0; - while (client->conns[i].state != HTTP_CLIENT_CONN_FREE) { + while (client->conns[i].state != CHTTP_CLIENT_CONN_FREE) { i++; - assert(i < HTTP_CLIENT_CAPACITY); + assert(i < CHTTP_CLIENT_CAPACITY); } client->num_conns++; - client->conns[i].state = HTTP_CLIENT_CONN_WAIT_METHOD; + client->conns[i].state = CHTTP_CLIENT_CONN_WAIT_METHOD; client->conns[i].handle = SOCKET_HANDLE_INVALID; client->conns[i].client = client; client->conns[i].user = NULL; @@ -97,30 +97,30 @@ HTTP_RequestBuilder http_client_get_builder(HTTP_Client *client) byte_queue_init(&client->conns[i].input, client->input_buffer_limit); byte_queue_init(&client->conns[i].output, client->output_buffer_limit); - return (HTTP_RequestBuilder) { client, i, client->conns[i].gen }; + return (CHTTP_RequestBuilder) { client, i, client->conns[i].gen }; } // TODO: test this function -static bool is_subdomain(HTTP_String domain, HTTP_String subdomain) +static bool is_subdomain(CHTTP_String domain, CHTTP_String subdomain) { - if (http_streq(domain, subdomain)) + if (chttp_streq(domain, subdomain)) return true; // Exact match if (domain.len > subdomain.len) return false; - HTTP_String subdomain_suffix = { + CHTTP_String subdomain_suffix = { subdomain.ptr + subdomain.len - domain.len, domain.len }; - if (subdomain_suffix.ptr[-1] != '.' || !http_streq(domain, subdomain_suffix)) + if (subdomain_suffix.ptr[-1] != '.' || !chttp_streq(domain, subdomain_suffix)) return false; return true; } // TODO: test this function -static bool is_subpath(HTTP_String path, HTTP_String subpath) +static bool is_subpath(CHTTP_String path, CHTTP_String subpath) { if (path.len > subpath.len) return false; @@ -129,16 +129,16 @@ static bool is_subpath(HTTP_String path, HTTP_String subpath) return false; subpath.len = path.len; - return http_streq(path, subpath); + return chttp_streq(path, subpath); } -static bool should_send_cookie(HTTP_CookieJarEntry entry, HTTP_URL url) +static bool should_send_cookie(CHTTP_CookieJarEntry entry, CHTTP_URL url) { // TODO: If the cookie is expired, ignore it regardless if (entry.exact_domain) { // Cookie domain and URL domain must match exactly - if (!http_streq(entry.domain, url.authority.host.text)) + if (!chttp_streq(entry.domain, url.authority.host.text)) return false; } else { // The URL's domain must match or be a subdomain of the cookie's domain @@ -148,7 +148,7 @@ static bool should_send_cookie(HTTP_CookieJarEntry entry, HTTP_URL url) if (entry.exact_path) { // Cookie path and URL path must match exactly - if (!http_streq(entry.path, url.path)) + if (!chttp_streq(entry.path, url.path)) return false; } else { if (!is_subpath(entry.path, url.path)) @@ -156,41 +156,41 @@ static bool should_send_cookie(HTTP_CookieJarEntry entry, HTTP_URL url) } if (entry.secure) { - if (!http_streq(url.scheme, HTTP_STR("https"))) + if (!chttp_streq(url.scheme, CHTTP_STR("https"))) return false; // Cookie was marked as secure but the target URL is not HTTPS } return true; } -static HTTP_String get_method_string(HTTP_Method method) +static CHTTP_String get_method_string(CHTTP_Method method) { switch (method) { - case HTTP_METHOD_GET : return HTTP_STR("GET"); - case HTTP_METHOD_HEAD : return HTTP_STR("HEAD"); - case HTTP_METHOD_POST : return HTTP_STR("POST"); - case HTTP_METHOD_PUT : return HTTP_STR("PUT"); - case HTTP_METHOD_DELETE : return HTTP_STR("DELETE"); - case HTTP_METHOD_CONNECT: return HTTP_STR("CONNECT"); - case HTTP_METHOD_OPTIONS: return HTTP_STR("OPTIONS"); - case HTTP_METHOD_TRACE : return HTTP_STR("TRACE"); - case HTTP_METHOD_PATCH : return HTTP_STR("PATCH"); + case CHTTP_METHOD_GET : return CHTTP_STR("GET"); + case CHTTP_METHOD_HEAD : return CHTTP_STR("HEAD"); + case CHTTP_METHOD_POST : return CHTTP_STR("POST"); + case CHTTP_METHOD_PUT : return CHTTP_STR("PUT"); + case CHTTP_METHOD_DELETE : return CHTTP_STR("DELETE"); + case CHTTP_METHOD_CONNECT: return CHTTP_STR("CONNECT"); + case CHTTP_METHOD_OPTIONS: return CHTTP_STR("OPTIONS"); + case CHTTP_METHOD_TRACE : return CHTTP_STR("TRACE"); + case CHTTP_METHOD_PATCH : return CHTTP_STR("PATCH"); } - return HTTP_STR("???"); + return CHTTP_STR("???"); } -void http_request_builder_set_user(HTTP_RequestBuilder builder, void *user) +void chttp_request_builder_set_user(CHTTP_RequestBuilder builder, void *user) { - HTTP_ClientConn *conn = request_builder_to_conn(builder); + CHTTP_ClientConn *conn = request_builder_to_conn(builder); if (conn == NULL) return; // Invalid builder conn->user = user; } -void http_request_builder_trace(HTTP_RequestBuilder builder, bool trace_bytes) +void chttp_request_builder_trace(CHTTP_RequestBuilder builder, bool trace_bytes) { - HTTP_ClientConn *conn = request_builder_to_conn(builder); + CHTTP_ClientConn *conn = request_builder_to_conn(builder); if (conn == NULL) return; // Invalid builder @@ -198,47 +198,47 @@ void http_request_builder_trace(HTTP_RequestBuilder builder, bool trace_bytes) } // TODO: comment -void http_request_builder_insecure(HTTP_RequestBuilder builder, +void chttp_request_builder_insecure(CHTTP_RequestBuilder builder, bool insecure) { - HTTP_ClientConn *conn = request_builder_to_conn(builder); + CHTTP_ClientConn *conn = request_builder_to_conn(builder); if (conn == NULL) return; // Invalid builder conn->dont_verify_cert = insecure; } -void http_request_builder_method(HTTP_RequestBuilder builder, - HTTP_Method method) +void chttp_request_builder_method(CHTTP_RequestBuilder builder, + CHTTP_Method method) { - HTTP_ClientConn *conn = request_builder_to_conn(builder); + CHTTP_ClientConn *conn = request_builder_to_conn(builder); if (conn == NULL) return; // Invalid builder - if (conn->state != HTTP_CLIENT_CONN_WAIT_METHOD) + if (conn->state != CHTTP_CLIENT_CONN_WAIT_METHOD) return; // Request line already written // Write method - HTTP_String method_str = get_method_string(method); + CHTTP_String method_str = get_method_string(method); byte_queue_write(&conn->output, method_str.ptr, method_str.len); byte_queue_write(&conn->output, " ", 1); - conn->state = HTTP_CLIENT_CONN_WAIT_URL; + conn->state = CHTTP_CLIENT_CONN_WAIT_URL; } -void http_request_builder_target(HTTP_RequestBuilder builder, - HTTP_String url) +void chttp_request_builder_target(CHTTP_RequestBuilder builder, + CHTTP_String url) { - HTTP_ClientConn *conn = request_builder_to_conn(builder); + CHTTP_ClientConn *conn = request_builder_to_conn(builder); if (conn == NULL) return; // Invalid builder - if (conn->state != HTTP_CLIENT_CONN_WAIT_URL) + if (conn->state != CHTTP_CLIENT_CONN_WAIT_URL) return; // Request line already written if (url.len == 0) { - conn->state = HTTP_CLIENT_CONN_COMPLETE; - conn->result = HTTP_ERROR_BADURL; + conn->state = CHTTP_CLIENT_CONN_COMPLETE; + conn->result = CHTTP_ERROR_BADURL; return; } @@ -246,8 +246,8 @@ void http_request_builder_target(HTTP_RequestBuilder builder, // URL pointers remain valid char *url_copy = malloc(url.len); if (url_copy == NULL) { - conn->state = HTTP_CLIENT_CONN_COMPLETE; - conn->result = HTTP_ERROR_OOM; + conn->state = CHTTP_CLIENT_CONN_COMPLETE; + conn->result = CHTTP_ERROR_OOM; return; } memcpy(url_copy, url.ptr, url.len); @@ -256,16 +256,16 @@ void http_request_builder_target(HTTP_RequestBuilder builder, conn->url_buffer.len = url.len; // Parse the copied URL (all url.* pointers will reference url_buffer) - if (http_parse_url(conn->url_buffer.ptr, conn->url_buffer.len, &conn->url) < 0) { - conn->state = HTTP_CLIENT_CONN_COMPLETE; - conn->result = HTTP_ERROR_BADURL; + if (chttp_parse_url(conn->url_buffer.ptr, conn->url_buffer.len, &conn->url) < 0) { + conn->state = CHTTP_CLIENT_CONN_COMPLETE; + conn->result = CHTTP_ERROR_BADURL; return; } - if (!http_streq(conn->url.scheme, HTTP_STR("http")) && - !http_streq(conn->url.scheme, HTTP_STR("https"))) { - conn->state = HTTP_CLIENT_CONN_COMPLETE; - conn->result = HTTP_ERROR_BADURL; + if (!chttp_streq(conn->url.scheme, CHTTP_STR("http")) && + !chttp_streq(conn->url.scheme, CHTTP_STR("https"))) { + conn->state = CHTTP_CLIENT_CONN_COMPLETE; + conn->result = CHTTP_ERROR_BADURL; return; } @@ -278,13 +278,13 @@ void http_request_builder_target(HTTP_RequestBuilder builder, conn->url.path.len); // Write query string - HTTP_String query = conn->url.query; + CHTTP_String query = conn->url.query; if (query.len > 0) { byte_queue_write(&conn->output, "?", 1); byte_queue_write(&conn->output, query.ptr, query.len); } - HTTP_String version = HTTP_STR(" HTTP/1.1"); + CHTTP_String version = CHTTP_STR(" HTTP/1.1"); byte_queue_write(&conn->output, version.ptr, version.len); byte_queue_write(&conn->output, "\r\n", 2); @@ -300,10 +300,10 @@ void http_request_builder_target(HTTP_RequestBuilder builder, // Find all entries from the cookie jar that should // be sent to this server and append headers for them - HTTP_Client *client = builder.client; - HTTP_CookieJar *cookie_jar = &client->cookie_jar; + CHTTP_Client *client = builder.client; + CHTTP_CookieJar *cookie_jar = &client->cookie_jar; for (int i = 0; i < cookie_jar->count; i++) { - HTTP_CookieJarEntry entry = cookie_jar->items[i]; + CHTTP_CookieJarEntry entry = cookie_jar->items[i]; if (should_send_cookie(entry, conn->url)) { // TODO: Adding one header per cookie may cause the number of // headers to increase significantly. Should probably group @@ -316,12 +316,12 @@ void http_request_builder_target(HTTP_RequestBuilder builder, } } - HTTP_String s; + CHTTP_String s; - s = HTTP_STR("Connection: Close\r\n"); + s = CHTTP_STR("Connection: Close\r\n"); byte_queue_write(&conn->output, s.ptr, s.len); - s = HTTP_STR("Content-Length: "); + s = CHTTP_STR("Content-Length: "); byte_queue_write(&conn->output, s.ptr, s.len); conn->content_length_value_offset = byte_queue_offset(&conn->output); @@ -329,20 +329,20 @@ void http_request_builder_target(HTTP_RequestBuilder builder, #define TEN_SPACES " " _Static_assert(sizeof(TEN_SPACES) == 10+1); - s = HTTP_STR(TEN_SPACES "\r\n"); + s = CHTTP_STR(TEN_SPACES "\r\n"); byte_queue_write(&conn->output, s.ptr, s.len); - conn->state = HTTP_CLIENT_CONN_WAIT_HEADER; + conn->state = CHTTP_CLIENT_CONN_WAIT_HEADER; } -void http_request_builder_header(HTTP_RequestBuilder builder, - HTTP_String str) +void chttp_request_builder_header(CHTTP_RequestBuilder builder, + CHTTP_String str) { - HTTP_ClientConn *conn = request_builder_to_conn(builder); + CHTTP_ClientConn *conn = request_builder_to_conn(builder); if (conn == NULL) return; - if (conn->state != HTTP_CLIENT_CONN_WAIT_HEADER) + if (conn->state != CHTTP_CLIENT_CONN_WAIT_HEADER) return; // Validate header: must contain a colon and no control characters @@ -362,33 +362,33 @@ void http_request_builder_header(HTTP_RequestBuilder builder, byte_queue_write(&conn->output, "\r\n", 2); } -void http_request_builder_body(HTTP_RequestBuilder builder, - HTTP_String str) +void chttp_request_builder_body(CHTTP_RequestBuilder builder, + CHTTP_String str) { - HTTP_ClientConn *conn = request_builder_to_conn(builder); + CHTTP_ClientConn *conn = request_builder_to_conn(builder); if (conn == NULL) return; // Transition from WAIT_HEADER to WAIT_BODY if needed - if (conn->state == HTTP_CLIENT_CONN_WAIT_HEADER) { + if (conn->state == CHTTP_CLIENT_CONN_WAIT_HEADER) { byte_queue_write(&conn->output, "\r\n", 2); conn->content_length_offset = byte_queue_offset(&conn->output); - conn->state = HTTP_CLIENT_CONN_WAIT_BODY; + conn->state = CHTTP_CLIENT_CONN_WAIT_BODY; } - if (conn->state != HTTP_CLIENT_CONN_WAIT_BODY) + if (conn->state != CHTTP_CLIENT_CONN_WAIT_BODY) return; byte_queue_write(&conn->output, str.ptr, str.len); } -static ConnectTarget url_to_connect_target(HTTP_URL url) +static ConnectTarget url_to_connect_target(CHTTP_URL url) { - HTTP_Authority authority = url.authority; + CHTTP_Authority authority = url.authority; ConnectTarget target; if (authority.port < 1) { - if (http_streq(url.scheme, HTTP_STR("https"))) + if (chttp_streq(url.scheme, CHTTP_STR("https"))) target.port = 443; else target.port = 80; @@ -396,42 +396,42 @@ static ConnectTarget url_to_connect_target(HTTP_URL url) target.port = authority.port; } - if (authority.host.mode == HTTP_HOST_MODE_NAME) { + if (authority.host.mode == CHTTP_HOST_MODE_NAME) { target.type = CONNECT_TARGET_NAME; target.name = authority.host.name; - } else if (authority.host.mode == HTTP_HOST_MODE_IPV4) { + } else if (authority.host.mode == CHTTP_HOST_MODE_IPV4) { target.type = CONNECT_TARGET_IPV4; target.ipv4 = authority.host.ipv4; - } else if (authority.host.mode == HTTP_HOST_MODE_IPV6) { + } else if (authority.host.mode == CHTTP_HOST_MODE_IPV6) { target.type = CONNECT_TARGET_IPV6; target.ipv6 = authority.host.ipv6; } else { - HTTP_UNREACHABLE; + CHTTP_UNREACHABLE; } return target; } -int http_request_builder_send(HTTP_RequestBuilder builder) +int chttp_request_builder_send(CHTTP_RequestBuilder builder) { - HTTP_Client *client = builder.client; + CHTTP_Client *client = builder.client; if (client == NULL) - return HTTP_ERROR_REQLIMIT; + return CHTTP_ERROR_REQLIMIT; - HTTP_ClientConn *conn = request_builder_to_conn(builder); + CHTTP_ClientConn *conn = request_builder_to_conn(builder); if (conn == NULL) - return HTTP_ERROR_BADHANDLE; + return CHTTP_ERROR_BADHANDLE; - if (conn->state == HTTP_CLIENT_CONN_COMPLETE) + if (conn->state == CHTTP_CLIENT_CONN_COMPLETE) goto error; // Early completion due to an error - if (conn->state == HTTP_CLIENT_CONN_WAIT_HEADER) { + if (conn->state == CHTTP_CLIENT_CONN_WAIT_HEADER) { byte_queue_write(&conn->output, "\r\n", 2); conn->content_length_offset = byte_queue_offset(&conn->output); - conn->state = HTTP_CLIENT_CONN_WAIT_BODY; + conn->state = CHTTP_CLIENT_CONN_WAIT_BODY; } - if (conn->state != HTTP_CLIENT_CONN_WAIT_BODY) + if (conn->state != CHTTP_CLIENT_CONN_WAIT_BODY) goto error; if (byte_queue_error(&conn->output)) @@ -446,16 +446,16 @@ int http_request_builder_send(HTTP_RequestBuilder builder) byte_queue_patch(&conn->output, conn->content_length_value_offset, tmp, len); ConnectTarget target = url_to_connect_target(conn->url); - bool secure = http_streq(conn->url.scheme, HTTP_STR("https")); + bool secure = chttp_streq(conn->url.scheme, CHTTP_STR("https")); if (socket_connect(&client->sockets, 1, &target, secure, conn->dont_verify_cert, conn) < 0) goto error; - conn->state = HTTP_CLIENT_CONN_FLUSHING; + conn->state = CHTTP_CLIENT_CONN_FLUSHING; conn->gen++; - return HTTP_OK; + return CHTTP_OK; error: - conn->state = HTTP_CLIENT_CONN_FREE; + conn->state = CHTTP_CLIENT_CONN_FREE; free(conn->url_buffer.ptr); byte_queue_free(&conn->input); byte_queue_free(&conn->output); @@ -463,17 +463,17 @@ error: return conn->result; } -static void save_one_cookie(HTTP_CookieJar *cookie_jar, - HTTP_Header set_cookie, HTTP_String domain, HTTP_String path) +static void save_one_cookie(CHTTP_CookieJar *cookie_jar, + CHTTP_Header set_cookie, CHTTP_String domain, CHTTP_String path) { - if (cookie_jar->count == HTTP_COOKIE_JAR_CAPACITY) + if (cookie_jar->count == CHTTP_COOKIE_JAR_CAPACITY) return; // Cookie jar capacity reached - HTTP_SetCookie parsed; - if (http_parse_set_cookie(set_cookie.value, &parsed) < 0) + CHTTP_SetCookie parsed; + if (chttp_parse_set_cookie(set_cookie.value, &parsed) < 0) return; // Ignore invalid Set-Cookie headers - HTTP_CookieJarEntry entry; + CHTTP_CookieJarEntry entry; entry.name = parsed.name; entry.value = parsed.value; @@ -522,32 +522,32 @@ static void save_one_cookie(HTTP_CookieJar *cookie_jar, cookie_jar->items[cookie_jar->count++] = entry; } -static void save_cookies(HTTP_CookieJar *cookie_jar, - HTTP_Header *headers, int num_headers, - HTTP_String domain, HTTP_String path) +static void save_cookies(CHTTP_CookieJar *cookie_jar, + CHTTP_Header *headers, int num_headers, + CHTTP_String domain, CHTTP_String path) { // TODO: remove expired cookies for (int i = 0; i < num_headers; i++) - if (http_streqcase(headers[i].name, HTTP_STR("Set-Cookie"))) // TODO: headers are case-insensitive, right? + if (chttp_streqcase(headers[i].name, CHTTP_STR("Set-Cookie"))) // TODO: headers are case-insensitive, right? save_one_cookie(cookie_jar, headers[i], domain, path); } -void http_client_register_events(HTTP_Client *client, +void chttp_client_register_events(CHTTP_Client *client, EventRegister *reg) { socket_manager_register_events(&client->sockets, reg); } -void http_client_process_events(HTTP_Client *client, +void chttp_client_process_events(CHTTP_Client *client, EventRegister reg) { - SocketEvent events[HTTP_CLIENT_CAPACITY]; + SocketEvent events[CHTTP_CLIENT_CAPACITY]; int num_events = socket_manager_translate_events(&client->sockets, events, reg); for (int i = 0; i < num_events; i++) { - HTTP_ClientConn *conn = events[i].user; + CHTTP_ClientConn *conn = events[i].user; if (conn == NULL) continue; // If a socket is not couple to a connection, // it means the response was already returned @@ -555,7 +555,7 @@ void http_client_process_events(HTTP_Client *client, if (events[i].type == SOCKET_EVENT_DISCONNECT) { - conn->state = HTTP_CLIENT_CONN_COMPLETE; + conn->state = CHTTP_CLIENT_CONN_COMPLETE; conn->result = -1; } else if (events[i].type == SOCKET_EVENT_READY) { @@ -566,7 +566,7 @@ void http_client_process_events(HTTP_Client *client, while (socket_ready(&client->sockets, conn->handle)) { - if (conn->state == HTTP_CLIENT_CONN_FLUSHING) { + if (conn->state == CHTTP_CLIENT_CONN_FLUSHING) { ByteView src = byte_queue_read_buf(&conn->output); @@ -575,7 +575,7 @@ void http_client_process_events(HTTP_Client *client, num = socket_send(&client->sockets, conn->handle, src.ptr, src.len); if (conn->trace_bytes) - print_bytes(HTTP_STR("<< "), (HTTP_String){src.ptr, num}); + print_bytes(CHTTP_STR("<< "), (CHTTP_String){src.ptr, num}); byte_queue_read_ack(&conn->output, num); @@ -586,10 +586,10 @@ void http_client_process_events(HTTP_Client *client, // Request fully sent, now wait for response if (byte_queue_empty(&conn->output)) - conn->state = HTTP_CLIENT_CONN_BUFFERING; + conn->state = CHTTP_CLIENT_CONN_BUFFERING; } - if (conn->state == HTTP_CLIENT_CONN_BUFFERING) { + if (conn->state == CHTTP_CLIENT_CONN_BUFFERING) { // Receive response data int min_recv = 1<<10; @@ -602,7 +602,7 @@ void http_client_process_events(HTTP_Client *client, num = socket_recv(&client->sockets, conn->handle, dst.ptr, dst.len); if (conn->trace_bytes) - print_bytes(HTTP_STR(">> "), (HTTP_String){dst.ptr, num}); + print_bytes(CHTTP_STR(">> "), (CHTTP_String){dst.ptr, num}); byte_queue_write_ack(&conn->input, num); @@ -612,7 +612,7 @@ void http_client_process_events(HTTP_Client *client, } ByteView src = byte_queue_read_buf(&conn->input); - int ret = http_parse_response(src.ptr, src.len, &conn->response); + int ret = chttp_parse_response(src.ptr, src.len, &conn->response); if (ret == 0) { // Still waiting @@ -635,7 +635,7 @@ void http_client_process_events(HTTP_Client *client, // Ready assert(ret > 0); - conn->state = HTTP_CLIENT_CONN_COMPLETE; + conn->state = CHTTP_CLIENT_CONN_COMPLETE; conn->result = 0; conn->response.context = client; @@ -653,36 +653,36 @@ void http_client_process_events(HTTP_Client *client, } } - if (conn->state == HTTP_CLIENT_CONN_COMPLETE) { + if (conn->state == CHTTP_CLIENT_CONN_COMPLETE) { // Decouple from the socket socket_set_user(&client->sockets, events[i].handle, NULL); socket_close(&client->sockets, events[i].handle); // Push to the ready queue - assert(client->num_ready < HTTP_CLIENT_CAPACITY); - int tail = (client->ready_head + client->num_ready) % HTTP_CLIENT_CAPACITY; + assert(client->num_ready < CHTTP_CLIENT_CAPACITY); + int tail = (client->ready_head + client->num_ready) % CHTTP_CLIENT_CAPACITY; client->ready[tail] = conn - client->conns; client->num_ready++; } } } -bool http_client_next_response(HTTP_Client *client, - int *result, void **user, HTTP_Response **response) +bool chttp_client_next_response(CHTTP_Client *client, + int *result, void **user, CHTTP_Response **response) { if (client->num_ready == 0) return false; - HTTP_ClientConn *conn = &client->conns[client->ready[client->ready_head]]; - client->ready_head = (client->ready_head + 1) % HTTP_CLIENT_CAPACITY; + CHTTP_ClientConn *conn = &client->conns[client->ready[client->ready_head]]; + client->ready_head = (client->ready_head + 1) % CHTTP_CLIENT_CAPACITY; client->num_ready--; - assert(conn->state == HTTP_CLIENT_CONN_COMPLETE); + assert(conn->state == CHTTP_CLIENT_CONN_COMPLETE); *result = conn->result; *user = conn->user; - if (conn->result == HTTP_OK) { + if (conn->result == CHTTP_OK) { *response = &conn->response; } else { *response = NULL; @@ -691,17 +691,17 @@ bool http_client_next_response(HTTP_Client *client, return true; } -void http_free_response(HTTP_Response *response) +void chttp_free_response(CHTTP_Response *response) { if (response == NULL || response->context == NULL) return; - HTTP_Client *client = response->context; + CHTTP_Client *client = response->context; response->context = NULL; // TODO: I'm positive there is a better way to do this. // It should just be a bouds check + subtraction. - HTTP_ClientConn *conn = NULL; - for (int i = 0; i < HTTP_CLIENT_CAPACITY; i++) + CHTTP_ClientConn *conn = NULL; + for (int i = 0; i < CHTTP_CLIENT_CAPACITY; i++) if (&client->conns[i].response == response) { conn = &client->conns[i]; break; @@ -709,7 +709,7 @@ void http_free_response(HTTP_Response *response) if (conn == NULL) return; - conn->state = HTTP_CLIENT_CONN_FREE; + conn->state = CHTTP_CLIENT_CONN_FREE; free(conn->url_buffer.ptr); byte_queue_free(&conn->input); byte_queue_free(&conn->output); @@ -722,86 +722,86 @@ void http_free_response(HTTP_Response *response) #define POLL poll #endif -void http_client_wait_response(HTTP_Client *client, - int *result, void **user, HTTP_Response **response) +void chttp_client_wait_response(CHTTP_Client *client, + int *result, void **user, CHTTP_Response **response) { for (;;) { - void *ptrs[HTTP_CLIENT_POLL_CAPACITY]; - struct pollfd polled[HTTP_CLIENT_POLL_CAPACITY]; + void *ptrs[CHTTP_CLIENT_POLL_CAPACITY]; + struct pollfd polled[CHTTP_CLIENT_POLL_CAPACITY]; EventRegister reg = { ptrs, polled, 0 }; - http_client_register_events(client, ®); + chttp_client_register_events(client, ®); if (reg.num_polled > 0) POLL(reg.polled, reg.num_polled, -1); - http_client_process_events(client, reg); + chttp_client_process_events(client, reg); - if (http_client_next_response(client, result, user, response)) + if (chttp_client_next_response(client, result, user, response)) break; } } -static _Thread_local HTTP_Client *implicit_client; +static _Thread_local CHTTP_Client *implicit_client; -static int perform_request(HTTP_Method method, - HTTP_String url, HTTP_String *headers, - int num_headers, HTTP_String body, - HTTP_Response **response) +static int perform_request(CHTTP_Method method, + CHTTP_String url, CHTTP_String *headers, + int num_headers, CHTTP_String body, + CHTTP_Response **response) { if (implicit_client == NULL) { - implicit_client = malloc(sizeof(HTTP_Client)); + implicit_client = malloc(sizeof(CHTTP_Client)); if (implicit_client == NULL) - return HTTP_ERROR_OOM; + return CHTTP_ERROR_OOM; - int ret = http_client_init(implicit_client); + int ret = chttp_client_init(implicit_client); if (ret < 0) { free(implicit_client); implicit_client = NULL; return ret; } } - HTTP_Client *client = implicit_client; + CHTTP_Client *client = implicit_client; - HTTP_RequestBuilder builder = http_client_get_builder(client); - http_request_builder_method(builder, method); - http_request_builder_target(builder, url); + CHTTP_RequestBuilder builder = chttp_client_get_builder(client); + chttp_request_builder_method(builder, method); + chttp_request_builder_target(builder, url); for (int i = 0; i < num_headers; i++) - http_request_builder_header(builder, headers[i]); - http_request_builder_body(builder, body); - int ret = http_request_builder_send(builder); + chttp_request_builder_header(builder, headers[i]); + chttp_request_builder_body(builder, body); + int ret = chttp_request_builder_send(builder); if (ret < 0) return ret; int result; void *user; - http_client_wait_response(client, &result, &user, response); + chttp_client_wait_response(client, &result, &user, response); return result; } -int http_get(HTTP_String url, HTTP_String *headers, - int num_headers, HTTP_Response **response) +int chttp_get(CHTTP_String url, CHTTP_String *headers, + int num_headers, CHTTP_Response **response) { - return perform_request(HTTP_METHOD_GET, url, headers, num_headers, HTTP_STR(""), response); + return perform_request(CHTTP_METHOD_GET, url, headers, num_headers, CHTTP_STR(""), response); } -int http_post(HTTP_String url, HTTP_String *headers, - int num_headers, HTTP_String body, - HTTP_Response **response) +int chttp_post(CHTTP_String url, CHTTP_String *headers, + int num_headers, CHTTP_String body, + CHTTP_Response **response) { - return perform_request(HTTP_METHOD_POST, url, headers, num_headers, body, response); + return perform_request(CHTTP_METHOD_POST, url, headers, num_headers, body, response); } -int http_put(HTTP_String url, HTTP_String *headers, - int num_headers, HTTP_String body, - HTTP_Response **response) +int chttp_put(CHTTP_String url, CHTTP_String *headers, + int num_headers, CHTTP_String body, + CHTTP_Response **response) { - return perform_request(HTTP_METHOD_PUT, url, headers, num_headers, body, response); + return perform_request(CHTTP_METHOD_PUT, url, headers, num_headers, body, response); } -int http_delete(HTTP_String url, HTTP_String *headers, - int num_headers, HTTP_Response **response) +int chttp_delete(CHTTP_String url, CHTTP_String *headers, + int num_headers, CHTTP_Response **response) { - return perform_request(HTTP_METHOD_DELETE, url, headers, num_headers, HTTP_STR(""), response); + return perform_request(CHTTP_METHOD_DELETE, url, headers, num_headers, CHTTP_STR(""), response); } diff --git a/src/client.h b/src/client.h index 71f2567..aa867a6 100644 --- a/src/client.h +++ b/src/client.h @@ -1,26 +1,26 @@ -#ifndef HTTP_CLIENT_CAPACITY +#ifndef CHTTP_CLIENT_CAPACITY // The maximum ammount of requests that can be performed // in parallel. -#define HTTP_CLIENT_CAPACITY (1<<7) +#define CHTTP_CLIENT_CAPACITY (1<<7) #endif // Maximum number of descriptors the client will want // to wait on. It's one per connection plus the wakeup // self-pipe. -#define HTTP_CLIENT_POLL_CAPACITY (HTTP_CLIENT_CAPACITY+1) +#define CHTTP_CLIENT_POLL_CAPACITY (CHTTP_CLIENT_CAPACITY+1) -#ifndef HTTP_COOKIE_JAR_CAPACITY +#ifndef CHTTP_COOKIE_JAR_CAPACITY // Maximum number of cookies that can be associated to a // single client. -#define HTTP_COOKIE_JAR_CAPACITY 128 +#define CHTTP_COOKIE_JAR_CAPACITY 128 #endif typedef struct { // Cookie name and value - HTTP_String name; - HTTP_String value; + CHTTP_String name; + CHTTP_String value; // If the "exact_domain" is true, the cookie // can only be sent to the exact domain referred @@ -28,7 +28,7 @@ typedef struct { // "exact_domain" is false, then the cookie is // compatible with subdomains. bool exact_domain; - HTTP_String domain; + CHTTP_String domain; // If "exact_path" is set, the cookie is only // compatible with requests to paths that match @@ -36,40 +36,40 @@ typedef struct { // then any path that starts with "path" is // compatible with the cookie. bool exact_path; - HTTP_String path; + CHTTP_String path; // This cookie can only be sent over HTTPS bool secure; -} HTTP_CookieJarEntry; +} CHTTP_CookieJarEntry; typedef struct { int count; - HTTP_CookieJarEntry items[HTTP_COOKIE_JAR_CAPACITY]; -} HTTP_CookieJar; + CHTTP_CookieJarEntry items[CHTTP_COOKIE_JAR_CAPACITY]; +} CHTTP_CookieJar; typedef enum { - HTTP_CLIENT_CONN_FREE, - HTTP_CLIENT_CONN_WAIT_METHOD, - HTTP_CLIENT_CONN_WAIT_URL, - HTTP_CLIENT_CONN_WAIT_HEADER, - HTTP_CLIENT_CONN_WAIT_BODY, - HTTP_CLIENT_CONN_FLUSHING, - HTTP_CLIENT_CONN_BUFFERING, - HTTP_CLIENT_CONN_COMPLETE, -} HTTP_ClientConnState; + CHTTP_CLIENT_CONN_FREE, + CHTTP_CLIENT_CONN_WAIT_METHOD, + CHTTP_CLIENT_CONN_WAIT_URL, + CHTTP_CLIENT_CONN_WAIT_HEADER, + CHTTP_CLIENT_CONN_WAIT_BODY, + CHTTP_CLIENT_CONN_FLUSHING, + CHTTP_CLIENT_CONN_BUFFERING, + CHTTP_CLIENT_CONN_COMPLETE, +} CHTTP_ClientConnState; // Fields of this struct are private -typedef struct HTTP_Client HTTP_Client; +typedef struct CHTTP_Client CHTTP_Client; typedef struct { - HTTP_ClientConnState state; + CHTTP_ClientConnState state; // Handle to the socket SocketHandle handle; // Pointer back to the client - HTTP_Client *client; + CHTTP_Client *client; // Generation counter for request builder validation uint16_t gen; @@ -85,11 +85,11 @@ typedef struct { bool dont_verify_cert; // Allocated copy of the URL string - HTTP_String url_buffer; + CHTTP_String url_buffer; // Parsed URL for connection establishment // All url.* pointers reference into url_buffer - HTTP_URL url; + CHTTP_URL url; // Data received from the server ByteQueue input; @@ -104,7 +104,7 @@ typedef struct { int result; // Parsed response once complete - HTTP_Response response; + CHTTP_Response response; // This offset points to the first byte that comes // after the string "Content-Length: ". @@ -115,10 +115,10 @@ typedef struct { // content byte subtracting it from the offset reached // when the request is marked as done. ByteQueueOffset content_length_offset; -} HTTP_ClientConn; +} CHTTP_ClientConn; // Fields of this struct are private -struct HTTP_Client { +struct CHTTP_Client { // Size limit of the input and output buffer of each // connection. @@ -126,18 +126,18 @@ struct HTTP_Client { uint32_t output_buffer_limit; // List of cookies created during this session - HTTP_CookieJar cookie_jar; + CHTTP_CookieJar cookie_jar; // Array of connections. The counter contains the // number of structs such that state!=FREE. int num_conns; - HTTP_ClientConn conns[HTTP_CLIENT_CAPACITY]; + CHTTP_ClientConn conns[CHTTP_CLIENT_CAPACITY]; // Queue of indices referring to connections that // are in the COMPLETE state. int num_ready; int ready_head; - int ready[HTTP_CLIENT_CAPACITY]; + int ready[CHTTP_CLIENT_CAPACITY]; // Asynchronous TCP and TLS socket abstraction SocketManager sockets; @@ -147,80 +147,80 @@ struct HTTP_Client { // manager with a pointer to it. This allows // allocating the exact number of sockets we // will need. - Socket socket_pool[HTTP_CLIENT_CAPACITY]; + Socket socket_pool[CHTTP_CLIENT_CAPACITY]; }; // Initialize an HTTP client object. This allows one to // perform a number of requests in parallel. -int http_client_init(HTTP_Client *client); +int chttp_client_init(CHTTP_Client *client); // Release resources associated to a client object. -void http_client_free(HTTP_Client *client); +void chttp_client_free(CHTTP_Client *client); // Set input and output buffer size limit for any // given connection. The default value is 1MB -void http_client_set_input_limit(HTTP_Client *client, uint32_t limit); -void http_client_set_output_limit(HTTP_Client *client, uint32_t limit); +void chttp_client_set_input_limit(CHTTP_Client *client, uint32_t limit); +void chttp_client_set_output_limit(CHTTP_Client *client, uint32_t limit); // When a thread is blocked waiting for client events, // other threads can call this function to wake it up. -int http_client_wakeup(HTTP_Client *client); +int chttp_client_wakeup(CHTTP_Client *client); typedef struct { - HTTP_Client *client; + CHTTP_Client *client; uint16_t index; uint16_t gen; -} HTTP_RequestBuilder; +} CHTTP_RequestBuilder; // Create a new request builder object. -HTTP_RequestBuilder http_client_get_builder(HTTP_Client *client); +CHTTP_RequestBuilder chttp_client_get_builder(CHTTP_Client *client); // TODO: comment -void http_request_builder_set_user(HTTP_RequestBuilder builder, +void chttp_request_builder_set_user(CHTTP_RequestBuilder builder, void *user); // TODO: comment -void http_request_builder_trace(HTTP_RequestBuilder builder, +void chttp_request_builder_trace(CHTTP_RequestBuilder builder, bool trace_bytes); // TODO: comment -void http_request_builder_insecure(HTTP_RequestBuilder builder, +void chttp_request_builder_insecure(CHTTP_RequestBuilder builder, bool insecure); // Set the method of the current request. This is the first // function of the request builder that the user must call. -void http_request_builder_method(HTTP_RequestBuilder builder, - HTTP_Method method); +void chttp_request_builder_method(CHTTP_RequestBuilder builder, + CHTTP_Method method); // Set the URL of the current request. This must be set after // the method and before any header/body -void http_request_builder_target(HTTP_RequestBuilder builder, - HTTP_String url); +void chttp_request_builder_target(CHTTP_RequestBuilder builder, + CHTTP_String url); // After the URL, the user may set zero or more headers. -void http_request_builder_header(HTTP_RequestBuilder builder, - HTTP_String str); +void chttp_request_builder_header(CHTTP_RequestBuilder builder, + CHTTP_String str); // Append bytes to the request's body. You can call this // any amount of times, as long as it's after having set // the URL. -void http_request_builder_body(HTTP_RequestBuilder builder, - HTTP_String str); +void chttp_request_builder_body(CHTTP_RequestBuilder builder, + CHTTP_String str); // Mark this request as complete. This invalidates the // builder. // Returns 0 on success, -1 on error. -int http_request_builder_send(HTTP_RequestBuilder builder); +int chttp_request_builder_send(CHTTP_RequestBuilder builder); // Resets the event register with the list of descriptors // the client wants monitored. -void http_client_register_events(HTTP_Client *client, +void chttp_client_register_events(CHTTP_Client *client, EventRegister *reg); // The caller has waited for poll() to return and some // I/O events to be triggered, so now the HTTP client // can continue its buffering and flushing operations. -void http_client_process_events(HTTP_Client *client, +void chttp_client_process_events(CHTTP_Client *client, EventRegister reg); // After some I/O events were processes, some responses @@ -228,33 +228,33 @@ void http_client_process_events(HTTP_Client *client, // buffered responses. If a request was available, true // is returned. If no more are avaiable, false is returned. // The returned response must be freed using the -// http_free_response function. +// chttp_free_response function. // TODO: Better comment talking about output arguments -bool http_client_next_response(HTTP_Client *client, - int *result, void **user, HTTP_Response **response); +bool chttp_client_next_response(CHTTP_Client *client, + int *result, void **user, CHTTP_Response **response); // TODO: comment -void http_client_wait_response(HTTP_Client *client, - int *result, void **user, HTTP_Response **response); +void chttp_client_wait_response(CHTTP_Client *client, + int *result, void **user, CHTTP_Response **response); // Free a response object. You can't access its fields // again after this. -void http_free_response(HTTP_Response *response); +void chttp_free_response(CHTTP_Response *response); // Perform a blocking GET request -int http_get(HTTP_String url, HTTP_String *headers, - int num_headers, HTTP_Response **response); +int chttp_get(CHTTP_String url, CHTTP_String *headers, + int num_headers, CHTTP_Response **response); // Perform a blocking POST request -int http_post(HTTP_String url, HTTP_String *headers, - int num_headers, HTTP_String body, - HTTP_Response **response); +int chttp_post(CHTTP_String url, CHTTP_String *headers, + int num_headers, CHTTP_String body, + CHTTP_Response **response); // Perform a blocking PUT request -int http_put(HTTP_String url, HTTP_String *headers, - int num_headers, HTTP_String body, - HTTP_Response **response); +int chttp_put(CHTTP_String url, CHTTP_String *headers, + int num_headers, CHTTP_String body, + CHTTP_Response **response); // Perform a blocking DELETE request -int http_delete(HTTP_String url, HTTP_String *headers, - int num_headers, HTTP_Response **response); +int chttp_delete(CHTTP_String url, CHTTP_String *headers, + int num_headers, CHTTP_Response **response); diff --git a/src/parse.c b/src/parse.c index a9624c1..21d6dd7 100644 --- a/src/parse.c +++ b/src/parse.c @@ -128,7 +128,7 @@ consume_absolute_path(Scanner *s) // path-absolute = "/" [ segment-nz *( "/" segment ) ] // path-rootless = segment-nz *( "/" segment ) // path-empty = 0 -static int parse_path(Scanner *s, HTTP_String *path, int abempty) +static int parse_path(Scanner *s, CHTTP_String *path, int abempty) { int start = s->cur; @@ -175,7 +175,7 @@ static int parse_path(Scanner *s, HTTP_String *path, int abempty) // (do nothing) } - *path = (HTTP_String) { + *path = (CHTTP_String) { s->src + start, s->cur - start, }; @@ -215,7 +215,7 @@ static void invert_bytes(void *p, int len) } } -static int parse_ipv4(Scanner *s, HTTP_IPv4 *ipv4) +static int parse_ipv4(Scanner *s, CHTTP_IPv4 *ipv4) { unsigned int out = 0; int i = 0; @@ -289,7 +289,7 @@ static int parse_ipv6_comp(Scanner *s) return (int) buf; } -static int parse_ipv6(Scanner *s, HTTP_IPv6 *ipv6) +static int parse_ipv6(Scanner *s, CHTTP_IPv6 *ipv6) { unsigned short head[8]; unsigned short tail[8]; @@ -359,7 +359,7 @@ static int is_regname(char c) return is_unreserved(c) || is_sub_delim(c); } -static int parse_regname(Scanner *s, HTTP_String *regname) +static int parse_regname(Scanner *s, CHTTP_String *regname) { if (s->cur == s->len || !is_regname(s->src[s->cur])) return -1; @@ -372,7 +372,7 @@ static int parse_regname(Scanner *s, HTTP_String *regname) return 0; } -static int parse_host(Scanner *s, HTTP_Host *host) +static int parse_host(Scanner *s, CHTTP_Host *host) { int ret; if (s->cur < s->len && s->src[s->cur] == '[') { @@ -380,13 +380,13 @@ static int parse_host(Scanner *s, HTTP_Host *host) s->cur++; int start = s->cur; - HTTP_IPv6 ipv6; + CHTTP_IPv6 ipv6; ret = parse_ipv6(s, &ipv6); if (ret < 0) return ret; - host->mode = HTTP_HOST_MODE_IPV6; + host->mode = CHTTP_HOST_MODE_IPV6; host->ipv6 = ipv6; - host->text = (HTTP_String) { s->src + start, s->cur - start }; + host->text = (CHTTP_String) { s->src + start, s->cur - start }; if (s->cur == s->len || s->src[s->cur] != ']') return -1; @@ -395,22 +395,22 @@ static int parse_host(Scanner *s, HTTP_Host *host) } else { int start = s->cur; - HTTP_IPv4 ipv4; + CHTTP_IPv4 ipv4; ret = parse_ipv4(s, &ipv4); if (ret >= 0) { - host->mode = HTTP_HOST_MODE_IPV4; + host->mode = CHTTP_HOST_MODE_IPV4; host->ipv4 = ipv4; } else { s->cur = start; - HTTP_String regname; + CHTTP_String regname; ret = parse_regname(s, ®name); if (ret < 0) return ret; - host->mode = HTTP_HOST_MODE_NAME; + host->mode = CHTTP_HOST_MODE_NAME; host->name = regname; } - host->text = (HTTP_String) { s->src + start, s->cur - start }; + host->text = (CHTTP_String) { s->src + start, s->cur - start }; } return 0; @@ -439,16 +439,16 @@ static int is_userinfo(char c) } // authority = [ userinfo "@" ] host [ ":" port ] -static int parse_authority(Scanner *s, HTTP_Authority *authority) +static int parse_authority(Scanner *s, CHTTP_Authority *authority) { - HTTP_String userinfo; + CHTTP_String userinfo; { int start = s->cur; CONSUME_OPTIONAL_SEQUENCE(s, is_userinfo); if (s->cur < s->len && s->src[s->cur] == '@') { - userinfo = (HTTP_String) { + userinfo = (CHTTP_String) { s->src + start, s->cur - start }; @@ -456,11 +456,11 @@ static int parse_authority(Scanner *s, HTTP_Authority *authority) } else { // Rollback s->cur = start; - userinfo = (HTTP_String) {NULL, 0}; + userinfo = (CHTTP_String) {NULL, 0}; } } - HTTP_Host host; + CHTTP_Host host; { int ret = parse_host(s, &host); if (ret < 0) @@ -487,9 +487,9 @@ static int parse_authority(Scanner *s, HTTP_Authority *authority) return 0; } -static int parse_uri(Scanner *s, HTTP_URL *url, int allow_fragment) +static int parse_uri(Scanner *s, CHTTP_URL *url, int allow_fragment) { - HTTP_String scheme = {0}; + CHTTP_String scheme = {0}; { int start = s->cur; if (s->cur == s->len || !is_scheme_head(s->src[s->cur])) @@ -497,7 +497,7 @@ static int parse_uri(Scanner *s, HTTP_URL *url, int allow_fragment) do s->cur++; while (s->cur < s->len && is_scheme_body(s->src[s->cur])); - scheme = (HTTP_String) { + scheme = (CHTTP_String) { s->src + start, s->cur - start, }; @@ -508,7 +508,7 @@ static int parse_uri(Scanner *s, HTTP_URL *url, int allow_fragment) } int abempty = 0; - HTTP_Authority authority = {0}; + CHTTP_Authority authority = {0}; if (s->len - s->cur > 1 && s->src[s->cur+0] == '/' && s->src[s->cur+1] == '/') { @@ -521,29 +521,29 @@ static int parse_uri(Scanner *s, HTTP_URL *url, int allow_fragment) abempty = 1; } - HTTP_String path; + CHTTP_String path; int ret = parse_path(s, &path, abempty); if (ret < 0) return ret; - HTTP_String query = {0}; + CHTTP_String query = {0}; if (s->cur < s->len && s->src[s->cur] == '?') { int start = s->cur; do s->cur++; while (s->cur < s->len && is_query(s->src[s->cur])); - query = (HTTP_String) { + query = (CHTTP_String) { s->src + start, s->cur - start, }; } - HTTP_String fragment = {0}; + CHTTP_String fragment = {0}; if (allow_fragment && s->cur < s->len && s->src[s->cur] == '#') { int start = s->cur; do s->cur++; while (s->cur < s->len && is_fragment(s->src[s->cur])); - fragment = (HTTP_String) { + fragment = (CHTTP_String) { s->src + start, s->cur - start, }; @@ -562,7 +562,7 @@ static int parse_uri(Scanner *s, HTTP_URL *url, int allow_fragment) // host = IP-literal / IPv4address / reg-name // IP-literal = "[" ( IPv6address / IPvFuture ) "]" // reg-name = *( unreserved / pct-encoded / sub-delims ) -static int parse_authority_form(Scanner *s, HTTP_Host *host, int *port) +static int parse_authority_form(Scanner *s, CHTTP_Host *host, int *port) { int ret; @@ -591,23 +591,23 @@ static int parse_authority_form(Scanner *s, HTTP_Host *host, int *port) return 0; } -static int parse_origin_form(Scanner *s, HTTP_String *path, HTTP_String *query) +static int parse_origin_form(Scanner *s, CHTTP_String *path, CHTTP_String *query) { int ret, start; start = s->cur; ret = consume_absolute_path(s); if (ret < 0) return ret; - *path = (HTTP_String) { s->src + start, s->cur - start }; + *path = (CHTTP_String) { s->src + start, s->cur - start }; if (s->cur < s->len && s->src[s->cur] == '?') { start = s->cur; do s->cur++; while (s->cur < s->len && is_query(s->src[s->cur])); - *query = (HTTP_String) { s->src + start, s->cur - start }; + *query = (CHTTP_String) { s->src + start, s->cur - start }; } else - *query = (HTTP_String) { NULL, 0 }; + *query = (CHTTP_String) { NULL, 0 }; return 0; } @@ -622,11 +622,11 @@ static int parse_asterisk_form(Scanner *s) return 0; } -static int parse_request_target(Scanner *s, HTTP_URL *url) +static int parse_request_target(Scanner *s, CHTTP_URL *url) { int ret; - memset(url, 0, sizeof(HTTP_URL)); + memset(url, 0, sizeof(CHTTP_URL)); // asterisk-form ret = parse_asterisk_form(s); @@ -644,7 +644,7 @@ static int parse_request_target(Scanner *s, HTTP_URL *url) return -1; } -bool consume_str(Scanner *scan, HTTP_String token) +bool consume_str(Scanner *scan, CHTTP_String token) { assert(token.len > 0); @@ -664,10 +664,10 @@ static int is_header_body(char c) return is_vchar(c) || c == ' ' || c == '\t'; } -static int parse_headers(Scanner *s, HTTP_Header *headers, int max_headers) +static int parse_headers(Scanner *s, CHTTP_Header *headers, int max_headers) { int num_headers = 0; - while (!consume_str(s, HTTP_STR("\r\n"))) { + while (!consume_str(s, CHTTP_STR("\r\n"))) { // RFC 9112: // field-line = field-name ":" OWS field-value OWS @@ -687,7 +687,7 @@ static int parse_headers(Scanner *s, HTTP_Header *headers, int max_headers) do s->cur++; while (s->cur < s->len && is_tchar(s->src[s->cur])); - HTTP_String name = { s->src + start, s->cur - start }; + CHTTP_String name = { s->src + start, s->cur - start }; if (s->cur == s->len || s->src[s->cur] != ':') return -1; // ERROR @@ -695,13 +695,13 @@ static int parse_headers(Scanner *s, HTTP_Header *headers, int max_headers) start = s->cur; CONSUME_OPTIONAL_SEQUENCE(s, is_header_body); - HTTP_String body = { s->src + start, s->cur - start }; - body = http_trim(body); + CHTTP_String body = { s->src + start, s->cur - start }; + body = chttp_trim(body); if (num_headers < max_headers) - headers[num_headers++] = (HTTP_Header) { name, body }; + headers[num_headers++] = (CHTTP_Header) { name, body }; - if (!consume_str(s, HTTP_STR("\r\n"))) { + if (!consume_str(s, CHTTP_STR("\r\n"))) { return -1; } } @@ -722,7 +722,7 @@ static bool is_space(char c) } static int -parse_transfer_encoding(HTTP_String src, TransferEncodingOption *dst, int max) +parse_transfer_encoding(CHTTP_String src, TransferEncodingOption *dst, int max) { Scanner s = { src.ptr, src.len, 0 }; @@ -733,10 +733,10 @@ parse_transfer_encoding(HTTP_String src, TransferEncodingOption *dst, int max) TransferEncodingOption opt; if (0) {} - else if (consume_str(&s, HTTP_STR("chunked"))) opt = TRANSFER_ENCODING_OPTION_CHUNKED; - else if (consume_str(&s, HTTP_STR("compress"))) opt = TRANSFER_ENCODING_OPTION_COMPRESS; - else if (consume_str(&s, HTTP_STR("deflate"))) opt = TRANSFER_ENCODING_OPTION_DEFLATE; - else if (consume_str(&s, HTTP_STR("gzip"))) opt = TRANSFER_ENCODING_OPTION_GZIP; + else if (consume_str(&s, CHTTP_STR("chunked"))) opt = TRANSFER_ENCODING_OPTION_CHUNKED; + else if (consume_str(&s, CHTTP_STR("compress"))) opt = TRANSFER_ENCODING_OPTION_COMPRESS; + else if (consume_str(&s, CHTTP_STR("deflate"))) opt = TRANSFER_ENCODING_OPTION_DEFLATE; + else if (consume_str(&s, CHTTP_STR("gzip"))) opt = TRANSFER_ENCODING_OPTION_GZIP; else return -1; // Invalid option if (num == max) @@ -778,8 +778,8 @@ parse_content_length(const char *src, int len, uint64_t *out) } static int parse_body(Scanner *s, - HTTP_Header *headers, int num_headers, - HTTP_String *body, bool body_expected) + CHTTP_Header *headers, int num_headers, + CHTTP_String *body, bool body_expected) { // RFC 9112 section 6: @@ -787,7 +787,7 @@ static int parse_body(Scanner *s, // Transfer-Encoding header field. Request message framing is independent of method // semantics. - int header_index = http_find_header(headers, num_headers, HTTP_STR("Transfer-Encoding")); + int header_index = chttp_find_header(headers, num_headers, CHTTP_STR("Transfer-Encoding")); if (header_index != -1) { // RFC 9112 section 6.1: @@ -795,10 +795,10 @@ static int parse_body(Scanner *s, // or process such a request in accordance with the Transfer-Encoding alone. Regardless, // the server MUST close the connection after responding to such a request to avoid the // potential attacks. - if (http_find_header(headers, num_headers, HTTP_STR("Content-Length")) != -1) + if (chttp_find_header(headers, num_headers, CHTTP_STR("Content-Length")) != -1) return -1; - HTTP_String value = headers[header_index].value; + CHTTP_String value = headers[header_index].value; // RFC 9112 section 6.1: // If any transfer coding other than chunked is applied to a request's content, the @@ -808,14 +808,14 @@ static int parse_body(Scanner *s, // coding or terminate the message by closing the connection. TransferEncodingOption opts[8]; - int num = parse_transfer_encoding(value, opts, HTTP_COUNT(opts)); + int num = parse_transfer_encoding(value, opts, CHTTP_COUNT(opts)); if (num != 1 || opts[0] != TRANSFER_ENCODING_OPTION_CHUNKED) return -1; - HTTP_String chunks_maybe[128]; - HTTP_String *chunks = chunks_maybe; + CHTTP_String chunks_maybe[128]; + CHTTP_String *chunks = chunks_maybe; int num_chunks = 0; - int max_chunks = HTTP_COUNT(chunks_maybe); + int max_chunks = CHTTP_COUNT(chunks_maybe); #define FREE_CHUNK_LIST \ if (chunks != chunks_maybe) \ @@ -905,7 +905,7 @@ static int parse_body(Scanner *s, max_chunks *= 2; - HTTP_String *new_chunks = malloc(max_chunks * sizeof(HTTP_String)); + CHTTP_String *new_chunks = malloc(max_chunks * sizeof(CHTTP_String)); if (new_chunks == NULL) { if (chunks != chunks_maybe) free(chunks); @@ -920,7 +920,7 @@ static int parse_body(Scanner *s, chunks = new_chunks; } - chunks[num_chunks++] = (HTTP_String) { chunk_ptr, chunk_len }; + chunks[num_chunks++] = (CHTTP_String) { chunk_ptr, chunk_len }; } char *content_ptr = content_start; @@ -929,7 +929,7 @@ static int parse_body(Scanner *s, content_ptr += chunks[i].len; } - *body = (HTTP_String) { + *body = (CHTTP_String) { content_start, content_ptr - content_start }; @@ -944,11 +944,11 @@ static int parse_body(Scanner *s, // If a valid Content-Length header field is present without Transfer-Encoding, // its decimal value defines the expected message body length in octets. - header_index = http_find_header(headers, num_headers, HTTP_STR("Content-Length")); + header_index = chttp_find_header(headers, num_headers, CHTTP_STR("Content-Length")); if (header_index != -1) { // Have Content-Length - HTTP_String value = headers[header_index].value; + CHTTP_String value = headers[header_index].value; uint64_t tmp; if (parse_content_length(value.ptr, value.len, &tmp) < 0) @@ -960,7 +960,7 @@ static int parse_body(Scanner *s, if (len > s->len - s->cur) return 0; // Incomplete request - *body = (HTTP_String) { s->src + s->cur, len }; + *body = (CHTTP_String) { s->src + s->cur, len }; s->cur += len; return 1; @@ -969,7 +969,7 @@ static int parse_body(Scanner *s, // No Content-Length or Transfer-Encoding if (body_expected) return -1; - *body = (HTTP_String) { NULL, 0 }; + *body = (CHTTP_String) { NULL, 0 }; return 1; } @@ -987,7 +987,7 @@ static int contains_head(char *src, int len) return 0; } -static int parse_request(Scanner *s, HTTP_Request *req) +static int parse_request(Scanner *s, CHTTP_Request *req) { if (!contains_head(s->src + s->cur, s->len - s->cur)) return 0; @@ -995,15 +995,15 @@ static int parse_request(Scanner *s, HTTP_Request *req) req->secure = false; if (0) {} - else if (consume_str(s, HTTP_STR("GET "))) req->method = HTTP_METHOD_GET; - else if (consume_str(s, HTTP_STR("POST "))) req->method = HTTP_METHOD_POST; - else if (consume_str(s, HTTP_STR("PUT "))) req->method = HTTP_METHOD_PUT; - else if (consume_str(s, HTTP_STR("HEAD "))) req->method = HTTP_METHOD_HEAD; - else if (consume_str(s, HTTP_STR("DELETE "))) req->method = HTTP_METHOD_DELETE; - else if (consume_str(s, HTTP_STR("CONNECT "))) req->method = HTTP_METHOD_CONNECT; - else if (consume_str(s, HTTP_STR("OPTIONS "))) req->method = HTTP_METHOD_OPTIONS; - else if (consume_str(s, HTTP_STR("TRACE "))) req->method = HTTP_METHOD_TRACE; - else if (consume_str(s, HTTP_STR("PATCH "))) req->method = HTTP_METHOD_PATCH; + else if (consume_str(s, CHTTP_STR("GET "))) req->method = CHTTP_METHOD_GET; + else if (consume_str(s, CHTTP_STR("POST "))) req->method = CHTTP_METHOD_POST; + else if (consume_str(s, CHTTP_STR("PUT "))) req->method = CHTTP_METHOD_PUT; + else if (consume_str(s, CHTTP_STR("HEAD "))) req->method = CHTTP_METHOD_HEAD; + else if (consume_str(s, CHTTP_STR("DELETE "))) req->method = CHTTP_METHOD_DELETE; + else if (consume_str(s, CHTTP_STR("CONNECT "))) req->method = CHTTP_METHOD_CONNECT; + else if (consume_str(s, CHTTP_STR("OPTIONS "))) req->method = CHTTP_METHOD_OPTIONS; + else if (consume_str(s, CHTTP_STR("TRACE "))) req->method = CHTTP_METHOD_TRACE; + else if (consume_str(s, CHTTP_STR("PATCH "))) req->method = CHTTP_METHOD_PATCH; else return -1; { @@ -1021,47 +1021,47 @@ static int parse_request(Scanner *s, HTTP_Request *req) s->cur = s2.cur; } - if (consume_str(s, HTTP_STR(" HTTP/1.1\r\n"))) { + if (consume_str(s, CHTTP_STR(" HTTP/1.1\r\n"))) { req->minor = 1; - } else if (consume_str(s, HTTP_STR(" HTTP/1.0\r\n")) || consume_str(s, HTTP_STR(" HTTP/1\r\n"))) { + } else if (consume_str(s, CHTTP_STR(" HTTP/1.0\r\n")) || consume_str(s, CHTTP_STR(" HTTP/1\r\n"))) { req->minor = 0; } else { return -1; } - int num_headers = parse_headers(s, req->headers, HTTP_MAX_HEADERS); + int num_headers = parse_headers(s, req->headers, CHTTP_MAX_HEADERS); if (num_headers < 0) return num_headers; req->num_headers = num_headers; // Request methods that typically don't have a body bool body_expected = true; - if (req->method == HTTP_METHOD_GET || - req->method == HTTP_METHOD_HEAD || - req->method == HTTP_METHOD_DELETE || - req->method == HTTP_METHOD_OPTIONS || - req->method == HTTP_METHOD_TRACE) + if (req->method == CHTTP_METHOD_GET || + req->method == CHTTP_METHOD_HEAD || + req->method == CHTTP_METHOD_DELETE || + req->method == CHTTP_METHOD_OPTIONS || + req->method == CHTTP_METHOD_TRACE) body_expected = false; return parse_body(s, req->headers, req->num_headers, &req->body, body_expected); } -int http_find_header(HTTP_Header *headers, int num_headers, HTTP_String name) +int chttp_find_header(CHTTP_Header *headers, int num_headers, CHTTP_String name) { for (int i = 0; i < num_headers; i++) - if (http_streqcase(name, headers[i].name)) + if (chttp_streqcase(name, headers[i].name)) return i; return -1; } -static int parse_response(Scanner *s, HTTP_Response *res) +static int parse_response(Scanner *s, CHTTP_Response *res) { if (!contains_head(s->src + s->cur, s->len - s->cur)) return 0; - if (consume_str(s, HTTP_STR("HTTP/1.1 "))) { + if (consume_str(s, CHTTP_STR("HTTP/1.1 "))) { res->minor = 1; - } else if (consume_str(s, HTTP_STR("HTTP/1.0 ")) || consume_str(s, HTTP_STR("HTTP/1 "))) { + } else if (consume_str(s, CHTTP_STR("HTTP/1.0 ")) || consume_str(s, CHTTP_STR("HTTP/1 "))) { res->minor = 0; } else { return -1; @@ -1093,7 +1093,7 @@ static int parse_response(Scanner *s, HTTP_Response *res) return -1; s->cur += 2; - int num_headers = parse_headers(s, res->headers, HTTP_MAX_HEADERS); + int num_headers = parse_headers(s, res->headers, CHTTP_MAX_HEADERS); if (num_headers < 0) return num_headers; res->num_headers = num_headers; @@ -1113,7 +1113,7 @@ static int parse_response(Scanner *s, HTTP_Response *res) return parse_body(s, res->headers, res->num_headers, &res->body, body_expected); } -int http_parse_ipv4(char *src, int len, HTTP_IPv4 *ipv4) +int chttp_parse_ipv4(char *src, int len, CHTTP_IPv4 *ipv4) { Scanner s = {src, len, 0}; int ret = parse_ipv4(&s, ipv4); @@ -1121,7 +1121,7 @@ int http_parse_ipv4(char *src, int len, HTTP_IPv4 *ipv4) return s.cur; } -int http_parse_ipv6(char *src, int len, HTTP_IPv6 *ipv6) +int chttp_parse_ipv6(char *src, int len, CHTTP_IPv6 *ipv6) { Scanner s = {src, len, 0}; int ret = parse_ipv6(&s, ipv6); @@ -1129,7 +1129,7 @@ int http_parse_ipv6(char *src, int len, HTTP_IPv6 *ipv6) return s.cur; } -int http_parse_url(char *src, int len, HTTP_URL *url) +int chttp_parse_url(char *src, int len, CHTTP_URL *url) { Scanner s = {src, len, 0}; int ret = parse_uri(&s, url, 1); @@ -1138,7 +1138,7 @@ int http_parse_url(char *src, int len, HTTP_URL *url) return ret; } -int http_parse_request(char *src, int len, HTTP_Request *req) +int chttp_parse_request(char *src, int len, CHTTP_Request *req) { Scanner s = {src, len, 0}; int ret = parse_request(&s, req); @@ -1147,7 +1147,7 @@ int http_parse_request(char *src, int len, HTTP_Request *req) return ret; } -int http_parse_response(char *src, int len, HTTP_Response *res) +int chttp_parse_response(char *src, int len, CHTTP_Response *res) { Scanner s = {src, len, 0}; int ret = parse_response(&s, res); @@ -1156,14 +1156,14 @@ int http_parse_response(char *src, int len, HTTP_Response *res) return ret; } -HTTP_String http_get_cookie(HTTP_Request *req, HTTP_String name) +CHTTP_String chttp_get_cookie(CHTTP_Request *req, CHTTP_String name) { // Simple cookie parsing - does not handle quoted values or special characters // See RFC 6265 for full cookie specification for (int i = 0; i < req->num_headers; i++) { - if (!http_streqcase(req->headers[i].name, HTTP_STR("Cookie"))) + if (!chttp_streqcase(req->headers[i].name, CHTTP_STR("Cookie"))) continue; char *src = req->headers[i].value.ptr; @@ -1181,7 +1181,7 @@ HTTP_String http_get_cookie(HTTP_Request *req, HTTP_String name) while (cur < len && src[cur] != '=') cur++; - HTTP_String cookie_name = { src + off, cur - off }; + CHTTP_String cookie_name = { src + off, cur - off }; if (cur == len) break; @@ -1191,9 +1191,9 @@ HTTP_String http_get_cookie(HTTP_Request *req, HTTP_String name) while (cur < len && src[cur] != ';') cur++; - HTTP_String cookie_value = { src + off, cur - off }; + CHTTP_String cookie_value = { src + off, cur - off }; - if (http_streq(name, cookie_name)) + if (chttp_streq(name, cookie_name)) return cookie_value; if (cur == len) @@ -1202,10 +1202,10 @@ HTTP_String http_get_cookie(HTTP_Request *req, HTTP_String name) } } - return HTTP_STR(""); + return CHTTP_STR(""); } -HTTP_String http_get_param(HTTP_String body, HTTP_String str, char *mem, int cap) +CHTTP_String chttp_get_param(CHTTP_String body, CHTTP_String str, char *mem, int cap) { // This is just a best-effort implementation @@ -1218,29 +1218,29 @@ HTTP_String http_get_param(HTTP_String body, HTTP_String str, char *mem, int cap while (cur < len) { - HTTP_String name; + CHTTP_String name; { int off = cur; while (cur < len && src[cur] != '=' && src[cur] != '&') cur++; - name = (HTTP_String) { src + off, cur - off }; + name = (CHTTP_String) { src + off, cur - off }; } - HTTP_String body = HTTP_STR(""); + CHTTP_String body = CHTTP_STR(""); if (cur < len) { cur++; if (src[cur-1] == '=') { int off = cur; while (cur < len && src[cur] != '&') cur++; - body = (HTTP_String) { src + off, cur - off }; + body = (CHTTP_String) { src + off, cur - off }; if (cur < len) cur++; } } - if (http_streq(str, name)) { + if (chttp_streq(str, name)) { bool percent_encoded = false; for (int i = 0; i < body.len; i++) @@ -1253,9 +1253,9 @@ HTTP_String http_get_param(HTTP_String body, HTTP_String str, char *mem, int cap return body; if (body.len > cap) - return (HTTP_String) { NULL, 0 }; + return (CHTTP_String) { NULL, 0 }; - HTTP_String decoded = { mem, 0 }; + CHTTP_String decoded = { mem, 0 }; for (int i = 0; i < body.len; i++) { char c = body.ptr[i]; @@ -1266,7 +1266,7 @@ HTTP_String http_get_param(HTTP_String body, HTTP_String str, char *mem, int cap if (body.len - i < 3 || !is_hex_digit(body.ptr[i+1]) || !is_hex_digit(body.ptr[i+2])) - return (HTTP_String) { NULL, 0 }; + return (CHTTP_String) { NULL, 0 }; int h = hex_digit_to_int(body.ptr[i+1]); int l = hex_digit_to_int(body.ptr[i+2]); @@ -1283,13 +1283,13 @@ HTTP_String http_get_param(HTTP_String body, HTTP_String str, char *mem, int cap } } - return HTTP_STR(""); + return CHTTP_STR(""); } -int http_get_param_i(HTTP_String body, HTTP_String str) +int chttp_get_param_i(CHTTP_String body, CHTTP_String str) { char buf[128]; - HTTP_String out = http_get_param(body, str, buf, (int) sizeof(buf)); + CHTTP_String out = chttp_get_param(body, str, buf, (int) sizeof(buf)); if (out.len == 0 || !is_digit(out.ptr[0])) return -1; @@ -1305,38 +1305,38 @@ int http_get_param_i(HTTP_String body, HTTP_String str) return res; } -bool http_match_host(HTTP_Request *req, HTTP_String domain, int port) +bool chttp_match_host(CHTTP_Request *req, CHTTP_String domain, int port) { - int idx = http_find_header(req->headers, req->num_headers, HTTP_STR("Host")); + int idx = chttp_find_header(req->headers, req->num_headers, CHTTP_STR("Host")); assert(idx != -1); // Requests without the host header are always rejected char tmp[1<<8]; if (port > -1 && port != 80) { int ret = snprintf(tmp, sizeof(tmp), "%.*s:%d", domain.len, domain.ptr, port); assert(ret > 0); - domain = (HTTP_String) { tmp, ret }; + domain = (CHTTP_String) { tmp, ret }; } - HTTP_String host = req->headers[idx].value; - return http_streqcase(host, domain); + CHTTP_String host = req->headers[idx].value; + return chttp_streqcase(host, domain); } // , :: GMT -static int parse_date(Scanner *s, HTTP_Date *out) +static int parse_date(Scanner *s, CHTTP_Date *out) { - struct { HTTP_String str; HTTP_WeekDay val; } week_day_table[] = { - { HTTP_STR("Mon, "), HTTP_WEEKDAY_MON }, - { HTTP_STR("Tue, "), HTTP_WEEKDAY_TUE }, - { HTTP_STR("Wed, "), HTTP_WEEKDAY_WED }, - { HTTP_STR("Thu, "), HTTP_WEEKDAY_THU }, - { HTTP_STR("Fri, "), HTTP_WEEKDAY_FRI }, - { HTTP_STR("Sat, "), HTTP_WEEKDAY_SAT }, - { HTTP_STR("Sun, "), HTTP_WEEKDAY_SUN }, + struct { CHTTP_String str; CHTTP_WeekDay val; } week_day_table[] = { + { CHTTP_STR("Mon, "), CHTTP_WEEKDAY_MON }, + { CHTTP_STR("Tue, "), CHTTP_WEEKDAY_TUE }, + { CHTTP_STR("Wed, "), CHTTP_WEEKDAY_WED }, + { CHTTP_STR("Thu, "), CHTTP_WEEKDAY_THU }, + { CHTTP_STR("Fri, "), CHTTP_WEEKDAY_FRI }, + { CHTTP_STR("Sat, "), CHTTP_WEEKDAY_SAT }, + { CHTTP_STR("Sun, "), CHTTP_WEEKDAY_SUN }, }; bool found = false; - for (int i = 0; i < HTTP_COUNT(week_day_table); i++) + for (int i = 0; i < CHTTP_COUNT(week_day_table); i++) if (consume_str(s, week_day_table[i].str)) { out->week_day = week_day_table[i].val; found = true; @@ -1354,23 +1354,23 @@ static int parse_date(Scanner *s, HTTP_Date *out) + (s->src[s->cur+1] - '0') * 1; s->cur += 2; - struct { HTTP_String str; HTTP_Month val; } month_table[] = { - { HTTP_STR(" Jan "), HTTP_MONTH_JAN }, - { HTTP_STR(" Feb "), HTTP_MONTH_FEB }, - { HTTP_STR(" Mar "), HTTP_MONTH_MAR }, - { HTTP_STR(" Apr "), HTTP_MONTH_APR }, - { HTTP_STR(" May "), HTTP_MONTH_MAY }, - { HTTP_STR(" Jun "), HTTP_MONTH_JUN }, - { HTTP_STR(" Jul "), HTTP_MONTH_JUL }, - { HTTP_STR(" Aug "), HTTP_MONTH_AUG }, - { HTTP_STR(" Sep "), HTTP_MONTH_SEP }, - { HTTP_STR(" Oct "), HTTP_MONTH_OCT }, - { HTTP_STR(" Nov "), HTTP_MONTH_NOV }, - { HTTP_STR(" Dec "), HTTP_MONTH_DEC }, + struct { CHTTP_String str; CHTTP_Month val; } month_table[] = { + { CHTTP_STR(" Jan "), CHTTP_MONTH_JAN }, + { CHTTP_STR(" Feb "), CHTTP_MONTH_FEB }, + { CHTTP_STR(" Mar "), CHTTP_MONTH_MAR }, + { CHTTP_STR(" Apr "), CHTTP_MONTH_APR }, + { CHTTP_STR(" May "), CHTTP_MONTH_MAY }, + { CHTTP_STR(" Jun "), CHTTP_MONTH_JUN }, + { CHTTP_STR(" Jul "), CHTTP_MONTH_JUL }, + { CHTTP_STR(" Aug "), CHTTP_MONTH_AUG }, + { CHTTP_STR(" Sep "), CHTTP_MONTH_SEP }, + { CHTTP_STR(" Oct "), CHTTP_MONTH_OCT }, + { CHTTP_STR(" Nov "), CHTTP_MONTH_NOV }, + { CHTTP_STR(" Dec "), CHTTP_MONTH_DEC }, }; found = false; - for (int i = 0; i < HTTP_COUNT(month_table); i++) + for (int i = 0; i < CHTTP_COUNT(month_table); i++) if (consume_str(s, month_table[i].str)) { out->month = month_table[i].val; found = true; @@ -1436,7 +1436,7 @@ static bool is_cookie_octet(char c) (c >= 0x5D && c <= 0x7E); } -int http_parse_set_cookie(HTTP_String str, HTTP_SetCookie *out) +int chttp_parse_set_cookie(CHTTP_String str, CHTTP_SetCookie *out) { Scanner s = { str.ptr, str.len, 0 }; @@ -1447,7 +1447,7 @@ int http_parse_set_cookie(HTTP_String str, HTTP_SetCookie *out) do s.cur++; while (s.cur < s.len && is_tchar(s.src[s.cur])); - out->name = (HTTP_String) { s.src + off, s.cur - off }; + out->name = (CHTTP_String) { s.src + off, s.cur - off }; // cookie-pair = cookie-name "=" cookie-value if (s.cur == s.len || s.src[s.cur] != '=') @@ -1462,13 +1462,13 @@ int http_parse_set_cookie(HTTP_String str, HTTP_SetCookie *out) s.cur++; if (s.cur == s.len || s.src[s.cur] != '"') return -1; // Missing closing double quote - out->value = (HTTP_String) { s.src + off, s.cur - off }; + out->value = (CHTTP_String) { s.src + off, s.cur - off }; s.cur++; // Consume closing double quote } else { int off = s.cur; while (s.cur < s.len && is_cookie_octet(s.src[s.cur])) s.cur++; - out->value = (HTTP_String) { s.src + off, s.cur - off }; + out->value = (CHTTP_String) { s.src + off, s.cur - off }; } // *( ";" SP cookie-av ) @@ -1477,20 +1477,20 @@ int http_parse_set_cookie(HTTP_String str, HTTP_SetCookie *out) // path-av / secure-av / httponly-av / // extension-av out->secure = false; - out->http_only = false; + out->chttp_only = false; out->have_date = false; out->have_max_age = false; out->have_domain = false; out->have_path = false; - while (consume_str(&s, HTTP_STR("; "))) { - if (consume_str(&s, HTTP_STR("Expires="))) { + while (consume_str(&s, CHTTP_STR("; "))) { + if (consume_str(&s, CHTTP_STR("Expires="))) { // expires-av = "Expires=" sane-cookie-date if (parse_date(&s, &out->date) < 0) return -1; out->have_date = true; - } else if (consume_str(&s, HTTP_STR("Max-Age="))) { + } else if (consume_str(&s, CHTTP_STR("Max-Age="))) { // max-age-av = "Max-Age=" non-zero-digit *DIGIT @@ -1507,7 +1507,7 @@ int http_parse_set_cookie(HTTP_String str, HTTP_SetCookie *out) out->have_max_age = true; out->max_age = value; - } else if (consume_str(&s, HTTP_STR("Domain="))) { + } else if (consume_str(&s, CHTTP_STR("Domain="))) { // domain-av = "Domain=" domain-value // domain-value = @@ -1557,9 +1557,9 @@ int http_parse_set_cookie(HTTP_String str, HTTP_SetCookie *out) } out->have_domain = true; - out->domain = (HTTP_String) { s.src + off, s.cur - off }; + out->domain = (CHTTP_String) { s.src + off, s.cur - off }; - } else if (consume_str(&s, HTTP_STR("Path="))) { + } else if (consume_str(&s, CHTTP_STR("Path="))) { // path-av = "Path=" path-value // path-value = @@ -1569,17 +1569,17 @@ int http_parse_set_cookie(HTTP_String str, HTTP_SetCookie *out) s.cur++; out->have_path = true; - out->path = (HTTP_String) { s.src + off, s.cur - off }; + out->path = (CHTTP_String) { s.src + off, s.cur - off }; - } else if (consume_str(&s, HTTP_STR("Secure"))) { + } else if (consume_str(&s, CHTTP_STR("Secure"))) { // secure-av = "Secure" out->secure = true; - } else if (consume_str(&s, HTTP_STR("HttpOnly"))) { + } else if (consume_str(&s, CHTTP_STR("HttpOnly"))) { // httponly-av = "HttpOnly" - out->http_only = true; + out->chttp_only = true; } else { return -1; // Invalid attribute diff --git a/src/parse.h b/src/parse.h index 0f3a0ec..3cd2afb 100644 --- a/src/parse.h +++ b/src/parse.h @@ -1,155 +1,155 @@ -#define HTTP_MAX_HEADERS 32 +#define CHTTP_MAX_HEADERS 32 typedef struct { unsigned int data; -} HTTP_IPv4; +} CHTTP_IPv4; typedef struct { unsigned short data[8]; -} HTTP_IPv6; +} CHTTP_IPv6; typedef enum { - HTTP_HOST_MODE_VOID = 0, - HTTP_HOST_MODE_NAME, - HTTP_HOST_MODE_IPV4, - HTTP_HOST_MODE_IPV6, -} HTTP_HostMode; + CHTTP_HOST_MODE_VOID = 0, + CHTTP_HOST_MODE_NAME, + CHTTP_HOST_MODE_IPV4, + CHTTP_HOST_MODE_IPV6, +} CHTTP_HostMode; typedef struct { - HTTP_HostMode mode; - HTTP_String text; + CHTTP_HostMode mode; + CHTTP_String text; union { - HTTP_String name; - HTTP_IPv4 ipv4; - HTTP_IPv6 ipv6; + CHTTP_String name; + CHTTP_IPv4 ipv4; + CHTTP_IPv6 ipv6; }; -} HTTP_Host; +} CHTTP_Host; typedef struct { - HTTP_String userinfo; - HTTP_Host host; + CHTTP_String userinfo; + CHTTP_Host host; int port; -} HTTP_Authority; +} CHTTP_Authority; // ZII typedef struct { - HTTP_String scheme; - HTTP_Authority authority; - HTTP_String path; - HTTP_String query; - HTTP_String fragment; -} HTTP_URL; + CHTTP_String scheme; + CHTTP_Authority authority; + CHTTP_String path; + CHTTP_String query; + CHTTP_String fragment; +} CHTTP_URL; typedef enum { - HTTP_METHOD_GET, - HTTP_METHOD_HEAD, - HTTP_METHOD_POST, - HTTP_METHOD_PUT, - HTTP_METHOD_DELETE, - HTTP_METHOD_CONNECT, - HTTP_METHOD_OPTIONS, - HTTP_METHOD_TRACE, - HTTP_METHOD_PATCH, -} HTTP_Method; + CHTTP_METHOD_GET, + CHTTP_METHOD_HEAD, + CHTTP_METHOD_POST, + CHTTP_METHOD_PUT, + CHTTP_METHOD_DELETE, + CHTTP_METHOD_CONNECT, + CHTTP_METHOD_OPTIONS, + CHTTP_METHOD_TRACE, + CHTTP_METHOD_PATCH, +} CHTTP_Method; typedef struct { - HTTP_String name; - HTTP_String value; -} HTTP_Header; + CHTTP_String name; + CHTTP_String value; +} CHTTP_Header; typedef struct { bool secure; - HTTP_Method method; - HTTP_URL url; + CHTTP_Method method; + CHTTP_URL url; int minor; int num_headers; - HTTP_Header headers[HTTP_MAX_HEADERS]; - HTTP_String body; -} HTTP_Request; + CHTTP_Header headers[CHTTP_MAX_HEADERS]; + CHTTP_String body; +} CHTTP_Request; typedef struct { void* context; int minor; int status; - HTTP_String reason; + CHTTP_String reason; int num_headers; - HTTP_Header headers[HTTP_MAX_HEADERS]; - HTTP_String body; -} HTTP_Response; + CHTTP_Header headers[CHTTP_MAX_HEADERS]; + CHTTP_String body; +} CHTTP_Response; -int http_parse_ipv4 (char *src, int len, HTTP_IPv4 *ipv4); -int http_parse_ipv6 (char *src, int len, HTTP_IPv6 *ipv6); -int http_parse_url (char *src, int len, HTTP_URL *url); -int http_parse_request (char *src, int len, HTTP_Request *req); -int http_parse_response (char *src, int len, HTTP_Response *res); +int chttp_parse_ipv4 (char *src, int len, CHTTP_IPv4 *ipv4); +int chttp_parse_ipv6 (char *src, int len, CHTTP_IPv6 *ipv6); +int chttp_parse_url (char *src, int len, CHTTP_URL *url); +int chttp_parse_request (char *src, int len, CHTTP_Request *req); +int chttp_parse_response (char *src, int len, CHTTP_Response *res); -int http_find_header (HTTP_Header *headers, int num_headers, HTTP_String name); +int chttp_find_header (CHTTP_Header *headers, int num_headers, CHTTP_String name); -HTTP_String http_get_cookie (HTTP_Request *req, HTTP_String name); -HTTP_String http_get_param (HTTP_String body, HTTP_String str, char *mem, int cap); -int http_get_param_i (HTTP_String body, HTTP_String str); +CHTTP_String chttp_get_cookie (CHTTP_Request *req, CHTTP_String name); +CHTTP_String chttp_get_param (CHTTP_String body, CHTTP_String str, char *mem, int cap); +int chttp_get_param_i (CHTTP_String body, CHTTP_String str); // Checks whether the request was meant for the host with the given // domain an port. If port is -1, the default value of 80 is assumed. -bool http_match_host(HTTP_Request *req, HTTP_String domain, int port); +bool chttp_match_host(CHTTP_Request *req, CHTTP_String domain, int port); // Date and cookie types for Set-Cookie header parsing typedef enum { - HTTP_WEEKDAY_MON, - HTTP_WEEKDAY_TUE, - HTTP_WEEKDAY_WED, - HTTP_WEEKDAY_THU, - HTTP_WEEKDAY_FRI, - HTTP_WEEKDAY_SAT, - HTTP_WEEKDAY_SUN, -} HTTP_WeekDay; + CHTTP_WEEKDAY_MON, + CHTTP_WEEKDAY_TUE, + CHTTP_WEEKDAY_WED, + CHTTP_WEEKDAY_THU, + CHTTP_WEEKDAY_FRI, + CHTTP_WEEKDAY_SAT, + CHTTP_WEEKDAY_SUN, +} CHTTP_WeekDay; typedef enum { - HTTP_MONTH_JAN, - HTTP_MONTH_FEB, - HTTP_MONTH_MAR, - HTTP_MONTH_APR, - HTTP_MONTH_MAY, - HTTP_MONTH_JUN, - HTTP_MONTH_JUL, - HTTP_MONTH_AUG, - HTTP_MONTH_SEP, - HTTP_MONTH_OCT, - HTTP_MONTH_NOV, - HTTP_MONTH_DEC, -} HTTP_Month; + CHTTP_MONTH_JAN, + CHTTP_MONTH_FEB, + CHTTP_MONTH_MAR, + CHTTP_MONTH_APR, + CHTTP_MONTH_MAY, + CHTTP_MONTH_JUN, + CHTTP_MONTH_JUL, + CHTTP_MONTH_AUG, + CHTTP_MONTH_SEP, + CHTTP_MONTH_OCT, + CHTTP_MONTH_NOV, + CHTTP_MONTH_DEC, +} CHTTP_Month; typedef struct { - HTTP_WeekDay week_day; + CHTTP_WeekDay week_day; int day; - HTTP_Month month; + CHTTP_Month month; int year; int hour; int minute; int second; -} HTTP_Date; +} CHTTP_Date; typedef struct { - HTTP_String name; - HTTP_String value; + CHTTP_String name; + CHTTP_String value; bool secure; - bool http_only; + bool chttp_only; bool have_date; - HTTP_Date date; + CHTTP_Date date; bool have_max_age; uint32_t max_age; bool have_domain; - HTTP_String domain; + CHTTP_String domain; bool have_path; - HTTP_String path; -} HTTP_SetCookie; + CHTTP_String path; +} CHTTP_SetCookie; // Parses a Set-Cookie header value // Returns 0 on success, -1 on error -int http_parse_set_cookie(HTTP_String str, HTTP_SetCookie *out); +int chttp_parse_set_cookie(CHTTP_String str, CHTTP_SetCookie *out); diff --git a/src/secure_context.c b/src/secure_context.c index 2780142..b068592 100644 --- a/src/secure_context.c +++ b/src/secure_context.c @@ -76,7 +76,7 @@ static int servername_callback(SSL *ssl, int *ad, void *arg) #endif int server_secure_context_init(ServerSecureContext *ctx, - HTTP_String cert_file, HTTP_String key_file) + CHTTP_String cert_file, CHTTP_String key_file) { #ifdef HTTPS_ENABLED SSL_CTX *p = SSL_CTX_new(TLS_server_method()); @@ -145,7 +145,7 @@ void server_secure_context_free(ServerSecureContext *ctx) } int server_secure_context_add_certificate(ServerSecureContext *ctx, - HTTP_String domain, HTTP_String cert_file, HTTP_String key_file) + CHTTP_String domain, CHTTP_String cert_file, CHTTP_String key_file) { #ifdef HTTPS_ENABLED if (ctx->num_certs == SERVER_CERTIFICATE_LIMIT) diff --git a/src/secure_context.h b/src/secure_context.h index fd5f4f4..aa862c3 100644 --- a/src/secure_context.h +++ b/src/secure_context.h @@ -34,7 +34,7 @@ typedef struct { } ServerSecureContext; int server_secure_context_init(ServerSecureContext *ctx, - HTTP_String cert_file, HTTP_String key_file); + CHTTP_String cert_file, CHTTP_String key_file); void server_secure_context_free(ServerSecureContext *ctx); int server_secure_context_add_certificate(ServerSecureContext *ctx, - HTTP_String domain, HTTP_String cert_file, HTTP_String key_file); + CHTTP_String domain, CHTTP_String cert_file, CHTTP_String key_file); diff --git a/src/server.c b/src/server.c index 9fff397..5f0057a 100644 --- a/src/server.c +++ b/src/server.c @@ -1,22 +1,22 @@ -static void http_server_conn_init(HTTP_ServerConn *conn, +static void chttp_server_conn_init(CHTTP_ServerConn *conn, SocketHandle handle, uint32_t input_buffer_limit, uint32_t output_buffer_limit) { - conn->state = HTTP_SERVER_CONN_BUFFERING; + conn->state = CHTTP_SERVER_CONN_BUFFERING; conn->handle = handle; conn->closing = false; byte_queue_init(&conn->input, input_buffer_limit); byte_queue_init(&conn->output, output_buffer_limit); } -static void http_server_conn_free(HTTP_ServerConn *conn) +static void chttp_server_conn_free(CHTTP_ServerConn *conn) { byte_queue_free(&conn->output); byte_queue_free(&conn->input); } -int http_server_init(HTTP_Server *server) +int chttp_server_init(CHTTP_Server *server) { server->input_buffer_limit = 1<<20; server->output_buffer_limit = 1<<20; @@ -26,8 +26,8 @@ int http_server_init(HTTP_Server *server) server->backlog = 32; server->num_conns = 0; - for (int i = 0; i < HTTP_SERVER_CAPACITY; i++) { - server->conns[i].state = HTTP_SERVER_CONN_FREE; + for (int i = 0; i < CHTTP_SERVER_CAPACITY; i++) { + server->conns[i].state = CHTTP_SERVER_CONN_FREE; server->conns[i].gen = 0; } @@ -35,77 +35,77 @@ int http_server_init(HTTP_Server *server) server->ready_head = 0; return socket_manager_init(&server->sockets, - server->socket_pool, HTTP_SERVER_CAPACITY); + server->socket_pool, CHTTP_SERVER_CAPACITY); } -void http_server_free(HTTP_Server *server) +void chttp_server_free(CHTTP_Server *server) { socket_manager_free(&server->sockets); for (int i = 0, j = 0; j < server->num_conns; i++) { - HTTP_ServerConn *conn = &server->conns[i]; - if (conn->state == HTTP_SERVER_CONN_FREE) + CHTTP_ServerConn *conn = &server->conns[i]; + if (conn->state == CHTTP_SERVER_CONN_FREE) continue; j++; - http_server_conn_free(conn); + chttp_server_conn_free(conn); } } -void http_server_set_input_limit(HTTP_Server *server, uint32_t limit) +void chttp_server_set_input_limit(CHTTP_Server *server, uint32_t limit) { server->input_buffer_limit = limit; } -void http_server_set_output_limit(HTTP_Server *server, uint32_t limit) +void chttp_server_set_output_limit(CHTTP_Server *server, uint32_t limit) { server->output_buffer_limit = limit; } -void http_server_set_trace_bytes(HTTP_Server *server, bool value) +void chttp_server_set_trace_bytes(CHTTP_Server *server, bool value) { server->trace_bytes = value; } -void http_server_set_reuse_addr(HTTP_Server *server, bool reuse) +void chttp_server_set_reuse_addr(CHTTP_Server *server, bool reuse) { server->reuse_addr = reuse; } -void http_server_set_backlog(HTTP_Server *server, int backlog) +void chttp_server_set_backlog(CHTTP_Server *server, int backlog) { server->backlog = backlog; } -int http_server_listen_tcp(HTTP_Server *server, - HTTP_String addr, Port port) +int chttp_server_listen_tcp(CHTTP_Server *server, + CHTTP_String addr, Port port) { return socket_manager_listen_tcp(&server->sockets, addr, port, server->backlog, server->reuse_addr); } -int http_server_listen_tls(HTTP_Server *server, - HTTP_String addr, Port port, HTTP_String cert_file_name, - HTTP_String key_file_name) +int chttp_server_listen_tls(CHTTP_Server *server, + CHTTP_String addr, Port port, CHTTP_String cert_file_name, + CHTTP_String key_file_name) { return socket_manager_listen_tls(&server->sockets, addr, port, server->backlog, server->reuse_addr, cert_file_name, key_file_name); } -int http_server_add_certificate(HTTP_Server *server, - HTTP_String domain, HTTP_String cert_file, HTTP_String key_file) +int chttp_server_add_certificate(CHTTP_Server *server, + CHTTP_String domain, CHTTP_String cert_file, CHTTP_String key_file) { return socket_manager_add_certificate(&server->sockets, domain, cert_file, key_file); } -int http_server_wakeup(HTTP_Server *server) +int chttp_server_wakeup(CHTTP_Server *server) { return socket_manager_wakeup(&server->sockets); } -void http_server_register_events(HTTP_Server *server, +void chttp_server_register_events(CHTTP_Server *server, EventRegister *reg) { socket_manager_register_events(&server->sockets, reg); @@ -117,12 +117,12 @@ void http_server_register_events(HTTP_Server *server, // to the ready queue. If the request is invalid, // close the socket. static void -check_request_buffer(HTTP_Server *server, HTTP_ServerConn *conn) +check_request_buffer(CHTTP_Server *server, CHTTP_ServerConn *conn) { - assert(conn->state == HTTP_SERVER_CONN_BUFFERING); + assert(conn->state == CHTTP_SERVER_CONN_BUFFERING); ByteView src = byte_queue_read_buf(&conn->input); - int ret = http_parse_request(src.ptr, src.len, &conn->request); + int ret = chttp_parse_request(src.ptr, src.len, &conn->request); if (ret < 0) { // Invalid request @@ -147,22 +147,22 @@ check_request_buffer(HTTP_Server *server, HTTP_ServerConn *conn) // Stop receiving I/O events while we are building the response socket_silent(&server->sockets, conn->handle, true); - conn->state = HTTP_SERVER_CONN_WAIT_STATUS; + conn->state = CHTTP_SERVER_CONN_WAIT_STATUS; conn->request_len = ret; conn->response_offset = byte_queue_offset(&conn->output); // Push to the ready queue - assert(server->num_ready < HTTP_SERVER_CAPACITY); - int tail = (server->ready_head + server->num_ready) % HTTP_SERVER_CAPACITY; + assert(server->num_ready < CHTTP_SERVER_CAPACITY); + int tail = (server->ready_head + server->num_ready) % CHTTP_SERVER_CAPACITY; server->ready[tail] = conn - server->conns; server->num_ready++; } } static void -http_server_conn_process_events(HTTP_Server *server, HTTP_ServerConn *conn) +chttp_server_conn_process_events(CHTTP_Server *server, CHTTP_ServerConn *conn) { - if (conn->state == HTTP_SERVER_CONN_FLUSHING) { + if (conn->state == CHTTP_SERVER_CONN_FLUSHING) { ByteView src = byte_queue_read_buf(&conn->output); @@ -171,7 +171,7 @@ http_server_conn_process_events(HTTP_Server *server, HTTP_ServerConn *conn) num = socket_send(&server->sockets, conn->handle, src.ptr, src.len); if (server->trace_bytes) - print_bytes(HTTP_STR("<< "), (HTTP_String) { src.ptr, num }); + print_bytes(CHTTP_STR("<< "), (CHTTP_String) { src.ptr, num }); byte_queue_read_ack(&conn->output, num); @@ -188,11 +188,11 @@ http_server_conn_process_events(HTTP_Server *server, HTTP_ServerConn *conn) socket_close(&server->sockets, conn->handle); return; } - conn->state = HTTP_SERVER_CONN_BUFFERING; + conn->state = CHTTP_SERVER_CONN_BUFFERING; } } - if (conn->state == HTTP_SERVER_CONN_BUFFERING) { + if (conn->state == CHTTP_SERVER_CONN_BUFFERING) { int min_recv = 1<<10; byte_queue_write_setmincap(&conn->input, min_recv); @@ -208,7 +208,7 @@ http_server_conn_process_events(HTTP_Server *server, HTTP_ServerConn *conn) num = socket_recv(&server->sockets, conn->handle, dst.ptr, dst.len); if (server->trace_bytes) - print_bytes(HTTP_STR(">> "), (HTTP_String) { dst.ptr, num }); + print_bytes(CHTTP_STR(">> "), (CHTTP_String) { dst.ptr, num }); byte_queue_write_ack(&conn->input, num); @@ -220,38 +220,38 @@ http_server_conn_process_events(HTTP_Server *server, HTTP_ServerConn *conn) } } -void http_server_process_events(HTTP_Server *server, +void chttp_server_process_events(CHTTP_Server *server, EventRegister reg) { - SocketEvent events[HTTP_SERVER_CAPACITY]; + SocketEvent events[CHTTP_SERVER_CAPACITY]; int num_events = socket_manager_translate_events(&server->sockets, events, reg); for (int i = 0; i < num_events; i++) { - HTTP_ServerConn *conn = events[i].user; + CHTTP_ServerConn *conn = events[i].user; if (events[i].type == SOCKET_EVENT_DISCONNECT) { - http_server_conn_free(conn); // TODO: what if this was in the ready queue? + chttp_server_conn_free(conn); // TODO: what if this was in the ready queue? server->num_conns--; } else if (events[i].type == SOCKET_EVENT_READY) { if (events[i].user == NULL) { - if (server->num_conns == HTTP_SERVER_CAPACITY) { + if (server->num_conns == CHTTP_SERVER_CAPACITY) { socket_close(&server->sockets, events[i].handle); continue; } int j = 0; - while (server->conns[j].state != HTTP_SERVER_CONN_FREE) { + while (server->conns[j].state != CHTTP_SERVER_CONN_FREE) { j++; - assert(i < HTTP_SERVER_CAPACITY); + assert(i < CHTTP_SERVER_CAPACITY); } conn = &server->conns[j]; - http_server_conn_init(conn, + chttp_server_conn_init(conn, events[i].handle, server->input_buffer_limit, server->output_buffer_limit); @@ -261,44 +261,44 @@ void http_server_process_events(HTTP_Server *server, } while (socket_ready(&server->sockets, events[i].handle) - && conn->state != HTTP_SERVER_CONN_WAIT_STATUS) - http_server_conn_process_events(server, conn); + && conn->state != CHTTP_SERVER_CONN_WAIT_STATUS) + chttp_server_conn_process_events(server, conn); } } } -bool http_server_next_request(HTTP_Server *server, - HTTP_Request **request, HTTP_ResponseBuilder *builder) +bool chttp_server_next_request(CHTTP_Server *server, + CHTTP_Request **request, CHTTP_ResponseBuilder *builder) { if (server->num_ready == 0) return false; - HTTP_ServerConn *conn = &server->conns[server->ready[server->ready_head]]; - server->ready_head = (server->ready_head + 1) % HTTP_SERVER_CAPACITY; + CHTTP_ServerConn *conn = &server->conns[server->ready[server->ready_head]]; + server->ready_head = (server->ready_head + 1) % CHTTP_SERVER_CAPACITY; server->num_ready--; - assert(conn->state == HTTP_SERVER_CONN_WAIT_STATUS); + assert(conn->state == CHTTP_SERVER_CONN_WAIT_STATUS); *request = &conn->request; - *builder = (HTTP_ResponseBuilder) { server, conn - server->conns, conn->gen }; + *builder = (CHTTP_ResponseBuilder) { server, conn - server->conns, conn->gen }; return true; } -void http_server_wait_request(HTTP_Server *server, - HTTP_Request **request, HTTP_ResponseBuilder *builder) +void chttp_server_wait_request(CHTTP_Server *server, + CHTTP_Request **request, CHTTP_ResponseBuilder *builder) { for (;;) { - void *ptrs[HTTP_SERVER_POLL_CAPACITY]; - struct pollfd polled[HTTP_SERVER_POLL_CAPACITY]; + void *ptrs[CHTTP_SERVER_POLL_CAPACITY]; + struct pollfd polled[CHTTP_SERVER_POLL_CAPACITY]; EventRegister reg = { ptrs, polled, 0 }; - http_server_register_events(server, ®); + chttp_server_register_events(server, ®); if (reg.num_polled > 0) POLL(reg.polled, reg.num_polled, -1); - http_server_process_events(server, reg); + chttp_server_process_events(server, reg); - if (http_server_next_request(server, request, builder)) + if (chttp_server_next_request(server, request, builder)) break; } } @@ -309,17 +309,17 @@ void http_server_wait_request(HTTP_Server *server, // can be returned, as any builder is invalidated by // incrementing the connection's generation counter // when a response is completed. -static HTTP_ServerConn* -builder_to_conn(HTTP_ResponseBuilder builder) +static CHTTP_ServerConn* +builder_to_conn(CHTTP_ResponseBuilder builder) { - HTTP_Server *server = builder.server; + CHTTP_Server *server = builder.server; if (server == NULL) return NULL; - if (builder.index > HTTP_SERVER_CAPACITY) + if (builder.index > CHTTP_SERVER_CAPACITY) return NULL; - HTTP_ServerConn *conn = &server->conns[builder.index]; + CHTTP_ServerConn *conn = &server->conns[builder.index]; if (builder.gen != conn->gen) return NULL; @@ -394,31 +394,31 @@ get_status_text(int code) } static void -write_status(HTTP_ServerConn *conn, int status) +write_status(CHTTP_ServerConn *conn, int status) { byte_queue_write_fmt(&conn->output, "HTTP/1.1 %d %s\r\n", status, get_status_text(status)); } -void http_response_builder_status(HTTP_ResponseBuilder builder, int status) +void chttp_response_builder_status(CHTTP_ResponseBuilder builder, int status) { - HTTP_ServerConn *conn = builder_to_conn(builder); + CHTTP_ServerConn *conn = builder_to_conn(builder); if (conn == NULL) return; - if (conn->state != HTTP_SERVER_CONN_WAIT_STATUS) { + if (conn->state != CHTTP_SERVER_CONN_WAIT_STATUS) { // Reset all response content and start from scrach. byte_queue_remove_from_offset(&conn->output, conn->response_offset); - conn->state = HTTP_SERVER_CONN_WAIT_STATUS; + conn->state = CHTTP_SERVER_CONN_WAIT_STATUS; } write_status(conn, status); - conn->state = HTTP_SERVER_CONN_WAIT_HEADER; + conn->state = CHTTP_SERVER_CONN_WAIT_HEADER; } -static bool is_header_valid(HTTP_String str) +static bool is_header_valid(CHTTP_String str) { bool has_colon = false; for (int i = 0; i < str.len; i++) { @@ -432,13 +432,13 @@ static bool is_header_valid(HTTP_String str) return has_colon; } -void http_response_builder_header(HTTP_ResponseBuilder builder, HTTP_String str) +void chttp_response_builder_header(CHTTP_ResponseBuilder builder, CHTTP_String str) { - HTTP_ServerConn *conn = builder_to_conn(builder); + CHTTP_ServerConn *conn = builder_to_conn(builder); if (conn == NULL) return; - if (conn->state != HTTP_SERVER_CONN_WAIT_HEADER) + if (conn->state != CHTTP_SERVER_CONN_WAIT_HEADER) return; // Header must contain a colon and no control characters @@ -449,19 +449,19 @@ void http_response_builder_header(HTTP_ResponseBuilder builder, HTTP_String str) byte_queue_write(&conn->output, "\r\n", 2); } -static void append_special_headers(HTTP_ServerConn *conn) +static void append_special_headers(CHTTP_ServerConn *conn) { - HTTP_String s; + CHTTP_String s; if (conn->closing) { - s = HTTP_STR("Connection: Close\r\n"); + s = CHTTP_STR("Connection: Close\r\n"); byte_queue_write(&conn->output, s.ptr, s.len); } else { - s = HTTP_STR("Connection: Keep-Alive\r\n"); + s = CHTTP_STR("Connection: Keep-Alive\r\n"); byte_queue_write(&conn->output, s.ptr, s.len); } - s = HTTP_STR("Content-Length: "); + s = CHTTP_STR("Content-Length: "); byte_queue_write(&conn->output, s.ptr, s.len); conn->content_length_value_offset = byte_queue_offset(&conn->output); @@ -469,14 +469,14 @@ static void append_special_headers(HTTP_ServerConn *conn) #define TEN_SPACES " " _Static_assert(sizeof(TEN_SPACES) == 10+1); - s = HTTP_STR(TEN_SPACES "\r\n"); + s = CHTTP_STR(TEN_SPACES "\r\n"); byte_queue_write(&conn->output, s.ptr, s.len); byte_queue_write(&conn->output, "\r\n", 2); conn->content_length_offset = byte_queue_offset(&conn->output); } -static void patch_special_headers(HTTP_ServerConn *conn) +static void patch_special_headers(CHTTP_ServerConn *conn) { int content_length = byte_queue_size_from_offset(&conn->output, conn->content_length_offset); @@ -487,52 +487,52 @@ static void patch_special_headers(HTTP_ServerConn *conn) byte_queue_patch(&conn->output, conn->content_length_value_offset, tmp, len); } -void http_response_builder_body(HTTP_ResponseBuilder builder, HTTP_String str) +void chttp_response_builder_body(CHTTP_ResponseBuilder builder, CHTTP_String str) { - HTTP_ServerConn *conn = builder_to_conn(builder); + CHTTP_ServerConn *conn = builder_to_conn(builder); if (conn == NULL) return; - if (conn->state == HTTP_SERVER_CONN_WAIT_HEADER) { + if (conn->state == CHTTP_SERVER_CONN_WAIT_HEADER) { append_special_headers(conn); - conn->state = HTTP_SERVER_CONN_WAIT_BODY; + conn->state = CHTTP_SERVER_CONN_WAIT_BODY; } - if (conn->state != HTTP_SERVER_CONN_WAIT_BODY) + if (conn->state != CHTTP_SERVER_CONN_WAIT_BODY) return; byte_queue_write(&conn->output, str.ptr, str.len); } -void http_response_builder_body_cap(HTTP_ResponseBuilder builder, int cap) +void chttp_response_builder_body_cap(CHTTP_ResponseBuilder builder, int cap) { - HTTP_ServerConn *conn = builder_to_conn(builder); + CHTTP_ServerConn *conn = builder_to_conn(builder); if (conn == NULL) return; - if (conn->state == HTTP_SERVER_CONN_WAIT_HEADER) { + if (conn->state == CHTTP_SERVER_CONN_WAIT_HEADER) { append_special_headers(conn); - conn->state = HTTP_SERVER_CONN_WAIT_BODY; + conn->state = CHTTP_SERVER_CONN_WAIT_BODY; } - if (conn->state != HTTP_SERVER_CONN_WAIT_BODY) + if (conn->state != CHTTP_SERVER_CONN_WAIT_BODY) return; byte_queue_write_setmincap(&conn->output, cap); } -char *http_response_builder_body_buf(HTTP_ResponseBuilder builder, int *cap) +char *chttp_response_builder_body_buf(CHTTP_ResponseBuilder builder, int *cap) { - HTTP_ServerConn *conn = builder_to_conn(builder); + CHTTP_ServerConn *conn = builder_to_conn(builder); if (conn == NULL) return NULL; - if (conn->state == HTTP_SERVER_CONN_WAIT_HEADER) { + if (conn->state == CHTTP_SERVER_CONN_WAIT_HEADER) { append_special_headers(conn); - conn->state = HTTP_SERVER_CONN_WAIT_BODY; + conn->state = CHTTP_SERVER_CONN_WAIT_BODY; } - if (conn->state != HTTP_SERVER_CONN_WAIT_BODY) + if (conn->state != CHTTP_SERVER_CONN_WAIT_BODY) return NULL; ByteView tmp = byte_queue_write_buf(&conn->output); @@ -540,45 +540,45 @@ char *http_response_builder_body_buf(HTTP_ResponseBuilder builder, int *cap) return tmp.ptr; } -void http_response_builder_body_ack(HTTP_ResponseBuilder builder, int num) +void chttp_response_builder_body_ack(CHTTP_ResponseBuilder builder, int num) { - HTTP_ServerConn *conn = builder_to_conn(builder); + CHTTP_ServerConn *conn = builder_to_conn(builder); if (conn == NULL) return; - if (conn->state != HTTP_SERVER_CONN_WAIT_BODY) + if (conn->state != CHTTP_SERVER_CONN_WAIT_BODY) return; byte_queue_write_ack(&conn->output, num); } -void http_response_builder_send(HTTP_ResponseBuilder builder) +void chttp_response_builder_send(CHTTP_ResponseBuilder builder) { - HTTP_ServerConn *conn = builder_to_conn(builder); + CHTTP_ServerConn *conn = builder_to_conn(builder); if (conn == NULL) return; - if (conn->state == HTTP_SERVER_CONN_WAIT_STATUS) { + if (conn->state == CHTTP_SERVER_CONN_WAIT_STATUS) { write_status(conn, 500); - conn->state = HTTP_SERVER_CONN_WAIT_HEADER; + conn->state = CHTTP_SERVER_CONN_WAIT_HEADER; } - if (conn->state == HTTP_SERVER_CONN_WAIT_HEADER) { + if (conn->state == CHTTP_SERVER_CONN_WAIT_HEADER) { append_special_headers(conn); - conn->state = HTTP_SERVER_CONN_WAIT_BODY; + conn->state = CHTTP_SERVER_CONN_WAIT_BODY; } - assert(conn->state == HTTP_SERVER_CONN_WAIT_BODY); + assert(conn->state == CHTTP_SERVER_CONN_WAIT_BODY); patch_special_headers(conn); // Remove the buffered request byte_queue_read_ack(&conn->input, conn->request_len); - conn->state = HTTP_SERVER_CONN_FLUSHING; + conn->state = CHTTP_SERVER_CONN_FLUSHING; conn->gen++; // Enable back I/O events socket_silent(&builder.server->sockets, conn->handle, false); - http_server_conn_process_events(builder.server, conn); + chttp_server_conn_process_events(builder.server, conn); } diff --git a/src/server.h b/src/server.h index 1cf22f9..bf7c292 100644 --- a/src/server.h +++ b/src/server.h @@ -1,49 +1,49 @@ -#ifndef HTTP_SERVER_CAPACITY +#ifndef CHTTP_SERVER_CAPACITY // The maximum ammount of requests that can be handled // in parallel. -#define HTTP_SERVER_CAPACITY (1<<9) +#define CHTTP_SERVER_CAPACITY (1<<9) #endif // Maximum number of descriptors the server will want // to wait on. It's one per connection plus two for the // TCP and TLS listener, plus one for the wakeup self-pipe. -#define HTTP_SERVER_POLL_CAPACITY (HTTP_SERVER_CAPACITY+3) +#define CHTTP_SERVER_POLL_CAPACITY (CHTTP_SERVER_CAPACITY+3) typedef enum { // This struct is unused - HTTP_SERVER_CONN_FREE, + CHTTP_SERVER_CONN_FREE, // No request was buffered yet. - HTTP_SERVER_CONN_BUFFERING, + CHTTP_SERVER_CONN_BUFFERING, // A request was just buffered and is waiting for // the user to build a response. To be specific, // it's waiting for the user to set a response status. - HTTP_SERVER_CONN_WAIT_STATUS, + CHTTP_SERVER_CONN_WAIT_STATUS, // A request is buffered and a status was set. Now // the user can set a header or append the first // bytes of the response body. - HTTP_SERVER_CONN_WAIT_HEADER, + CHTTP_SERVER_CONN_WAIT_HEADER, // A request is buffered and some bytes were appended // to the response. Now the user can either append more // bytes or send out the response. - HTTP_SERVER_CONN_WAIT_BODY, + CHTTP_SERVER_CONN_WAIT_BODY, // A response has been produced and it's being flushed. - HTTP_SERVER_CONN_FLUSHING, + CHTTP_SERVER_CONN_FLUSHING, -} HTTP_ServerConnState; +} CHTTP_ServerConnState; // This structure represents the HTTP connection to // a client. typedef struct { // If false, this struct is unused - HTTP_ServerConnState state; + CHTTP_ServerConnState state; // Handle to the socket SocketHandle handle; @@ -68,7 +68,7 @@ typedef struct { // When the state is WAIT_STATUS, WAIT_HEADER, // or WAIT_BODY, this contains the parsed version // of the buffered request. - HTTP_Request request; + CHTTP_Request request; // Length of the buffered request when the request // field is valid. @@ -93,7 +93,7 @@ typedef struct { // it from the offset reached when the response is marked // as done. ByteQueueOffset content_length_offset; -} HTTP_ServerConn; +} CHTTP_ServerConn; typedef struct { @@ -109,13 +109,13 @@ typedef struct { // Array of connections. The counter contains the // number of structs such that state=FREE. int num_conns; - HTTP_ServerConn conns[HTTP_SERVER_CAPACITY]; + CHTTP_ServerConn conns[CHTTP_SERVER_CAPACITY]; // Queue of indices referring to connections that // are in the WAIT_STATUS state. int num_ready; int ready_head; - int ready[HTTP_SERVER_CAPACITY]; + int ready[CHTTP_SERVER_CAPACITY]; // Asynchronous TCP and TLS socket abstraction SocketManager sockets; @@ -125,74 +125,74 @@ typedef struct { // manager with a pointer to it. This allows // allocating the exact number of sockets we // will need. - Socket socket_pool[HTTP_SERVER_CAPACITY]; + Socket socket_pool[CHTTP_SERVER_CAPACITY]; -} HTTP_Server; +} CHTTP_Server; // Initialize the HTTP server object. By default, it won't // listen for connections. You need to call // -// http_server_listen_tcp -// http_server_listen_tls +// chttp_server_listen_tcp +// chttp_server_listen_tls // // to listen for connection. Note that you can have a // single server listening for HTTP and HTTPS requests // by calling both. -int http_server_init(HTTP_Server *server); +int chttp_server_init(CHTTP_Server *server); // Release resources associated to the server. -void http_server_free(HTTP_Server *server); +void chttp_server_free(CHTTP_Server *server); // Set input and output buffer size limit for any // given connection. The default value is 1MB -void http_server_set_input_limit(HTTP_Server *server, uint32_t limit); -void http_server_set_output_limit(HTTP_Server *server, uint32_t limit); +void chttp_server_set_input_limit(CHTTP_Server *server, uint32_t limit); +void chttp_server_set_output_limit(CHTTP_Server *server, uint32_t limit); // TODO: Comment -void http_server_set_trace_bytes(HTTP_Server *server, bool value); +void chttp_server_set_trace_bytes(CHTTP_Server *server, bool value); // TODO: Comment -void http_server_set_reuse_addr(HTTP_Server *server, bool reuse); +void chttp_server_set_reuse_addr(CHTTP_Server *server, bool reuse); // TODO: comment -void http_server_set_backlog(HTTP_Server *server, int backlog); +void chttp_server_set_backlog(CHTTP_Server *server, int backlog); // Enable listening for plain HTTP requests at the // specified interface. -int http_server_listen_tcp(HTTP_Server *server, - HTTP_String addr, Port port); +int chttp_server_listen_tcp(CHTTP_Server *server, + CHTTP_String addr, Port port); // Enable listening for HTTPS requests at the specified // interfact, using the specified certificate and key // to verify the connection. -int http_server_listen_tls(HTTP_Server *server, HTTP_String addr, Port port, - HTTP_String cert_file_name, HTTP_String key_file_name); +int chttp_server_listen_tls(CHTTP_Server *server, CHTTP_String addr, Port port, + CHTTP_String cert_file_name, CHTTP_String key_file_name); // Add the certificate for an additional domain when // the server is listening for HTTPS requests. -int http_server_add_certificate(HTTP_Server *server, - HTTP_String domain, HTTP_String cert_file, HTTP_String key_file); +int chttp_server_add_certificate(CHTTP_Server *server, + CHTTP_String domain, CHTTP_String cert_file, CHTTP_String key_file); // When a thread is blocked waiting for server events, // other threads can call this function to wake it up. -int http_server_wakeup(HTTP_Server *server); +int chttp_server_wakeup(CHTTP_Server *server); // Resets the event register with the list of descriptors // the server wants monitored. -void http_server_register_events(HTTP_Server *server, +void chttp_server_register_events(CHTTP_Server *server, EventRegister *reg); // The caller has waited for poll() to return and some // I/O events to be triggered, so now the HTTP server // can continue its buffering and flushing operations. -void http_server_process_events(HTTP_Server *server, +void chttp_server_process_events(CHTTP_Server *server, EventRegister reg); typedef struct { - HTTP_Server *server; + CHTTP_Server *server; uint16_t index; uint16_t gen; -} HTTP_ResponseBuilder; +} CHTTP_ResponseBuilder; // After some I/O events were processes, some requests // may be availabe. This function returns one of the @@ -202,32 +202,32 @@ typedef struct { // respond in batches. // For each request returned by this function, the user // must build a response using the response builder API. -bool http_server_next_request(HTTP_Server *server, - HTTP_Request **request, HTTP_ResponseBuilder *builder); +bool chttp_server_next_request(CHTTP_Server *server, + CHTTP_Request **request, CHTTP_ResponseBuilder *builder); // TODO: comment -void http_server_wait_request(HTTP_Server *server, - HTTP_Request **request, HTTP_ResponseBuilder *builder); +void chttp_server_wait_request(CHTTP_Server *server, + CHTTP_Request **request, CHTTP_ResponseBuilder *builder); // This function is called to set the status code of // a request's response. If this function is called // after the other response builder functions, it will // reset the response and set a new status. -void http_response_builder_status(HTTP_ResponseBuilder builder, int status); +void chttp_response_builder_status(CHTTP_ResponseBuilder builder, int status); // Append a header to the response. This can only be // used after having set the status and before appending // to the body. -void http_response_builder_header(HTTP_ResponseBuilder builder, HTTP_String str); +void chttp_response_builder_header(CHTTP_ResponseBuilder builder, CHTTP_String str); // Append some bytes to the response's body -void http_response_builder_body(HTTP_ResponseBuilder builder, HTTP_String str); +void chttp_response_builder_body(CHTTP_ResponseBuilder builder, CHTTP_String str); // TODO: comment -void http_response_builder_body_cap(HTTP_ResponseBuilder builder, int cap); -char *http_response_builder_body_buf(HTTP_ResponseBuilder builder, int *cap); -void http_response_builder_body_ack(HTTP_ResponseBuilder builder, int num); +void chttp_response_builder_body_cap(CHTTP_ResponseBuilder builder, int cap); +char *chttp_response_builder_body_buf(CHTTP_ResponseBuilder builder, int *cap); +void chttp_response_builder_body_ack(CHTTP_ResponseBuilder builder, int num); // Mark the response as complete. This will invalidate // the response builder handle. -void http_response_builder_send(HTTP_ResponseBuilder builder); +void chttp_response_builder_send(CHTTP_ResponseBuilder builder); diff --git a/src/socket.c b/src/socket.c index d88acc7..0b6efea 100644 --- a/src/socket.c +++ b/src/socket.c @@ -39,7 +39,7 @@ static int create_socket_pair(NATIVE_SOCKET *a, NATIVE_SOCKET *b, bool *global_c WSADATA wsaData; WORD wVersionRequested = MAKEWORD(2, 2); if (WSAStartup(wVersionRequested, &wsaData)) - return HTTP_ERROR_UNSPECIFIED; + return CHTTP_ERROR_UNSPECIFIED; sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (sock == INVALID_SOCKET && *global_cleanup) @@ -49,7 +49,7 @@ static int create_socket_pair(NATIVE_SOCKET *a, NATIVE_SOCKET *b, bool *global_c if (sock == INVALID_SOCKET) { if (*global_cleanup) WSACleanup(); - return HTTP_ERROR_UNSPECIFIED; + return CHTTP_ERROR_UNSPECIFIED; } // Bind to loopback address with port 0 (dynamic port assignment) @@ -64,21 +64,21 @@ static int create_socket_pair(NATIVE_SOCKET *a, NATIVE_SOCKET *b, bool *global_c closesocket(sock); if (*global_cleanup) WSACleanup(); - return HTTP_ERROR_UNSPECIFIED; + return CHTTP_ERROR_UNSPECIFIED; } if (getsockname(sock, (struct sockaddr*)&addr, &addr_len) == SOCKET_ERROR) { closesocket(sock); if (*global_cleanup) WSACleanup(); - return HTTP_ERROR_UNSPECIFIED; + return CHTTP_ERROR_UNSPECIFIED; } if (connect(sock, (struct sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR) { closesocket(sock); if (*global_cleanup) WSACleanup(); - return HTTP_ERROR_UNSPECIFIED; + return CHTTP_ERROR_UNSPECIFIED; } // Optional: Set socket to non-blocking mode @@ -88,20 +88,20 @@ static int create_socket_pair(NATIVE_SOCKET *a, NATIVE_SOCKET *b, bool *global_c closesocket(sock); if (*global_cleanup) WSACleanup(); - return HTTP_ERROR_UNSPECIFIED; + return CHTTP_ERROR_UNSPECIFIED; } *a = sock; *b = sock; - return HTTP_OK; + return CHTTP_OK; #else *global_cleanup = false; int fds[2]; if (pipe(fds) < 0) - return HTTP_ERROR_UNSPECIFIED; + return CHTTP_ERROR_UNSPECIFIED; *a = fds[0]; *b = fds[1]; - return HTTP_OK; + return CHTTP_OK; #endif } @@ -110,23 +110,23 @@ static int set_socket_blocking(NATIVE_SOCKET sock, bool value) #ifdef _WIN32 u_long mode = !value; if (ioctlsocket(sock, FIONBIO, &mode) == SOCKET_ERROR) - return HTTP_ERROR_UNSPECIFIED; - return HTTP_OK; + return CHTTP_ERROR_UNSPECIFIED; + return CHTTP_OK; #endif #ifdef __linux__ int flags = fcntl(sock, F_GETFL, 0); if (flags < 0) - return HTTP_ERROR_UNSPECIFIED; + return CHTTP_ERROR_UNSPECIFIED; if (value) flags &= ~O_NONBLOCK; else flags |= O_NONBLOCK; if (fcntl(sock, F_SETFL, flags) < 0) - return HTTP_ERROR_UNSPECIFIED; - return HTTP_OK; + return CHTTP_ERROR_UNSPECIFIED; + return CHTTP_OK; #endif } -static NATIVE_SOCKET create_listen_socket(HTTP_String addr, +static NATIVE_SOCKET create_listen_socket(CHTTP_String addr, Port port, bool reuse_addr, int backlog) { NATIVE_SOCKET sock = socket(AF_INET, SOCK_STREAM, 0); @@ -212,7 +212,7 @@ int socket_manager_init(SocketManager *sm, Socket *socks, socks[i].state = SOCKET_STATE_FREE; socks[i].gen = 1; } - return HTTP_OK; + return CHTTP_OK; } void socket_manager_free(SocketManager *sm) @@ -238,57 +238,57 @@ void socket_manager_free(SocketManager *sm) } int socket_manager_listen_tcp(SocketManager *sm, - HTTP_String addr, Port port, int backlog, + CHTTP_String addr, Port port, int backlog, bool reuse_addr) { if (sm->plain_sock != NATIVE_SOCKET_INVALID) - return HTTP_ERROR_UNSPECIFIED; + return CHTTP_ERROR_UNSPECIFIED; sm->plain_sock = create_listen_socket(addr, port, reuse_addr, backlog); if (sm->plain_sock == NATIVE_SOCKET_INVALID) - return HTTP_ERROR_UNSPECIFIED; + return CHTTP_ERROR_UNSPECIFIED; - return HTTP_OK; + return CHTTP_OK; } int socket_manager_listen_tls(SocketManager *sm, - HTTP_String addr, Port port, int backlog, - bool reuse_addr, HTTP_String cert_file, - HTTP_String key_file) + CHTTP_String addr, Port port, int backlog, + bool reuse_addr, CHTTP_String cert_file, + CHTTP_String key_file) { #ifndef HTTPS_ENABLED - return HTTP_ERROR_NOTLS; + return CHTTP_ERROR_NOTLS; #endif if (sm->secure_sock != NATIVE_SOCKET_INVALID) - return HTTP_ERROR_UNSPECIFIED; + return CHTTP_ERROR_UNSPECIFIED; sm->secure_sock = create_listen_socket(addr, port, reuse_addr, backlog); if (sm->secure_sock == NATIVE_SOCKET_INVALID) - return HTTP_ERROR_UNSPECIFIED; + return CHTTP_ERROR_UNSPECIFIED; if (server_secure_context_init(&sm->server_secure_context, cert_file, key_file) < 0) { CLOSE_NATIVE_SOCKET(sm->secure_sock); sm->secure_sock = NATIVE_SOCKET_INVALID; - return HTTP_ERROR_UNSPECIFIED; + return CHTTP_ERROR_UNSPECIFIED; } - return HTTP_OK; + return CHTTP_OK; } int socket_manager_add_certificate(SocketManager *sm, - HTTP_String domain, HTTP_String cert_file, HTTP_String key_file) + CHTTP_String domain, CHTTP_String cert_file, CHTTP_String key_file) { if (sm->secure_sock == NATIVE_SOCKET_INVALID) - return HTTP_ERROR_UNSPECIFIED; + return CHTTP_ERROR_UNSPECIFIED; int ret = server_secure_context_add_certificate( &sm->server_secure_context, domain, cert_file, key_file); if (ret < 0) return ret; - return HTTP_OK; + return CHTTP_OK; } static bool is_secure(Socket *s) @@ -428,13 +428,13 @@ static void socket_update(Socket *s) struct sockaddr_in buf; buf.sin_family = AF_INET; buf.sin_port = htons(addr.port); - memcpy(&buf.sin_addr, &addr.ipv4, sizeof(HTTP_IPv4)); + memcpy(&buf.sin_addr, &addr.ipv4, sizeof(CHTTP_IPv4)); ret = connect(sock, (struct sockaddr*) &buf, sizeof(buf)); } else { struct sockaddr_in6 buf; buf.sin6_family = AF_INET6; buf.sin6_port = htons(addr.port); - memcpy(&buf.sin6_addr, &addr.ipv6, sizeof(HTTP_IPv6)); + memcpy(&buf.sin6_addr, &addr.ipv6, sizeof(CHTTP_IPv6)); ret = connect(sock, (struct sockaddr*) &buf, sizeof(buf)); } @@ -693,12 +693,12 @@ int socket_manager_wakeup(SocketManager *sm) char byte = 1; #ifdef _WIN32 if (send(sm->signal_sock, &byte, 1, 0) < 0) - return HTTP_ERROR_UNSPECIFIED; + return CHTTP_ERROR_UNSPECIFIED; #else if (write(sm->signal_sock, &byte, 1) < 0) - return HTTP_ERROR_UNSPECIFIED; + return CHTTP_ERROR_UNSPECIFIED; #endif - return HTTP_OK; + return CHTTP_OK; } void socket_manager_register_events( @@ -929,7 +929,7 @@ static int resolve_connect_targets(ConnectTarget *targets, RegisteredName *name = malloc(sizeof(RegisteredName) + targets[i].name.len + 1); if (name == NULL) { free_addr_list(resolved, num_resolved); - return HTTP_ERROR_OOM; + return CHTTP_ERROR_OOM; } name->refs = 0; memcpy(name->data, targets[i].name.ptr, targets[i].name.len); @@ -939,7 +939,7 @@ static int resolve_connect_targets(ConnectTarget *targets, // 512 bytes is more than enough for a DNS hostname (max 253 chars) char hostname[1<<9]; if (targets[i].name.len >= (int) sizeof(hostname)) - return HTTP_ERROR_OOM; + return CHTTP_ERROR_OOM; memcpy(hostname, targets[i].name.ptr, targets[i].name.len); hostname[targets[i].name.len] = '\0'; #endif @@ -951,12 +951,12 @@ static int resolve_connect_targets(ConnectTarget *targets, free(name); #endif free_addr_list(resolved, num_resolved); - return HTTP_ERROR_UNSPECIFIED; + return CHTTP_ERROR_UNSPECIFIED; } for (struct addrinfo *rp = res; rp; rp = rp->ai_next) { if (rp->ai_family == AF_INET) { - HTTP_IPv4 ipv4 = *(HTTP_IPv4*) &((struct sockaddr_in*)rp->ai_addr)->sin_addr; + CHTTP_IPv4 ipv4 = *(CHTTP_IPv4*) &((struct sockaddr_in*)rp->ai_addr)->sin_addr; if (num_resolved < max_resolved) { resolved[num_resolved].is_ipv4 = true; resolved[num_resolved].ipv4 = ipv4; @@ -968,7 +968,7 @@ static int resolve_connect_targets(ConnectTarget *targets, num_resolved++; } } else if (rp->ai_family == AF_INET6) { - HTTP_IPv6 ipv6 = *(HTTP_IPv6*) &((struct sockaddr_in6*)rp->ai_addr)->sin6_addr; + CHTTP_IPv6 ipv6 = *(CHTTP_IPv6*) &((struct sockaddr_in6*)rp->ai_addr)->sin6_addr; if (num_resolved < max_resolved) { resolved[num_resolved].is_ipv4 = false; resolved[num_resolved].ipv6 = ipv6; @@ -1024,17 +1024,17 @@ int socket_connect(SocketManager *sm, int num_targets, void *user) { if (sm->num_used == sm->max_used) - return HTTP_ERROR_UNSPECIFIED; + return CHTTP_ERROR_UNSPECIFIED; #ifdef HTTPS_ENABLED if (!sm->at_least_one_secure_connect) { if (client_secure_context_init(&sm->client_secure_context) < 0) - return HTTP_ERROR_UNSPECIFIED; + return CHTTP_ERROR_UNSPECIFIED; sm->at_least_one_secure_connect = true; } #else if (secure) - return HTTP_ERROR_NOTLS; + return CHTTP_ERROR_NOTLS; #endif AddressAndPort resolved[MAX_CONNECT_TARGETS]; @@ -1042,7 +1042,7 @@ int socket_connect(SocketManager *sm, int num_targets, targets, num_targets, resolved, MAX_CONNECT_TARGETS); if (num_resolved <= 0) - return HTTP_ERROR_UNSPECIFIED; + return CHTTP_ERROR_UNSPECIFIED; Socket *s = sm->sockets; while (s->state != SOCKET_STATE_FREE) { @@ -1059,7 +1059,7 @@ int socket_connect(SocketManager *sm, int num_targets, s->next_addr = 0; s->addrs = malloc(num_resolved * sizeof(AddressAndPort)); if (s->addrs == NULL) - return HTTP_ERROR_OOM; + return CHTTP_ERROR_OOM; for (int i = 0; i < num_resolved; i++) s->addrs[i] = resolved[i]; } @@ -1083,7 +1083,7 @@ int socket_connect(SocketManager *sm, int num_targets, sm->num_used++; socket_update(s); - return HTTP_OK; + return CHTTP_OK; } static bool would_block(void) diff --git a/src/socket.h b/src/socket.h index adaf4e5..ea4d76c 100644 --- a/src/socket.h +++ b/src/socket.h @@ -123,8 +123,8 @@ typedef struct { // Internal use only typedef struct { union { - HTTP_IPv4 ipv4; - HTTP_IPv6 ipv6; + CHTTP_IPv4 ipv4; + CHTTP_IPv6 ipv6; }; bool is_ipv4; Port port; @@ -241,7 +241,7 @@ void socket_manager_free(SocketManager *sm); // can only be used once per manager. // Returns 0 on success, -1 on error. int socket_manager_listen_tcp(SocketManager *sm, - HTTP_String addr, Port port, int backlog, + CHTTP_String addr, Port port, int backlog, bool reuse_addr); // Same as the previous function, but incoming @@ -252,9 +252,9 @@ int socket_manager_listen_tcp(SocketManager *sm, // and secure connections. // Returns 0 on success, -1 on error. int socket_manager_listen_tls(SocketManager *sm, - HTTP_String addr, Port port, int backlog, - bool reuse_addr, HTTP_String cert_file, - HTTP_String key_file); + CHTTP_String addr, Port port, int backlog, + bool reuse_addr, CHTTP_String cert_file, + CHTTP_String key_file); // If the socket manager was configures to accept // TLS connections, this adds additional certificates @@ -262,7 +262,7 @@ int socket_manager_listen_tls(SocketManager *sm, // authenticity. // Returns 0 on success, -1 on error. int socket_manager_add_certificate(SocketManager *sm, - HTTP_String domain, HTTP_String cert_file, HTTP_String key_file); + CHTTP_String domain, CHTTP_String cert_file, CHTTP_String key_file); // When a thread is blocked on a poll() call for // descriptors associated to this socket manager, @@ -305,9 +305,9 @@ typedef struct { ConnectTargetType type; Port port; union { - HTTP_IPv4 ipv4; - HTTP_IPv6 ipv6; - HTTP_String name; + CHTTP_IPv4 ipv4; + CHTTP_IPv6 ipv6; + CHTTP_String name; }; } ConnectTarget;