bunkum

an old and silly c99 web server with some fun features
Log | Files | Refs | README

commit cda90e9a0c789da9dff20ab27d45e471b442900b
parent 4646a3f8e61747636bff2eded1b257b531bcf533
Author: quantumish <freifeld.david@gmail.com>
Date:   Tue, 11 Apr 2023 22:47:27 -0700

Finish adding test plus add debugging util

Diffstat:
Mhttp/request.c | 29++++++++++++++++++++++-------
Mtest.c | 37+++++++++++++++++++++++--------------
Mtest.h | 1+
Mtestutils.c | 7+++++++
4 files changed, 53 insertions(+), 21 deletions(-)

diff --git a/http/request.c b/http/request.c @@ -13,7 +13,7 @@ const char* method_name(enum http_method m) { } const enum http_method method_codes[] = {DELETE, CONNECT, PUT, POST, TRACE, HEAD, OPTIONS, GET}; -enum http_method method_enum(char* p) { +enum http_method method_enum(char* p) { return method_codes[((*(uint64_t*)p*0x1b8b6e6d) % 0x100000000) >> 28]; } @@ -47,7 +47,7 @@ shitvec_t hdr_parse_accept(char* val) { do { next = strtok(NULL, ","); float q = 1; - char* qptr = NULL; + char* qptr = NULL; if ((qptr = (char*)memchr(start, ';', next-start))) { sscanf(qptr, ";q=%f", &q); } @@ -68,13 +68,13 @@ int req_parse(request_t* req) { int matched = sscanf(req->buf, "%s %s HTTP/%f\r\n", (char*)method, (char*)req->path, &req->ver); if (matched < 3 || matched == EOF) return -1; req->method = method_enum((char*)method); - + req->headers = shitvec_new(sizeof(header_line_t)); char* start = memchr(req->buf, '\n', MAX_HEADER_NAME+MAX_HEADER_VALUE)+1; while (start+MAX_HEADER_NAME+MAX_HEADER_VALUE < req->buf+req->bufsize) { header_line_t hdr = header_line_new(); int matched = sscanf(start, "%32[^:]: %s", hdr.name, hdr.value); - if (matched == 0) return 0; // No more headers; + if (matched == 0) return 0; // No more headers; else if (matched == 1) { if (hdr.name[0] == '\r') return 0; // TODO sketch return -1; // Uhh... half a header. @@ -112,10 +112,25 @@ void test_method_str_to_enum() { }; void test_hdr_parse_accept() { - char* hdr = "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8"; + char hdr[MAX_HEADER_VALUE] = "text/html,application/xml;q=0.9,image/webp,*/*;q=0.8"; shitvec_t mtypes = hdr_parse_accept(hdr); - assert_size_eq(mtypes.vec_sz, 5); - // TODO write the rest of this. + assert_size_eq(mtypes.vec_sz, 4); + + struct req_mimetype* mtype = shitvec_get(&mtypes, 0); + assert_str_eq("text/html", mtype->item); + assert_float_eq(1.0, mtype->q); + + mtype = shitvec_get(&mtypes, 1); + assert_str_eq("image/webp", mtype->item); + assert_float_eq(1.0, mtype->q); + + mtype = shitvec_get(&mtypes, 2); + assert_str_eq("application/xml", mtype->item); + assert_float_eq(0.9, mtype->q); + + mtype = shitvec_get(&mtypes, 3); + assert_str_eq("*/*", mtype->item); + assert_float_eq(0.8, mtype->q); } #endif diff --git a/test.c b/test.c @@ -59,12 +59,26 @@ void get_symbols(char* path) { fclose(fptr); } +int run_test_safe(bool(*testf)(void)) { + pid_t pid = fork(); + if (pid == 0) { + testf(); + exit(0); + } else { + int status; + waitpid(pid, &status, 0); + return status; + } +} + #define ANSI_RED "\x1b[31m" #define ANSI_GREEN "\x1b[32m" #define ANSI_BOLD "\x1b[1m" #define ANSI_RESET "\x1b[0m" int main(int argc, char** argv) { + bool imode = false; + if (argc > 2 && strcmp(argv[2], "-i") == 0) imode = true; get_symbols(argv[1]); char path[64] = {0}; sprintf(path, "./%s", argv[1]); @@ -76,22 +90,17 @@ int main(int argc, char** argv) { printf(" %s ", sym+5); fflush(STDIN_FILENO); bool(*testf)(void) = dlsym(lib, sym); - pid_t pid = fork(); - if (pid == 0) { - testf(); - exit(0); + int status = run_test_safe(testf); + + if (status == 0) { + passed += 1; + puts(" " ANSI_GREEN "[GOOD]" ANSI_RESET); } else { - int status; - waitpid(pid, &status, 0); - if (status == 0) { - passed += 1; - puts(" " ANSI_GREEN "[GOOD]" ANSI_RESET); - } else { - printf(" " ANSI_RED "[BAD]" ANSI_RESET); - if (status != 1) printf(ANSI_RED " (%d)" ANSI_RESET, status); - printf("\n"); - } + printf(" " ANSI_RED "[BAD]" ANSI_RESET); + if (status != 1) printf(ANSI_RED " (%d)" ANSI_RESET, status); + printf("\n"); } + if (status != 0 && status != 1 && imode) testf(); } printf("\n" ANSI_GREEN "%ld tests" ANSI_RESET " passed, " ANSI_RED "%ld tests" ANSI_RESET " failed.\n" ANSI_RESET, passed, total-passed); diff --git a/test.h b/test.h @@ -5,6 +5,7 @@ #include <stddef.h> void assert_str_eq(char* a, char* b); +void assert_float_eq(float a, float b); void assert_size_eq(size_t a, size_t b); void assert_bool(bool expr); diff --git a/testutils.c b/testutils.c @@ -18,6 +18,13 @@ void assert_size_eq(size_t a, size_t b) { } } +void assert_float_eq(float a, float b) { + if (a != b) { + printf("(%f != %f)", a, b); + exit(1); + } +} + void assert_bool(bool expr) { if (!expr) { exit(1);