From 3b83159707622ed6881c01db63a48137b9b56a31 Mon Sep 17 00:00:00 2001 From: adjoly Date: Mon, 17 Mar 2025 12:01:30 +0100 Subject: [PATCH 01/10] =?UTF-8?q?=E3=80=8C=F0=9F=8F=97=EF=B8=8F=E3=80=8D?= =?UTF-8?q?=20wip:=20Added=20example=20of=20config=20file=20need=20review?= =?UTF-8?q?=20&&=20added=20tomlpp=20to=20./lib=20in=20submodule?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitmodules | 3 +++ exemples/test.toml | 21 +++++++++++++++++++++ lib/tomlpp | 1 + 3 files changed, 25 insertions(+) create mode 100644 .gitmodules create mode 100644 exemples/test.toml create mode 160000 lib/tomlpp diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..228b417 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "lib/tomlpp"] + path = lib/tomlpp + url = https://github.com/keyzox71/tomlpp diff --git a/exemples/test.toml b/exemples/test.toml new file mode 100644 index 0000000..0c3b0ff --- /dev/null +++ b/exemples/test.toml @@ -0,0 +1,21 @@ +[server] +server_names = { "localhost", "2B5.local" } # can be a array or a str +port = { 8080, 8090 } # can be a array or a int + +root = "/nfs/adjoly/workspace/kanel.ovh" +max_post_size = "10M" + +cookies = true +uploads = false +dirlist = true + +methods = {"GET", "POST", "DELETE"} +index = "index.html" + +[server.error_page] +404 = "not_found.html" +401 = "unauthorized.html" +402 = "uwu.html" + +[server.cgi] +py = "/usr/bin/python3" diff --git a/lib/tomlpp b/lib/tomlpp new file mode 160000 index 0000000..05777d6 --- /dev/null +++ b/lib/tomlpp @@ -0,0 +1 @@ +Subproject commit 05777d656d0b0f499dc3ddf1e3a9b18eb819ada5 From 14bc77ab567ad5a7d1e86987f98c9061fa83b714 Mon Sep 17 00:00:00 2001 From: adjoly Date: Wed, 19 Mar 2025 14:02:35 +0100 Subject: [PATCH 02/10] =?UTF-8?q?=E3=80=8C=F0=9F=8E=89=E3=80=8D=20init:=20?= =?UTF-8?q?Started=20handling=20config?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 4 +-- lib/tomlpp | 2 +- src/main.cpp | 97 ++-------------------------------------------------- 3 files changed, 5 insertions(+), 98 deletions(-) diff --git a/Makefile b/Makefile index dceb576..9876588 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ # By: adjoly +#+ +:+ +#+ # # +#+#+#+#+#+ +#+ # # Created: 2024/10/25 16:09:27 by adjoly #+# #+# # -# Updated: 2025/02/03 16:43:32 by mmoussou ### ########.fr # +# Updated: 2025/03/19 14:01:12 by adjoly ### ########.fr # # # # **************************************************************************** # @@ -45,7 +45,7 @@ $(NAME): $(OBJS) $(OBJSDIR)%.o: %.cpp @mkdir -p $(@D) - @$(CC) $(FLAGS) -I$(INCLUDES) -c $< -o $@ + @$(CC) $(FLAGS) -I$(INCLUDES) -Ilib/tomlpp/includes -c $< -o $@ @printf "$(DELETE)$(GREEN)「🔨」 build($<): object compiled\n" clean: diff --git a/lib/tomlpp b/lib/tomlpp index 05777d6..0b51282 160000 --- a/lib/tomlpp +++ b/lib/tomlpp @@ -1 +1 @@ -Subproject commit 05777d656d0b0f499dc3ddf1e3a9b18eb819ada5 +Subproject commit 0b512825bc9166a04446cef5ff3a1026d53d4f3b diff --git a/src/main.cpp b/src/main.cpp index c718751..75636b5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6,101 +6,8 @@ /* By: mmoussou -#include - -#define PORT 8080 -#define BUFFER_SIZE 4096 - -int server_socket; - -void close_socket(int signal) -{ - close(server_socket); - exit(signal); -} - -int main() { - // handle ctrl-C to close server socket - if (signal(SIGINT, close_socket) == SIG_ERR) { - std::cerr << "Error registering signal handler!" << std::endl; - return 1; - } - - // create a socket - server_socket = socket(AF_INET, SOCK_STREAM, 0); - if (server_socket == -1) { - std::cerr << "Failed to create socket" << std::endl; - return 1; - } - - // prepare the server address - sockaddr_in server_address; - std::memset(&server_address, 0, sizeof(server_address)); - server_address.sin_family = AF_INET; - server_address.sin_addr.s_addr = INADDR_ANY; - server_address.sin_port = htons(PORT); - - // bind the socket to the address - if (bind(server_socket, (sockaddr*)&server_address, sizeof(server_address)) == -1) { - std::cerr << "Failed to bind socket" << std::endl; - return 1; - } - - // listen for incoming connections - if (listen(server_socket, 5) == -1) { - std::cerr << "Failed to listen on socket" << std::endl; - return 1; - } - - std::cout << "Server is listening on port " << PORT << std::endl; - - while (true) { - // accept an incoming connection - sockaddr_in client_address; - socklen_t client_address_len = sizeof(client_address); - int client_socket = accept(server_socket, (sockaddr*)&client_address, &client_address_len); - if (client_socket == -1) { - std::cerr << "Failed to accept connection" << std::endl; - continue; - } - - // receive the HTTP request - char buffer[BUFFER_SIZE]; - std::memset(buffer, 0, BUFFER_SIZE); - ssize_t bytes_received = recv(client_socket, buffer, BUFFER_SIZE - 1, 0); - if (bytes_received == -1) { - std::cerr << "Failed to receive request" << std::endl; - close(client_socket); - continue; - } - - // parse the request - std::string received_data(buffer, bytes_received); - //HttpRequest request = parseRequest(received_data); - http::Get request(received_data); - - std::cout << "Received " << request.getMethod() << " request for " << request.getTarget() << std::endl; - - // handle the request - std::string response; - if (request.getMethod() == "GET") - { - response = request.execute().str(); - } - else - { - response = "HTTP/1.1 501 Not Implemented\r\nContent-Type: text/html\r\n\r\n

501 Not Implemented

