feat: add CGI standalone
This commit is contained in:
parent
e792429b50
commit
13f14e8e5e
@ -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;
|
||||
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
@ -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;
|
||||
|
||||
@ -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();
|
||||
}
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
Reference in New Issue
Block a user