diff --git a/README.md b/README.md index cd5fffd..3fbf570 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ A minimal web server. This is a personal project; it is not intended to be a pro - libssl - libcyaml - libyaml +- myclib (on my profile) - [doxygen](https://www.doxygen.nl/) - Optional, just to build the docs. It requires `dot`. diff --git a/include/http/http.h b/include/http/http.h index 49d9bfe..ee80251 100644 --- a/include/http/http.h +++ b/include/http/http.h @@ -1,10 +1,10 @@ #ifndef CWS_HTTP_H #define CWS_HTTP_H +#include +#include #include -#include "myclib/hashmap/myhashmap.h" -#include "myclib/string/mystring.h" #include "utils/config.h" #define CWS_HTTP_HEADER_MAX 512 @@ -29,12 +29,12 @@ typedef enum cws_http_status_t { * */ typedef struct cws_http_t { - int sockfd; /**< Socket file descriptor */ - cws_http_method method; /**< HTTP request method */ - mcl_string *location; /**< Resource requested */ - mcl_string *location_path; /**< Full resource path */ - mcl_string *http_version; /**< HTTP version */ - mcl_hashmap *headers; /**< Headers hash map */ + int sockfd; /**< Socket file descriptor */ + cws_http_method 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 */ } cws_http; /** @@ -43,7 +43,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(mcl_string *request_str, int sockfd, cws_config *config); +cws_http *cws_http_parse(string_s *request_str, int sockfd, cws_config *config); int cws_http_get_content_type(cws_http *request, char *content_type); diff --git a/include/server/server.h b/include/server/server.h index 4afcc0e..df2e3d6 100644 --- a/include/server/server.h +++ b/include/server/server.h @@ -1,11 +1,11 @@ #ifndef CWS_SERVER_H #define CWS_SERVER_H +#include #include #include #include -#include "myclib/hashmap/myhashmap.h" #include "utils/config.h" /* Clients max queue */ @@ -48,7 +48,7 @@ typedef enum cws_server_ret_t { cws_server_ret cws_server_start(cws_config *config); cws_server_ret cws_server_loop(int server_fd, cws_config *config); -int cws_server_handle_new_client(int server_fd, mcl_hashmap *clients); +int cws_server_handle_new_client(int server_fd, hashmap_s *clients); int cws_server_accept_client(int server_fd, struct sockaddr_storage *their_sa, socklen_t *theirsa_size); cws_server_ret cws_fd_set_nonblocking(int sockfd); diff --git a/include/server/worker.h b/include/server/worker.h index 382c889..0254cd9 100644 --- a/include/server/worker.h +++ b/include/server/worker.h @@ -1,9 +1,9 @@ #ifndef CWS_WORKER_H #define CWS_WORKER_H +#include #include -#include "myclib/hashmap/myhashmap.h" #include "server/server.h" typedef struct cws_worker_t { @@ -11,17 +11,17 @@ typedef struct cws_worker_t { int pipefd[2]; size_t clients_num; pthread_t thread; - mcl_hashmap *clients; + hashmap_s *clients; cws_config *config; } cws_worker; -cws_worker **cws_worker_init(size_t workers_num, mcl_hashmap *clients, cws_config *config); +cws_worker **cws_worker_init(size_t workers_num, hashmap_s *clients, cws_config *config); void cws_worker_free(cws_worker **workers, size_t workers_num); void *cws_worker_loop(void *arg); -void cws_server_close_client(int epfd, int client_fd, mcl_hashmap *clients); +void cws_server_close_client(int epfd, int client_fd, hashmap_s *clients); 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, mcl_hashmap *clients, cws_config *config); +cws_server_ret cws_server_handle_client_data(int epfd, int client_fd, hashmap_s *clients, cws_config *config); #endif diff --git a/meson.build b/meson.build index 837e840..a0330db 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') cc = meson.get_compiler('c') @@ -9,10 +9,12 @@ incdir = include_directories('include') libssl = dependency('libssl') libyaml = dependency('yaml-0.1') libcyaml = dependency('libcyaml') -libmath = cc.find_library('m', required : true) -deps = [libssl, libyaml, libcyaml, libmath] +libmath = cc.find_library('m', required: true) +libmyclib = cc.find_library('myclib', required: true) -add_global_arguments('-DUSE_COLORS', language : 'c') -add_global_arguments('-DEVELOPER', language : 'c') +deps = [libssl, libyaml, libcyaml, libmath, libmyclib] -executable('cws', server + myclib, include_directories : incdir, dependencies : deps) +add_global_arguments('-DUSE_COLORS', language: 'c') +add_global_arguments('-DEVELOPER', language: 'c') + +executable('cws', server, include_directories: incdir, dependencies: deps) diff --git a/src/http/http.c b/src/http/http.c index 2665ab6..ca4494d 100644 --- a/src/http/http.c +++ b/src/http/http.c @@ -17,9 +17,9 @@ static void cws_http_init(cws_http **request) { return; } - (*request)->http_version = mcl_string_new("", 16); - (*request)->location = mcl_string_new("", 128); - (*request)->location_path = mcl_string_new("", 512); + (*request)->http_version = string_new("", 16); + (*request)->location = string_new("", 128); + (*request)->location_path = string_new("", 512); } static int cws_http_parse_method(cws_http *request, const char *method) { @@ -36,7 +36,7 @@ static int cws_http_parse_method(cws_http *request, const char *method) { return -1; } -cws_http *cws_http_parse(mcl_string *request_str, int sockfd, cws_config *config) { +cws_http *cws_http_parse(string_s *request_str, int sockfd, cws_config *config) { if (!request_str || !config) { return NULL; } @@ -49,9 +49,9 @@ cws_http *cws_http_parse(mcl_string *request_str, int sockfd, cws_config *config request->sockfd = sockfd; /* Prepare the virtual_host struct */ - cws_virtual_host vhost; + // TODO: cws_virtual_host vhost; - char *request_str_cpy = strdup(mcl_string_cstr(request_str)); + char *request_str_cpy = strdup(string_cstr(request_str)); if (!request_str_cpy) { free(request); @@ -91,14 +91,14 @@ cws_http *cws_http_parse(mcl_string *request_str, int sockfd, cws_config *config return NULL; } // CWS_LOG_DEBUG("location: %s", pch); - mcl_string_append(request->location, pch); + string_append(request->location, pch); // TODO: mcl_string_append(request->location_path, config->www); /* Adjust location path */ - if (strcmp(mcl_string_cstr(request->location), "/") == 0) { - mcl_string_append(request->location_path, "/index.html"); + if (strcmp(string_cstr(request->location), "/") == 0) { + string_append(request->location_path, "/index.html"); } else { - mcl_string_append(request->location_path, mcl_string_cstr(request->location)); + string_append(request->location_path, string_cstr(request->location)); } // CWS_LOG_DEBUG("location path: %s", mcl_string_cstr(request->location_path)); @@ -111,11 +111,11 @@ cws_http *cws_http_parse(mcl_string *request_str, int sockfd, cws_config *config return NULL; } // CWS_LOG_DEBUG("version: %s", pch); - mcl_string_append(request->http_version, pch); + string_append(request->http_version, pch); /* Parse headers until a \r\n */ - request->headers = mcl_hm_init(my_str_hash_fn, my_str_equal_fn, my_str_free_fn, my_str_free_fn, sizeof(char) * CWS_HTTP_HEADER_MAX, - sizeof(char) * CWS_HTTP_HEADER_CONTENT_MAX); + request->headers = + hm_new(my_str_hash_fn, my_str_equal_fn, my_str_free_fn, my_str_free_fn, sizeof(char) * CWS_HTTP_HEADER_MAX, sizeof(char) * CWS_HTTP_HEADER_CONTENT_MAX); char *header_colon; while (pch) { /* Get header line */ @@ -141,7 +141,7 @@ cws_http *cws_http_parse(mcl_string *request_str, int sockfd, cws_config *config strncpy(hv, hvalue, sizeof(hv)); // CWS_LOG_DEBUG("hkey: %s -> %s", hk, hv); - mcl_hm_set(request->headers, hk, hv); + hm_set(request->headers, hk, hv); } /* TODO: Parse body */ @@ -219,7 +219,7 @@ int cws_http_send_resource(cws_http *request) { /* keep-alive by default */ int keepalive = 1; - FILE *file = fopen(mcl_string_cstr(request->location_path), "rb"); + FILE *file = fopen(string_cstr(request->location_path), "rb"); if (file == NULL) { cws_http_send_response(request, CWS_HTTP_NOT_FOUND); return 0; @@ -260,12 +260,12 @@ int cws_http_send_resource(cws_http *request) { /* Check for keep-alive */ char conn[32] = "keep-alive"; - mcl_bucket *connection = mcl_hm_get(request->headers, "Connection"); + bucket_s *connection = hm_get(request->headers, "Connection"); if (connection && strcmp((char *)connection->value, "keep-alive") == 0) { strcpy(conn, "keep-alive"); keepalive = 0; } - mcl_hm_free_bucket(connection); + hm_free_bucket(connection); char *response = NULL; size_t response_len = cws_http_response_builder(&response, "HTTP/1.1", CWS_HTTP_OK, content_type, conn, file_data, content_length); @@ -295,7 +295,7 @@ int cws_http_send_resource(cws_http *request) { } int cws_http_get_content_type(cws_http *request, char *content_type) { - char *ptr = strrchr(mcl_string_cstr(request->location_path), '.'); + char *ptr = strrchr(string_cstr(request->location_path), '.'); if (ptr == NULL) { return -1; } @@ -334,12 +334,12 @@ void cws_http_send_simple_html(cws_http *request, cws_http_status status, char * size_t body_len = strlen(body); char conn[32] = "keep-alive"; - mcl_bucket *connection = mcl_hm_get(request->headers, "Connection"); + bucket_s *connection = hm_get(request->headers, "Connection"); if (connection) { strncpy(conn, (char *)connection->value, sizeof(conn) - 1); conn[sizeof(conn) - 1] = '\0'; } - mcl_hm_free_bucket(connection); + hm_free_bucket(connection); char *response = NULL; size_t response_len = cws_http_response_builder(&response, "HTTP/1.1", status, "text/html", conn, body, body_len); @@ -354,9 +354,9 @@ void cws_http_send_simple_html(cws_http *request, cws_http_status status, char * } void cws_http_free(cws_http *request) { - mcl_hm_free(request->headers); - mcl_string_free(request->http_version); - mcl_string_free(request->location); - mcl_string_free(request->location_path); + hm_free(request->headers); + string_free(request->http_version); + string_free(request->location); + string_free(request->location_path); free(request); } diff --git a/src/server/server.c b/src/server/server.c index ccb02a5..6d20067 100644 --- a/src/server/server.c +++ b/src/server/server.c @@ -108,7 +108,7 @@ cws_server_ret cws_server_loop(int server_fd, cws_config *config) { return ret; } - mcl_hashmap *clients = mcl_hm_init(my_int_hash_fn, my_int_equal_fn, my_int_free_key_fn, my_str_free_fn, sizeof(int), sizeof(char) * INET_ADDRSTRLEN); + hashmap_s *clients = hm_new(my_int_hash_fn, my_int_equal_fn, my_int_free_key_fn, my_str_free_fn, sizeof(int), sizeof(char) * INET_ADDRSTRLEN); if (clients == NULL) { return CWS_SERVER_HASHMAP_INIT; } @@ -117,7 +117,7 @@ cws_server_ret cws_server_loop(int server_fd, cws_config *config) { size_t workers_index = 0; cws_worker **workers = cws_worker_init(workers_num, clients, config); if (workers == NULL) { - mcl_hm_free(clients); + hm_free(clients); return CWS_SERVER_WORKER_ERROR; } @@ -145,7 +145,7 @@ cws_server_ret cws_server_loop(int server_fd, cws_config *config) { /* Add client to worker */ int random = 10; - mcl_hm_set(clients, &client_fd, &random); + hm_set(clients, &client_fd, &random); write(workers[workers_index]->pipefd[1], &client_fd, sizeof(int)); workers_index = (workers_index + 1) % workers_num; } @@ -154,12 +154,12 @@ cws_server_ret cws_server_loop(int server_fd, cws_config *config) { close(epfd); cws_worker_free(workers, workers_num); - mcl_hm_free(clients); + hm_free(clients); return CWS_SERVER_OK; } -int cws_server_handle_new_client(int server_fd, mcl_hashmap *clients) { +int cws_server_handle_new_client(int server_fd, hashmap_s *clients) { struct sockaddr_storage their_sa; socklen_t theirsa_size = sizeof their_sa; char ip[INET_ADDRSTRLEN]; diff --git a/src/server/worker.c b/src/server/worker.c index b2f3749..5cee690 100644 --- a/src/server/worker.c +++ b/src/server/worker.c @@ -34,7 +34,7 @@ static int cws_worker_setup_epoll(cws_worker *worker) { return 0; } -cws_worker **cws_worker_init(size_t workers_num, mcl_hashmap *clients, cws_config *config) { +cws_worker **cws_worker_init(size_t workers_num, hashmap_s *clients, cws_config *config) { cws_worker **workers = malloc(sizeof(cws_worker) * workers_num); if (workers == NULL) { return NULL; @@ -117,12 +117,12 @@ void *cws_worker_loop(void *arg) { return NULL; } -void cws_server_close_client(int epfd, int client_fd, mcl_hashmap *clients) { - mcl_bucket *client = mcl_hm_get(clients, &client_fd); +void cws_server_close_client(int epfd, int client_fd, hashmap_s *clients) { + bucket_s *client = hm_get(clients, &client_fd); if (client) { cws_epoll_del(epfd, client_fd); - mcl_hm_remove(clients, &client_fd); - mcl_hm_free_bucket(client); + hm_remove(clients, &client_fd); + hm_free_bucket(client); } } @@ -151,12 +151,12 @@ cws_server_ret cws_epoll_del(int epfd, int sockfd) { return CWS_SERVER_OK; } -static size_t cws_read_data(int sockfd, mcl_string **str) { +static size_t cws_read_data(int sockfd, string_s **str) { size_t total_bytes = 0; ssize_t bytes_read; if (*str == NULL) { - *str = mcl_string_new("", 4096); + *str = string_new("", 4096); } char tmp[4096]; @@ -180,19 +180,19 @@ static size_t cws_read_data(int sockfd, mcl_string **str) { } total_bytes += bytes_read; - mcl_string_append(*str, tmp); + string_append(*str, tmp); } return total_bytes; } -cws_server_ret cws_server_handle_client_data(int epfd, int client_fd, mcl_hashmap *clients, cws_config *config) { +cws_server_ret cws_server_handle_client_data(int epfd, int client_fd, hashmap_s *clients, cws_config *config) { /* Read data from socket */ - mcl_string *data = NULL; + string_s *data = NULL; size_t total_bytes = cws_read_data(client_fd, &data); if (total_bytes <= 0) { if (data) { - mcl_string_free(data); + string_free(data); } cws_server_close_client(epfd, client_fd, clients); @@ -201,7 +201,7 @@ cws_server_ret cws_server_handle_client_data(int epfd, int client_fd, mcl_hashma /* Parse HTTP request */ cws_http *request = cws_http_parse(data, client_fd, config); - mcl_string_free(data); + string_free(data); if (request == NULL) { cws_server_close_client(epfd, client_fd, clients);