diff --git a/webserv/config/ServerConfig.cpp b/webserv/config/ServerConfig.cpp index 353e34c..69e62c2 100644 --- a/webserv/config/ServerConfig.cpp +++ b/webserv/config/ServerConfig.cpp @@ -163,7 +163,13 @@ void ServerConfig::parseDirectives(const std::string &declarations) auto directive = DirectiveFactory::createDirective(line); directives_.push_back(std::move(directive)); } - Log::info("Parsed " + std::to_string(directives_.size()) + " directives.", {{"declarations", declarations}}); + Log::info("Parsed " + std::to_string(directives_.size()) + " directives."); + for (const auto &dir : directives_) + { + std::stringstream debugStream; + debugStream << "Directive parsed: " << *dir; + Log::debug(debugStream.str()); + } } DirectiveValue ServerConfig::operator[](const std::string &directive) const diff --git a/webserv/config/directive/ADirective.cpp b/webserv/config/directive/ADirective.cpp index 9c2a8c8..aed7e9c 100644 --- a/webserv/config/directive/ADirective.cpp +++ b/webserv/config/directive/ADirective.cpp @@ -1,4 +1,4 @@ -#include // for ADirective +#include DirectiveValue ADirective::get() const { @@ -13,4 +13,11 @@ std::string ADirective::getName() const void ADirective::setName(const std::string &name) { name_ = name; -} \ No newline at end of file +} + +// Non-member stream operator implementations +std::ostream &operator<<(std::ostream &os, const DirectiveValue &dv) +{ + return os << dv.toString(); +} + diff --git a/webserv/config/directive/ADirective.hpp b/webserv/config/directive/ADirective.hpp index 681574f..1685624 100644 --- a/webserv/config/directive/ADirective.hpp +++ b/webserv/config/directive/ADirective.hpp @@ -1,18 +1,10 @@ #pragma once -#include +#include +#include #include -class DirectiveValue -{ - public: - DirectiveValue(std::any value) : value_(value) {} - template operator T() const { return std::any_cast(value_); } - - private: - std::any value_; -}; class ADirective { @@ -26,36 +18,19 @@ class ADirective ADirective(ADirective &&other) noexcept = delete; ADirective &operator=(ADirective &&other) noexcept = delete; - virtual ~ADirective() {} - - virtual void parse(const std::string &value) = 0; - - [[nodiscard]] virtual std::any getValue() const = 0; - - [[nodiscard]] DirectiveValue get() const; - - [[nodiscard]] std::string getName() const; + virtual ~ADirective() = default; void setName(const std::string &name); + virtual void parse(const std::string &value) = 0; + + [[nodiscard]] virtual DirectiveValueType getValue() const = 0; + [[nodiscard]] DirectiveValue get() const; + [[nodiscard]] std::string getName() const; + // [[nodiscard]] std::string toString() const; protected: - std::string name_; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes) + std::string name_; }; -// Supported directives: - -// - listen INT {server} -// - host STRING {server} -// - server_name STRING {server} -// - root STRING {server, location} -// - index STRING[] {server, location} -// - error_page INT STIRNG {server, location} -// - client_max_body_size SIZE {server, location} -// - autoindex BOOL {location} -// - allowed_methods STRING[] {location} -// - cgi_pass STRING {location} -// - cgi_ext STRING[] {location} -// - cgi_timout INT {location} -// - upload_enabled BOOL {location} -// - upload_store STRING {location} -// - redirect INT STRING {location} \ No newline at end of file +// Non-member stream operator for ADirective +std::ostream &operator<<(std::ostream &os, const ADirective &directive); \ No newline at end of file diff --git a/webserv/config/directive/BoolDirective.cpp b/webserv/config/directive/BoolDirective.cpp index 34f4b9a..731455d 100644 --- a/webserv/config/directive/BoolDirective.cpp +++ b/webserv/config/directive/BoolDirective.cpp @@ -24,7 +24,7 @@ void BoolDirective::parse(const std::string &arg) } } -std::any BoolDirective::getValue() const +DirectiveValueType BoolDirective::getValue() const { return value_; } \ No newline at end of file diff --git a/webserv/config/directive/BoolDirective.hpp b/webserv/config/directive/BoolDirective.hpp index baf2af3..ff84b81 100644 --- a/webserv/config/directive/BoolDirective.hpp +++ b/webserv/config/directive/BoolDirective.hpp @@ -20,7 +20,7 @@ class BoolDirective : public ADirective void parse(const std::string &value) override; - [[nodiscard]] std::any getValue() const override; + [[nodiscard]] DirectiveValueType getValue() const override; private: bool value_ = false; diff --git a/webserv/config/directive/DirectiveFactory.cpp b/webserv/config/directive/DirectiveFactory.cpp index 76df3e2..a9f77bd 100644 --- a/webserv/config/directive/DirectiveFactory.cpp +++ b/webserv/config/directive/DirectiveFactory.cpp @@ -3,10 +3,14 @@ #include // for DirectiveFactory #include #include +#include #include #include #include // for trim, findCorrespondingClosingBrace, trimSemi #include // for Log +#include + + std::unique_ptr DirectiveFactory::createDirective(const std::string &line) { @@ -57,6 +61,8 @@ const std::unordered_map &Direc [](const std::string &name, const std::string &arg) { return std::make_unique(name, arg); }}, {"StringDirective", [](const std::string &name, const std::string &arg) { return std::make_unique(name, arg); }}, + {"IntStringDirective", + [](const std::string &name, const std::string &arg) { return std::make_unique(name, arg); }}, {"VectorDirective", [](const std::string &name, const std::string &arg) { return std::make_unique(name, arg); }}, }; diff --git a/webserv/config/directive/DirectiveFactory.hpp b/webserv/config/directive/DirectiveFactory.hpp index d7eed66..2bf6348 100644 --- a/webserv/config/directive/DirectiveFactory.hpp +++ b/webserv/config/directive/DirectiveFactory.hpp @@ -29,7 +29,7 @@ class DirectiveFactory {.name = "server_name", .type = "VectorDirective", .context = "SL"}, {.name = "root", .type = "StringDirective", .context = "SL"}, {.name = "index", .type = "VectorDirective", .context = "SL"}, - {.name = "error_page", .type = "VectorDirective", .context = "SL"}, + {.name = "error_page", .type = "IntStringDirective", .context = "SL"}, {.name = "client_max_body_size", .type = "SizeDirective", .context = "SL"}, {.name = "autoindex", .type = "BoolDirective", .context = "L"}, {.name = "allowed_methods", .type = "VectorDirective", .context = "L"}, diff --git a/webserv/config/directive/DirectiveValue.cpp b/webserv/config/directive/DirectiveValue.cpp new file mode 100644 index 0000000..9566bde --- /dev/null +++ b/webserv/config/directive/DirectiveValue.cpp @@ -0,0 +1,58 @@ +#include +#include + +#include +#include +#include // for is_same_v, decay_t +#include // for pair, move +#include // for variant, visit +#include // for vector + +std::string DirectiveValue::toString() const +{ + return std::visit( + [](const auto &val) -> std::string { + using T = std::decay_t; + + if constexpr (std::is_same_v || std::is_same_v) + { + return std::to_string(val); + } + else if constexpr (std::is_same_v) + { + return val; + } + else if constexpr (std::is_same_v) + { + return val ? "true" : "false"; + } + else if constexpr (std::is_same_v>) + { + std::string result = "["; + for (size_t i = 0; i < val.size(); ++i) + { + if (i > 0) + { + result += ", "; + } + result += "\"" + val[i] + "\""; + } + result += "]"; + return result; + } + else if constexpr (std::is_same_v>) + { + return std::to_string(val.first) + " \"" + val.second + "\""; + } + else + { + return ""; + } + }, + value_); +} + +std::ostream &operator<<(std::ostream &os, const ADirective &directive) +{ + return os << directive.getName() << ": " << directive.get().toString(); +} \ No newline at end of file diff --git a/webserv/config/directive/DirectiveValue.hpp b/webserv/config/directive/DirectiveValue.hpp new file mode 100644 index 0000000..a2f97d5 --- /dev/null +++ b/webserv/config/directive/DirectiveValue.hpp @@ -0,0 +1,36 @@ +#pragma once + +#include // for size_t +#include // for ostream, operator<< +#include // for string, basic_string, char_traits, to_string +#include // for variant, visit, get, holds_alternative +#include // for vector +#include // for pair, move + +// Define all possible directive value types +using DirectiveValueType = std::variant, // index, allowed_methods, cgi_ext + std::pair // error_page (status, path), redirect + >; + +class DirectiveValue +{ + public: + DirectiveValue(DirectiveValueType value) : value_(std::move(value)) {} + + template T get() const { return std::get(value_); } + + template [[nodiscard]] bool holds() const { return std::holds_alternative(value_); } + + [[nodiscard]] std::string toString() const; + + + private: + DirectiveValueType value_; +}; + +// Non-member stream operator for DirectiveValue +std::ostream &operator<<(std::ostream &os, const DirectiveValue &dv); diff --git a/webserv/config/directive/IntDirective.cpp b/webserv/config/directive/IntDirective.cpp index 87fefb2..ceace88 100644 --- a/webserv/config/directive/IntDirective.cpp +++ b/webserv/config/directive/IntDirective.cpp @@ -7,7 +7,7 @@ void IntDirective::parse(const std::string &value) value_ = std::stoi(value); // TODO: check parsing } -std::any IntDirective::getValue() const +DirectiveValueType IntDirective::getValue() const { return value_; } \ No newline at end of file diff --git a/webserv/config/directive/IntDirective.hpp b/webserv/config/directive/IntDirective.hpp index 38a1598..6c72611 100644 --- a/webserv/config/directive/IntDirective.hpp +++ b/webserv/config/directive/IntDirective.hpp @@ -20,7 +20,7 @@ class IntDirective : public ADirective void parse(const std::string &value) override; - [[nodiscard]] std::any getValue() const override; + [[nodiscard]] DirectiveValueType getValue() const override; private: int value_ = 0; diff --git a/webserv/config/directive/IntStringDirective.cpp b/webserv/config/directive/IntStringDirective.cpp new file mode 100644 index 0000000..f51b017 --- /dev/null +++ b/webserv/config/directive/IntStringDirective.cpp @@ -0,0 +1,21 @@ +#include "webserv/log/Log.hpp" +#include // for IntDirective +#include // for trim +#include // for std::getline, std::basic_istream, std::char_traits, std::basic_stringbuf + + +void IntStringDirective::parse(const std::string &value) +{ + std::istringstream iss(value); + int intPart = 0; + std::string strPart; + iss >> intPart; + std::getline(iss, strPart); + strPart = utils::trim(strPart); // Remove leading space + value_ = std::make_pair(intPart, strPart); +} + +DirectiveValueType IntStringDirective::getValue() const +{ + return value_; +} \ No newline at end of file diff --git a/webserv/config/directive/IntStringDirective.hpp b/webserv/config/directive/IntStringDirective.hpp new file mode 100644 index 0000000..3f14340 --- /dev/null +++ b/webserv/config/directive/IntStringDirective.hpp @@ -0,0 +1,27 @@ +#pragma once + +#include "ADirective.hpp" + +#include + +class IntStringDirective : public ADirective +{ + public: + IntStringDirective() = delete; + + IntStringDirective(const std::string &name, const std::string &value) : ADirective(name) { parse(value); } + + IntStringDirective(const IntStringDirective &other) = delete; + IntStringDirective &operator=(const IntStringDirective &other) = delete; + IntStringDirective(IntStringDirective &&other) noexcept = delete; + IntStringDirective &operator=(IntStringDirective &&other) noexcept = delete; + + ~IntStringDirective() override = default; + + void parse(const std::string &value) override; + + [[nodiscard]] DirectiveValueType getValue() const override; + + private: + std::pair value_ = {0, ""}; +}; \ No newline at end of file diff --git a/webserv/config/directive/SizeDirective.cpp b/webserv/config/directive/SizeDirective.cpp index cc29303..83e65de 100644 --- a/webserv/config/directive/SizeDirective.cpp +++ b/webserv/config/directive/SizeDirective.cpp @@ -43,7 +43,7 @@ void SizeDirective::parse(const std::string &value) value_ *= multiplier; } -std::any SizeDirective::getValue() const +DirectiveValueType SizeDirective::getValue() const { return value_; } \ No newline at end of file diff --git a/webserv/config/directive/SizeDirective.hpp b/webserv/config/directive/SizeDirective.hpp index 4ff77e8..e4df266 100644 --- a/webserv/config/directive/SizeDirective.hpp +++ b/webserv/config/directive/SizeDirective.hpp @@ -20,7 +20,7 @@ class SizeDirective : public ADirective void parse(const std::string &value) override; - [[nodiscard]] std::any getValue() const override; + [[nodiscard]] DirectiveValueType getValue() const override; private: size_t value_ = 0; diff --git a/webserv/config/directive/StringDirective.cpp b/webserv/config/directive/StringDirective.cpp index 7d94f79..12b910c 100644 --- a/webserv/config/directive/StringDirective.cpp +++ b/webserv/config/directive/StringDirective.cpp @@ -7,7 +7,7 @@ void StringDirective::parse(const std::string &value) value_ = value; } -std::any StringDirective::getValue() const +DirectiveValueType StringDirective::getValue() const { return value_; } \ No newline at end of file diff --git a/webserv/config/directive/StringDirective.hpp b/webserv/config/directive/StringDirective.hpp index 8a15684..1f0feb5 100644 --- a/webserv/config/directive/StringDirective.hpp +++ b/webserv/config/directive/StringDirective.hpp @@ -18,7 +18,7 @@ class StringDirective : public ADirective void parse(const std::string &value) override; - [[nodiscard]] std::any getValue() const override; + [[nodiscard]] DirectiveValueType getValue() const override; private: std::string value_; diff --git a/webserv/config/directive/VectorDirective.cpp b/webserv/config/directive/VectorDirective.cpp index 13146a5..758940a 100644 --- a/webserv/config/directive/VectorDirective.cpp +++ b/webserv/config/directive/VectorDirective.cpp @@ -6,10 +6,10 @@ void VectorDirective::parse(const std::string &value) { std::stringstream ss(value); - while(ss.good()) + while (ss.good()) { std::string item; - std::getline(ss, item, ' ');// index indx.html + std::getline(ss, item, ' '); // index indx.html if (!item.empty()) { value_.push_back(item); @@ -17,7 +17,7 @@ void VectorDirective::parse(const std::string &value) } } -std::any VectorDirective::getValue() const +DirectiveValueType VectorDirective::getValue() const { return value_; } \ No newline at end of file diff --git a/webserv/config/directive/VectorDirective.hpp b/webserv/config/directive/VectorDirective.hpp index 2ddddc5..dfd811f 100644 --- a/webserv/config/directive/VectorDirective.hpp +++ b/webserv/config/directive/VectorDirective.hpp @@ -21,7 +21,7 @@ class VectorDirective : public ADirective void parse(const std::string &value) override; - [[nodiscard]] std::any getValue() const override; + [[nodiscard]] DirectiveValueType getValue() const override; private: std::vector value_; diff --git a/webserv/server/Server.cpp b/webserv/server/Server.cpp index 0e97869..0382cb5 100644 --- a/webserv/server/Server.cpp +++ b/webserv/server/Server.cpp @@ -86,8 +86,10 @@ void Server::setupServerSocket(const ServerConfig &config) { try { + auto host = config["host"].get(); + auto port = config["listen"].get(); std::unique_ptr serverSocket = std::make_unique(); - serverSocket->bind(config["host"], config["listen"]); + serverSocket->bind(host, port); serverSocket->listen(SOMAXCONN); int server_fd = serverSocket->getFd();