feat(structural rules)
This commit is contained in:
parent
010ee3e8b6
commit
4f89a2918c
@ -4,6 +4,7 @@
|
|||||||
#include <webserv/config/validation/directive_rules/AValidationRule.hpp> // for AValidationRule
|
#include <webserv/config/validation/directive_rules/AValidationRule.hpp> // for AValidationRule
|
||||||
#include <webserv/config/validation/directive_rules/AllowedValuesRule.hpp> // for AllowedValuesRule
|
#include <webserv/config/validation/directive_rules/AllowedValuesRule.hpp> // for AllowedValuesRule
|
||||||
#include <webserv/config/validation/directive_rules/PortValidationRule.hpp> // for PortValidationRule
|
#include <webserv/config/validation/directive_rules/PortValidationRule.hpp> // for PortValidationRule
|
||||||
|
#include <webserv/config/validation/structural_rules/StructuralRules.hpp> // for structural rules
|
||||||
#include <webserv/log/Log.hpp> // for LOCATION, Log
|
#include <webserv/log/Log.hpp> // for LOCATION, Log
|
||||||
|
|
||||||
#include <string> // for basic_string, string
|
#include <string> // for basic_string, string
|
||||||
@ -12,6 +13,11 @@ ConfigValidator::ConfigValidator(const GlobalConfig *config) : engine_(std::make
|
|||||||
{
|
{
|
||||||
Log::trace(LOCATION);
|
Log::trace(LOCATION);
|
||||||
|
|
||||||
|
/*Structural Rules*/
|
||||||
|
engine_->addStructuralRule(std::make_unique<MinimumServerBlocksRule>(1));
|
||||||
|
engine_->addStructuralRule(std::make_unique<RequiredLocationBlocksRule>(1));
|
||||||
|
engine_->addStructuralRule(std::make_unique<UniqueServerNamesRule>());
|
||||||
|
|
||||||
/*Global Directive Rules*/
|
/*Global Directive Rules*/
|
||||||
|
|
||||||
/*Server Directive Rules*/
|
/*Server Directive Rules*/
|
||||||
|
|||||||
@ -28,6 +28,14 @@ void ValidationEngine::addLocationRule(const std::string &directiveName, std::un
|
|||||||
addRule(locationRules_, directiveName, std::move(rule));
|
addRule(locationRules_, directiveName, std::move(rule));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ValidationEngine::addStructuralRule(std::unique_ptr<AStructuralValidationRule> rule)
|
||||||
|
{
|
||||||
|
Log::trace(LOCATION);
|
||||||
|
if (rule != nullptr) {
|
||||||
|
structuralRules_.push_back(std::move(rule));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ValidationEngine::addRule(RuleMap &ruleMap, const std::string &directiveName,
|
void ValidationEngine::addRule(RuleMap &ruleMap, const std::string &directiveName,
|
||||||
std::unique_ptr<AValidationRule> rule)
|
std::unique_ptr<AValidationRule> rule)
|
||||||
{
|
{
|
||||||
@ -68,7 +76,7 @@ std::vector<ValidationResult> ValidationEngine::getWarnings() const
|
|||||||
|
|
||||||
bool ValidationEngine::hasErrors() const
|
bool ValidationEngine::hasErrors() const
|
||||||
{
|
{
|
||||||
for (const auto &result : results_)
|
for (const auto &result : results_) //NOLINT(readability-use-anyofallof)
|
||||||
{
|
{
|
||||||
if (!result.isValidResult())
|
if (!result.isValidResult())
|
||||||
{
|
{
|
||||||
@ -114,13 +122,44 @@ void ValidationEngine::validateConfig(RuleMap const &rulesMap, const AConfig *co
|
|||||||
void ValidationEngine::validateLocationConfig(const std::string &path, const LocationConfig *config)
|
void ValidationEngine::validateLocationConfig(const std::string &path, const LocationConfig *config)
|
||||||
{
|
{
|
||||||
Log::trace(LOCATION);
|
Log::trace(LOCATION);
|
||||||
|
|
||||||
|
// Run location structural validation rules
|
||||||
|
for (const auto &rule : structuralRules_) {
|
||||||
|
try {
|
||||||
|
ValidationResult result = rule->validateLocation(config);
|
||||||
|
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()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run location directive validation rules
|
||||||
validateConfig(locationRules_, config);
|
validateConfig(locationRules_, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ValidationEngine::validateServerConfig(const ServerConfig *config)
|
void ValidationEngine::validateServerConfig(const ServerConfig *config)
|
||||||
{
|
{
|
||||||
Log::trace(LOCATION);
|
Log::trace(LOCATION);
|
||||||
|
|
||||||
|
// Run server structural validation rules
|
||||||
|
for (const auto &rule : structuralRules_) {
|
||||||
|
try {
|
||||||
|
ValidationResult result = rule->validateServer(config);
|
||||||
|
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()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run server directive validation rules
|
||||||
validateConfig(serverRules_, config);
|
validateConfig(serverRules_, config);
|
||||||
|
|
||||||
for (const auto &path : config->getLocationPaths())
|
for (const auto &path : config->getLocationPaths())
|
||||||
{
|
{
|
||||||
const LocationConfig *locationConfig = config->getLocation(path);
|
const LocationConfig *locationConfig = config->getLocation(path);
|
||||||
@ -134,7 +173,23 @@ void ValidationEngine::validateServerConfig(const ServerConfig *config)
|
|||||||
void ValidationEngine::validateGlobalConfig(const GlobalConfig *config)
|
void ValidationEngine::validateGlobalConfig(const GlobalConfig *config)
|
||||||
{
|
{
|
||||||
Log::trace(LOCATION);
|
Log::trace(LOCATION);
|
||||||
|
|
||||||
|
// Run global structural validation rules
|
||||||
|
for (const auto &rule : structuralRules_) {
|
||||||
|
try {
|
||||||
|
ValidationResult result = rule->validateGlobal(config);
|
||||||
|
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()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run global directive validation rules
|
||||||
validateConfig(globalRules_, config);
|
validateConfig(globalRules_, config);
|
||||||
|
|
||||||
for (const auto *serverConfig : config->getServerConfigs())
|
for (const auto *serverConfig : config->getServerConfigs())
|
||||||
{
|
{
|
||||||
validateServerConfig(serverConfig);
|
validateServerConfig(serverConfig);
|
||||||
@ -149,6 +204,8 @@ ValidationEngine::ValidationEngine(const GlobalConfig *globalConfig) : globalCon
|
|||||||
void ValidationEngine::validate()
|
void ValidationEngine::validate()
|
||||||
{
|
{
|
||||||
Log::trace(LOCATION);
|
Log::trace(LOCATION);
|
||||||
|
results_.clear(); // Clear previous results
|
||||||
|
|
||||||
if (globalConfig_ != nullptr)
|
if (globalConfig_ != nullptr)
|
||||||
{
|
{
|
||||||
validateGlobalConfig(globalConfig_);
|
validateGlobalConfig(globalConfig_);
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
#include <webserv/config/ServerConfig.hpp>
|
#include <webserv/config/ServerConfig.hpp>
|
||||||
#include <webserv/config/validation/ValidationResult.hpp> // for ValidationResult
|
#include <webserv/config/validation/ValidationResult.hpp> // for ValidationResult
|
||||||
#include <webserv/config/validation/directive_rules/AValidationRule.hpp> // for AValidationRule
|
#include <webserv/config/validation/directive_rules/AValidationRule.hpp> // for AValidationRule
|
||||||
|
#include <webserv/config/validation/structural_rules/AStructuralValidationRule.hpp> // for AStructuralValidationRule
|
||||||
|
|
||||||
#include <map> // for map
|
#include <map> // for map
|
||||||
#include <memory> // for unique_ptr
|
#include <memory> // for unique_ptr
|
||||||
@ -33,6 +34,9 @@ class ValidationEngine
|
|||||||
void addServerRule(const std::string &directiveName, std::unique_ptr<AValidationRule> rule);
|
void addServerRule(const std::string &directiveName, std::unique_ptr<AValidationRule> rule);
|
||||||
void addLocationRule(const std::string &directiveName, std::unique_ptr<AValidationRule> rule);
|
void addLocationRule(const std::string &directiveName, std::unique_ptr<AValidationRule> rule);
|
||||||
|
|
||||||
|
// Structural validation rules
|
||||||
|
void addStructuralRule(std::unique_ptr<AStructuralValidationRule> rule);
|
||||||
|
|
||||||
void validate();
|
void validate();
|
||||||
|
|
||||||
[[nodiscard]] std::vector<ValidationResult> getValidationResults() const;
|
[[nodiscard]] std::vector<ValidationResult> getValidationResults() const;
|
||||||
@ -47,9 +51,11 @@ class ValidationEngine
|
|||||||
void validateGlobalConfig(const GlobalConfig *config);
|
void validateGlobalConfig(const GlobalConfig *config);
|
||||||
void validateServerConfig(const ServerConfig *config);
|
void validateServerConfig(const ServerConfig *config);
|
||||||
void validateLocationConfig(const std::string &path, const LocationConfig *config);
|
void validateLocationConfig(const std::string &path, const LocationConfig *config);
|
||||||
|
|
||||||
RuleMap globalRules_;
|
RuleMap globalRules_;
|
||||||
RuleMap serverRules_;
|
RuleMap serverRules_;
|
||||||
RuleMap locationRules_;
|
RuleMap locationRules_;
|
||||||
|
std::vector<std::unique_ptr<AStructuralValidationRule>> structuralRules_;
|
||||||
const GlobalConfig *globalConfig_;
|
const GlobalConfig *globalConfig_;
|
||||||
|
|
||||||
std::vector<ValidationResult> results_;
|
std::vector<ValidationResult> results_;
|
||||||
|
|||||||
@ -0,0 +1,58 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "webserv/config/validation/ValidationResult.hpp"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class GlobalConfig;
|
||||||
|
class ServerConfig;
|
||||||
|
class LocationConfig;
|
||||||
|
|
||||||
|
class AStructuralValidationRule
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::string ruleName_;
|
||||||
|
std::string description_;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
AStructuralValidationRule(const std::string &ruleName, const std::string &description)
|
||||||
|
: ruleName_(ruleName), description_(description) {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual ~AStructuralValidationRule() = default;
|
||||||
|
|
||||||
|
AStructuralValidationRule(const AStructuralValidationRule &other) = delete;
|
||||||
|
AStructuralValidationRule &operator=(const AStructuralValidationRule &other) = delete;
|
||||||
|
AStructuralValidationRule(AStructuralValidationRule &&other) noexcept = delete;
|
||||||
|
AStructuralValidationRule &operator=(AStructuralValidationRule &&other) noexcept = delete;
|
||||||
|
|
||||||
|
// Virtual validation methods - override as needed
|
||||||
|
[[nodiscard]] virtual ValidationResult validateGlobal(const GlobalConfig *config) const
|
||||||
|
{
|
||||||
|
static_cast<void>(config); // Suppress unused parameter warning
|
||||||
|
return ValidationResult::success(); // Default: no global validation
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] virtual ValidationResult validateServer(const ServerConfig *config) const
|
||||||
|
{
|
||||||
|
static_cast<void>(config); // Suppress unused parameter warning
|
||||||
|
return ValidationResult::success(); // Default: no server validation
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] virtual ValidationResult validateLocation(const LocationConfig *config) const
|
||||||
|
{
|
||||||
|
static_cast<void>(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 getDescription() const
|
||||||
|
{
|
||||||
|
return description_;
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
#include "webserv/config/validation/structural_rules/MinimumServerBlocksRule.hpp"
|
||||||
|
|
||||||
|
#include "webserv/config/GlobalConfig.hpp"
|
||||||
|
#include "webserv/log/Log.hpp"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
MinimumServerBlocksRule::MinimumServerBlocksRule(size_t minimumServers)
|
||||||
|
: AStructuralValidationRule("MinimumServerBlocksRule",
|
||||||
|
"Ensures global config has at least " + std::to_string(minimumServers) + " server block(s)"),
|
||||||
|
minimumServers_(minimumServers)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ValidationResult MinimumServerBlocksRule::validateGlobal(const GlobalConfig *config) const
|
||||||
|
{
|
||||||
|
Log::trace(LOCATION);
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ValidationResult::success();
|
||||||
|
}
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "webserv/config/validation/structural_rules/AStructuralValidationRule.hpp"
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
class GlobalConfig;
|
||||||
|
|
||||||
|
class MinimumServerBlocksRule : public AStructuralValidationRule
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
size_t minimumServers_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit MinimumServerBlocksRule(size_t minimumServers = 1);
|
||||||
|
|
||||||
|
~MinimumServerBlocksRule() override = default;
|
||||||
|
|
||||||
|
MinimumServerBlocksRule(const MinimumServerBlocksRule &other) = delete;
|
||||||
|
MinimumServerBlocksRule &operator=(const MinimumServerBlocksRule &other) = delete;
|
||||||
|
MinimumServerBlocksRule(MinimumServerBlocksRule &&other) noexcept = delete;
|
||||||
|
MinimumServerBlocksRule &operator=(MinimumServerBlocksRule &&other) noexcept = delete;
|
||||||
|
|
||||||
|
[[nodiscard]] ValidationResult validateGlobal(const GlobalConfig *config) const override;
|
||||||
|
};
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
#include "webserv/config/validation/structural_rules/RequiredLocationBlocksRule.hpp"
|
||||||
|
|
||||||
|
#include "webserv/config/ServerConfig.hpp"
|
||||||
|
#include "webserv/log/Log.hpp"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
RequiredLocationBlocksRule::RequiredLocationBlocksRule(size_t minimumLocations)
|
||||||
|
: AStructuralValidationRule("RequiredLocationBlocksRule",
|
||||||
|
"Ensures server has at least " + std::to_string(minimumLocations) + " location block(s)"),
|
||||||
|
minimumLocations_(minimumLocations)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ValidationResult RequiredLocationBlocksRule::validateServer(const ServerConfig *config) const
|
||||||
|
{
|
||||||
|
Log::trace(LOCATION);
|
||||||
|
|
||||||
|
if (config == nullptr) {
|
||||||
|
return ValidationResult::error("Server config is null");
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t locationCount = config->getLocationPaths().size();
|
||||||
|
|
||||||
|
if (locationCount < minimumLocations_) {
|
||||||
|
return ValidationResult::error(
|
||||||
|
"Server block must have at least " + std::to_string(minimumLocations_) +
|
||||||
|
" location block(s), but found " + std::to_string(locationCount));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ValidationResult::success();
|
||||||
|
}
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "webserv/config/validation/structural_rules/AStructuralValidationRule.hpp"
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
class ServerConfig;
|
||||||
|
|
||||||
|
class RequiredLocationBlocksRule : public AStructuralValidationRule
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
size_t minimumLocations_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit RequiredLocationBlocksRule(size_t minimumLocations = 1);
|
||||||
|
|
||||||
|
~RequiredLocationBlocksRule() override = default;
|
||||||
|
|
||||||
|
RequiredLocationBlocksRule(const RequiredLocationBlocksRule &other) = delete;
|
||||||
|
RequiredLocationBlocksRule &operator=(const RequiredLocationBlocksRule &other) = delete;
|
||||||
|
RequiredLocationBlocksRule(RequiredLocationBlocksRule &&other) noexcept = delete;
|
||||||
|
RequiredLocationBlocksRule &operator=(RequiredLocationBlocksRule &&other) noexcept = delete;
|
||||||
|
|
||||||
|
[[nodiscard]] ValidationResult validateServer(const ServerConfig *config) const override;
|
||||||
|
};
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
// Base class
|
||||||
|
#include "webserv/config/validation/structural_rules/AStructuralValidationRule.hpp"
|
||||||
|
|
||||||
|
// Concrete structural validation rules
|
||||||
|
#include "webserv/config/validation/structural_rules/MinimumServerBlocksRule.hpp"
|
||||||
|
#include "webserv/config/validation/structural_rules/RequiredLocationBlocksRule.hpp"
|
||||||
|
#include "webserv/config/validation/structural_rules/UniqueServerNamesRule.hpp"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Structural Validation Rules for WebServ Configuration
|
||||||
|
*
|
||||||
|
* These rules validate the overall structure and relationships
|
||||||
|
* between configuration blocks, rather than individual directive values.
|
||||||
|
*
|
||||||
|
* Available Rules:
|
||||||
|
*
|
||||||
|
* 1. MinimumServerBlocksRule - Ensures global config has minimum number of server blocks
|
||||||
|
* 2. RequiredLocationBlocksRule - Ensures each server has minimum number of location blocks
|
||||||
|
* 3. UniqueServerNamesRule - Ensures all server names are unique across configuration
|
||||||
|
*
|
||||||
|
* Usage:
|
||||||
|
*
|
||||||
|
* // In ValidationEngine setup
|
||||||
|
* engine.addStructuralRule(std::make_unique<MinimumServerBlocksRule>(1));
|
||||||
|
* engine.addStructuralRule(std::make_unique<RequiredLocationBlocksRule>(1));
|
||||||
|
* engine.addStructuralRule(std::make_unique<UniqueServerNamesRule>());
|
||||||
|
*
|
||||||
|
* Each rule inherits from AStructuralValidationRule and can validate at:
|
||||||
|
* - Global level (validateGlobal)
|
||||||
|
* - Server level (validateServer)
|
||||||
|
* - Location level (validateLocation)
|
||||||
|
*
|
||||||
|
* Rules have descriptive names and descriptions set in their constructors.
|
||||||
|
*/
|
||||||
@ -0,0 +1,49 @@
|
|||||||
|
#include "webserv/config/validation/structural_rules/UniqueServerNamesRule.hpp"
|
||||||
|
|
||||||
|
#include "webserv/config/GlobalConfig.hpp"
|
||||||
|
#include "webserv/config/ServerConfig.hpp"
|
||||||
|
#include "webserv/log/Log.hpp"
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
#include <set>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
UniqueServerNamesRule::UniqueServerNamesRule()
|
||||||
|
: AStructuralValidationRule("UniqueServerNamesRule",
|
||||||
|
"Ensures all server blocks have unique server names")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ValidationResult UniqueServerNamesRule::validateGlobal(const GlobalConfig *config) const
|
||||||
|
{
|
||||||
|
Log::trace(LOCATION);
|
||||||
|
|
||||||
|
if (config == nullptr) {
|
||||||
|
return ValidationResult::error("Global config is null");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::set<std::string> serverNames;
|
||||||
|
auto servers = config->getServerConfigs();
|
||||||
|
|
||||||
|
for (const auto *server : servers) {
|
||||||
|
if (server == nullptr) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto serverNameOpt = server->get<std::string>("server_name");
|
||||||
|
auto listenOpt = server->get<int>("listen");
|
||||||
|
if (serverNameOpt.has_value() && listenOpt.has_value()) {
|
||||||
|
const std::string &serverName = serverNameOpt.value();
|
||||||
|
int listenPort = listenOpt.value();
|
||||||
|
|
||||||
|
if (serverNames.contains(serverName + ":" + std::to_string(listenPort))) {
|
||||||
|
return ValidationResult::error(
|
||||||
|
"Duplicate server name '" + serverName + "' found in configuration");
|
||||||
|
}
|
||||||
|
|
||||||
|
serverNames.insert(serverName + ":" + std::to_string(listenPort));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ValidationResult::success();
|
||||||
|
}
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "webserv/config/validation/structural_rules/AStructuralValidationRule.hpp"
|
||||||
|
|
||||||
|
class GlobalConfig;
|
||||||
|
|
||||||
|
class UniqueServerNamesRule : public AStructuralValidationRule
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
UniqueServerNamesRule();
|
||||||
|
|
||||||
|
~UniqueServerNamesRule() override = default;
|
||||||
|
|
||||||
|
UniqueServerNamesRule(const UniqueServerNamesRule &other) = delete;
|
||||||
|
UniqueServerNamesRule &operator=(const UniqueServerNamesRule &other) = delete;
|
||||||
|
UniqueServerNamesRule(UniqueServerNamesRule &&other) noexcept = delete;
|
||||||
|
UniqueServerNamesRule &operator=(UniqueServerNamesRule &&other) noexcept = delete;
|
||||||
|
|
||||||
|
[[nodiscard]] ValidationResult validateGlobal(const GlobalConfig *config) const override;
|
||||||
|
};
|
||||||
Loading…
Reference in New Issue
Block a user