From dbc318cdfac0e652f17d9d771ac892ac36dd0099 Mon Sep 17 00:00:00 2001 From: whaffman Date: Mon, 6 Oct 2025 16:00:38 +0200 Subject: [PATCH] feat : add structural validation rules to ConfigValidator --- webserv/config/validation/ConfigValidator.cpp | 1 - .../config/validation/ValidationEngine.cpp | 77 +++++++++++-------- .../config/validation/ValidationEngine.hpp | 4 +- .../AStructuralValidationRule.hpp | 26 +++---- .../MinimumServerBlocksRule.cpp | 15 ++-- .../MinimumServerBlocksRule.hpp | 4 +- 6 files changed, 69 insertions(+), 58 deletions(-) diff --git a/webserv/config/validation/ConfigValidator.cpp b/webserv/config/validation/ConfigValidator.cpp index 80af27d..4e55128 100644 --- a/webserv/config/validation/ConfigValidator.cpp +++ b/webserv/config/validation/ConfigValidator.cpp @@ -1,5 +1,4 @@ #include - #include // for ValidationEngine #include // for AValidationRule #include // for AllowedValuesRule diff --git a/webserv/config/validation/ValidationEngine.cpp b/webserv/config/validation/ValidationEngine.cpp index fc2eb87..a26741b 100644 --- a/webserv/config/validation/ValidationEngine.cpp +++ b/webserv/config/validation/ValidationEngine.cpp @@ -1,9 +1,8 @@ -#include - #include // for AConfig #include // for GlobalConfig #include // for LocationConfig #include // for ServerConfig +#include #include // for ValidationResult #include // for AValidationRule #include // for Log, LOCATION @@ -31,7 +30,8 @@ void ValidationEngine::addLocationRule(const std::string &directiveName, std::un void ValidationEngine::addStructuralRule(std::unique_ptr rule) { Log::trace(LOCATION); - if (rule != nullptr) { + if (rule != nullptr) + { structuralRules_.push_back(std::move(rule)); } } @@ -76,7 +76,7 @@ std::vector ValidationEngine::getWarnings() const bool ValidationEngine::hasErrors() const { - for (const auto &result : results_) //NOLINT(readability-use-anyofallof) + for (const auto &result : results_) // NOLINT(readability-use-anyofallof) { if (!result.isValidResult()) { @@ -122,20 +122,25 @@ void ValidationEngine::validateConfig(RuleMap const &rulesMap, const AConfig *co void ValidationEngine::validateLocationConfig(const std::string &path, const LocationConfig *config) { Log::trace(LOCATION); - + // Run location structural validation rules - for (const auto &rule : structuralRules_) { - try { + for (const auto &rule : structuralRules_) + { + try + { ValidationResult result = rule->validateLocation(config); - if (!result.isValidResult()) { + if (!result.isValidResult()) + { results_.push_back(result); } - } catch (const std::exception &e) { - results_.push_back(ValidationResult::error( - "Structural rule '" + rule->getRuleName() + "' threw exception for location '" + path + "': " + e.what())); + } + catch (const std::exception &e) + { + results_.push_back(ValidationResult::error("Structural rule '" + rule->getRuleName() + + "' threw exception for location '" + path + "': " + e.what())); } } - + // Run location directive validation rules validateConfig(locationRules_, config); } @@ -143,23 +148,28 @@ void ValidationEngine::validateLocationConfig(const std::string &path, const Loc void ValidationEngine::validateServerConfig(const ServerConfig *config) { Log::trace(LOCATION); - + // Run server structural validation rules - for (const auto &rule : structuralRules_) { - try { + for (const auto &rule : structuralRules_) + { + try + { ValidationResult result = rule->validateServer(config); - if (!result.isValidResult()) { + if (!result.isValidResult()) + { results_.push_back(result); } - } catch (const std::exception &e) { - results_.push_back(ValidationResult::error( - "Structural rule '" + rule->getRuleName() + "' threw exception: " + e.what())); + } + catch (const std::exception &e) + { + results_.push_back( + ValidationResult::error("Structural rule '" + rule->getRuleName() + "' threw exception: " + e.what())); } } - + // Run server directive validation rules validateConfig(serverRules_, config); - + for (const auto &path : config->getLocationPaths()) { const LocationConfig *locationConfig = config->getLocation(path); @@ -173,23 +183,28 @@ void ValidationEngine::validateServerConfig(const ServerConfig *config) void ValidationEngine::validateGlobalConfig(const GlobalConfig *config) { Log::trace(LOCATION); - + // Run global structural validation rules - for (const auto &rule : structuralRules_) { - try { + for (const auto &rule : structuralRules_) + { + try + { ValidationResult result = rule->validateGlobal(config); - if (!result.isValidResult()) { + if (!result.isValidResult()) + { results_.push_back(result); } - } catch (const std::exception &e) { - results_.push_back(ValidationResult::error( - "Structural rule '" + rule->getRuleName() + "' threw exception: " + e.what())); + } + catch (const std::exception &e) + { + results_.push_back( + ValidationResult::error("Structural rule '" + rule->getRuleName() + "' threw exception: " + e.what())); } } - + // Run global directive validation rules validateConfig(globalRules_, config); - + for (const auto *serverConfig : config->getServerConfigs()) { validateServerConfig(serverConfig); @@ -205,7 +220,7 @@ void ValidationEngine::validate() { Log::trace(LOCATION); results_.clear(); // Clear previous results - + if (globalConfig_ != nullptr) { validateGlobalConfig(globalConfig_); diff --git a/webserv/config/validation/ValidationEngine.hpp b/webserv/config/validation/ValidationEngine.hpp index c9f1645..1563ec9 100644 --- a/webserv/config/validation/ValidationEngine.hpp +++ b/webserv/config/validation/ValidationEngine.hpp @@ -4,8 +4,8 @@ #include #include #include -#include // for ValidationResult -#include // for AValidationRule +#include // for ValidationResult +#include // for AValidationRule #include // for AStructuralValidationRule #include // for map diff --git a/webserv/config/validation/structural_rules/AStructuralValidationRule.hpp b/webserv/config/validation/structural_rules/AStructuralValidationRule.hpp index 19a5cee..49a6c73 100644 --- a/webserv/config/validation/structural_rules/AStructuralValidationRule.hpp +++ b/webserv/config/validation/structural_rules/AStructuralValidationRule.hpp @@ -10,15 +10,17 @@ class LocationConfig; class AStructuralValidationRule { -private: + private: std::string ruleName_; std::string description_; -protected: + protected: AStructuralValidationRule(const std::string &ruleName, const std::string &description) - : ruleName_(ruleName), description_(description) {} + : ruleName_(ruleName), description_(description) + { + } -public: + public: virtual ~AStructuralValidationRule() = default; AStructuralValidationRule(const AStructuralValidationRule &other) = delete; @@ -29,30 +31,24 @@ public: // Virtual validation methods - override as needed [[nodiscard]] virtual ValidationResult validateGlobal(const GlobalConfig *config) const { - static_cast(config); // Suppress unused parameter warning + static_cast(config); // Suppress unused parameter warning return ValidationResult::success(); // Default: no global validation } [[nodiscard]] virtual ValidationResult validateServer(const ServerConfig *config) const { - static_cast(config); // Suppress unused parameter warning + static_cast(config); // Suppress unused parameter warning return ValidationResult::success(); // Default: no server validation } [[nodiscard]] virtual ValidationResult validateLocation(const LocationConfig *config) const { - static_cast(config); // Suppress unused parameter warning + static_cast(config); // Suppress unused parameter warning return ValidationResult::success(); // Default: no location validation } // Non-virtual getters - set in constructor - [[nodiscard]] std::string getRuleName() const - { - return ruleName_; - } + [[nodiscard]] std::string getRuleName() const { return ruleName_; } - [[nodiscard]] std::string getDescription() const - { - return description_; - } + [[nodiscard]] std::string getDescription() const { return description_; } }; \ No newline at end of file diff --git a/webserv/config/validation/structural_rules/MinimumServerBlocksRule.cpp b/webserv/config/validation/structural_rules/MinimumServerBlocksRule.cpp index fb9a23d..11d3fb8 100644 --- a/webserv/config/validation/structural_rules/MinimumServerBlocksRule.cpp +++ b/webserv/config/validation/structural_rules/MinimumServerBlocksRule.cpp @@ -6,8 +6,8 @@ #include MinimumServerBlocksRule::MinimumServerBlocksRule(size_t minimumServers) - : AStructuralValidationRule("MinimumServerBlocksRule", - "Ensures global config has at least " + std::to_string(minimumServers) + " server block(s)"), + : AStructuralValidationRule("MinimumServerBlocksRule", "Ensures global config has at least " + + std::to_string(minimumServers) + " server block(s)"), minimumServers_(minimumServers) { } @@ -16,16 +16,17 @@ ValidationResult MinimumServerBlocksRule::validateGlobal(const GlobalConfig *con { Log::trace(LOCATION); - if (config == nullptr) { + if (config == nullptr) + { return ValidationResult::error("Global config is null"); } size_t serverCount = config->getServerConfigs().size(); - if (serverCount < minimumServers_) { - return ValidationResult::error( - "Global configuration must have at least " + std::to_string(minimumServers_) + - " server block(s), but found " + std::to_string(serverCount)); + if (serverCount < minimumServers_) + { + return ValidationResult::error("Global configuration must have at least " + std::to_string(minimumServers_) + + " server block(s), but found " + std::to_string(serverCount)); } return ValidationResult::success(); diff --git a/webserv/config/validation/structural_rules/MinimumServerBlocksRule.hpp b/webserv/config/validation/structural_rules/MinimumServerBlocksRule.hpp index 431df8b..177e110 100644 --- a/webserv/config/validation/structural_rules/MinimumServerBlocksRule.hpp +++ b/webserv/config/validation/structural_rules/MinimumServerBlocksRule.hpp @@ -8,10 +8,10 @@ class GlobalConfig; class MinimumServerBlocksRule : public AStructuralValidationRule { -private: + private: size_t minimumServers_; -public: + public: explicit MinimumServerBlocksRule(size_t minimumServers = 1); ~MinimumServerBlocksRule() override = default;