webserv/webserv/config/AConfig.cpp

147 lines
3.7 KiB
C++

#include <webserv/config/AConfig.hpp> // for AConfig
#include <webserv/config/directive/ADirective.hpp> // for ADirective
#include <webserv/config/directive/DirectiveFactory.hpp> // for DirectiveFactory
#include <webserv/config/directive/DirectiveValue.hpp> // for DirectiveValue
#include <webserv/log/Log.hpp> // for Log, LOCATION
#include <webserv/utils/utils.hpp> // for trim
#include <sstream> // for basic_stringstream, stringstream
#include <utility> // for pair, move
#include <ranges> // for filter
AConfig::AConfig(const AConfig *parent) : parent_(parent) {}
void AConfig::addDirective(const std::string &line)
{
auto directive = DirectiveFactory::createDirective(line);
if (directive)
{
directives_.emplace_back(std::move(directive));
}
}
const ADirective *AConfig::getDirective(const std::string &name) const
{
for (const auto &directive : directives_)
{
if (directive->getName() == name)
{
return directive.get();
}
}
if (parent_ != nullptr)
{
return parent_->getDirective(name);
}
return nullptr;
}
std::vector<const ADirective *> AConfig::getDirectives() const
{
std::vector<const ADirective *> result;
result.reserve(directives_.size());
for (const auto &directive : directives_)
{
result.push_back(directive.get());
}
return result;
}
bool AConfig::has(const std::string &name) const
{
if (owns(name))
{
return true;
}
if (parent_ != nullptr)
{
return parent_->has(name);
}
return false;
}
bool AConfig::owns(const std::string &name) const
{
for (const auto &directive : directives_)
{
if (directive->getName() == name)
{
return true;
}
}
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::debug("Global Declaration: " + line);
addDirective(line);
}
}
std::string AConfig::getErrorPage(int statusCode) const
{
// TODO
Log::trace(LOCATION);
for (const auto &directive : directives_)
{
if (directive->getName() == "error_page")
{
auto value = directive->getValue().try_get<std::pair<int, std::string>>();
if (value && value->first == statusCode)
{
return value->second;
}
}
}
if (parent_ != nullptr)
{
return parent_->getErrorPage(statusCode);
}
return ""; // Return empty string if not found
}
std::string AConfig::getCGIPath(const std::string &extension) const
{
Log::trace(LOCATION);
for (const auto &directive : directives_ | std::views::filter([](const auto &d) {
return d->getName() == "cgi_ext";
}))
{
if (!directive->getValue().holds<std::vector<std::string>>())
{
continue;
}
auto exts = directive->getValue().try_get<std::vector<std::string>>().value();
{
continue;
}
auto cgiPath = exts.back();
exts.pop_back(); // Last element is the CGI path
auto it = std::ranges::find(exts, extension);
if (it != exts.end())
{
return cgiPath;
}
}
if (parent_ != nullptr)
{
return parent_->getCGIPath(extension);
}
return {}; // Return empty string if not found
}