From 1e80839864a31a5ecb062cc0ea234d35900dcbdc Mon Sep 17 00:00:00 2001 From: Quinten Date: Thu, 25 Sep 2025 17:51:37 +0200 Subject: [PATCH] refactor(ServerConfig): update directive parsing and improve server socket binding --- webserv/client/Client.cpp | 2 +- webserv/config/ServerConfig.cpp | 194 ++++++++++++++---------- webserv/config/ServerConfig.hpp | 23 +-- webserv/config/directive/ADirective.hpp | 3 +- webserv/server/Server.cpp | 4 +- 5 files changed, 132 insertions(+), 94 deletions(-) diff --git a/webserv/client/Client.cpp b/webserv/client/Client.cpp index 3e0e4ed..9fe9cec 100644 --- a/webserv/client/Client.cpp +++ b/webserv/client/Client.cpp @@ -80,7 +80,7 @@ std::string Client::getResponse() const } // further validation can be added here response += "Content-Length: 18\r\n\r\n"; - response += "Server port " + std::to_string(server_config_.getPort()) + "\r\n"; + response += "Server port 8080\r\n"; Log::debug("Sending response:\n" + response); return response; diff --git a/webserv/config/ServerConfig.cpp b/webserv/config/ServerConfig.cpp index 22c4656..353e34c 100644 --- a/webserv/config/ServerConfig.cpp +++ b/webserv/config/ServerConfig.cpp @@ -2,6 +2,9 @@ #include #include // for findCorrespondingClosingBrace, trim #include // for Log, LOCATION +#include // for DirectiveFactory +#include // for ADirective + #include // for size_t #include // for basic_istringstream, basic_istream, istringstream @@ -54,92 +57,123 @@ void ServerConfig::parseServerBlock(const std::string &block) parseDirectives(serverDeclarations); } +// void ServerConfig::parseDirectives(const std::string &declarations) +// { +// Log::info("Parsing server directives"); +// std::string line; +// std::istringstream stream(declarations); +// while (std::getline(stream, line)) +// { +// std::string directive; +// std::istringstream lineStream{line}; +// lineStream >> directive; +// if (!directive.empty()) +// { +// std::string value; +// lineStream >> value; +// if (directive == "listen") +// { + +// port_ = std::stoi(value); +// if (port_ < 1 || port_ > 65535) +// { +// throw std::runtime_error("Invalid port number: " + std::to_string(port_)); +// } +// Log::debug("Set port to " + std::to_string(port_)); +// } +// else if (directive == "root") +// { +// root_ = value; +// Log::debug("Set root to " + root_); +// } +// else if (directive == "host") +// { +// host_ = value; +// Log::debug("Set host to " + host_); +// } +// else if (directive == "cgi_pass") +// { +// cgi_pass_ = value; +// Log::debug("Set cgi_pass to " + cgi_pass_); +// } +// else if (directive == "cgi_ext") +// { +// cgi_ext_ = value; +// Log::debug("Set cgi_ext to " + cgi_ext_); +// } +// else if (directive == "index") +// { +// index_files_.clear(); +// std::string indexFile; +// while (lineStream >> indexFile) +// { +// index_files_.push_back(indexFile); +// Log::debug("Added index file: " + indexFile); +// } +// } +// else if (directive == "error_page") +// { +// int statusCode = std::stoi("-1"); +// std::string errorPagePath; +// lineStream >> errorPagePath; +// Log::debug("Set error_page for status " + std::to_string(statusCode) + " to " + errorPagePath); +// } +// else +// { +// Log::warning("Unknown directive: " + directive); +// } +// } +// } +// } + +// const LocationConfig &ServerConfig::getLocation(const std::string &path) const +// { +// if (locations_.count(path) > 0) // NOLINT +// { +// return locations_.at(path); +// } +// Log::error("Location not found: " + path); +// throw std::runtime_error("Location not found: " + path); +// } + +// std::vector ServerConfig::getLocationPaths() const +// { +// std::vector paths; +// paths.reserve(locations_.size()); +// for (const auto &pair : locations_) +// { +// paths.push_back(pair.first); +// } +// return paths; +// } + void ServerConfig::parseDirectives(const std::string &declarations) { - Log::info("Parsing server directives"); + Log::trace(LOCATION); + std::stringstream ss(declarations); std::string line; - std::istringstream stream(declarations); - while (std::getline(stream, line)) + while (ss.good()) { - std::string directive; - std::istringstream lineStream{line}; - lineStream >> directive; - if (!directive.empty()) + std::getline(ss, line); + line = utils::trim(line); + if (line.empty()) { - std::string value; - lineStream >> value; - if (directive == "listen") - { + continue; + } + auto directive = DirectiveFactory::createDirective(line); + directives_.push_back(std::move(directive)); + } + Log::info("Parsed " + std::to_string(directives_.size()) + " directives.", {{"declarations", declarations}}); +} - port_ = std::stoi(value); - if (port_ < 1 || port_ > 65535) - { - throw std::runtime_error("Invalid port number: " + std::to_string(port_)); - } - Log::debug("Set port to " + std::to_string(port_)); - } - else if (directive == "root") - { - root_ = value; - Log::debug("Set root to " + root_); - } - else if (directive == "host") - { - host_ = value; - Log::debug("Set host to " + host_); - } - else if (directive == "cgi_pass") - { - cgi_pass_ = value; - Log::debug("Set cgi_pass to " + cgi_pass_); - } - else if (directive == "cgi_ext") - { - cgi_ext_ = value; - Log::debug("Set cgi_ext to " + cgi_ext_); - } - else if (directive == "index") - { - index_files_.clear(); - std::string indexFile; - while (lineStream >> indexFile) - { - index_files_.push_back(indexFile); - Log::debug("Added index file: " + indexFile); - } - } - else if (directive == "error_page") - { - int statusCode = std::stoi("-1"); - std::string errorPagePath; - lineStream >> errorPagePath; - Log::debug("Set error_page for status " + std::to_string(statusCode) + " to " + errorPagePath); - } - else - { - Log::warning("Unknown directive: " + directive); - } +DirectiveValue ServerConfig::operator[](const std::string &directive) const +{ + for (const auto& dir : directives_) + { + if (dir->getName() == directive) + { + return dir->get(); } } -} - -const LocationConfig &ServerConfig::getLocation(const std::string &path) const -{ - if (locations_.count(path) > 0) // NOLINT - { - return locations_.at(path); - } - Log::error("Location not found: " + path); - throw std::runtime_error("Location not found: " + path); -} - -std::vector ServerConfig::getLocationPaths() const -{ - std::vector paths; - paths.reserve(locations_.size()); - for (const auto &pair : locations_) - { - paths.push_back(pair.first); - } - return paths; + throw std::runtime_error("Directive not found: " + directive); } \ No newline at end of file diff --git a/webserv/config/ServerConfig.hpp b/webserv/config/ServerConfig.hpp index 127f7f0..3738ad9 100644 --- a/webserv/config/ServerConfig.hpp +++ b/webserv/config/ServerConfig.hpp @@ -1,8 +1,10 @@ #pragma once +#include "webserv/config/directive/ADirective.hpp" #include #include +#include #include #include @@ -12,22 +14,24 @@ class ServerConfig public: ServerConfig(const std::string &serverBlock); - [[nodiscard]] const std::string &getHost() const { return host_; } + // [[nodiscard]] const std::string &getHost() const { return host_; } - [[nodiscard]] int getPort() const { return port_; } + // [[nodiscard]] int getPort() const { return port_; } - [[nodiscard]] const std::string &getRoot() const { return root_; } + // [[nodiscard]] const std::string &getRoot() const { return root_; } - [[nodiscard]] const std::string &getCgiPass() const { return cgi_pass_; } + // [[nodiscard]] const std::string &getCgiPass() const { return cgi_pass_; } - [[nodiscard]] const std::string &getCgiExt() const { return cgi_ext_; } + // [[nodiscard]] const std::string &getCgiExt() const { return cgi_ext_; } - [[nodiscard]] const std::map &getErrorPages() const { return error_page_; } + // [[nodiscard]] const std::map &getErrorPages() const { return error_page_; } - [[nodiscard]] const std::vector &getIndexFiles() const { return index_files_; } + // [[nodiscard]] const std::vector &getIndexFiles() const { return index_files_; } - [[nodiscard]] const LocationConfig &getLocation(const std::string &path) const; - [[nodiscard]] std::vector getLocationPaths() const; + // [[nodiscard]] const LocationConfig &getLocation(const std::string &path) const; + // [[nodiscard]] std::vector getLocationPaths() const; + + DirectiveValue operator[](const std::string &directive) const; private: std::string host_; @@ -38,6 +42,7 @@ class ServerConfig std::map error_page_; std::vector index_files_; std::map locations_; + std::vector> directives_; void parseServerBlock(const std::string &block); void parseDirectives(const std::string &declarations); diff --git a/webserv/config/directive/ADirective.hpp b/webserv/config/directive/ADirective.hpp index c2350d2..681574f 100644 --- a/webserv/config/directive/ADirective.hpp +++ b/webserv/config/directive/ADirective.hpp @@ -1,7 +1,6 @@ #pragma once #include -#include #include class DirectiveValue @@ -40,7 +39,7 @@ class ADirective void setName(const std::string &name); protected: - std::string name_; + std::string name_; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes) }; // Supported directives: diff --git a/webserv/server/Server.cpp b/webserv/server/Server.cpp index bfed7ea..0e97869 100644 --- a/webserv/server/Server.cpp +++ b/webserv/server/Server.cpp @@ -87,7 +87,7 @@ void Server::setupServerSocket(const ServerConfig &config) try { std::unique_ptr serverSocket = std::make_unique(); - serverSocket->bind(config.getHost(), config.getPort()); + serverSocket->bind(config["host"], config["listen"]); serverSocket->listen(SOMAXCONN); int server_fd = serverSocket->getFd(); @@ -95,7 +95,7 @@ void Server::setupServerSocket(const ServerConfig &config) listeners_.push_back(std::move(serverSocket)); fdToConfig_.insert({server_fd, std::cref(config)}); - Log::info("Server listening on " + config.getHost() + ":" + std::to_string(config.getPort()) + "..."); + // Log::info("Server listening on " + std::string(config["host"]) + ":" + static_cast(config["listen"]) + "..."); } catch (const std::exception &e) {