feat: add CGI standalone

This commit is contained in:
whaffman 2025-10-31 16:01:38 +01:00
parent e792429b50
commit 13f14e8e5e
6 changed files with 65 additions and 13 deletions

View File

@ -122,13 +122,14 @@ server {
cgi_enabled yes;
cgi_handler .php /usr/bin/php-cgi;
cgi_handler .cgi;
}
server {
listen 8083;
host 127.0.0.1;
server_name localhost;
client_max_body_size 1000m;
client_max_body_size 100m;
root ./htdocs/YoupiBanane/;
index index.html index2.htm;
@ -145,7 +146,7 @@ server {
location /post_body {
root ./htdocs/YoupiBanane/;
client_max_body_size 1000m;
client_max_body_size 100m;
allowed_methods POST;
}

View File

@ -150,6 +150,10 @@ std::string AConfig::getCGIPath(const std::string &extension) const
}
auto exts = directive->getValue().try_get<std::vector<std::string>>().value();
auto cgiPath = exts.back();
if (cgiPath.starts_with("."))
{
continue;
}
exts.pop_back(); // Last element is the CGI path
auto it = std::ranges::find(exts, "." + extension);
if (it != exts.end())
@ -162,4 +166,36 @@ std::string AConfig::getCGIPath(const std::string &extension) const
return parent_->getCGIPath(extension);
}
return {}; // Return empty string if not found
}
bool AConfig::isCGI(const std::string &extension) const
{
Log::trace(LOCATION);
for (const auto &directive : directives_)
{
if (directive->getName() != "cgi_handler")
{
continue;
}
if (!directive->getValue().holds<std::vector<std::string>>())
{
continue;
}
auto exts = directive->getValue().try_get<std::vector<std::string>>().value();
if (!exts.back().starts_with("."))
{
exts.pop_back(); // Last element is the CGI path
}
auto it = std::ranges::find(exts, "." + extension);
if (it != exts.end())
{
return true;
}
}
if (parent_ != nullptr)
{
return parent_->isCGI(extension);
}
return false; // Return false if not found
}

View File

@ -24,6 +24,7 @@ class AConfig
void addDirective(const std::string &line);
[[nodiscard]] std::string getErrorPage(int statusCode) const;
[[nodiscard]] std::string getCGIPath(const std::string &extension) const;
[[nodiscard]] bool isCGI(const std::string &extension) const;
[[nodiscard]] bool has(const std::string &name) const;
[[nodiscard]] bool owns(const std::string &name) const;

View File

@ -30,26 +30,32 @@ ValidationResult CgiExtValidationRule::validateValue(const AConfig *config, cons
}
auto cgiExt = directive->getValue().get<std::vector<std::string>>();
if (cgiExt.size() != 2)
if (cgiExt.size() == 0 || cgiExt.size() > 2)
{
return ValidationResult::error("Directive '" + directive->getName()
+ "' has invalid format, expected extension and path");
+ "' has invalid format, expected extension [and path]");
}
auto extension = std::string(cgiExt[0]);
auto path = std::string(cgiExt[1]);
if (extension.empty() || extension[0] != '.')
{
return ValidationResult::error("Directive '" + directive->getName() + "' has invalid extension '" + extension
+ "'");
+ "'");
}
if (!isAllowedCGIExtension(extension))
{
return ValidationResult::error("Directive '" + directive->getName() + "' has unsupported extension '"
+ extension + "'");
+ extension + "'");
}
if (!FileUtils::isFile(path))
if (cgiExt.size() == 2)
{
return ValidationResult::error("Directive '" + directive->getName() + "' has invalid path '" + path + "'");
auto path = std::string(cgiExt[1]);
if (!FileUtils::isFile(path))
{
return ValidationResult::error("Directive '" + directive->getName() + "' has invalid path '" + path + "'");
}
}
return ValidationResult::success();
}

View File

@ -79,12 +79,20 @@ void CgiProcess::spawn()
// Prepare arguments
std::string fullPath = uri.getFullPath();
char *args[] = {const_cast<char *>(cgiPath.c_str()), const_cast<char *>(fullPath.c_str()), nullptr};
char *args[3] = {nullptr, nullptr, nullptr};
if (!cgiPath.empty())
{
args[0] = const_cast<char *>(cgiPath.c_str());
args[1] = const_cast<char *>(fullPath.c_str());
}
else
{
args[0] = const_cast<char *>(fullPath.c_str());
}
// Log::debug("With args:", {args[0], args[1]});
// TODO: Close all FDs
execve(const_cast<char *>(cgiPath.c_str()), args, cgiEnv.toEnvp());
execve(args[0], args, cgiEnv.toEnvp());
exit(1);
}
else

View File

@ -151,7 +151,7 @@ bool URI::isValid() const noexcept
bool URI::isCgi() const noexcept
{
return !getCgiPath().empty();
return config_->isCGI(getExtension());
}
bool URI::isRedirect() const noexcept