diff --git a/config/default.conf b/config/default.conf index 9678cb7..93fd93b 100644 --- a/config/default.conf +++ b/config/default.conf @@ -22,20 +22,20 @@ server { location / { autoindex off; index index.html; - allow_methods GET POST DELETE; + allowed_methods GET POST DELETE; } location /uploads { root /var/www/uploads; autoindex on; - allow_methods GET POST; + allowed_methods GET POST; } location /images { root /var/www/images; autoindex off; index index.jpg; - allow_methods GET; + allowed_methods GET; } cgi_pass /cgi-bin/; @@ -63,20 +63,20 @@ server { location / { autoindex off; index index.html; - allow_methods GET POST DELETE; + allowed_methods GET POST DELETE; } location /2uploads { root /var/www/uploads; autoindex on; - allow_methods GET POST; + allowed_methods GET POST; } location /2images { root /var/www/images; autoindex off; index index.jpg; - allow_methods GET; + allowed_methods GET; } cgi_pass /cgi-bin/; diff --git a/webserv/client/Client.cpp b/webserv/client/Client.cpp index 9fe9cec..080e53d 100644 --- a/webserv/client/Client.cpp +++ b/webserv/client/Client.cpp @@ -4,11 +4,11 @@ #include // for Server #include // for Socket +#include // for uint8_t #include // for reference_wrapper, cref, ref #include // for map #include // for pair, move -#include // for uint8_t #include // for ssize_t Client::Client(std::unique_ptr socket, Server &server, const ServerConfig &server_config) diff --git a/webserv/client/Client.hpp b/webserv/client/Client.hpp index a342203..2ca27a3 100644 --- a/webserv/client/Client.hpp +++ b/webserv/client/Client.hpp @@ -5,10 +5,9 @@ #include #include -#include // for unique_ptr -#include // for string - #include // for size_t +#include // for unique_ptr +#include // for string class Server; class Socket; diff --git a/webserv/config/AConfig.cpp b/webserv/config/AConfig.cpp new file mode 100644 index 0000000..34b6dd1 --- /dev/null +++ b/webserv/config/AConfig.cpp @@ -0,0 +1,62 @@ +#include // for AConfig +#include // for ADirective +#include // for DirectiveFactory +#include // for trim +#include // for Log, LOCATION + +AConfig::AConfig(const AConfig *parent) : parent_(parent) {} + +void AConfig::addDirective(const std::string &line) +{ + auto directive = DirectiveFactory::createDirective(line); + if (directive) + { + directives_[directive->getName()] = std::move(directive); + } +} + +const ADirective *AConfig::getDirective(const std::string &name) const +{ + auto it = directives_.find(name); + if (it != directives_.end()) + { + return it->second.get(); + } + if (parent_ != nullptr) + { + return parent_->getDirective(name); + } + return nullptr; +} + +bool AConfig::hasDirective(const std::string &name) const +{ + if (directives_.contains(name)) // NOLINT + { + return true; + } + if (parent_ != nullptr) + { + return parent_->hasDirective(name); + } + return false; +} + +void AConfig::parseDirectives(const std::string &declarations) +{ + Log::trace(LOCATION); + std::stringstream ss(declarations); + std::string line; + while (ss.good()) + { + std::getline(ss, line); + line = utils::trim(line); + if (line.empty()) + { + continue; + } + Log::info("Global Declaration: " + line); + auto directive = DirectiveFactory::createDirective(line); + directives_[directive->getName()] = std::move(directive); + } +} diff --git a/webserv/config/AConfig.hpp b/webserv/config/AConfig.hpp index e69de29..bad0a55 100644 --- a/webserv/config/AConfig.hpp +++ b/webserv/config/AConfig.hpp @@ -0,0 +1,50 @@ +#pragma once + +#include "webserv/config/directive/DirectiveValue.hpp" + +#include // for ADirective + +#include +#include +#include + +class AConfig +{ + public: + AConfig() = default; + AConfig(const AConfig *parent); + AConfig(const AConfig &other) = delete; + AConfig &operator=(const AConfig &other) = delete; + AConfig(AConfig &&other) noexcept = delete; + AConfig &operator=(AConfig &&other) noexcept = delete; + + virtual ~AConfig() = default; + + void addDirective(const std::string &line); + [[nodiscard]] const ADirective *getDirective(const std::string &name) const; + + [[nodiscard]] bool hasDirective(const std::string &name) const; + + template T getDirectiveValue(const std::string &name, const T &defaultValue = T{}) const + { + const auto *directive = getDirective(name); + if (!directive) + { + return defaultValue; + } + + auto value = directive->getValue(); + if (value.holds()) + { + return value.get(); + } + return defaultValue; + } + + protected: + virtual void parseBlock(const std::string &block) = 0; + void parseDirectives(const std::string &declarations); + std::map> + directives_; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes) + const AConfig *parent_ = nullptr; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes) +}; \ No newline at end of file diff --git a/webserv/config/ConfigManager.cpp b/webserv/config/ConfigManager.cpp index c7b97fe..8b929c3 100644 --- a/webserv/config/ConfigManager.cpp +++ b/webserv/config/ConfigManager.cpp @@ -2,13 +2,12 @@ #include // for ServerConfig #include // for DirectiveFactory #include // for trim, findCorrespondingClosingBrace, trimSemi -#include // for Log +#include // for Log, LOCATION -#include // for size_t -#include // for basic_ifstream, basic_istream, basic_filebuf, basic_ostream::operator<<, ifstream, istringstream, stringstream +#include // for basic_ifstream, basic_istream, basic_filebuf, basic_ostream::operator<<, stringstream, ifstream, istringstream #include // for basic_stringstream, basic_istringstream #include // for runtime_error -#include +#include // for basic_string, char_traits, string, operator+, to_string, getline, operator<=> ConfigManager::ConfigManager() : initialized_(false) {} @@ -32,40 +31,6 @@ void ConfigManager::init(const std::string &filePath) initialized_ = true; } -void removeEmptyLines(std::string &str) -{ - std::istringstream stream(str); - std::string line; - std::string result; - - while (std::getline(stream, line)) - { - if (!utils::trim(line).empty()) - { - result += utils::trimSemi(utils::trim(line)) + '\n'; - } - } - str = result; -} - -void removeComments(std::string &str) -{ - size_t pos = 0; - while ((pos = str.find('#', pos)) != std::string::npos) - { - size_t end = str.find('\n', pos); - if (end == std::string::npos) - { - str.erase(pos); - } - else - { - str.erase(pos, end - pos); - } - } - removeEmptyLines(str); -} - void ConfigManager::parseConfigFile(const std::string &filePath) { // Placeholder for actual file parsing logic @@ -81,56 +46,18 @@ void ConfigManager::parseConfigFile(const std::string &filePath) std::stringstream buffer; buffer << file.rdbuf(); std::string content = buffer.str(); - removeComments(content); + utils::removeComments(content); + globalConfig_ = std::make_unique(content); - std::string globalDeclarations; - Log::trace("Content before parsing servers:\n" + content); - size_t pos = 0; - while (true) - { - size_t serverPos = content.find("server", pos); - size_t bracePos = content.find('{', serverPos); - if (serverPos == std::string::npos || bracePos == std::string::npos) - { - // No more server blocks, remaining is global - globalDeclarations += content.substr(pos); - break; - } - // Add global declarations before this server block - globalDeclarations += content.substr(pos, serverPos - pos); - Log::trace(LOCATION, {{"pos", std::to_string(pos)}, - {"serverPos", std::to_string(serverPos)}, - {"globalDeclarations", globalDeclarations}}); - size_t closeBrace = utils::findCorrespondingClosingBrace(content, bracePos); - if (closeBrace == std::string::npos) - { - throw std::runtime_error("Malformed block in config file."); - } - // Optionally parse the server block here - std::string serverBlock = content.substr(bracePos + 1, closeBrace - bracePos - 1); - serverConfigs_.emplace_back(serverBlock); - pos = closeBrace + 1; - } - - parseGlobalDeclarations(globalDeclarations); // Implement this function to handle global config + // Implement this function to handle global config file.close(); } -void ConfigManager::parseGlobalDeclarations(const std::string &declarations) +std::vector ConfigManager::getServerConfigs() const { - Log::trace(LOCATION); - std::stringstream ss(declarations); - std::string line; - while (ss.good()) + if (!initialized_) { - std::getline(ss, line); - line = utils::trim(line); - if (line.empty()) - { - continue; - } - Log::info("Global Declaration: " + line); - auto directive = DirectiveFactory::createDirective(line); - globalDirectives_.push_back(std::move(directive)); + throw std::runtime_error("ConfigManager is not initialized."); } -} + return globalConfig_->getServerConfigs(); +} \ No newline at end of file diff --git a/webserv/config/ConfigManager.hpp b/webserv/config/ConfigManager.hpp index 6033201..671a473 100644 --- a/webserv/config/ConfigManager.hpp +++ b/webserv/config/ConfigManager.hpp @@ -1,11 +1,13 @@ #pragma once -#include "webserv/config/directive/ADirective.hpp" -#include +#include +#include // for ServerConfig -#include -#include -#include +#include // for unique_ptr +#include // for string +#include // for vector + +class ADirective; class ConfigManager { @@ -18,15 +20,13 @@ class ConfigManager void init(const std::string &filePath); static ConfigManager &getInstance(); - [[nodiscard]] const std::vector &getServerConfigs() const { return serverConfigs_; } + [[nodiscard]] std::vector getServerConfigs() const; private: bool initialized_; ConfigManager(); ~ConfigManager(); - std::vector serverConfigs_; - std::vector> globalDirectives_; + std::unique_ptr globalConfig_; void parseConfigFile(const std::string &filePath); - void parseGlobalDeclarations(const std::string &declarations); }; \ No newline at end of file diff --git a/webserv/config/GlobalConfig.cpp b/webserv/config/GlobalConfig.cpp new file mode 100644 index 0000000..6bb802c --- /dev/null +++ b/webserv/config/GlobalConfig.cpp @@ -0,0 +1,52 @@ +#include +#include +#include // for Log, LOCATION + +#include + +GlobalConfig::GlobalConfig(const std::string &block) +{ + parseBlock(block); +} + +void GlobalConfig::parseBlock(const std::string &block) +{ + std::string directives; + Log::trace("Content before parsing servers:\n" + block); + size_t pos = 0; + while (true) + { + size_t serverPos = block.find("server", pos); + size_t bracePos = block.find('{', serverPos); + if (serverPos == std::string::npos || bracePos == std::string::npos) + { + // No more server blocks, remaining is global + directives += block.substr(pos); + break; + } + // Add global declarations before this server block + directives += block.substr(pos, serverPos - pos); + size_t closeBrace = utils::findCorrespondingClosingBrace(block, bracePos); + if (closeBrace == std::string::npos) + { + throw std::runtime_error("Malformed block in config file."); + } + // Optionally parse the server block here + std::string serverBlock = block.substr(bracePos + 1, closeBrace - bracePos - 1); + servers_.emplace_back(std::make_unique(serverBlock, this)); + pos = closeBrace + 1; + } + + parseDirectives(directives); +} + +std::vector GlobalConfig::getServerConfigs() const +{ + std::vector serverConfigs; + serverConfigs.reserve(servers_.size()); + for (const auto &serverPtr : servers_) + { + serverConfigs.push_back(serverPtr.get()); + } + return serverConfigs; +} \ No newline at end of file diff --git a/webserv/config/GlobalConfig.hpp b/webserv/config/GlobalConfig.hpp new file mode 100644 index 0000000..4609945 --- /dev/null +++ b/webserv/config/GlobalConfig.hpp @@ -0,0 +1,25 @@ +#pragma once + +#include // for AConfig +#include + +class GlobalConfig : public AConfig +{ + public: + GlobalConfig() = delete; + GlobalConfig(const std::string &Block); + + GlobalConfig(const GlobalConfig &other) = delete; + GlobalConfig &operator=(const GlobalConfig &other) = delete; + GlobalConfig(GlobalConfig &&other) noexcept = delete; + GlobalConfig &operator=(GlobalConfig &&other) noexcept = delete; + + ~GlobalConfig() override = default; + [[nodiscard]] std::vector getServerConfigs() const; + + private: + AConfig *parent_ = nullptr; + std::vector> servers_; + + void parseBlock(const std::string &block) override; +}; \ No newline at end of file diff --git a/webserv/config/LocationConfig.cpp b/webserv/config/LocationConfig.cpp index f9ef194..6f8658e 100644 --- a/webserv/config/LocationConfig.cpp +++ b/webserv/config/LocationConfig.cpp @@ -1,47 +1,14 @@ +#include // for AConfig #include -#include -#include +#include // for Log, LOCATION -#include -#include - -LocationConfig::LocationConfig(const std::string &locationBlock) : autoIndex_(false) +LocationConfig::LocationConfig(const std::string &block, const AConfig *parent) : AConfig(parent) { - parseLocationBlock(locationBlock); + parseBlock(block); } -void LocationConfig::parseLocationBlock(const std::string &block) +void LocationConfig::parseBlock(const std::string &block) { + Log::trace(LOCATION); parseDirectives(block); -} - -void LocationConfig::parseDirectives(const std::string &declarations) -{ - std::istringstream stream(declarations); - std::string line; - while (std::getline(stream, line)) - { - std::string directive; - std::istringstream lineStream{utils::trim(line)}; - lineStream >> directive; - if (!directive.empty()) - { - std::string value; - lineStream >> value; - if (directive == "autoindex") - { - autoIndex_ = (value == "on"); - Log::info("Set autoindex to " + std::string(autoIndex_ ? "on" : "off")); - } - else if (directive == "index") - { - indexFile_ = value; - Log::info("Set index file to " + indexFile_); - } - else - { - directives_[directive] = value; - } - } - } -} +} \ No newline at end of file diff --git a/webserv/config/LocationConfig.hpp b/webserv/config/LocationConfig.hpp index f839e77..44a3b46 100644 --- a/webserv/config/LocationConfig.hpp +++ b/webserv/config/LocationConfig.hpp @@ -1,19 +1,20 @@ #pragma once -#include -#include +#include // for AConfig -class LocationConfig +class LocationConfig : public AConfig { public: - LocationConfig(const std::string &locationBlock); + LocationConfig() = delete; + LocationConfig(const std::string &Block, const AConfig *parent = nullptr); + + LocationConfig(const LocationConfig &other) = delete; + LocationConfig &operator=(const LocationConfig &other) = delete; + LocationConfig(LocationConfig &&other) noexcept = delete; + LocationConfig &operator=(LocationConfig &&other) noexcept = delete; + + ~LocationConfig() override = default; private: - std::string path_; - bool autoIndex_; - std::string indexFile_; - std::map directives_; - - void parseLocationBlock(const std::string &block); - void parseDirectives(const std::string &declarations); -}; + void parseBlock(const std::string &block) override; +}; \ No newline at end of file diff --git a/webserv/config/ServerConfig.cpp b/webserv/config/ServerConfig.cpp index 69e62c2..10f6d3b 100644 --- a/webserv/config/ServerConfig.cpp +++ b/webserv/config/ServerConfig.cpp @@ -1,30 +1,18 @@ -#include // for LocationConfig +#include #include -#include // for findCorrespondingClosingBrace, trim -#include // for Log, LOCATION -#include // for DirectiveFactory -#include // for ADirective +#include +#include // for Log, LOCATION - -#include // for size_t -#include // for basic_istringstream, basic_istream, istringstream -#include // for runtime_error -#include // for basic_string, char_traits, operator+, allocator, string, operator==, operator>>, operator<=>, to_string, stoi, getline -#include // for pair - -ServerConfig::ServerConfig(std::string const &serverBlock) : port_(80) +ServerConfig::ServerConfig(const std::string &block, const AConfig *parent) : AConfig(parent) { - parseServerBlock(serverBlock); + parseBlock(block); } -void ServerConfig::parseServerBlock(const std::string &block) +void ServerConfig::parseBlock(const std::string &block) { - // Placeholder for actual server block parsing logic Log::trace(LOCATION); - // Placeholder for actual file parsing logic - - std::string serverDeclarations; + std::string directives; size_t pos = 0; while (true) @@ -35,12 +23,12 @@ void ServerConfig::parseServerBlock(const std::string &block) if (locationPos == std::string::npos || bracePos == std::string::npos) { // No more server blocks, remaining is global - serverDeclarations += block.substr(pos); + directives += block.substr(pos); break; } std::string locationPath = utils::trim(block.substr(locationPos, bracePos - (locationPos))); // Add global declarations before this server block - serverDeclarations += block.substr(pos, locationPos - pos); + directives += block.substr(pos, locationPos - pos); size_t closeBrace = utils::findCorrespondingClosingBrace(block, bracePos); if (closeBrace == std::string::npos) { @@ -48,138 +36,28 @@ void ServerConfig::parseServerBlock(const std::string &block) } // Optionally parse the server block here std::string locationBlock = block.substr(bracePos + 1, closeBrace - bracePos - 1); - locations_.emplace(locationPath, locationBlock); + locations_[locationPath] = std::make_unique(locationBlock, this); Log::debug("Added location: " + locationPath, {{"block", locationBlock}}); pos = closeBrace + 1; } // parseGlobalDeclarations(Declarations); // Implement this function to handle global config - parseDirectives(serverDeclarations); + parseDirectives(directives); } -// 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) +const LocationConfig *ServerConfig::getLocation(const std::string &path) const { - Log::trace(LOCATION); - std::stringstream ss(declarations); - std::string line; - while (ss.good()) - { - std::getline(ss, line); - line = utils::trim(line); - if (line.empty()) - { - continue; - } - auto directive = DirectiveFactory::createDirective(line); - directives_.push_back(std::move(directive)); - } - 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()); - } + auto it = locations_.find(path); + return (it != locations_.end()) ? it->second.get() : nullptr; } -DirectiveValue ServerConfig::operator[](const std::string &directive) const +std::vector ServerConfig::getLocationPaths() const { - for (const auto& dir : directives_) + std::vector paths; + paths.reserve(locations_.size()); + for (const auto &pair : locations_) { - if (dir->getName() == directive) - { - return dir->get(); - } + paths.push_back(pair.first); } - throw std::runtime_error("Directive not found: " + directive); + return paths; } \ No newline at end of file diff --git a/webserv/config/ServerConfig.hpp b/webserv/config/ServerConfig.hpp index 3738ad9..4116ce9 100644 --- a/webserv/config/ServerConfig.hpp +++ b/webserv/config/ServerConfig.hpp @@ -1,49 +1,27 @@ #pragma once -#include "webserv/config/directive/ADirective.hpp" -#include +#include // for AConfig +#include // for LocationConfig -#include -#include -#include -#include - -// TODO remove implementation details from header -class ServerConfig +class ServerConfig : public AConfig { public: - ServerConfig(const std::string &serverBlock); + ServerConfig() = delete; + ServerConfig(const std::string &Block, const AConfig *parent = nullptr); - // [[nodiscard]] const std::string &getHost() const { return host_; } + ServerConfig(const ServerConfig &other) = delete; + ServerConfig &operator=(const ServerConfig &other) = delete; + ServerConfig(ServerConfig &&other) noexcept = delete; + ServerConfig &operator=(ServerConfig &&other) noexcept = delete; - // [[nodiscard]] int getPort() const { return port_; } + ~ServerConfig() override = default; - // [[nodiscard]] const std::string &getRoot() const { return root_; } - - // [[nodiscard]] const std::string &getCgiPass() const { return cgi_pass_; } - - // [[nodiscard]] const std::string &getCgiExt() const { return cgi_ext_; } - - // [[nodiscard]] const std::map &getErrorPages() const { return error_page_; } - - // [[nodiscard]] const std::vector &getIndexFiles() const { return index_files_; } - - // [[nodiscard]] const LocationConfig &getLocation(const std::string &path) const; - // [[nodiscard]] std::vector getLocationPaths() const; - - DirectiveValue operator[](const std::string &directive) const; + [[nodiscard]] const LocationConfig *getLocation(const std::string &path) const; + [[nodiscard]] std::vector getLocationPaths() const; private: - std::string host_; - int port_; - std::string root_; - std::string cgi_pass_; - std::string cgi_ext_; - std::map error_page_; - std::vector index_files_; - std::map locations_; - std::vector> directives_; + std::map> locations_; + AConfig *parent_ = nullptr; - void parseServerBlock(const std::string &block); - void parseDirectives(const std::string &declarations); -}; + void parseBlock(const std::string &block) override; +}; \ No newline at end of file diff --git a/webserv/config/directive/ADirective.cpp b/webserv/config/directive/ADirective.cpp index aed7e9c..28f45aa 100644 --- a/webserv/config/directive/ADirective.cpp +++ b/webserv/config/directive/ADirective.cpp @@ -1,8 +1,9 @@ #include +#include // for DirectiveValue, operator<< -DirectiveValue ADirective::get() const +DirectiveValue ADirective::getValue() const { - return {getValue()}; + return {getValueType()}; } std::string ADirective::getName() const @@ -16,8 +17,8 @@ void ADirective::setName(const std::string &name) } // Non-member stream operator implementations -std::ostream &operator<<(std::ostream &os, const DirectiveValue &dv) -{ - return os << dv.toString(); -} +std::ostream &operator<<(std::ostream &os, const ADirective &directive) +{ + return os << directive.getName() << ": " << directive.getValue().toString(); +} \ No newline at end of file diff --git a/webserv/config/directive/ADirective.hpp b/webserv/config/directive/ADirective.hpp index 1685624..a6ee2e5 100644 --- a/webserv/config/directive/ADirective.hpp +++ b/webserv/config/directive/ADirective.hpp @@ -1,10 +1,10 @@ #pragma once -#include -#include -#include - +#include // for DirectiveValue, DirectiveValueType +#include // for ostream +#include // for string, basic_string +#include // for move class ADirective { @@ -23,8 +23,8 @@ class ADirective 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]] virtual DirectiveValueType getValueType() const = 0; + [[nodiscard]] DirectiveValue getValue() const; [[nodiscard]] std::string getName() const; // [[nodiscard]] std::string toString() const; diff --git a/webserv/config/directive/BoolDirective.cpp b/webserv/config/directive/BoolDirective.cpp index 731455d..dacc044 100644 --- a/webserv/config/directive/BoolDirective.cpp +++ b/webserv/config/directive/BoolDirective.cpp @@ -1,14 +1,19 @@ #include // for IntDirective #include // for trim -#include -#include -#include +#include // for __transform_fn, transform +#include // for tolower +#include // for invalid_argument + +BoolDirective::BoolDirective(const std::string &name, const std::string &value) + : ADirective(name) // NOLINT(bugprone-easily-swappable-parameters) +{ + parse(value); +} void BoolDirective::parse(const std::string &arg) { - std::string value = arg; - value = utils::trim(value); + std::string value = utils::trim(arg); std::ranges::transform(value, value.begin(), ::tolower); if (value == "true" || value == "1" || value == "on" || value == "yes") { @@ -24,7 +29,7 @@ void BoolDirective::parse(const std::string &arg) } } -DirectiveValueType BoolDirective::getValue() const +DirectiveValueType BoolDirective::getValueType() const { return value_; } \ No newline at end of file diff --git a/webserv/config/directive/BoolDirective.hpp b/webserv/config/directive/BoolDirective.hpp index ff84b81..ff3bbc8 100644 --- a/webserv/config/directive/BoolDirective.hpp +++ b/webserv/config/directive/BoolDirective.hpp @@ -1,27 +1,28 @@ #pragma once -#include "ADirective.hpp" +#include // for ADirective +#include // for DirectiveValueType -#include +#include // for string, basic_string class BoolDirective : public ADirective { - public: - BoolDirective() = delete; + public: + BoolDirective() = delete; - BoolDirective(const std::string &name, const std::string &value) : ADirective(name) { parse(value); } + BoolDirective(const std::string &name, const std::string &value); - BoolDirective(const BoolDirective &other) = delete; - BoolDirective &operator=(const BoolDirective &other) = delete; - BoolDirective(BoolDirective &&other) noexcept = delete; - BoolDirective &operator=(BoolDirective &&other) noexcept = delete; + BoolDirective(const BoolDirective &other) = delete; + BoolDirective &operator=(const BoolDirective &other) = delete; + BoolDirective(BoolDirective &&other) noexcept = delete; + BoolDirective &operator=(BoolDirective &&other) noexcept = delete; - ~BoolDirective() override = default; + ~BoolDirective() override = default; - void parse(const std::string &value) override; + void parse(const std::string &arg) override; - [[nodiscard]] DirectiveValueType getValue() const override; + [[nodiscard]] DirectiveValueType getValueType() const override; - private: - bool value_ = false; + private: + bool value_ = false; }; \ No newline at end of file diff --git a/webserv/config/directive/DirectiveFactory.cpp b/webserv/config/directive/DirectiveFactory.cpp index a9f77bd..51d1e27 100644 --- a/webserv/config/directive/DirectiveFactory.cpp +++ b/webserv/config/directive/DirectiveFactory.cpp @@ -1,19 +1,22 @@ -#include -#include -#include // for DirectiveFactory -#include -#include -#include -#include -#include -#include // for trim, findCorrespondingClosingBrace, trimSemi -#include // for Log -#include +#include "webserv/log/Log.hpp" +#include // for BoolDirective +#include // for DirectiveFactory +#include // for IntDirective +#include // for IntStringDirective +#include // for SizeDirective +#include // for StringDirective +#include // for VectorDirective +#include // for trim, trimSemi +#include // for basic_stringstream, stringstream +#include // for invalid_argument + +class ADirective; std::unique_ptr DirectiveFactory::createDirective(const std::string &line) { + Log::trace(LOCATION); std::stringstream ss(line); std::string name; ss >> name; @@ -61,8 +64,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); }}, + {"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 2bf6348..b8df032 100644 --- a/webserv/config/directive/DirectiveFactory.hpp +++ b/webserv/config/directive/DirectiveFactory.hpp @@ -1,9 +1,12 @@ -#include "webserv/config/directive/ADirective.hpp" +#pragma once +#include // for ADirective -#include -#include -#include -#include +#include // for array +#include // for function +#include // for unique_ptr +#include // for string +#include // for string_view +#include // for unordered_map class DirectiveFactory { diff --git a/webserv/config/directive/DirectiveValue.cpp b/webserv/config/directive/DirectiveValue.cpp index eec67bf..d7b7a94 100644 --- a/webserv/config/directive/DirectiveValue.cpp +++ b/webserv/config/directive/DirectiveValue.cpp @@ -1,13 +1,13 @@ -#include +#include // for ADirective, operator<< #include -#include -#include -#include // for is_same_v, decay_t -#include // for pair, move -#include // for variant, visit -#include // for vector - // +#include // for size_t +#include // for string, basic_string, allocator, char_traits, operator+, to_string, operator<< +#include // for pair +#include // for visit +#include // for vector + +// // std::string DirectiveValue::toString() const // { @@ -78,7 +78,7 @@ std::string DirectiveValue::toString() const value_); } -std::ostream &operator<<(std::ostream &os, const ADirective &directive) +std::ostream &operator<<(std::ostream &os, const DirectiveValue &dv) { - return os << directive.getName() << ": " << directive.get().toString(); + return os << dv.toString(); } \ No newline at end of file diff --git a/webserv/config/directive/DirectiveValue.hpp b/webserv/config/directive/DirectiveValue.hpp index 383f402..bedd5b6 100644 --- a/webserv/config/directive/DirectiveValue.hpp +++ b/webserv/config/directive/DirectiveValue.hpp @@ -3,20 +3,17 @@ #include // for size_t #include // for ostream, operator<< #include // for string, basic_string, char_traits, to_string +#include // for pair, move #include // for variant, visit, get, holds_alternative #include // for vector -#include // for pair, move // Visitor overload pattern for std::visit -template -struct overloaded : Ts... { - using Ts::operator()...; +template struct overloaded : Ts... +{ + using Ts::operator()...; }; -template -overloaded(Ts...) -> overloaded; - - +template overloaded(Ts...) -> overloaded; // Define all possible directive value types using DirectiveValueType = std::variant [[nodiscard]] bool holds() const { return std::holds_alternative(value_); } [[nodiscard]] std::string toString() const; - private: DirectiveValueType value_; diff --git a/webserv/config/directive/IntDirective.cpp b/webserv/config/directive/IntDirective.cpp index ceace88..f4f1e5c 100644 --- a/webserv/config/directive/IntDirective.cpp +++ b/webserv/config/directive/IntDirective.cpp @@ -1,13 +1,17 @@ #include // for IntDirective -#include +IntDirective::IntDirective(const std::string &name, const std::string &value) + : ADirective(name) // NOLINT(bugprone-easily-swappable-parameters) +{ + parse(value); +} void IntDirective::parse(const std::string &value) { value_ = std::stoi(value); // TODO: check parsing } -DirectiveValueType IntDirective::getValue() const +DirectiveValueType IntDirective::getValueType() const { return value_; } \ No newline at end of file diff --git a/webserv/config/directive/IntDirective.hpp b/webserv/config/directive/IntDirective.hpp index 6c72611..1f83da8 100644 --- a/webserv/config/directive/IntDirective.hpp +++ b/webserv/config/directive/IntDirective.hpp @@ -1,15 +1,16 @@ #pragma once -#include "ADirective.hpp" +#include // for ADirective +#include // for DirectiveValueType -#include +#include // for string, basic_string class IntDirective : public ADirective { public: IntDirective() = delete; - IntDirective(const std::string &name, const std::string &value) : ADirective(name) { parse(value); } + IntDirective(const std::string &name, const std::string &value); IntDirective(const IntDirective &other) = delete; IntDirective &operator=(const IntDirective &other) = delete; @@ -20,7 +21,7 @@ class IntDirective : public ADirective void parse(const std::string &value) override; - [[nodiscard]] DirectiveValueType getValue() const override; + [[nodiscard]] DirectiveValueType getValueType() const override; private: int value_ = 0; diff --git a/webserv/config/directive/IntStringDirective.cpp b/webserv/config/directive/IntStringDirective.cpp index f51b017..005150a 100644 --- a/webserv/config/directive/IntStringDirective.cpp +++ b/webserv/config/directive/IntStringDirective.cpp @@ -1,8 +1,13 @@ -#include "webserv/log/Log.hpp" #include // for IntDirective -#include // for trim -#include // for std::getline, std::basic_istream, std::char_traits, std::basic_stringbuf +#include // for trim +#include // for basic_istringstream, basic_istream::operator>>, istringstream + +IntStringDirective::IntStringDirective(const std::string &name, const std::string &value) + : ADirective(name) // NOLINT(bugprone-easily-swappable-parameters) +{ + parse(value); +} void IntStringDirective::parse(const std::string &value) { @@ -15,7 +20,7 @@ void IntStringDirective::parse(const std::string &value) value_ = std::make_pair(intPart, strPart); } -DirectiveValueType IntStringDirective::getValue() const +DirectiveValueType IntStringDirective::getValueType() const { return value_; } \ No newline at end of file diff --git a/webserv/config/directive/IntStringDirective.hpp b/webserv/config/directive/IntStringDirective.hpp index 3f14340..a0f5280 100644 --- a/webserv/config/directive/IntStringDirective.hpp +++ b/webserv/config/directive/IntStringDirective.hpp @@ -1,15 +1,16 @@ #pragma once +#include // for ADirective +#include // for DirectiveValueType -#include "ADirective.hpp" - -#include +#include // for basic_string, string +#include // for pair class IntStringDirective : public ADirective { public: IntStringDirective() = delete; - IntStringDirective(const std::string &name, const std::string &value) : ADirective(name) { parse(value); } + IntStringDirective(const std::string &name, const std::string &value); IntStringDirective(const IntStringDirective &other) = delete; IntStringDirective &operator=(const IntStringDirective &other) = delete; @@ -20,7 +21,7 @@ class IntStringDirective : public ADirective void parse(const std::string &value) override; - [[nodiscard]] DirectiveValueType getValue() const override; + [[nodiscard]] DirectiveValueType getValueType() const override; private: std::pair value_ = {0, ""}; diff --git a/webserv/config/directive/SizeDirective.cpp b/webserv/config/directive/SizeDirective.cpp index 83e65de..f6180b6 100644 --- a/webserv/config/directive/SizeDirective.cpp +++ b/webserv/config/directive/SizeDirective.cpp @@ -1,10 +1,15 @@ #include // for SizeDirective #include // for trim -#include -#include -#include -#include +#include // for __transform_fn, transform +#include // for tolower +#include // for invalid_argument + +SizeDirective::SizeDirective(const std::string &name, const std::string &value) + : ADirective(name) // NOLINT(bugprone-easily-swappable-parameters) +{ + parse(value); +} void SizeDirective::parse(const std::string &value) { @@ -43,7 +48,7 @@ void SizeDirective::parse(const std::string &value) value_ *= multiplier; } -DirectiveValueType SizeDirective::getValue() const +DirectiveValueType SizeDirective::getValueType() const { return value_; } \ No newline at end of file diff --git a/webserv/config/directive/SizeDirective.hpp b/webserv/config/directive/SizeDirective.hpp index e4df266..5cd0baf 100644 --- a/webserv/config/directive/SizeDirective.hpp +++ b/webserv/config/directive/SizeDirective.hpp @@ -1,15 +1,17 @@ #pragma once -#include "ADirective.hpp" +#include // for ADirective +#include // for DirectiveValueType -#include +#include // for size_t +#include // for string, basic_string class SizeDirective : public ADirective { public: SizeDirective() = delete; - SizeDirective(const std::string &name, const std::string &value) : ADirective(name) { parse(value); } + SizeDirective(const std::string &name, const std::string &value); SizeDirective(const SizeDirective &other) = delete; SizeDirective &operator=(const SizeDirective &other) = delete; @@ -20,7 +22,7 @@ class SizeDirective : public ADirective void parse(const std::string &value) override; - [[nodiscard]] DirectiveValueType getValue() const override; + [[nodiscard]] DirectiveValueType getValueType() const override; private: size_t value_ = 0; diff --git a/webserv/config/directive/StringDirective.cpp b/webserv/config/directive/StringDirective.cpp index 12b910c..d519b90 100644 --- a/webserv/config/directive/StringDirective.cpp +++ b/webserv/config/directive/StringDirective.cpp @@ -1,13 +1,17 @@ #include // for IntDirective -#include +StringDirective::StringDirective(const std::string &name, const std::string &value) + : ADirective(name) // NOLINT(bugprone-easily-swappable-parameters) +{ + parse(value); +} void StringDirective::parse(const std::string &value) { value_ = value; } -DirectiveValueType StringDirective::getValue() const +DirectiveValueType StringDirective::getValueType() const { return value_; } \ No newline at end of file diff --git a/webserv/config/directive/StringDirective.hpp b/webserv/config/directive/StringDirective.hpp index 1f0feb5..f0befbd 100644 --- a/webserv/config/directive/StringDirective.hpp +++ b/webserv/config/directive/StringDirective.hpp @@ -1,14 +1,16 @@ #pragma once -#include "ADirective.hpp" +#include // for ADirective +#include // for DirectiveValueType + +#include // for string, basic_string class StringDirective : public ADirective { public: StringDirective() = delete; - StringDirective(const std::string &name, const std::string &value) : ADirective(name) { parse(value); } - + StringDirective(const std::string &name, const std::string &value); StringDirective(const StringDirective &other) = delete; StringDirective &operator=(const StringDirective &other) = delete; StringDirective(StringDirective &&other) noexcept = delete; @@ -18,7 +20,7 @@ class StringDirective : public ADirective void parse(const std::string &value) override; - [[nodiscard]] DirectiveValueType getValue() const override; + [[nodiscard]] DirectiveValueType getValueType() const override; private: std::string value_; diff --git a/webserv/config/directive/VectorDirective.cpp b/webserv/config/directive/VectorDirective.cpp index 758940a..6cad90c 100644 --- a/webserv/config/directive/VectorDirective.cpp +++ b/webserv/config/directive/VectorDirective.cpp @@ -1,7 +1,12 @@ #include // for IntDirective -#include -#include // for std::getline, std::basic_istream, std::char_traits, std::basic_stringbuf +#include // for basic_stringstream, stringstream + +VectorDirective::VectorDirective(const std::string &name, const std::string &value) + : ADirective(name) // NOLINT(bugprone-easily-swappable-parameters) +{ + parse(value); +} void VectorDirective::parse(const std::string &value) { @@ -17,7 +22,7 @@ void VectorDirective::parse(const std::string &value) } } -DirectiveValueType VectorDirective::getValue() const +DirectiveValueType VectorDirective::getValueType() const { return value_; } \ No newline at end of file diff --git a/webserv/config/directive/VectorDirective.hpp b/webserv/config/directive/VectorDirective.hpp index dfd811f..379cf6a 100644 --- a/webserv/config/directive/VectorDirective.hpp +++ b/webserv/config/directive/VectorDirective.hpp @@ -1,16 +1,17 @@ #pragma once -#include "ADirective.hpp" +#include // for ADirective +#include // for DirectiveValueType -#include -#include +#include // for basic_string, string +#include // for vector class VectorDirective : public ADirective { public: VectorDirective() = delete; - VectorDirective(const std::string &name, const std::string &value) : ADirective(name) { parse(value); } + VectorDirective(const std::string &name, const std::string &value); VectorDirective(const VectorDirective &other) = delete; VectorDirective &operator=(const VectorDirective &other) = delete; @@ -21,7 +22,7 @@ class VectorDirective : public ADirective void parse(const std::string &value) override; - [[nodiscard]] DirectiveValueType getValue() const override; + [[nodiscard]] DirectiveValueType getValueType() const override; private: std::vector value_; diff --git a/webserv/config/utils.cpp b/webserv/config/utils.cpp index 38ef03c..94f927e 100644 --- a/webserv/config/utils.cpp +++ b/webserv/config/utils.cpp @@ -1,6 +1,7 @@ #include +#include #include #include @@ -69,4 +70,38 @@ size_t findCorrespondingClosingBrace(const std::string &str, size_t openPos) } return std::string::npos; } + +void removeEmptyLines(std::string &str) +{ + std::istringstream stream(str); + std::string line; + std::string result; + + while (std::getline(stream, line)) + { + if (!utils::trim(line).empty()) + { + result += utils::trimSemi(utils::trim(line)) + '\n'; + } + } + str = result; +} + +void removeComments(std::string &str) +{ + size_t pos = 0; + while ((pos = str.find('#', pos)) != std::string::npos) + { + size_t end = str.find('\n', pos); + if (end == std::string::npos) + { + str.erase(pos); + } + else + { + str.erase(pos, end - pos); + } + } + removeEmptyLines(str); +} } // namespace utils diff --git a/webserv/config/utils.hpp b/webserv/config/utils.hpp index a1ec2b4..70cb6c0 100644 --- a/webserv/config/utils.hpp +++ b/webserv/config/utils.hpp @@ -9,4 +9,6 @@ size_t stoul(const std::string &str, int base = 10); std::string trimSemi(const std::string &str); std::string trim(const std::string &str); size_t findCorrespondingClosingBrace(const std::string &str, size_t openPos); +void removeEmptyLines(std::string &str); +void removeComments(std::string &str); } // namespace utils diff --git a/webserv/http/HttpRequest.cpp b/webserv/http/HttpRequest.cpp index 321d953..bd98191 100644 --- a/webserv/http/HttpRequest.cpp +++ b/webserv/http/HttpRequest.cpp @@ -1,11 +1,13 @@ -#include "webserv/config/utils.hpp" +#include "webserv/config/utils.hpp" // for stoul #include // for CRLF, DOUBLE_CRLF #include #include // for Log, LOCATION -#include // for optional, operator> +#include // for map +#include // for optional #include // for basic_stringstream, basic_istream, stringstream +#include // for pair #include // for vector class ServerConfig; diff --git a/webserv/log/Log.hpp b/webserv/log/Log.hpp index ffb5ec2..d416bcc 100644 --- a/webserv/log/Log.hpp +++ b/webserv/log/Log.hpp @@ -2,6 +2,7 @@ #include // for array #include // for steady_clock +#include // for uint8_t #include // for ios_base #include // for map #include // for unique_ptr @@ -9,8 +10,6 @@ #include // for string_view #include // for unordered_map -#include // for uint8_t - class Channel; // Forward declaration constexpr const char *extractFilename(const char *path) diff --git a/webserv/main.cpp b/webserv/main.cpp index a4e5073..1f28768 100644 --- a/webserv/main.cpp +++ b/webserv/main.cpp @@ -1,14 +1,11 @@ -#include // for ConfigManager -#include // for ADirective -#include // for IntDirective -#include // for Log, LOCATION -#include // for Server +#include // for ConfigManager +#include // for Log, LOCATION +#include // for Server #include // for basic_ostream, operator<<, cerr, ios_base #include // for map -#include -#include // for basic_string, char_traits, allocator, operator+, operator<=> -#include // for pair +#include // for basic_string, char_traits, allocator, operator+, operator<=> +#include // for pair int main(int argc, char **argv) { @@ -24,7 +21,7 @@ int main(int argc, char **argv) Log::warning("Testing context: " + LOCATION, {{"key1", "value1"}, {"key2", "value2"}}); ConfigManager::getInstance().init(argv[1]); // NOLINT Server server(ConfigManager::getInstance()); - + server.start(); return 0; } \ No newline at end of file diff --git a/webserv/server/Server.cpp b/webserv/server/Server.cpp index 0382cb5..630d139 100644 --- a/webserv/server/Server.cpp +++ b/webserv/server/Server.cpp @@ -4,15 +4,15 @@ #include #include // for Socket +#include // for errno #include // for strerror, strlen #include // for exception #include // for unique_ptr, allocator, make_unique #include // for runtime_error -#include // for operator+, to_string, basic_string, char_traits, string +#include // for basic_string, operator+, to_string, char_traits, string #include // for move, pair #include // for vector -#include // for errno #include // for epoll_event, epoll_ctl, EPOLLIN, EPOLLOUT, epoll_create1, epoll_wait, EPOLLERR, EPOLLHUP, EPOLL_CTL_ADD, EPOLL_CTL_DEL, EPOLL_CTL_MOD #include // for send, SOMAXCONN #include // for ssize_t @@ -48,7 +48,7 @@ void Server::start() for (const auto &config : configManager_.getServerConfigs()) { - setupServerSocket(config); + setupServerSocket(*config); } if (fdToConfig_.empty()) { @@ -86,8 +86,8 @@ void Server::setupServerSocket(const ServerConfig &config) { try { - auto host = config["host"].get(); - auto port = config["listen"].get(); + auto host = config.getDirectiveValue("host"); + auto port = config.getDirectiveValue("listen"); std::unique_ptr serverSocket = std::make_unique(); serverSocket->bind(host, port); serverSocket->listen(SOMAXCONN); @@ -97,7 +97,8 @@ void Server::setupServerSocket(const ServerConfig &config) listeners_.push_back(std::move(serverSocket)); fdToConfig_.insert({server_fd, std::cref(config)}); - // Log::info("Server listening on " + std::string(config["host"]) + ":" + static_cast(config["listen"]) + "..."); + Log::info("Server listening on " + host + ":" + std::to_string(port) + "..."); + // static_cast(config["listen"]) + "..."); } catch (const std::exception &e) { diff --git a/webserv/server/Server.hpp b/webserv/server/Server.hpp index a4bd6e5..0bf42f5 100644 --- a/webserv/server/Server.hpp +++ b/webserv/server/Server.hpp @@ -5,13 +5,12 @@ #include // for ServerConfig #include // for Socket +#include // for uint32_t #include // for reference_wrapper #include // for unique_ptr #include // for unordered_map #include // for vector -#include // for uint32_t - class Client; class ConfigManager;