diff --git a/arquivo.conf b/arquivo.conf new file mode 100644 index 0000000..d136441 --- /dev/null +++ b/arquivo.conf @@ -0,0 +1,60 @@ +server { + server_name server.com; + listen 127.0.0.1:4242; + error_page 403 error_pages/403.html; + error_page 404 error_pages/404.html; + error_page 405 error_pages/405.html; + error_page 413 error_pages/413.html; + error_page 500 error_pages/500.html; + client_max_body_size 100000; + + location / { + autoindex on; + allow_methods GET POST DELETE; + root web_root; + upload_dir web_root/uploads + index index.html index.php; + cgi .php cgi-bin/php-cgi; + } + + location /potato/ { + autoindex on; + root web_root; + allow_methods GET POST DELETE; + } + + location /redirect/ { + return 301 https://google.com; + } + +} +server { + server_name server2.com; + listen 127.0.0.1:4242; + error_page 403 error_pages/403.html; + error_page 404 error_pages/404.html; + error_page 405 error_pages/405.html; + error_page 413 error_pages/413.html; + error_page 500 error_pages/500.html; + client_max_body_size 100; + + location / { + autoindex off; + allow_methods GET POST; + root web_root; + upload_dir web_root/uploads + index index.html index.php; + cgi .php cgi-bin/php-cgi; + } + + location /potato2/ { + autoindex on; + root web_root; + allow_methods GET; + } + + location /redirect/ { + return 301 https://google.com; + } + +} \ No newline at end of file diff --git a/include/Config.hpp b/include/Config.hpp new file mode 100644 index 0000000..83d45c3 --- /dev/null +++ b/include/Config.hpp @@ -0,0 +1,42 @@ +#ifndef CONFIG_HPP +#define CONFIG_HPP + +#include "common.hpp" + +struct LocationConfig { + std::string path; + bool autoindex; + std::vector allow_methods; + std::string root; + std::string upload_dir; + std::vector index; + std::string cgi_extension; + std::string cgi_path; + std::string redirect; +}; + +struct ServerConfig { + std::string server_name; + std::string listen; + std::map error_pages; + size_t client_max_body_size; + std::vector locations; +}; + +class Config { + public: + Config(const std::string &filePath); + const std::vector& getServers() const; + void printServers() const; + + private: + std::string filePath; + std::vector servers; + + void parseConfigFile(); + void parseServerBlock(const std::vector &lines, size_t &index); + void parseLocationBlock(const std::vector &lines, size_t &index, ServerConfig &server); + std::string trim(const std::string& str); +}; + +#endif diff --git a/src/Config.cpp b/src/Config.cpp new file mode 100644 index 0000000..89df398 --- /dev/null +++ b/src/Config.cpp @@ -0,0 +1,147 @@ +#include "Config.hpp" + +Config::Config(const std::string& filePath) : filePath(filePath) { + parseConfigFile(); +} + +void Config::parseConfigFile() { + std::ifstream configFile(filePath.c_str()); + if (!configFile.is_open()) { + std::cerr << "Error opening config file: " << filePath << std::endl; + return; + } + + std::string line; + std::vector lines; + while (std::getline(configFile, line)) + lines.push_back(line); + size_t index = 0; + while (index < lines.size()) { + std::string trimmedLine = trim(lines[index]); + if (trimmedLine == "server {") + parseServerBlock(lines, index); + ++index; + } +} + +void Config::parseServerBlock(const std::vector& lines, size_t& index) { + ServerConfig server; + + while (++index < lines.size()) { + std::string trimmedLine = trim(lines[index]); + if (trimmedLine == "}") + break; + else if (trimmedLine.find("server_name") == 0) + server.server_name = trimmedLine.substr(12); + else if (trimmedLine.find("listen") == 0) { + std::istringstream iss(trimmedLine.substr(7)); + iss >> server.listen; + } + else if (trimmedLine.find("client_max_body_size") == 0) { + std::istringstream iss(trimmedLine.substr(21)); + iss >> server.client_max_body_size; + } + else if (trimmedLine.find("error_page") == 0) { + size_t pos = trimmedLine.find(' ', 11); + int errorCode; + std::istringstream iss(trimmedLine.substr(11, pos - 11)); + iss >> errorCode; + std::string errorPage = trimmedLine.substr(pos + 1); + server.error_pages[errorCode] = errorPage; + } + else if (trimmedLine.find("location") == 0) + parseLocationBlock(lines, index, server); + } + + servers.push_back(server); +} + + +void Config::parseLocationBlock(const std::vector& lines, size_t& index, ServerConfig& server) { + LocationConfig location; + + size_t pos = lines[index].find(' '); + location.path = lines[index].substr(pos + 1); + + while (++index < lines.size()) { + std::string trimmedLine = trim(lines[index]); + if (trimmedLine == "}") + break; + else if (trimmedLine.find("autoindex") == 0) + location.autoindex = (trimmedLine.substr(10) == "on"); + else if (trimmedLine.find("root") == 0) + location.root = trimmedLine.substr(5); + else if (trimmedLine.find("upload_dir") == 0) + location.upload_dir = trimmedLine.substr(11); + else if (trimmedLine.find("index") == 0) { + std::istringstream iss(trimmedLine.substr(6)); + std::string idx; + while (iss >> idx) + location.index.push_back(idx); + } + else if (trimmedLine.find("allow_methods") == 0) { + std::istringstream iss(trimmedLine.substr(14)); + std::string method; + while (iss >> method) + location.allow_methods.push_back(method); + } + else if (trimmedLine.find("cgi_extension") == 0) + location.cgi_extension = trimmedLine.substr(14); + else if (trimmedLine.find("cgi_path") == 0) + location.cgi_path = trimmedLine.substr(9); + else if (trimmedLine.find("redirect") == 0) + location.redirect = trimmedLine.substr(9); + } + + server.locations.push_back(location); +} + +std::string Config::trim(const std::string& str) { + size_t first = 0; + size_t last = str.size() - 1; + + while (first <= last && std::isspace(str[first])) + ++first; + while (last >= first && std::isspace(str[last])) + --last; + if (first > last) + return ""; + return str.substr(first, last - first + 1); +} + +void Config::printServers() const { + std::cout << "Number of servers: " << servers.size() << "\n\n"; + for (size_t i = 0; i < servers.size(); ++i) { + const ServerConfig& server = servers[i]; + std::cout << "Server Name: " << server.server_name << "\n"; + std::cout << "Listen: " << server.listen << "\n"; + std::cout << "Client Max Body Size: " << server.client_max_body_size << "\n"; + + for (std::map::const_iterator it = server.error_pages.begin(); it != server.error_pages.end(); ++it) { + std::cout << "Error Page " << it->first << ": " << it->second << "\n"; + } + + for (size_t j = 0; j < server.locations.size(); ++j) { + const LocationConfig& location = server.locations[j]; + std::cout << "Location: " << location.path << "\n"; + std::cout << " Autoindex: " << (location.autoindex ? "on" : "off") << "\n"; + std::cout << " Root: " << location.root << "\n"; + std::cout << " Upload Dir: " << location.upload_dir << "\n"; + std::cout << " Index: "; + for (size_t k = 0; k < location.index.size(); ++k) + std::cout << location.index[k] << " "; + std::cout << "\n"; + std::cout << " Allow Methods: "; + for (size_t k = 0; k < location.allow_methods.size(); ++k) + std::cout << location.allow_methods[k] << " "; + std::cout << "\n"; + if (!location.cgi_extension.empty()) { + std::cout << " CGI Extension: " << location.cgi_extension << "\n"; + std::cout << " CGI Path: " << location.cgi_path << "\n"; + } + if (!location.redirect.empty()) + std::cout << " Redirect: " << location.redirect << "\n"; + } + std::cout << "\n"; + } +} diff --git a/src/main.cpp b/src/main.cpp index c5a1b76..1055a26 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,11 +2,15 @@ int main(void) { - try { - Server server("127.0.0.1", PORT); - server.run(); - } catch (std::exception &e) { - std::cerr << RED("Error: ") << e.what() << std::endl; - } - return 0; + Config config("arquivo.conf"); + config.printServers(); + + + // try { + // Server server("127.0.0.1", PORT); + // server.run(); + // } catch (std::exception &e) { + // std::cerr << RED("Error: ") << e.what() << std::endl; + // } + // return 0; }