diff --git a/asl.c b/asl.c index 68acd48..69bc81f 100644 --- a/asl.c +++ b/asl.c @@ -143,40 +143,50 @@ int asl_post(struct request *r, int client) { (void)client; - const char poor_btn[] = "poor"; - const char good_btn[] = "good"; - const char great_btn[] = "great"; - - printf("params=\"%s\"\n", r->parameters); + static const struct str poor_btn = STR("poor"); + static const struct str good_btn = STR("good"); + static const struct str great_btn = STR("great"); + + for (long i = 0; i < r->param_count; ++i) { + printf("param %li=", i); + str_print(stdout, &r->params[i].key); + puts("="); + str_print(stdout, &r->params[i].value); + puts("\n"); + } - struct param button = {0}; - if (find_param(&button, r, "button") != 0) { + struct http_param button = {0}; + if (find_param(r, "button", &button) != 0) { // No button param! perror("No button param in parameters.\n"); return EINVAL; } - printf("button param: %s:%s.\n", button.name, button.value); + puts("button param: "); + str_print(stdout, &button.key); + puts(":"); + str_print(stdout, &button.value); + puts("\n"); struct quiz_item *card = quiz + current_quiz_item; - if (strcmp(poor_btn, button.value) == 0) { + if (str_cmp(&poor_btn, &button.value) == 0) { // Review this card again during this quiz and reduce the // confidence by half. card->confidence = (int)((float)card->confidence * 0.5); - } else if (strcmp(good_btn, button.value) == 0) { + } else if (str_cmp(&good_btn, &button.value) == 0) { // Boost the confidence by 1 and review this card that many // days in the future. card->confidence += 1; card->next_review = s_quiz_start + (SECONDS_PER_DAY * card->confidence); - } else if (strcmp(great_btn, button.value) == 0) { + } else if (str_cmp(&great_btn, &button.value) == 0) { // Double the confidence and review the card that many days in // the future. card->confidence *= 2; card->next_review = s_quiz_start + (SECONDS_PER_DAY * card->confidence); } else { - printf("Unrecognized button value: \"%s\"\n", button.value); + puts("Unrecognized button value"); } printf("card confidence:%i review time:%lu\n", card->confidence, card->next_review); @@ -399,7 +409,9 @@ static int show_done_page(int client) perror("Failed to open asl_done.html file"); return errno; } - return send_file_with_replaced_params(f, client); + int err = send_file_with_replaced_params(f, client); + fclose(f); + return err; } /* diff --git a/base_defs.c b/base_defs.c index 43a3ce2..57480c2 100644 --- a/base_defs.c +++ b/base_defs.c @@ -1,2 +1,4 @@ #define DEFINE_POOL // Bring in the definitions for the pool functions. #include "pool.h" +#define DEFINE_STR // Bring in the definitions for the str. +#include "str.h" diff --git a/crvr.c b/crvr.c index 6fb620b..1376d47 100644 --- a/crvr.c +++ b/crvr.c @@ -179,7 +179,7 @@ int parse_request_buffer(struct request *request, struct pool *p) if (path.s[path.len] == '/') { struct str actual_path = {0}; long space_needed = path.len + index_page.len; - int error = alloc_str(p, space_needed, &actual_path); + int error = str_alloc(p, space_needed, &actual_path); if (error) { fprintf(stderr, "Failed to allocate actual path: %i.\n", error); @@ -308,7 +308,7 @@ int handle_post_request(int client, struct request *r, struct pool *p, printf("Have %lu bytes of content, Need to read in %lu more bytes\n", bytes_received, bytes_needed); - alloc_str(p, bytes_needed, &r->post_params_buffer); + str_alloc(p, bytes_needed, &r->post_params_buffer); long bytes_read = 0; while (bytes_read < bytes_needed) { // Need to update space below if this isn't the case. diff --git a/http.c b/http.c index dc210da..9356ab3 100644 --- a/http.c +++ b/http.c @@ -5,6 +5,7 @@ */ #include "http.h" +#include #include #include #include @@ -14,55 +15,20 @@ const char ok_header[] = "HTTP/1.1 200 OK"; -int find_param(struct param out[static 1], struct request r[static 1], - const char *param_name) +int find_param(const struct request *r, const char *param_name, + struct http_param *out) { - *out = (struct param){0}; - - if (!param_name) - return EINVAL; - char *param = strstr(r->parameters, param_name); - if (!param) { - printf("Did not find %s in parameters.\n", param_name); - return EINVAL; - } - - printf("param: \"%s\"\n", param); + if (!out || !r || !param_name) return EINVAL; - size_t param_name_len = strlen(param_name); - (void)strncpy(out->name, param_name, param_name_len); - - param += param_name_len; - printf("after name param: \"%s\"\n", param); - if ('=' != *param) { - printf("Param is not '=': \"%c\" (0x%hhx)\n", *param, *param); - return EINVAL; - } - param += sizeof((char)'='); - printf("after = param: \"%s\"\n", param); - - /* - * Look for a \r\n or \0. If either one is encountered that's the end - * of the parameter value. - */ - size_t value_end = 0; - printf("Checking param: "); - for (; param[value_end]; ++value_end) { - printf("'%c', ", param[value_end]); - if (('\n' == param[value_end]) && (value_end > 0) && - (param[value_end - 1] == '\r')) { - value_end -= (sizeof((char)'\r') + sizeof((char)'\n')); - break; + static_assert(SIZE_MAX > LONG_MAX); + assert((size_t)r->param_count < LEN(r->params)); + for (long i = 0; i < r->param_count; ++i) { + if (str_cmp_cstr(&r->params[i].key, param_name) == 0) { + *out = r->params[i]; + return 0; } } - printf("\n"); - - for (size_t i = 0; i < value_end; ++i) { - out->value[i] = param[i]; - } - printf("param %s:%s.\n", out->name, out->value); - - return 0; + return ENOENT; } int header_find_value(struct request *r, const char *key, struct str *value) @@ -81,7 +47,6 @@ int header_find_value(struct request *r, const char *key, struct str *value) void print_request(struct request *r) { const char *type_str = NULL; - size_t i; if (r->type == GET) { type_str = "GET"; @@ -92,17 +57,21 @@ void print_request(struct request *r) } printf("Request:\n" "Type: %s\n" - "Path: %s\n" - "Format: %s\n" - "Headers:\n", - type_str, r->path, r->format); - for (i = 0; i < r->header_count; ++i) { - printf("\t%s: %s\n", r->headers[i].key, r->headers[i].value); - } - if (r->parameters) { + "Path: ", type_str); + str_print(stdout, &r->path); + puts("\nFormat: "); + str_print(stdout, &r->format); + puts("\n"); + if (r->param_count > 0) { printf("Parameters:\n" "-----------\n"); - print_blob(r->parameters, r->param_len, 20); + for (long i = 0; i < r->param_count; ++i) { + printf("%li: ", i); + str_print(stdout, &r->params[i].key); + puts(":"); + str_print(stdout, &r->params[i].value); + puts("\n"); + } printf("-----------\n"); } } diff --git a/http.h b/http.h index 452d8b0..1a6de78 100644 --- a/http.h +++ b/http.h @@ -56,17 +56,18 @@ struct request { */ extern const char ok_header[]; -/* - * Searches for a parameter in the http request. +/** + * @brief Searches for a parameter in the http request. * - * out - The location to save the parameter data when found. - * r - The request to search through. - * param_name - The name of the parameter to look for. + * @param[out] out - The location to save the parameter data when found. + * @param[in] r - The request to search through. + * @param[in] param_name - The name of the parameter to look for. * - * Returns zero if the parameter was found, or an error code otherwise. + * @return Returns zero if the parameter was found or ENOENT if it wasn't + * found. Returns an error code on error. */ -int find_param(struct http_param *out, struct request *r, - const char *param_name); +int find_param(const struct request *r, const char *param_name, + struct http_param *out); /** * @brief Lookup a header parameter in the request. diff --git a/pool.h b/pool.h index 8d65b25..2e5c0ae 100644 --- a/pool.h +++ b/pool.h @@ -34,7 +34,7 @@ struct pool { * Returns 0 if the pool, p, was successfully initialized to the desired * size. Otherwise returns an error code. */ -int pool_init(struct pool *p, unsigned long desired_size); +int pool_init(struct pool *p, long desired_size); /** * @brief Return the number of unused bytes in the pool. @@ -132,7 +132,7 @@ int pool_reset(struct pool *p, long offset); #include #include -int pool_init(struct pool *p, unsigned long desired_size) +int pool_init(struct pool *p, const long desired_size) { assert(p && (p->buffer == NULL)); p->offset = 0; @@ -156,7 +156,8 @@ void pool_free(struct pool *p) void *pool_alloc(struct pool *p, long byte_amount) { - unsigned long alignment = sizeof(void*) - byte_amount % sizeof(void*); + long alignment = (long)sizeof(void*) - byte_amount % + (long)sizeof(void*); byte_amount += alignment; if ((p->offset + byte_amount) > p->cap) return NULL; assert(p->buffer); diff --git a/str.h b/str.h index 1649584..fcb105c 100644 --- a/str.h +++ b/str.h @@ -14,8 +14,9 @@ #ifndef BASE_STR_H #define BASE_STR_H -#include +#include #include +#include struct pool; @@ -78,7 +79,7 @@ int str_print(FILE *f, const struct str *s); * * @return Returns 0 if successful, otherwise returns an error code. */ -int alloc_str(struct pool *p, const long space_needed, struct str *s); +int str_alloc(struct pool *p, const long space_needed, struct str *s); /** * @brief Copies the c-string into an str. @@ -94,7 +95,7 @@ int alloc_str(struct pool *p, const long space_needed, struct str *s); * @return Returns 0 if the data was copied to the pool and the str was updated. * Otherwise returns an error code. */ -int alloc_from_str(struct pool *p, const char *cstr, const long len, +int str_alloc_from_cstr(struct pool *p, const char *cstr, const long len, struct str *s); /** @@ -128,6 +129,8 @@ int str_copy_to_cstr(const struct str *s, char *dest, long dest_len); #include #include "pool.h" +#define LONG_9 ((long)'9' - (long)'0') + int str_cmp(const struct str *a, const struct str *b) { if (a == b) return 0; @@ -184,7 +187,7 @@ int str_print(FILE *f, const struct str *s) return result; } -int alloc_str(struct pool *p, const long space_needed, struct str *s) +int str_alloc(struct pool *p, const long space_needed, struct str *s) { if (!p || !s || (space_needed <= 0)) return EINVAL; @@ -194,22 +197,22 @@ int alloc_str(struct pool *p, const long space_needed, struct str *s) return 0; } -int alloc_from_str(struct pool *p, const char *cstr, const long len, +int str_alloc_from_cstr(struct pool *p, const char *cstr, const long len, struct str *s) { - int err = alloc_str(p, len, s); + int err = str_alloc(p, len, s); if (err) return err; - (void)memcpy(s->s, cstr, s->len); + assert(s->len > 0); + (void)memcpy(s->s, cstr, (size_t)s->len); return 0; } -#define LONG_9 ((long)'9' - (long)'0'); int str_to_long(const struct str *s, long *l, long base) { if (!s || !l || (base <= 0)) return EINVAL; - const double max_value = round(powf((double)base, (double)s->len)); + const double max_value = round(pow((double)base, (double)s->len)); if (max_value > (double)LONG_MAX) return ERANGE; long value = 0; long c = 0; @@ -220,6 +223,7 @@ int str_to_long(const struct str *s, long *l, long base) value *= base; value += c; } + return 0; } int str_copy_to_cstr(const struct str *s, char *dest, long dest_len) @@ -227,7 +231,8 @@ int str_copy_to_cstr(const struct str *s, char *dest, long dest_len) if (!s || !dest || (dest_len <= 0)) return EINVAL; if (s->len >= dest_len) return ENOSPC; - memcpy(dest, s->s, s->len); + assert(s->len > 0); + memcpy(dest, s->s, (size_t)s->len); dest[s->len + 1] = 0; return 0; } diff --git a/unix.mk b/unix.mk index 59700bb..290d08e 100644 --- a/unix.mk +++ b/unix.mk @@ -12,5 +12,5 @@ CXXFLAGS=$(BUILD) -std=c++17 CFLAGS=$(BUILD) -std=c17 -Ibase LDFLAGS=$(SANITIZERS) -LDLIBS= +LDLIBS=-lm RM=rm -f