diff --git a/include/http/http.h b/include/http/http.h index 0d89ccc..895fb9d 100644 --- a/include/http/http.h +++ b/include/http/http.h @@ -5,8 +5,6 @@ #include #include -#include "utils/config.h" - #define CWS_HTTP_HEADER_MAX 512 #define CWS_HTTP_HEADER_CONTENT_MAX 1024 @@ -24,39 +22,26 @@ typedef enum cws_http_status { CWS_HTTP_NOT_IMPLEMENTED, } cws_http_status_e; -/** - * @brief HTTP request struct - * - */ typedef struct cws_http { - int sockfd; /**< Socket file descriptor */ - cws_http_method_e method; /**< HTTP request method */ - string_s *location; /**< Resource requested */ - string_s *location_path; /**< Full resource path */ - string_s *http_version; /**< HTTP version */ - hashmap_s *headers; /**< Headers hash map */ + int sockfd; + cws_http_method_e method; + string_s *location; + string_s *location_path; + string_s *http_version; + hashmap_s *headers; } cws_http_s; -/** - * @brief Parses a HTTP request - * - * @param[in] request_str The http request sent to the server - * @return Returns a http_t pointer to the request - */ -cws_http_s *cws_http_parse(string_s *request_str, int sockfd, cws_config_s *config); +cws_http_s *cws_http_parse(string_s *request_str, int sockfd); int cws_http_get_content_type(cws_http_s *request, char *content_type); -/** - * @brief Build the http response - * - * @return Returns the size of the response - */ size_t cws_http_response_builder(char **response, char *http_version, cws_http_status_e status, char *content_type, char *connection, char *body, size_t body_len_bytes); void cws_http_send_response(cws_http_s *request, cws_http_status_e status); + int cws_http_send_resource(cws_http_s *request); + void cws_http_send_simple_html(cws_http_s *request, cws_http_status_e status, char *title, char *description); void cws_http_free(cws_http_s *request); diff --git a/include/server/worker.h b/include/server/worker.h index 836f353..582fac2 100644 --- a/include/server/worker.h +++ b/include/server/worker.h @@ -30,6 +30,6 @@ cws_server_ret cws_epoll_add(int epfd, int sockfd, uint32_t events); cws_server_ret cws_epoll_del(int epfd, int sockfd); -cws_server_ret cws_server_handle_client_data(int epfd, int client_fd, cws_config_s *config); +cws_server_ret cws_server_handle_client_data(int epfd, int client_fd); #endif diff --git a/meson.build b/meson.build index a0330db..cb4a692 100644 --- a/meson.build +++ b/meson.build @@ -1,4 +1,4 @@ -project('cws', 'c', version: '0.1.0') +project('cws', 'c', version: '0.1.0', default_options: ['c_std=c23', 'warning_level=3']) cc = meson.get_compiler('c') diff --git a/src/http/http.c b/src/http/http.c index 5986e89..639a0fc 100644 --- a/src/http/http.c +++ b/src/http/http.c @@ -35,8 +35,8 @@ static int cws_http_parse_method(cws_http_s *request, const char *method) { return -1; } -cws_http_s *cws_http_parse(string_s *request_str, int sockfd, cws_config_s *config) { - if (!request_str || !config) { +cws_http_s *cws_http_parse(string_s *request_str, int sockfd) { + if (!request_str) { return NULL; } @@ -47,9 +47,6 @@ cws_http_s *cws_http_parse(string_s *request_str, int sockfd, cws_config_s *conf } request->sockfd = sockfd; - /* Prepare the virtual_host struct */ - // TODO: cws_virtual_host vhost; - char *request_str_cpy = strdup(string_cstr(request_str)); if (!request_str_cpy) { free(request); @@ -61,6 +58,7 @@ cws_http_s *cws_http_parse(string_s *request_str, int sockfd, cws_config_s *conf char *pch = NULL; /* Parse HTTP method */ + // TODO: fix strtok_r pch = strtok_r(request_str_cpy, " ", &saveptr); if (pch == NULL) { cws_http_free(request); diff --git a/src/main.c b/src/main.c index 2b221b0..4725942 100644 --- a/src/main.c +++ b/src/main.c @@ -1,3 +1,5 @@ +#define _XOPEN_SOURCE 700 + #include #include #include @@ -8,7 +10,7 @@ #include "utils/config.h" #include "utils/debug.h" -void cws_signal_handler(int signo) { cws_server_run = 0; } +void cws_signal_handler(int) { cws_server_run = 0; } int main(void) { struct sigaction act = {.sa_handler = cws_signal_handler, .sa_flags = 0, .sa_mask = {{0}}}; @@ -18,8 +20,9 @@ int main(void) { } cws_config_s *config = cws_config_init(); - if (config == NULL) { + if (!config) { CWS_LOG_ERROR("Unable to read config file"); + return EXIT_FAILURE; } @@ -36,6 +39,9 @@ int main(void) { CWS_LOG_INFO("Running cws on http://%s:%s...", config->hostname, config->port); ret = cws_server_loop(&server); + if (ret != CWS_SERVER_OK) { + CWS_LOG_ERROR("Unable to start web server"); + } CWS_LOG_INFO("Shutting down cws..."); cws_server_shutdown(&server); diff --git a/src/server/server.c b/src/server/server.c index 00996ea..3ae6395 100644 --- a/src/server/server.c +++ b/src/server/server.c @@ -112,10 +112,12 @@ cws_server_ret cws_server_loop(cws_server_s *server) { while (cws_server_run) { int nfds = epoll_wait(server->epfd, events, 128, -1); + /* epoll error */ if (nfds < 0) { continue; } + /* No events */ if (nfds == 0) { continue; } diff --git a/src/server/worker.c b/src/server/worker.c index 2cb4322..3a681b4 100644 --- a/src/server/worker.c +++ b/src/server/worker.c @@ -78,6 +78,10 @@ cws_worker_s **cws_worker_new(size_t workers_num, cws_config_s *config) { } void cws_worker_free(cws_worker_s **workers, size_t workers_num) { + if (!workers) { + return; + } + for (size_t i = 0; i < workers_num; ++i) { pthread_join(workers[i]->thread, NULL); free(workers[i]); @@ -93,7 +97,12 @@ void *cws_worker_loop(void *arg) { int nfds; while (cws_server_run) { - nfds = epoll_wait(worker->epfd, events, 64, 1000); + nfds = epoll_wait(worker->epfd, events, 64, -1); + + if (nfds < 0) { + continue; + } + if (nfds == 0) { continue; } @@ -108,7 +117,7 @@ void *cws_worker_loop(void *arg) { } else { /* Handle client data */ int client_fd = events[i].data.fd; - cws_server_handle_client_data(worker->epfd, client_fd, worker->config); + cws_server_handle_client_data(worker->epfd, client_fd); } } } @@ -116,7 +125,10 @@ void *cws_worker_loop(void *arg) { return NULL; } -void cws_server_close_client(int epfd, int client_fd) { cws_epoll_del(epfd, client_fd); } +void cws_server_close_client(int epfd, int client_fd) { + cws_epoll_del(epfd, client_fd); + sock_close(client_fd); +} cws_server_ret cws_epoll_add(int epfd, int sockfd, uint32_t events) { struct epoll_event event; @@ -178,9 +190,9 @@ static size_t cws_read_data(int sockfd, string_s **str) { return total_bytes; } -cws_server_ret cws_server_handle_client_data(int epfd, int client_fd, cws_config_s *config) { +cws_server_ret cws_server_handle_client_data(int epfd, int client_fd) { /* Read data from socket */ - string_s *data = NULL; + string_s *data; size_t total_bytes = cws_read_data(client_fd, &data); if (total_bytes <= 0) { if (data) { @@ -192,7 +204,7 @@ cws_server_ret cws_server_handle_client_data(int epfd, int client_fd, cws_config } /* Parse HTTP request */ - cws_http_s *request = cws_http_parse(data, client_fd, config); + cws_http_s *request = cws_http_parse(data, client_fd); string_free(data); if (request == NULL) {