From 8ff2bb608c55f739d89ca30ba6c10cef61b1f303 Mon Sep 17 00:00:00 2001 From: Francesco Date: Thu, 8 May 2025 16:58:42 +0200 Subject: [PATCH] fix http parser and config --- .gitignore | 1 - README.md | 2 +- config.yaml | 4 ++-- include/http/http.h | 7 +++---- include/server/server.h | 8 ++++---- include/utils/config.h | 4 ++-- src/http/http.c | 12 +++++++++--- src/main.c | 15 +++++++++------ src/server/server.c | 13 ++++++------- src/utils/config.c | 7 +++++-- test/hashmap_test.c | 12 +++++++++--- 11 files changed, 50 insertions(+), 35 deletions(-) diff --git a/.gitignore b/.gitignore index 49b6b03..7922831 100644 --- a/.gitignore +++ b/.gitignore @@ -56,4 +56,3 @@ modules.order Module.symvers Mkfile.old dkms.conf -doxygen-awesome-css diff --git a/README.md b/README.md index a11e068..3ea058c 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ A minimal web server. This is a personal project; it is not intended to be a pro - libcyaml - libyaml - [doxygen](https://www.doxygen.nl/) - - Optional, just to build the docs. + - Optional, just to build the docs. It requires `dot`. ## How to build diff --git a/config.yaml b/config.yaml index 6733aff..f479853 100644 --- a/config.yaml +++ b/config.yaml @@ -1,6 +1,6 @@ # Default config file of CWS -host: localhost +hostname: localhost port: 3030 - +www: "www" # Directory used to retrieve html files cert: "cert.pem" key: "key.pem" diff --git a/include/http/http.h b/include/http/http.h index 0a83c1e..38262a2 100644 --- a/include/http/http.h +++ b/include/http/http.h @@ -1,10 +1,9 @@ #ifndef CWS_HTTP_H #define CWS_HTTP_H +#include "utils/config.h" #include "utils/hashmap.h" -#define CWS_WWW "../www" /**< Directory used to get html files */ -/** In the future I'll move conf stuff under a server struct, I can skip just because I want something that works */ #define CWS_HTTP_LOCATION_LEN 512 #define CWS_HTTP_LOCATION_PATH_LEN 1024 #define CWS_HTTP_VERSION_LEN 8 @@ -14,8 +13,8 @@ typedef enum cws_http_method_t { CWS_HTTP_POST, /**< POST method */ CWS_HTTP_PUT, CWS_HTTP_DELETE, + CWS_HTTP_HEAD, } cws_http_method; -/* In the future I'll add HEAD, PUT, DELETE */ /** * @brief HTTP request struct @@ -39,7 +38,7 @@ typedef struct cws_http_t { * @param[in] request_str The http request sent to the server * @return Returns a http_t pointer to the request */ -cws_http *cws_http_parse(char *request_str, int sockfd); +cws_http *cws_http_parse(char *request_str, int sockfd, cws_config *config); void cws_http_parse_method(cws_http *request, const char *method); void cws_http_get_content_type(cws_http *request, char *content_type); diff --git a/include/server/server.h b/include/server/server.h index 1ebe261..344c4e2 100644 --- a/include/server/server.h +++ b/include/server/server.h @@ -4,6 +4,7 @@ #include #include +#include "utils/config.h" #include "utils/hashmap.h" /* Clients max queue */ @@ -21,11 +22,10 @@ extern volatile bool cws_server_run; /** * @brief Runs the server * - * @param[in] hostname The hostname of the server (default localhost, it could be NULL) - * @param[in] service The service (found in /etc/services) or the port where to run + * @param[in] config The server's config * @return 0 on success, -1 on error */ -int cws_server_start(const char *hostname, const char *service); +int cws_server_start(cws_config *config); /** * @brief Setups hints object @@ -41,7 +41,7 @@ void cws_server_setup_hints(struct addrinfo *hints, size_t len, const char *host * * @param[in,out] sockfd Socket of the commincation endpoint */ -void cws_server_loop(int sockfd); +void cws_server_loop(int sockfd, cws_config *config); /** * @brief Adds a file descriptor to the interest list diff --git a/include/utils/config.h b/include/utils/config.h index e4c9475..28a1fe5 100644 --- a/include/utils/config.h +++ b/include/utils/config.h @@ -2,9 +2,9 @@ #define CWS_CONFIG_H typedef struct cws_config_t { - char *host; + char *hostname; char *port; - + char *www; char *cert; char *key; } cws_config; diff --git a/src/http/http.c b/src/http/http.c index 4f41de2..3d85a7e 100644 --- a/src/http/http.c +++ b/src/http/http.c @@ -8,7 +8,7 @@ #include "utils/colors.h" #include "utils/utils.h" -cws_http *cws_http_parse(char *request_str, int sockfd) { +cws_http *cws_http_parse(char *request_str, int sockfd, cws_config *config) { cws_http *request = malloc(sizeof(cws_http)); if (request == NULL) { return NULL; @@ -21,6 +21,8 @@ cws_http *cws_http_parse(char *request_str, int sockfd) { /* Parse HTTP method */ char *pch = strtok(request_str, " "); if (pch == NULL) { + cws_http_free(request); + return NULL; } CWS_LOG_DEBUG("[http] method: %s", pch); @@ -29,6 +31,8 @@ cws_http *cws_http_parse(char *request_str, int sockfd) { /* Parse location */ pch = strtok(NULL, " "); if (pch == NULL) { + cws_http_free(request); + return NULL; } CWS_LOG_DEBUG("[http] location: %s", pch); @@ -36,15 +40,17 @@ cws_http *cws_http_parse(char *request_str, int sockfd) { /* Adjust location path */ if (strcmp(request->location, "/") == 0) { - snprintf(request->location_path, CWS_HTTP_LOCATION_PATH_LEN, "%s/index.html", CWS_WWW); + snprintf(request->location_path, CWS_HTTP_LOCATION_PATH_LEN, "%s/index.html", config->www); } else { - snprintf(request->location_path, CWS_HTTP_LOCATION_PATH_LEN, "%s%s", CWS_WWW, request->location); + snprintf(request->location_path, CWS_HTTP_LOCATION_PATH_LEN, "%s%s", config->www, request->location); } CWS_LOG_DEBUG("[http] location path: %s", request->location_path); /* Parse HTTP version */ pch = strtok(NULL, " \r\n"); if (pch == NULL) { + cws_http_free(request); + return NULL; } CWS_LOG_DEBUG("[http] version: %s", pch); diff --git a/src/main.c b/src/main.c index 99dacfb..dc62933 100644 --- a/src/main.c +++ b/src/main.c @@ -12,18 +12,21 @@ void cws_signal_handler(int signo) { cws_server_run = false; } int main(int argc, char **argv) { int ret; + struct sigaction act = {.sa_handler = cws_signal_handler}; + ret = sigaction(SIGINT, &act, NULL); + if (!ret) { + CWS_LOG_ERROR("sigaction()"); + return 1; + } + cws_config *config = cws_config_init(); if (config == NULL) { CWS_LOG_ERROR("Unable to read config file"); return 1; } - struct sigaction act = {.sa_handler = cws_signal_handler}; - ret = sigaction(SIGINT, &act, NULL); - - CWS_LOG_INFO("Running cws on http://%s:%s...", config->host, config->port); - - ret = cws_server_start(config->host, config->port); + CWS_LOG_INFO("Running cws on http://%s:%s...", config->hostname, config->port); + ret = cws_server_start(config); if (ret < 0) { CWS_LOG_ERROR("Unable to start web server"); } diff --git a/src/server/server.c b/src/server/server.c index 55409d0..19ab232 100644 --- a/src/server/server.c +++ b/src/server/server.c @@ -13,18 +13,17 @@ #include "http/http.h" #include "utils/colors.h" -#include "utils/hashmap.h" #include "utils/utils.h" volatile bool cws_server_run = 1; -int cws_server_start(const char *hostname, const char *service) { +int cws_server_start(cws_config *config) { struct addrinfo hints; struct addrinfo *res; - cws_server_setup_hints(&hints, sizeof hints, hostname); + cws_server_setup_hints(&hints, sizeof hints, config->hostname); - int status = getaddrinfo(hostname, service, &hints, &res); + int status = getaddrinfo(config->hostname, config->port, &hints, &res); if (status != 0) { CWS_LOG_ERROR("getaddrinfo() error: %s", gai_strerror(status)); exit(EXIT_FAILURE); @@ -51,7 +50,7 @@ int cws_server_start(const char *hostname, const char *service) { exit(EXIT_FAILURE); } - cws_server_loop(sockfd); + cws_server_loop(sockfd, config); freeaddrinfo(res); close(sockfd); @@ -74,7 +73,7 @@ void cws_server_setup_hints(struct addrinfo *hints, size_t len, const char *host } } -void cws_server_loop(int sockfd) { +void cws_server_loop(int sockfd, cws_config *config) { struct sockaddr_storage their_sa; socklen_t theirsa_size = sizeof their_sa; @@ -132,7 +131,7 @@ void cws_server_loop(int sockfd) { data[bytes_read] = '\0'; /* Parse HTTP request */ - cws_http *request = cws_http_parse(data, client_fd); + cws_http *request = cws_http_parse(data, client_fd, config); if (request == NULL) { cws_server_close_client(epfd, client_fd, clients); diff --git a/src/utils/config.c b/src/utils/config.c index 4c13593..beb6ee1 100644 --- a/src/utils/config.c +++ b/src/utils/config.c @@ -9,10 +9,13 @@ static const cyaml_config_t cyaml_config = { }; static const cyaml_schema_field_t top_mapping_schema[] = { - CYAML_FIELD_STRING_PTR("host", CYAML_FLAG_POINTER, cws_config, host, 0, CYAML_UNLIMITED), + CYAML_FIELD_STRING_PTR("hostname", CYAML_FLAG_POINTER, cws_config, hostname, 0, CYAML_UNLIMITED), CYAML_FIELD_STRING_PTR("port", CYAML_FLAG_POINTER, cws_config, port, 0, CYAML_UNLIMITED), + CYAML_FIELD_STRING_PTR("www", CYAML_FLAG_POINTER, cws_config, www, 0, CYAML_UNLIMITED), CYAML_FIELD_STRING_PTR("cert", CYAML_FLAG_POINTER, cws_config, cert, 0, CYAML_UNLIMITED), - CYAML_FIELD_STRING_PTR("key", CYAML_FLAG_POINTER, cws_config, key, 0, CYAML_UNLIMITED), CYAML_FIELD_END}; + CYAML_FIELD_STRING_PTR("key", CYAML_FLAG_POINTER, cws_config, key, 0, CYAML_UNLIMITED), + CYAML_FIELD_END +}; static const cyaml_schema_value_t top_schema = { CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER, cws_config, top_mapping_schema), diff --git a/test/hashmap_test.c b/test/hashmap_test.c index 19667ef..430dcd8 100644 --- a/test/hashmap_test.c +++ b/test/hashmap_test.c @@ -34,10 +34,16 @@ int main(void) { cws_hashmap *str_hashmap = cws_hm_init(my_hash_fn, my_equal_fn, my_free_fn, my_free_fn); char *key = strdup("test1"); - char *value = strdup("value1"); + if (key == NULL) { + CWS_LOG_ERROR("strdup() key"); - if (key == NULL || value == NULL) { - CWS_LOG_ERROR("strdup()"); + return 1; + } + + char *value = strdup("value1"); + if (value == NULL) { + CWS_LOG_ERROR("strdup() value"); + free(key); return 1; }