"; - } - - send(client_socket, response.c_str(), response.length(), 0); - close(client_socket); - } - - close(server_socket); - return 0; -} +#include From 43df2b18a71708f5633d8089e1c555b7663dacbb Mon Sep 17 00:00:00 2001 From: adjoly Date: Wed, 19 Mar 2025 15:52:31 +0100 Subject: [PATCH 03/10] =?UTF-8?q?=E3=80=8C=F0=9F=8F=97=EF=B8=8F=E3=80=8D?= =?UTF-8?q?=20wip:=20Started=20reading=20subject?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .clang-format | 5 +++++ exemples/test.toml | 38 +++++++++++++++++++++++--------- includes/config/AConfig.hpp | 25 +++++++++++++++++++++ includes/config/ARoute.hpp | 15 +++++++++++++ includes/config/ParsedConfig.hpp | 22 ++++++++++++++++++ includes/config/Route.hpp | 32 +++++++++++++++++++++++++++ includes/config/default.hpp | 16 ++++++++++++++ lib/tomlpp | 2 +- src/main.cpp | 4 +++- 9 files changed, 146 insertions(+), 13 deletions(-) create mode 100644 .clang-format create mode 100644 includes/config/AConfig.hpp create mode 100644 includes/config/ARoute.hpp create mode 100644 includes/config/ParsedConfig.hpp create mode 100644 includes/config/Route.hpp create mode 100644 includes/config/default.hpp diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..7a2deec --- /dev/null +++ b/.clang-format @@ -0,0 +1,5 @@ +UseTab: Always +IndentWidth: 4 +TabWidth: 4 +AlignConsecutiveDeclarations: true +ConstructorInitializerIndentWidth: 4 diff --git a/exemples/test.toml b/exemples/test.toml index 0c3b0ff..4db457e 100644 --- a/exemples/test.toml +++ b/exemples/test.toml @@ -1,21 +1,37 @@ [server] -server_names = { "localhost", "2B5.local" } # can be a array or a str -port = { 8080, 8090 } # can be a array or a int +server_names = { "localhost", "2B5.local" } +host = "localhost" +port = 8080 -root = "/nfs/adjoly/workspace/kanel.ovh" -max_post_size = "10M" +root = "/var/www/html" +methods = { "GET", "POST", "DELETE" } -cookies = true +dirlist = false uploads = false -dirlist = true +cookies = false -methods = {"GET", "POST", "DELETE"} -index = "index.html" +cgi_path = "/bin/php" +cgi_ext = ".php" -[server.error_page] +client_max_body_size = "10M" + +[server.error_pages] 404 = "not_found.html" 401 = "unauthorized.html" 402 = "uwu.html" -[server.cgi] -py = "/usr/bin/python3" +[server.location./] +methods = { "GET" } +root = "/var/www/html" +dirlist = true + +[server.location./api] +methods = { "GET", "POST" } +uploads = true +root = "/var/www/api" +upload_path = "/etc/webserv/up" +cgi_path = "/bin/go" +cgi_ext = ".go" + +[server.location./redir] +redirect = "https://kanel.ovh" diff --git a/includes/config/AConfig.hpp b/includes/config/AConfig.hpp new file mode 100644 index 0000000..ce612ab --- /dev/null +++ b/includes/config/AConfig.hpp @@ -0,0 +1,25 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* AConfig.hpp :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: adjoly +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/03/19 14:11:28 by adjoly #+# #+# */ +/* Updated: 2025/03/19 14:27:56 by adjoly ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#pragma once + +#include +#include +#include + +class AConfig { + public: + protected: + private: + std::vector serverNames; + std::map cgi; +}; diff --git a/includes/config/ARoute.hpp b/includes/config/ARoute.hpp new file mode 100644 index 0000000..db5a1e6 --- /dev/null +++ b/includes/config/ARoute.hpp @@ -0,0 +1,15 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ARoute.hpp :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: adjoly +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/03/19 14:59:41 by adjoly #+# #+# */ +/* Updated: 2025/03/19 15:52:16 by adjoly ### ########.fr */ +/* */ +/* ************************************************************************** */ + +class Route { + +}; diff --git a/includes/config/ParsedConfig.hpp b/includes/config/ParsedConfig.hpp new file mode 100644 index 0000000..05ba4f3 --- /dev/null +++ b/includes/config/ParsedConfig.hpp @@ -0,0 +1,22 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ParsedConfig.hpp :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: adjoly +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/03/19 14:11:28 by adjoly #+# #+# */ +/* Updated: 2025/03/19 15:52:16 by adjoly ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#pragma once + + +class config { + public: + protected: + private: + std::map cgi; + +}; diff --git a/includes/config/Route.hpp b/includes/config/Route.hpp new file mode 100644 index 0000000..6dbcaac --- /dev/null +++ b/includes/config/Route.hpp @@ -0,0 +1,32 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* Route.hpp :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: adjoly +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/03/19 14:59:41 by adjoly #+# #+# */ +/* Updated: 2025/03/19 15:52:16 by adjoly ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#pragma once + +#include + +namespace webserv { +namespace config { + +struct cgi { + std::string path; + std::string ext; +}; + +class Route { + public: + protected: + private: +}; + +} // namespace config +} // namespace webserv diff --git a/includes/config/default.hpp b/includes/config/default.hpp new file mode 100644 index 0000000..6337e52 --- /dev/null +++ b/includes/config/default.hpp @@ -0,0 +1,16 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* default.hpp :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: adjoly +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/03/19 14:15:51 by adjoly #+# #+# */ +/* Updated: 2025/03/19 14:16:39 by adjoly ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#pragma once + +#include +#include "Config.hpp" diff --git a/lib/tomlpp b/lib/tomlpp index 0b51282..d81ec4a 160000 --- a/lib/tomlpp +++ b/lib/tomlpp @@ -1 +1 @@ -Subproject commit 0b512825bc9166a04446cef5ff3a1026d53d4f3b +Subproject commit d81ec4a0baf2771e083f3514cb0b7794bbe68f42 diff --git a/src/main.cpp b/src/main.cpp index 75636b5..446d767 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6,8 +6,10 @@ /* By: mmoussou + +int main(int, char **) { return 0; } From 30951f436ca921a68cc4d51c22c72ffbdb213e47 Mon Sep 17 00:00:00 2001 From: adjoly Date: Wed, 19 Mar 2025 17:39:03 +0100 Subject: [PATCH 04/10] =?UTF-8?q?=E3=80=8C=F0=9F=8F=97=EF=B8=8F=E3=80=8D?= =?UTF-8?q?=20wip:=20Started=20route=20class?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- exemples/test.toml | 10 +++--- includes/config/ARoute.hpp | 15 -------- includes/config/ParsedConfig.hpp | 22 ------------ includes/config/Route.hpp | 38 ++++++++++++++++----- includes/config/{AConfig.hpp => Server.hpp} | 21 +++++++----- src/main.cpp | 6 ++-- 6 files changed, 52 insertions(+), 60 deletions(-) delete mode 100644 includes/config/ARoute.hpp delete mode 100644 includes/config/ParsedConfig.hpp rename includes/config/{AConfig.hpp => Server.hpp} (72%) diff --git a/exemples/test.toml b/exemples/test.toml index 4db457e..a61f6f4 100644 --- a/exemples/test.toml +++ b/exemples/test.toml @@ -10,8 +10,7 @@ dirlist = false uploads = false cookies = false -cgi_path = "/bin/php" -cgi_ext = ".php" +cgi.py = "/usr/bin/python3" client_max_body_size = "10M" @@ -24,14 +23,17 @@ client_max_body_size = "10M" methods = { "GET" } root = "/var/www/html" dirlist = true +client_max_body_size = "10M" + +[server.location./.error_pages] +500 = "uwu.html" [server.location./api] methods = { "GET", "POST" } uploads = true root = "/var/www/api" upload_path = "/etc/webserv/up" -cgi_path = "/bin/go" -cgi_ext = ".go" +cgi.go = "/bin/go" [server.location./redir] redirect = "https://kanel.ovh" diff --git a/includes/config/ARoute.hpp b/includes/config/ARoute.hpp deleted file mode 100644 index db5a1e6..0000000 --- a/includes/config/ARoute.hpp +++ /dev/null @@ -1,15 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* ARoute.hpp :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: adjoly +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2025/03/19 14:59:41 by adjoly #+# #+# */ -/* Updated: 2025/03/19 15:52:16 by adjoly ### ########.fr */ -/* */ -/* ************************************************************************** */ - -class Route { - -}; diff --git a/includes/config/ParsedConfig.hpp b/includes/config/ParsedConfig.hpp deleted file mode 100644 index 05ba4f3..0000000 --- a/includes/config/ParsedConfig.hpp +++ /dev/null @@ -1,22 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* ParsedConfig.hpp :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: adjoly +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2025/03/19 14:11:28 by adjoly #+# #+# */ -/* Updated: 2025/03/19 15:52:16 by adjoly ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#pragma once - - -class config { - public: - protected: - private: - std::map cgi; - -}; diff --git a/includes/config/Route.hpp b/includes/config/Route.hpp index 6dbcaac..6f3fff3 100644 --- a/includes/config/Route.hpp +++ b/includes/config/Route.hpp @@ -6,26 +6,46 @@ /* By: adjoly +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/03/19 14:59:41 by adjoly #+# #+# */ -/* Updated: 2025/03/19 15:52:16 by adjoly ### ########.fr */ +/* Updated: 2025/03/19 17:35:09 by adjoly ### ########.fr */ /* */ /* ************************************************************************** */ #pragma once +#include "cppeleven.hpp" +#include "node/ANode.hpp" +#include +#include #include +#include +#include namespace webserv { namespace config { -struct cgi { - std::string path; - std::string ext; -}; - class Route { - public: - protected: - private: + public: + Route(std::map *node) { + if (node == not_nullptr) + throw std::runtime_error("location table does not exist"); + std::map *errorPagesTable = (*node)["error_pages"]->getTable(); + if (errorPagesTable == not_nullptr) + throw std::runtime_error("error_pages not present"); + } + ~Route(void) {} + + protected: + private: + bool _dirlist; + bool _cookies; + bool _uploads; + bool _redirect; + int32_t _maxBody; + std::string _root; + std::string _upRoot; + std::map *_cgi; + std::vector *_methods; + std::map *_errPages; }; } // namespace config diff --git a/includes/config/AConfig.hpp b/includes/config/Server.hpp similarity index 72% rename from includes/config/AConfig.hpp rename to includes/config/Server.hpp index ce612ab..a6f37ff 100644 --- a/includes/config/AConfig.hpp +++ b/includes/config/Server.hpp @@ -1,25 +1,30 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* AConfig.hpp :+: :+: :+: */ +/* Server.hpp :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: adjoly +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/03/19 14:11:28 by adjoly #+# #+# */ -/* Updated: 2025/03/19 14:27:56 by adjoly ### ########.fr */ +/* Updated: 2025/03/19 16:54:35 by adjoly ### ########.fr */ /* */ /* ************************************************************************** */ #pragma once -#include -#include -#include +#include "Route.hpp" -class AConfig { +namespace webserv { +namespace config { + +class Server { public: protected: private: - std::vector serverNames; - std::map cgi; + Route *_default; + std::vector *_routes; }; + +} // namespace config + +} // namespace webserv diff --git a/src/main.cpp b/src/main.cpp index 446d767..9ced085 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6,10 +6,12 @@ /* By: mmoussou -int main(int, char **) { return 0; } +int main(int, char **) { + return 0; +} From 4153e6dcdbff10caa05703dd0ce7d467f53d470d Mon Sep 17 00:00:00 2001 From: adjoly Date: Thu, 20 Mar 2025 14:42:35 +0100 Subject: [PATCH 05/10] =?UTF-8?q?=E3=80=8C=F0=9F=8F=97=EF=B8=8F=E3=80=8D?= =?UTF-8?q?=20wip:=20Added=20logger=20class?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- includes/config/Route.hpp | 145 ++++++++++++++++++++++++++++++++++--- includes/config/Server.hpp | 8 +- includes/log.hpp | 82 +++++++++++++++++++++ 3 files changed, 221 insertions(+), 14 deletions(-) create mode 100644 includes/log.hpp diff --git a/includes/config/Route.hpp b/includes/config/Route.hpp index 6f3fff3..8edddc4 100644 --- a/includes/config/Route.hpp +++ b/includes/config/Route.hpp @@ -6,7 +6,7 @@ /* By: adjoly +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/03/19 14:59:41 by adjoly #+# #+# */ -/* Updated: 2025/03/19 17:35:09 by adjoly ### ########.fr */ +/* Updated: 2025/03/20 09:27:58 by adjoly ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,6 +14,10 @@ #include "cppeleven.hpp" #include "node/ANode.hpp" +#include "node/Array.hpp" +#include +#include +#include #include #include #include @@ -23,29 +27,148 @@ namespace webserv { namespace config { +int32_t parseSize(std::string size) { + if (size[size.size()] == 'M') + return std::atoi(size.c_str()) * 1024 * 1024; + if (size[size.size()] == 'K') + return std::atoi(size.c_str()) * 1024; + if (isalpha(size[size.size()])) + return std::atoi(size.c_str()); + return -1; +} + class Route { public: Route(std::map *node) { if (node == not_nullptr) throw std::runtime_error("location table does not exist"); - std::map *errorPagesTable = (*node)["error_pages"]->getTable(); - if (errorPagesTable == not_nullptr) - throw std::runtime_error("error_pages not present"); + + _methods[0] = false; + _methods[1] = false; + _methods[2] = false; + + std::map::iterator it; + + it = (*node).find("redirect"); + if (it != node->end()) { + toml::ANode *redirNode = it->second; + if (redirNode->type() == toml::STRING) { + _redirect = true; + _root = *(std::string *)redirNode->getValue(); + _cookies = false; + _uploads = false; + _dirlist = false; + _cgi = not_nullptr; + _methods[0] = false; + _methods[1] = false; + _methods[2] = false; + _err_pages = not_nullptr; + _upRoot = not_nullptr; + return; + } + } + + it = (*node).find("uploads"); + if (it != node->end()) { + toml::ANode *uploadsNode = it->second; + if (uploadsNode->type() == toml::BOOL) + _uploads = *(bool *)uploadsNode->getValue(); + } + it = (*node).find("dirlist"); + if (it != node->end()) { + toml::ANode *dirlistNode = it->second; + if (dirlistNode->type() == toml::BOOL) + _dirlist = *(bool *)dirlistNode->getValue(); + } + it = (*node).find("cookies"); + if (it != node->end()) { + toml::ANode *cookiesNode = it->second; + if (cookiesNode->type() == toml::BOOL) + _cookies = *(bool *)cookiesNode->getValue(); + } + it = (*node).find("root"); + if (it != node->end()) { + toml::ANode *rootNode = it->second; + if (rootNode->type() == toml::STRING) + _root = *(std::string *)rootNode->getValue(); + } + it = (*node).find("client_max_body_size"); + if (it != node->end()) { + toml::ANode *rootNode = it->second; + if (rootNode->type() == toml::STRING) { + int32_t maxBody = + parseSize(*(std::string *)rootNode->getValue()); + if (maxBody != 0 && maxBody != -1) + _max_body = maxBody; + else { + std::cerr << "root size is not correctttt" + << std::endl; /// change that later TODO + _max_body = 10485760; + } + } + } + + it = (*node).find("methods"); + if (it != node->end()) { + toml::ANode *methodsNode = it->second; + if (methodsNode->type() == toml::ARRAY) { + std::vector::iterator methods = + methodsNode->getArray()->begin(); + for (; methods != methodsNode->getArray()->end(); methods++) { + if ((*methods)->type() == toml::STRING) { + std::string method = + *(std::string *)(*methods)->getValue(); + if (method == "GET") + _methods[0] = true; + else if (method == "POST") + _methods[1] = true; + else if (method == "DELETE") + _methods[2] = true; + else + throw std::runtime_error("da fuk that not a valid " + "methods bro"); // replace + // with + // warning + // log + } else { + throw std::runtime_error( + "error why did you put something elle than a " + "string"); // replace with log func + } + } + } + } + + it = (*node).find("error_pages"); + if (it != node->end()) { + toml::ANode *errorPagesNode = it->second; + // for loop on it and add to error pages and atoi the name of the + // page(need to be a deep copy) TODO + } + + it = (*node).find("cgi"); + if (it != node->end()) { + toml::ANode *cgiNode = it->second; + // for loop on it and add to cgi (need to be a deep copy) TODO + } } ~Route(void) {} protected: private: - bool _dirlist; - bool _cookies; - bool _uploads; - bool _redirect; - int32_t _maxBody; + bool _dirlist; + bool _cookies; + bool _uploads; + bool _redirect; + + int32_t _max_body; + std::string _root; std::string _upRoot; std::map *_cgi; - std::vector *_methods; - std::map *_errPages; + + bool _methods[3]; // 1: GET, 2: POST, 3: DELETE + std::map *_err_pages; }; } // namespace config diff --git a/includes/config/Server.hpp b/includes/config/Server.hpp index a6f37ff..955354f 100644 --- a/includes/config/Server.hpp +++ b/includes/config/Server.hpp @@ -6,7 +6,7 @@ /* By: adjoly +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/03/19 14:11:28 by adjoly #+# #+# */ -/* Updated: 2025/03/19 16:54:35 by adjoly ### ########.fr */ +/* Updated: 2025/03/19 23:09:56 by adjoly ### ########.fr */ /* */ /* ************************************************************************** */ @@ -21,8 +21,10 @@ class Server { public: protected: private: - Route *_default; - std::vector *_routes; + Route *_default; + std::vector *_routes; + std::string host; + std::vector server_names; }; } // namespace config diff --git a/includes/log.hpp b/includes/log.hpp new file mode 100644 index 0000000..d863e80 --- /dev/null +++ b/includes/log.hpp @@ -0,0 +1,82 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* log.hpp :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: adjoly +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/03/20 09:28:27 by adjoly #+# #+# */ +/* Updated: 2025/03/20 14:42:26 by adjoly ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#pragma once + +#include +#include +#include +#include +#include + +namespace webserv { +class Logger { + public: + Logger(std::string fileName) { + if (fileName.empty()) + _ttyOnly = true; + else { + _file.open(fileName.c_str(), std::ios::app); + _ttyOnly = false; + } + if (!_file.is_open()) { + throw std::runtime_error("could not open fileeee"); // TODO change that shit but i dont know what to put other than a htrow + } + } + + ~Logger(void) { _file.close(); } + + void info(std::string &msg) { + std::stringstream ss = printPogitMsg("✏️", "webserv", "info", msg); + std::cerr << ss << std::endl; + if (!_ttyOnly) { + _file << ss << std::endl; + } + } + void warn(std::string &msg) { + std::stringstream ss = printPogitMsg("🔨", "webserv", "warning", msg); + std::cerr << ss << std::endl; + if (!_ttyOnly) { + _file << ss << std::endl; + } + + } + void error(std::string &msg) { + std::stringstream ss = printPogitMsg("🚧", "webserv", "error", msg); + std::cerr << ss << std::endl; + if (!_ttyOnly) { + _file << ss << std::endl; + } + } + + protected: + private: + std::stringstream printPogitMsg(std::string emoji, std::string type, std::string what, std::string msg) { + std::stringstream os; +#ifdef tty + if (what.empty()) + os << type << ":" << msg; + else + os << type << "(" << what << "):" << msg; +#else + if (what.empty()) + os << "「" << emoji << "」" << type << ":" << msg; + else + os << "「" << emoji << "」" << type << "(" << what << "):" << msg; +#endif + return os; + } + bool _ttyOnly; + std::ofstream _file; +}; + +}; // namespace webserv From 29cebdee0ed5c0764deb5ef9d5d8471b49b143a4 Mon Sep 17 00:00:00 2001 From: adjoly Date: Fri, 21 Mar 2025 11:09:48 +0100 Subject: [PATCH 06/10] =?UTF-8?q?=E3=80=8C=F0=9F=94=A8=E3=80=8D=20fix:=20r?= =?UTF-8?q?emoved=20trash=20code?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- includes/config/Route.hpp | 114 ++------------------------------------ includes/log.hpp | 8 +-- 2 files changed, 8 insertions(+), 114 deletions(-) diff --git a/includes/config/Route.hpp b/includes/config/Route.hpp index 8edddc4..777555b 100644 --- a/includes/config/Route.hpp +++ b/includes/config/Route.hpp @@ -6,13 +6,14 @@ /* By: adjoly +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/03/19 14:59:41 by adjoly #+# #+# */ -/* Updated: 2025/03/20 09:27:58 by adjoly ### ########.fr */ +/* Updated: 2025/03/21 11:09:38 by adjoly ### ########.fr */ /* */ /* ************************************************************************** */ #pragma once #include "cppeleven.hpp" +#include "log.hpp" #include "node/ANode.hpp" #include "node/Array.hpp" #include @@ -42,115 +43,6 @@ class Route { Route(std::map *node) { if (node == not_nullptr) throw std::runtime_error("location table does not exist"); - - _methods[0] = false; - _methods[1] = false; - _methods[2] = false; - - std::map::iterator it; - - it = (*node).find("redirect"); - if (it != node->end()) { - toml::ANode *redirNode = it->second; - if (redirNode->type() == toml::STRING) { - _redirect = true; - _root = *(std::string *)redirNode->getValue(); - _cookies = false; - _uploads = false; - _dirlist = false; - _cgi = not_nullptr; - _methods[0] = false; - _methods[1] = false; - _methods[2] = false; - _err_pages = not_nullptr; - _upRoot = not_nullptr; - return; - } - } - - it = (*node).find("uploads"); - if (it != node->end()) { - toml::ANode *uploadsNode = it->second; - if (uploadsNode->type() == toml::BOOL) - _uploads = *(bool *)uploadsNode->getValue(); - } - it = (*node).find("dirlist"); - if (it != node->end()) { - toml::ANode *dirlistNode = it->second; - if (dirlistNode->type() == toml::BOOL) - _dirlist = *(bool *)dirlistNode->getValue(); - } - it = (*node).find("cookies"); - if (it != node->end()) { - toml::ANode *cookiesNode = it->second; - if (cookiesNode->type() == toml::BOOL) - _cookies = *(bool *)cookiesNode->getValue(); - } - it = (*node).find("root"); - if (it != node->end()) { - toml::ANode *rootNode = it->second; - if (rootNode->type() == toml::STRING) - _root = *(std::string *)rootNode->getValue(); - } - it = (*node).find("client_max_body_size"); - if (it != node->end()) { - toml::ANode *rootNode = it->second; - if (rootNode->type() == toml::STRING) { - int32_t maxBody = - parseSize(*(std::string *)rootNode->getValue()); - if (maxBody != 0 && maxBody != -1) - _max_body = maxBody; - else { - std::cerr << "root size is not correctttt" - << std::endl; /// change that later TODO - _max_body = 10485760; - } - } - } - - it = (*node).find("methods"); - if (it != node->end()) { - toml::ANode *methodsNode = it->second; - if (methodsNode->type() == toml::ARRAY) { - std::vector::iterator methods = - methodsNode->getArray()->begin(); - for (; methods != methodsNode->getArray()->end(); methods++) { - if ((*methods)->type() == toml::STRING) { - std::string method = - *(std::string *)(*methods)->getValue(); - if (method == "GET") - _methods[0] = true; - else if (method == "POST") - _methods[1] = true; - else if (method == "DELETE") - _methods[2] = true; - else - throw std::runtime_error("da fuk that not a valid " - "methods bro"); // replace - // with - // warning - // log - } else { - throw std::runtime_error( - "error why did you put something elle than a " - "string"); // replace with log func - } - } - } - } - - it = (*node).find("error_pages"); - if (it != node->end()) { - toml::ANode *errorPagesNode = it->second; - // for loop on it and add to error pages and atoi the name of the - // page(need to be a deep copy) TODO - } - - it = (*node).find("cgi"); - if (it != node->end()) { - toml::ANode *cgiNode = it->second; - // for loop on it and add to cgi (need to be a deep copy) TODO - } } ~Route(void) {} @@ -167,6 +59,8 @@ class Route { std::string _upRoot; std::map *_cgi; + Logger *_log; + bool _methods[3]; // 1: GET, 2: POST, 3: DELETE std::map *_err_pages; }; diff --git a/includes/log.hpp b/includes/log.hpp index d863e80..755147d 100644 --- a/includes/log.hpp +++ b/includes/log.hpp @@ -6,7 +6,7 @@ /* By: adjoly +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/03/20 09:28:27 by adjoly #+# #+# */ -/* Updated: 2025/03/20 14:42:26 by adjoly ### ########.fr */ +/* Updated: 2025/03/20 14:55:09 by adjoly ### ########.fr */ /* */ /* ************************************************************************** */ @@ -35,14 +35,14 @@ class Logger { ~Logger(void) { _file.close(); } - void info(std::string &msg) { + void info(std::string msg) { std::stringstream ss = printPogitMsg("✏️", "webserv", "info", msg); std::cerr << ss << std::endl; if (!_ttyOnly) { _file << ss << std::endl; } } - void warn(std::string &msg) { + void warn(std::string msg) { std::stringstream ss = printPogitMsg("🔨", "webserv", "warning", msg); std::cerr << ss << std::endl; if (!_ttyOnly) { @@ -50,7 +50,7 @@ class Logger { } } - void error(std::string &msg) { + void error(std::string msg) { std::stringstream ss = printPogitMsg("🚧", "webserv", "error", msg); std::cerr << ss << std::endl; if (!_ttyOnly) { From 3024aa398588e2664ed4a2bd87588fbfabf27e28 Mon Sep 17 00:00:00 2001 From: adjoly Date: Fri, 21 Mar 2025 20:01:38 +0100 Subject: [PATCH 07/10] =?UTF-8?q?=E3=80=8C=E2=9C=A8=E3=80=8D=20feat:=20Upd?= =?UTF-8?q?ated=20tomlpp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/tomlpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/tomlpp b/lib/tomlpp index d81ec4a..40d6a05 160000 --- a/lib/tomlpp +++ b/lib/tomlpp @@ -1 +1 @@ -Subproject commit d81ec4a0baf2771e083f3514cb0b7794bbe68f42 +Subproject commit 40d6a059a0fdf79e49686fe11af189256ad7fc37 From dbba3f0668611bc9327d6b0f78aa812982a91fca Mon Sep 17 00:00:00 2001 From: adjoly Date: Mon, 24 Mar 2025 10:52:02 +0100 Subject: [PATCH 08/10] =?UTF-8?q?=E3=80=8C=F0=9F=8F=97=EF=B8=8F=E3=80=8D?= =?UTF-8?q?=20wip:=20Nearly=20finished=20config=20file=20parsing?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- includes/config/Config.hpp | 19 +++++ includes/config/Route.hpp | 88 ++++++++++++++------ lib/tomlpp | 2 +- src/config/Route.cpp | 165 +++++++++++++++++++++++++++++++++++++ 4 files changed, 250 insertions(+), 24 deletions(-) create mode 100644 includes/config/Config.hpp create mode 100644 src/config/Route.cpp diff --git a/includes/config/Config.hpp b/includes/config/Config.hpp new file mode 100644 index 0000000..cc340c1 --- /dev/null +++ b/includes/config/Config.hpp @@ -0,0 +1,19 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* Config.hpp :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: adjoly +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/03/23 11:36:01 by adjoly #+# #+# */ +/* Updated: 2025/03/23 12:09:10 by adjoly ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#pragma once + +#include + +namespace webserv { +namespace config {}; +}; // namespace webserv diff --git a/includes/config/Route.hpp b/includes/config/Route.hpp index 777555b..43159d3 100644 --- a/includes/config/Route.hpp +++ b/includes/config/Route.hpp @@ -6,7 +6,7 @@ /* By: adjoly +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/03/19 14:59:41 by adjoly #+# #+# */ -/* Updated: 2025/03/21 11:09:38 by adjoly ### ########.fr */ +/* Updated: 2025/03/24 10:48:37 by adjoly ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,37 +14,20 @@ #include "cppeleven.hpp" #include "log.hpp" -#include "node/ANode.hpp" -#include "node/Array.hpp" -#include +#include "node/default.hpp" #include #include #include -#include #include #include -#include namespace webserv { namespace config { -int32_t parseSize(std::string size) { - if (size[size.size()] == 'M') - return std::atoi(size.c_str()) * 1024 * 1024; - if (size[size.size()] == 'K') - return std::atoi(size.c_str()) * 1024; - if (isalpha(size[size.size()])) - return std::atoi(size.c_str()); - return -1; -} - class Route { public: - Route(std::map *node) { - if (node == not_nullptr) - throw std::runtime_error("location table does not exist"); - } - ~Route(void) {} + Route(toml::ANode *, Logger *); + ~Route(void); protected: private: @@ -61,8 +44,67 @@ class Route { Logger *_log; - bool _methods[3]; // 1: GET, 2: POST, 3: DELETE - std::map *_err_pages; + bool _methods[3]; ///> A methods boolean array which correspond to - 0: GET, 1: POST, 2: DELETE + std::map *_err_pages; ///> An error pages map to map error specified in the config file + toml::ANode *_table; + + /** + * @brief Can be used to access a value in the _table(ANode *) of a specific type + * + * @param The name of the value to get + * @param The type of the value to get + * + * @return The value got or not_nullptr + */ + void *accessValue(std::string, toml::nodeType); + + + /** + * @brief Can be used to parse a table of cgi + * + * @param The table to get cgi from + * + * @return A pointer to a map of cgi + */ + std::map *_parseCGI(std::map *); + + /** + * @brief Can be used to parse a table of error pages + * + * @param The table to get the error pages from + * + * @return A pointer to a map of error pages + */ + std::map *_parseErrPages(std::map *); + + /** + * @brief Can be used to parse a array of methods + * + * @param The table to get the methods from + */ + void _parseMethods(std::vector *); + + /** + * @brief Can be used to sed err pages to the default error pages + */ + void _defaultErrPages(void); + + /** + * @brief Can be used to parse a string of a number with a size (ex. 10M) + * + * @param The input string + * + * @return The number in bytes + */ + int32_t _parseSize(std::string size) { + if (size[size.size()] == 'M') + return std::atoi(size.c_str()) * 1024 * 1024; + if (size[size.size()] == 'K') + return std::atoi(size.c_str()) * 1024; + if (isalpha(size[size.size()])) + return std::atoi(size.c_str()); + return -1; + } }; } // namespace config diff --git a/lib/tomlpp b/lib/tomlpp index 40d6a05..3131ed3 160000 --- a/lib/tomlpp +++ b/lib/tomlpp @@ -1 +1 @@ -Subproject commit 40d6a059a0fdf79e49686fe11af189256ad7fc37 +Subproject commit 3131ed3ac4f80a17e0175bff7a0084420cbb7410 diff --git a/src/config/Route.cpp b/src/config/Route.cpp new file mode 100644 index 0000000..0656360 --- /dev/null +++ b/src/config/Route.cpp @@ -0,0 +1,165 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* Route.cpp :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: adjoly +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/03/21 20:37:02 by adjoly #+# #+# */ +/* Updated: 2025/03/24 10:51:29 by adjoly ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "cppeleven.hpp" +#include "log.hpp" +#include "node/ANode.hpp" +#include "node/default.hpp" +#include +#include +#include + +using namespace webserv::config; + +std::map * +Route::_parseCGI(std::map *table) { + std::map *cgi = + new std::map; + void *val; + + for (std::map::iterator it = table->begin(); + it != table->end(); it++) { + val = accessValue(it->first, toml::STRING); + if (val != not_nullptr) + cgi->insert(it->first, *static_cast(val)); + } + + return cgi; +} + +std::map * +Route::_parseErrPages(std::map *table) { + std::map *errPages = new std::map; + void *val; + int nb; + + for (std::map::iterator it = table->begin(); + it != table->end(); it++) { + val = accessValue(it->first, toml::STRING); + if (val != not_nullptr) { + nb = std::atoi(it->first.c_str()); + if (nb != 0 && (nb >= 400 && nb <= 599)) + (*errPages)[nb] = *static_cast(val); + else + _log->warn("error page - " + it->first + " is not valid :("); + } + } + return errPages; +} + +void Route::_parseMethods(std::vector *table) { + std::string val; + + _methods[0] = false; + _methods[1] = false; + _methods[2] = false; + for (std::vector::iterator it = table->begin(); + it != table->end(); it++) { + if ((*it)->type() == toml::STRING) { + val = *static_cast((*it)->getValue()); + if (val == "GET") + _methods[0] = true; + if (val == "POST") + _methods[1] = true; + if (val == "DELETE") + _methods[2] = true; + } + } +} + +void Route::_defaultErrPages(void) { + _err_pages = new std::map; + + (*_err_pages)[400] = _root + "/400.html"; + (*_err_pages)[403] = _root + "/403.html"; + (*_err_pages)[404] = _root + "/404.html"; +} + +Route::Route(toml::ANode *table, Logger *logger) + : _max_body(10485760), _log(logger) { + void *val; + + _table = table; + _log = logger; + val = accessValue("redirect", toml::STRING); + if (val != not_nullptr) { + _root = *static_cast(val); + _redirect = true; + return; + } + val = accessValue("dirlist", toml::BOOL); + if (val != not_nullptr) + _dirlist = *static_cast(val); + else + _dirlist = true; + val = accessValue("cookies", toml::BOOL); + if (val != not_nullptr) + _cookies = *static_cast(val); + else + _cookies = false; + val = accessValue("uploads", toml::BOOL); + if (val != not_nullptr) + _uploads = *static_cast(val); + val = accessValue("root", toml::STRING); + if (val != not_nullptr) + _root = *static_cast(val); + else +#ifdef PKGS + _root = "/var/www/html" +#else + _root = "./html"; +#endif + val = accessValue("upload_path", toml::STRING); + if (val != not_nullptr) + _upRoot = *static_cast(val); + val = accessValue("client_max_body_size", toml::STRING); + if (val != not_nullptr) + _max_body = _parseSize(*static_cast(val)); + val = accessValue("cgi", toml::TABLE); + if (val != not_nullptr) + _cgi = + _parseCGI(static_cast *>(val)); + else + _cgi = not_nullptr; + val = accessValue("error_pages", toml::TABLE); + if (val != not_nullptr) + _err_pages = _parseErrPages( + static_cast *>(val)); + else + _err_pages = _defaultErrPages(); + val = accessValue("methods", toml::ARRAY); + if (val != not_nullptr) + _parseMethods(static_cast *>(val)); + else { + _methods[0] = true; + _methods[1] = false; + _methods[2] = false; + } +} + +void *Route::accessValue(std::string name, toml::nodeType type) { + void *val; + bool found; + + val = _table->access(name, type, found); + if (val != not_nullptr) { + return val; + } else { + if (found == false) { + return not_nullptr; + } else { + _log->warn("found - " + name + " but is not " + + toml::nodeTypeToStr(type) + ", skipping..."); + return not_nullptr; + } + } +} From 1f18956cb6b8ec171d20e4d4addc072d6254d3df Mon Sep 17 00:00:00 2001 From: adjoly Date: Wed, 26 Mar 2025 08:48:33 +0100 Subject: [PATCH 09/10] =?UTF-8?q?=E3=80=8C=E2=9C=A8=E3=80=8D=20feat:=20Fin?= =?UTF-8?q?ished=20parsing=20(should=20be=20working)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 4 +- exemples/test.toml | 15 --- includes/{config/Config.hpp => cgi.hpp} | 20 ++-- includes/config/Route.hpp | 33 ++---- includes/config/Server.hpp | 73 +++++++++++- includes/config/default.hpp | 46 +++++++- includes/log.hpp | 65 ++++++++--- lib/tomlpp | 2 +- src/config/Route.cpp | 127 ++++++++------------- src/config/Server.cpp | 145 ++++++++++++++++++++++++ src/main.cpp | 4 +- 11 files changed, 384 insertions(+), 150 deletions(-) rename includes/{config/Config.hpp => cgi.hpp} (70%) create mode 100644 src/config/Server.cpp diff --git a/Makefile b/Makefile index 9876588..f191630 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ # By: adjoly +#+ +:+ +#+ # # +#+#+#+#+#+ +#+ # # Created: 2024/10/25 16:09:27 by adjoly #+# #+# # -# Updated: 2025/03/19 14:01:12 by adjoly ### ########.fr # +# Updated: 2025/03/25 18:13:53 by adjoly ### ########.fr # # # # **************************************************************************** # @@ -24,7 +24,7 @@ SRCS = $(shell find . -name '*.cpp') OBJS = $(addprefix $(OBJSDIR), $(SRCS:.cpp=.o)) -FLAGS = -Wall -Werror -Wextra -std=c++98 -MMD -MP +FLAGS = -Wall -Werror -Wextra -std=c++98 -MMD -MP -g RED = \033[0;31m GREEN = \033[0;32m diff --git a/exemples/test.toml b/exemples/test.toml index a61f6f4..777ed4b 100644 --- a/exemples/test.toml +++ b/exemples/test.toml @@ -3,17 +3,6 @@ server_names = { "localhost", "2B5.local" } host = "localhost" port = 8080 -root = "/var/www/html" -methods = { "GET", "POST", "DELETE" } - -dirlist = false -uploads = false -cookies = false - -cgi.py = "/usr/bin/python3" - -client_max_body_size = "10M" - [server.error_pages] 404 = "not_found.html" 401 = "unauthorized.html" @@ -25,12 +14,8 @@ root = "/var/www/html" dirlist = true client_max_body_size = "10M" -[server.location./.error_pages] -500 = "uwu.html" - [server.location./api] methods = { "GET", "POST" } -uploads = true root = "/var/www/api" upload_path = "/etc/webserv/up" cgi.go = "/bin/go" diff --git a/includes/config/Config.hpp b/includes/cgi.hpp similarity index 70% rename from includes/config/Config.hpp rename to includes/cgi.hpp index cc340c1..90f9cce 100644 --- a/includes/config/Config.hpp +++ b/includes/cgi.hpp @@ -1,19 +1,23 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* Config.hpp :+: :+: :+: */ +/* cgi.hpp :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: adjoly +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ -/* Created: 2025/03/23 11:36:01 by adjoly #+# #+# */ -/* Updated: 2025/03/23 12:09:10 by adjoly ### ########.fr */ +/* Created: 2025/03/24 14:17:34 by adjoly #+# #+# */ +/* Updated: 2025/03/24 14:20:00 by adjoly ### ########.fr */ /* */ /* ************************************************************************** */ #pragma once -#include - -namespace webserv { -namespace config {}; -}; // namespace webserv +#include +class cgi { + public: + cgi(); + ~cgi(void); + protected: + private: + std::string _request; +}; diff --git a/includes/config/Route.hpp b/includes/config/Route.hpp index 43159d3..a09e6ed 100644 --- a/includes/config/Route.hpp +++ b/includes/config/Route.hpp @@ -6,7 +6,7 @@ /* By: adjoly +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/03/19 14:59:41 by adjoly #+# #+# */ -/* Updated: 2025/03/24 10:48:37 by adjoly ### ########.fr */ +/* Updated: 2025/03/26 08:31:41 by adjoly ### ########.fr */ /* */ /* ************************************************************************** */ @@ -33,31 +33,20 @@ class Route { private: bool _dirlist; bool _cookies; - bool _uploads; bool _redirect; int32_t _max_body; std::string _root; - std::string _upRoot; + std::string _up_root; + std::string _index; std::map *_cgi; Logger *_log; - bool _methods[3]; ///> A methods boolean array which correspond to - 0: GET, 1: POST, 2: DELETE - std::map *_err_pages; ///> An error pages map to map error specified in the config file - toml::ANode *_table; - - /** - * @brief Can be used to access a value in the _table(ANode *) of a specific type - * - * @param The name of the value to get - * @param The type of the value to get - * - * @return The value got or not_nullptr - */ - void *accessValue(std::string, toml::nodeType); - + bool _methods[3]; ///> A methods boolean array which correspond to - 0: GET, + ///1: POST, 2: DELETE + toml::ANode *_table; /** * @brief Can be used to parse a table of cgi @@ -66,7 +55,8 @@ class Route { * * @return A pointer to a map of cgi */ - std::map *_parseCGI(std::map *); + std::map * + _parseCGI(toml::ANode *); /** * @brief Can be used to parse a table of error pages @@ -75,19 +65,20 @@ class Route { * * @return A pointer to a map of error pages */ - std::map *_parseErrPages(std::map *); + std::map * + _parseErrPages(std::map *); /** * @brief Can be used to parse a array of methods * * @param The table to get the methods from */ - void _parseMethods(std::vector *); + void _parseMethods(std::vector *); /** * @brief Can be used to sed err pages to the default error pages */ - void _defaultErrPages(void); + void _defaultErrPages(void); /** * @brief Can be used to parse a string of a number with a size (ex. 10M) diff --git a/includes/config/Server.hpp b/includes/config/Server.hpp index 955354f..34c3964 100644 --- a/includes/config/Server.hpp +++ b/includes/config/Server.hpp @@ -6,25 +6,86 @@ /* By: adjoly +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/03/19 14:11:28 by adjoly #+# #+# */ -/* Updated: 2025/03/19 23:09:56 by adjoly ### ########.fr */ +/* Updated: 2025/03/25 17:56:34 by adjoly ### ########.fr */ /* */ /* ************************************************************************** */ #pragma once -#include "Route.hpp" +#include "config/default.hpp" +#include "cppeleven.hpp" +#include "node/ANode.hpp" namespace webserv { namespace config { class Server { public: + Server(std::string); + ~Server(); + + /** + * @brief Can be used to get the path of a specific error page or return + * an empty string + * + * @param The http error code for the page + */ + std::string getErrorPage(int page) { + if (_err_pages->find(page) != _err_pages->end()) + return (*_err_pages)[page]; + else + return ""; + } + + /** + * @brief Can be used to get a pointer to a specific route (or not_nullptr + * if not found) + */ + Route *getRoute(std::string route) { + if (_routes->find(route) != _routes->end()) + return (*_routes)[route]; + else + return not_nullptr; + } + + /** + * @brief Can be used to get the Logger pointer + */ + Logger *getLogger(void) { return _log; } + + // @brief Can be used to get a server name + std::vector *getServerNames(void) { return _server_names; } + // @brief Can be used to get the host specified in the config file + std::string getHost(void) { return _host; } + // @brief Can be used to get the port specified in the config file + int getPort(void) { return _port; } + protected: private: - Route *_default; - std::vector *_routes; - std::string host; - std::vector server_names; + std::map + *_routes; ///> A map of all the route present in the config file + std::map *_err_pages; ///> An error pages map to map error + /// specified in the config file + + std::vector + *_server_names; ///> A vector with all the server names + + std::string _host; ///> The host on which the server will be exposed + unsigned short _port; ///> The port on which the server will be exposed + + toml::ANode *_table; ///> The table used for the parsing (is deleted at the + /// end of the constructor) + Logger *_log; ///> A pointer to the logger class + + std::map * + _parseErrPages(std::map *table); + + /** + * @brief Can be used to get the [server] table in _table + * + * @return A pointer to the [server] table as an ANode + */ + toml::ANode *_getServerTable(void); }; } // namespace config diff --git a/includes/config/default.hpp b/includes/config/default.hpp index 6337e52..5ff94dc 100644 --- a/includes/config/default.hpp +++ b/includes/config/default.hpp @@ -6,11 +6,53 @@ /* By: adjoly +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/03/19 14:15:51 by adjoly #+# #+# */ -/* Updated: 2025/03/19 14:16:39 by adjoly ### ########.fr */ +/* Updated: 2025/03/26 08:39:08 by adjoly ### ########.fr */ /* */ /* ************************************************************************** */ #pragma once +#include "Route.hpp" +#include "Server.hpp" +#include "cppeleven.hpp" +#include "node/Table.hpp" +#include "node/default.hpp" #include -#include "Config.hpp" + +namespace webserv { +namespace config { + +/** + * @brief Can be used to access a value in the _table(ANode *) of a specific + *type + * + * @param The name of the value to get + * @param The type of the value to get + * @param The table to search in + * @param A Logger class + * + * @return The value got or not_nullptr + */ +static inline void *accessValue(const std::string &name, toml::nodeType type, + toml::ANode *table, Logger *log) { + void *val; + bool found = false; + + if (table == not_nullptr) + return not_nullptr; + val = dynamic_cast(table)->access(name, type, found); + if (found == true && val != not_nullptr) { + return val; + } else { + if (found == false) { + return not_nullptr; + } else { + log->warn("found - " + name + " but is not " + + toml::nodeTypeToStr(type) + ", skipping..."); + return not_nullptr; + } + } +} + +}; // namespace config +}; // namespace webserv diff --git a/includes/log.hpp b/includes/log.hpp index 755147d..df5e305 100644 --- a/includes/log.hpp +++ b/includes/log.hpp @@ -6,7 +6,7 @@ /* By: adjoly +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/03/20 09:28:27 by adjoly #+# #+# */ -/* Updated: 2025/03/20 14:55:09 by adjoly ### ########.fr */ +/* Updated: 2025/03/25 17:50:45 by adjoly ### ########.fr */ /* */ /* ************************************************************************** */ @@ -21,37 +21,69 @@ namespace webserv { class Logger { public: - Logger(std::string fileName) { + Logger(const std::string &fileName) : _fileName(fileName) { if (fileName.empty()) _ttyOnly = true; else { _file.open(fileName.c_str(), std::ios::app); _ttyOnly = false; } - if (!_file.is_open()) { - throw std::runtime_error("could not open fileeee"); // TODO change that shit but i dont know what to put other than a htrow + if (!_file.is_open() && !_ttyOnly) { + throw std::runtime_error( + "could not open fileeee"); // TODO change that shit but i dont + // know what to put other than a + // htrow } } - ~Logger(void) { _file.close(); } + Logger(const Logger &other) : _ttyOnly(other._ttyOnly) { + if (!other._ttyOnly) { + _file.open(other._fileName.c_str(), std::ios::app); + if (!_file.is_open()) { + throw std::runtime_error("Could not open file: " + + other._fileName); + } + } + } - void info(std::string msg) { - std::stringstream ss = printPogitMsg("✏️", "webserv", "info", msg); + // Copy assignment operator + Logger &operator=(const Logger &other) { + if (this != &other) { + if (_file.is_open()) { + _file.close(); + } + _ttyOnly = other._ttyOnly; + if (!other._ttyOnly) { + _file.open(other._fileName.c_str(), std::ios::app); + if (!_file.is_open()) { + throw std::runtime_error("Could not open file: " + + other._fileName); + } + } + } + return *this; + } + ~Logger(void) { + if (_file.is_open()) + _file.close(); + } + + void info(const std::string &msg) { + std::string ss = printPogitMsg("✏️", "webserv", "info", msg); std::cerr << ss << std::endl; if (!_ttyOnly) { _file << ss << std::endl; } } - void warn(std::string msg) { - std::stringstream ss = printPogitMsg("🔨", "webserv", "warning", msg); + void warn(const std::string &msg) { + std::string ss = printPogitMsg("🔨", "webserv", "warning", msg); std::cerr << ss << std::endl; if (!_ttyOnly) { _file << ss << std::endl; } - } - void error(std::string msg) { - std::stringstream ss = printPogitMsg("🚧", "webserv", "error", msg); + void error(const std::string &msg) { + std::string ss = printPogitMsg("🚧", "webserv", "error", msg); std::cerr << ss << std::endl; if (!_ttyOnly) { _file << ss << std::endl; @@ -60,7 +92,10 @@ class Logger { protected: private: - std::stringstream printPogitMsg(std::string emoji, std::string type, std::string what, std::string msg) { + std::string printPogitMsg(const std::string &emoji, + const std::string &type, + const std::string &what, + const std::string &msg) { std::stringstream os; #ifdef tty if (what.empty()) @@ -73,8 +108,10 @@ class Logger { else os << "「" << emoji << "」" << type << "(" << what << "):" << msg; #endif - return os; + return os.str(); } + + std::string _fileName; bool _ttyOnly; std::ofstream _file; }; diff --git a/lib/tomlpp b/lib/tomlpp index 3131ed3..d9e5070 160000 --- a/lib/tomlpp +++ b/lib/tomlpp @@ -1 +1 @@ -Subproject commit 3131ed3ac4f80a17e0175bff7a0084420cbb7410 +Subproject commit d9e507093a3b37d35d5115d766e6d81044cacb00 diff --git a/src/config/Route.cpp b/src/config/Route.cpp index 0656360..db52d41 100644 --- a/src/config/Route.cpp +++ b/src/config/Route.cpp @@ -1,61 +1,42 @@ -/* ************************************************************************** */ -/* */ /* ::: :::::::: */ /* Route.cpp :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: adjoly +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/03/21 20:37:02 by adjoly #+# #+# */ -/* Updated: 2025/03/24 10:51:29 by adjoly ### ########.fr */ +/* Updated: 2025/03/26 08:19:25 by adjoly ### ########.fr */ /* */ /* ************************************************************************** */ #include "cppeleven.hpp" #include "log.hpp" -#include "node/ANode.hpp" #include "node/default.hpp" -#include +#include #include #include using namespace webserv::config; -std::map * -Route::_parseCGI(std::map *table) { +std::map *Route::_parseCGI(toml::ANode *table) { std::map *cgi = new std::map; void *val; - for (std::map::iterator it = table->begin(); - it != table->end(); it++) { - val = accessValue(it->first, toml::STRING); - if (val != not_nullptr) - cgi->insert(it->first, *static_cast(val)); + for (std::map::iterator it = + table->getTable()->begin(); + it != table->getTable()->end(); it++) { + val = accessValue(it->first, toml::STRING, table, _log); + if (val != not_nullptr) { + if (cgi->find(it->first) != cgi->end()) + continue; + else + (*cgi)[it->first] = *static_cast(val); + } } return cgi; } -std::map * -Route::_parseErrPages(std::map *table) { - std::map *errPages = new std::map; - void *val; - int nb; - - for (std::map::iterator it = table->begin(); - it != table->end(); it++) { - val = accessValue(it->first, toml::STRING); - if (val != not_nullptr) { - nb = std::atoi(it->first.c_str()); - if (nb != 0 && (nb >= 400 && nb <= 599)) - (*errPages)[nb] = *static_cast(val); - else - _log->warn("error page - " + it->first + " is not valid :("); - } - } - return errPages; -} - void Route::_parseMethods(std::vector *table) { std::string val; @@ -76,40 +57,46 @@ void Route::_parseMethods(std::vector *table) { } } -void Route::_defaultErrPages(void) { - _err_pages = new std::map; - - (*_err_pages)[400] = _root + "/400.html"; - (*_err_pages)[403] = _root + "/403.html"; - (*_err_pages)[404] = _root + "/404.html"; -} - Route::Route(toml::ANode *table, Logger *logger) : _max_body(10485760), _log(logger) { void *val; + bool found; - _table = table; _log = logger; - val = accessValue("redirect", toml::STRING); + _table = table; + if (_table->type() != toml::TABLE) { + _log->warn("location need to be a table and not a :" + + toml::nodeTypeToStr(_table->type())); + return; + } + val = accessValue("redirect", toml::STRING, _table, _log); if (val != not_nullptr) { _root = *static_cast(val); _redirect = true; return; - } - val = accessValue("dirlist", toml::BOOL); + } else + _redirect = false; + val = accessValue("dirlist", toml::BOOL, _table, _log); if (val != not_nullptr) _dirlist = *static_cast(val); else _dirlist = true; - val = accessValue("cookies", toml::BOOL); + val = accessValue("cookies", toml::BOOL, _table, _log); if (val != not_nullptr) _cookies = *static_cast(val); - else + else _cookies = false; - val = accessValue("uploads", toml::BOOL); + val = accessValue("upload_path", toml::STRING, _table, _log); if (val != not_nullptr) - _uploads = *static_cast(val); - val = accessValue("root", toml::STRING); + _up_root = *static_cast(val); + else + _up_root = ""; + val = accessValue("index", toml::STRING, _table, _log); + if (val != not_nullptr) + _index = *static_cast(val); + else + _index = "index.html"; + val = accessValue("root", toml::STRING, _table, _log); if (val != not_nullptr) _root = *static_cast(val); else @@ -118,25 +105,17 @@ Route::Route(toml::ANode *table, Logger *logger) #else _root = "./html"; #endif - val = accessValue("upload_path", toml::STRING); - if (val != not_nullptr) - _upRoot = *static_cast(val); - val = accessValue("client_max_body_size", toml::STRING); + val = + accessValue("client_max_body_size", toml::STRING, _table, _log); if (val != not_nullptr) _max_body = _parseSize(*static_cast(val)); - val = accessValue("cgi", toml::TABLE); - if (val != not_nullptr) - _cgi = - _parseCGI(static_cast *>(val)); + std::map::iterator it = + _table->accessIt("cgi", toml::TABLE, found); + if (found == true && it != _table->getTable()->end()) + _cgi = _parseCGI(it->second); else _cgi = not_nullptr; - val = accessValue("error_pages", toml::TABLE); - if (val != not_nullptr) - _err_pages = _parseErrPages( - static_cast *>(val)); - else - _err_pages = _defaultErrPages(); - val = accessValue("methods", toml::ARRAY); + val = accessValue("methods", toml::ARRAY, _table, _log); if (val != not_nullptr) _parseMethods(static_cast *>(val)); else { @@ -146,20 +125,8 @@ Route::Route(toml::ANode *table, Logger *logger) } } -void *Route::accessValue(std::string name, toml::nodeType type) { - void *val; - bool found; - - val = _table->access(name, type, found); - if (val != not_nullptr) { - return val; - } else { - if (found == false) { - return not_nullptr; - } else { - _log->warn("found - " + name + " but is not " + - toml::nodeTypeToStr(type) + ", skipping..."); - return not_nullptr; - } - } +Route::~Route(void) { + if (_redirect == false) + if (_cgi != not_nullptr) + delete _cgi; } diff --git a/src/config/Server.cpp b/src/config/Server.cpp new file mode 100644 index 0000000..06b4e77 --- /dev/null +++ b/src/config/Server.cpp @@ -0,0 +1,145 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* Server.cpp :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: adjoly +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/03/24 15:10:07 by adjoly #+# #+# */ +/* Updated: 2025/03/26 08:47:50 by adjoly ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "config/Server.hpp" +#include "config/Route.hpp" +#include "cppeleven.hpp" +#include "log.hpp" +#include "node/ANode.hpp" +#include "node/Table.hpp" +#include "node/default.hpp" +#include "tomlpp.hpp" +#include +#include +#include +#include + +using namespace webserv::config; + +toml::ANode *Server::_getServerTable(void) { + toml::ANode *serverT; + + std::map::iterator table = + _table->getTable()->find("server"); + if (table == _table->getTable()->end()) + throw std::runtime_error( + "could not find any [server] table in config file :("); + else + serverT = table->second; + return serverT; +} + +Server::Server(std::string file_name) { + toml::Toml *tomlFile = new toml::Toml(file_name); + + try { + tomlFile->parse(); + } catch (std::runtime_error &e) { + throw e; + } + bool found; + + std::map *map; + _table = tomlFile->getParsedFile(); + + void *val = _table->access("log_file", toml::STRING, found); + std::string log_file = ""; + if (found == true && val != not_nullptr) { + std::string log_file = *static_cast(val); + } + _log = new Logger(log_file); + _table = _getServerTable(); + + // host and port parsing + void *host = accessValue("host", toml::STRING, _table, _log); + if (host != not_nullptr) { + _host = *static_cast(host); + } else { + throw std::runtime_error( + "no host specified - please specify one in server.host"); + } + void *port = accessValue("port", toml::INT, _table, _log); + if (host != not_nullptr) { + _port = *static_cast(port); + } else { + throw std::runtime_error( + "no port specified - please specify one in server.port"); + } + + // server_names parsing + std::map::iterator it = + _table->accessIt("server_names", toml::ARRAY, found); + if (found == true && it != _table->getTable()->end()) { + std::vector::iterator vecIt = + it->second->getArray()->begin(); + _server_names = new std::vector; + for (; vecIt != it->second->getArray()->end(); vecIt++) { + std::string str = *static_cast((*vecIt)->getValue()); + _server_names->push_back(str); + } + } else + _log->warn( + "no server_names all request will be accepted from any hostname"); + + // error_pages parsing + map = static_cast *>( + accessValue("error_pages", toml::TABLE, _table, _log)); + if (map != not_nullptr) { + _err_pages = _parseErrPages(map); + } else + _err_pages = not_nullptr; + + // location parsing + it = _table->accessIt("location", toml::TABLE, found); + if (found == true && it != _table->getTable()->end()) { + _routes = new std::map; + std::map *location_table = it->second->getTable(); + for (it = location_table->begin(); it != location_table->end(); it++) { + if (_routes->find(it->first) != _routes->end()) + continue; + (*_routes)[it->first] = new Route(it->second, _log); + } + } + delete tomlFile->getParsedFile(); + delete tomlFile; +} + +Server::~Server(void) { + std::map::iterator it = _routes->begin(); + for (; it != _routes->end(); it++) { + delete it->second; + } + delete _routes; + delete _err_pages; + delete _server_names; + delete _log; // to see if nessecary +} + +std::map * +Server::_parseErrPages(std::map *table) { + std::map *errPages = new std::map; + void *val; + int nb; + + for (std::map::iterator it = table->begin(); + it != table->end(); it++) { + val = accessValue(it->first, toml::STRING, _table, _log); + if (val != not_nullptr) { + nb = std::atoi(it->first.c_str()); + if (nb >= 400 && nb <= 599) + (*errPages)[nb] = *static_cast(val); + else + _log->warn("error page - " + it->first + " is not valid :("); + } + } + return errPages; +} diff --git a/src/main.cpp b/src/main.cpp index 9ced085..7af2e1d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6,12 +6,14 @@ /* By: mmoussou int main(int, char **) { + webserv::config::Server serverConf("exemples/test.toml"); return 0; } From 479cc85543262db81d6b86947d83bcf2f8fbf871 Mon Sep 17 00:00:00 2001 From: Adam <45126464+KeyZox71@users.noreply.github.com> Date: Sat, 29 Mar 2025 13:24:47 +0100 Subject: [PATCH 10/10] Create .clang-format --- .clang-format | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .clang-format diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..7a2deec --- /dev/null +++ b/.clang-format @@ -0,0 +1,5 @@ +UseTab: Always +IndentWidth: 4 +TabWidth: 4 +AlignConsecutiveDeclarations: true +ConstructorInitializerIndentWidth: 4