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; + } + } +}