feat: better status hanlding cgi and custom env
This commit is contained in:
parent
c2bdbeb307
commit
6d3941ddf2
@ -17,7 +17,7 @@ CgiExtValidationRule::CgiExtValidationRule(bool requiresValue)
|
||||
|
||||
bool isAllowedCGIExtension(const std::string &extension)
|
||||
{
|
||||
static const std::vector<std::string> allowedExtensions = {".php", ".py", ".bla", ".sh", ".cgi"};
|
||||
static const std::vector<std::string> allowedExtensions = {".php", ".py", ".bla", ".cgi", ".sh"};
|
||||
return std::ranges::any_of(allowedExtensions, [&extension](const auto &it) { return extension == it; });
|
||||
}
|
||||
|
||||
|
||||
@ -1,14 +1,19 @@
|
||||
#include <webserv/handler/CgiEnvironment.hpp>
|
||||
#include "webserv/http/HttpRequest.hpp"
|
||||
#include "webserv/log/Log.hpp"
|
||||
|
||||
#include <webserv/handler/CgiEnvironment.hpp>
|
||||
#include <webserv/handler/URI.hpp> // for URI
|
||||
#include <webserv/http/HttpHeaders.hpp> // for HttpHeaders
|
||||
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <cstring> // for strcpy, size_t
|
||||
#include <optional> // for optional
|
||||
#include <utility> // for pair
|
||||
|
||||
CgiEnvironment::CgiEnvironment(const URI &uri, const HttpRequest &request)
|
||||
{
|
||||
Log::trace(LOCATION);
|
||||
env_["GATEWAY_INTERFACE"] = "CGI/1.1";
|
||||
env_["SERVER_PROTOCOL"] = "HTTP/1.1";
|
||||
env_["REQUEST_METHOD"] = request.getMethod();
|
||||
@ -38,7 +43,7 @@ CgiEnvironment::CgiEnvironment(const URI &uri, const HttpRequest &request)
|
||||
env_["SERVER_NAME"] = host;
|
||||
env_["SERVER_PORT"] = std::to_string(port);
|
||||
env_["REMOTE_ADDR"] = request.getClient().getClientAddress(); // Placeholder, should be set to actual remote address
|
||||
env_["REDIRECT_STATUS"] = "200"; // Required by PHP with force-cgi-redirect enabled
|
||||
env_["REDIRECT_STATUS"] = "200"; // Required by PHP with force-cgi-redirect enabled
|
||||
env_["SERVER_SOFTWARE"] = "Webserv/1.0";
|
||||
env_["REQUEST_SCHEME"] = "HTTP";
|
||||
env_["HTTP_VERSION"] = "1.1";
|
||||
@ -49,6 +54,8 @@ CgiEnvironment::CgiEnvironment(const URI &uri, const HttpRequest &request)
|
||||
env_["HTTP_ACCEPT"] = headers.get("Accept");
|
||||
env_["HTTP_ACCEPT_LANGUAGE"] = headers.get("Accept-Language");
|
||||
env_["HTTP_ACCEPT_ENCODING"] = headers.get("Accept-Encoding");
|
||||
|
||||
appendCustomHeaders(headers);
|
||||
}
|
||||
|
||||
char **CgiEnvironment::toEnvp() const
|
||||
@ -64,3 +71,20 @@ char **CgiEnvironment::toEnvp() const
|
||||
envp[index] = nullptr; // Null-terminate the array
|
||||
return envp;
|
||||
}
|
||||
|
||||
void CgiEnvironment::appendCustomHeaders(const HttpHeaders &headers)
|
||||
{
|
||||
Log::trace(LOCATION);
|
||||
for (const auto &header : headers.getAll())
|
||||
{
|
||||
if (!header.first.starts_with("x-"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
std::string key = "HTTP_" + header.first;
|
||||
std::transform(key.begin(), key.end(), key.begin(), ::toupper);
|
||||
std::replace(key.begin(), key.end(), '-', '_');
|
||||
env_[key] = header.second;
|
||||
Log::debug("Added custom header with key: " + key + " And value: " + header.second);
|
||||
}
|
||||
}
|
||||
@ -18,5 +18,6 @@ class CgiEnvironment
|
||||
[[nodiscard]] char **toEnvp() const;
|
||||
|
||||
private:
|
||||
void appendCustomHeaders(const HttpHeaders &headers);
|
||||
std::map<std::string, std::string> env_;
|
||||
};
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
#include <webserv/handler/CgiHandler.hpp>
|
||||
|
||||
#include <webserv/client/Client.hpp> // for Client
|
||||
#include <webserv/handler/CgiHandler.hpp>
|
||||
#include <webserv/handler/CgiProcess.hpp> // for CgiProcess
|
||||
#include <webserv/handler/ErrorHandler.hpp> // for ErrorHandler
|
||||
#include <webserv/http/HttpRequest.hpp> // for HttpRequest
|
||||
@ -11,6 +10,8 @@
|
||||
#include <webserv/utils/utils.hpp> // for trim
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <functional> // for function
|
||||
#include <utility> // for move
|
||||
|
||||
@ -268,7 +269,16 @@ void CgiHandler::parseCgiBody()
|
||||
{
|
||||
Log::trace(LOCATION);
|
||||
|
||||
// Append the body to the response
|
||||
auto status = response_.getHeaders().get("Status");
|
||||
|
||||
if (cgiProcess_->getExitCode() > 0 && !status.empty())
|
||||
{
|
||||
response_.setStatus(500);
|
||||
}
|
||||
else if (!status.empty())
|
||||
{
|
||||
response_.setStatus(std::atoi(status.c_str()));
|
||||
}
|
||||
response_.appendBody(buffer_);
|
||||
response_.setComplete();
|
||||
buffer_.clear();
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
#include <webserv/handler/CgiProcess.hpp>
|
||||
|
||||
#include <webserv/handler/CgiEnvironment.hpp> // for CgiEnvironment
|
||||
#include <webserv/handler/CgiHandler.hpp> // for CgiHandler
|
||||
#include <webserv/handler/CgiProcess.hpp>
|
||||
#include <webserv/handler/URI.hpp> // for URI
|
||||
#include <webserv/http/HttpRequest.hpp> // for HttpRequest
|
||||
#include <webserv/log/Log.hpp> // for Log
|
||||
@ -19,7 +18,7 @@
|
||||
#include <sys/wait.h> // for waitpid, WNOHANG
|
||||
#include <unistd.h> // for close, dup2, pipe2, execve, fork, STDERR_FILENO, STDIN_FILENO, STDOUT_FILENO
|
||||
|
||||
CgiProcess::CgiProcess(const HttpRequest &request, CgiHandler &handler) : request_(request), handler_(handler), _pid(-1)
|
||||
CgiProcess::CgiProcess(const HttpRequest &request, CgiHandler &handler) : request_(request), handler_(handler), pid_(-1), status_(-1)
|
||||
{
|
||||
if (!request_.getUri().isCgi())
|
||||
{
|
||||
@ -49,8 +48,8 @@ void CgiProcess::spawn()
|
||||
}
|
||||
// NOLINTEND
|
||||
CgiEnvironment cgiEnv(uri, request_);
|
||||
_pid = fork();
|
||||
if (_pid < 0)
|
||||
pid_ = fork();
|
||||
if (pid_ < 0)
|
||||
{
|
||||
close(pipeStdin[0]);
|
||||
close(pipeStdin[1]);
|
||||
@ -60,7 +59,7 @@ void CgiProcess::spawn()
|
||||
close(pipeStderr[1]);
|
||||
throw std::runtime_error("Failed to fork");
|
||||
}
|
||||
if (_pid == 0)
|
||||
if (pid_ == 0)
|
||||
{
|
||||
dup2(pipeStdin[0], STDIN_FILENO);
|
||||
dup2(pipeStdout[1], STDOUT_FILENO);
|
||||
@ -98,34 +97,34 @@ void CgiProcess::spawn()
|
||||
close(pipeStdout[1]);
|
||||
close(pipeStderr[1]);
|
||||
|
||||
Log::debug("CGI process forked with PID: " + std::to_string(_pid));
|
||||
Log::debug("CGI process forked with PID: " + std::to_string(pid_));
|
||||
|
||||
// request_.getClient().setCgiSockets(std::move(cgiStdIn), std::move(cgiStdOut)); // move the sockets to the
|
||||
// client
|
||||
handler_.setCgiSockets(std::move(cgiStdIn), std::move(cgiStdOut), std::move(cgiStdErr));
|
||||
|
||||
handler_.setPid(_pid);
|
||||
handler_.setPid(pid_);
|
||||
}
|
||||
}
|
||||
|
||||
void CgiProcess::kill() const noexcept
|
||||
{
|
||||
if (_pid > 0)
|
||||
if (pid_ > 0)
|
||||
{
|
||||
::kill(_pid, SIGKILL);
|
||||
Log::debug("Killed CGI process with PID: " + std::to_string(_pid));
|
||||
::kill(pid_, SIGKILL);
|
||||
Log::debug("Killed CGI process with PID: " + std::to_string(pid_));
|
||||
}
|
||||
}
|
||||
|
||||
void CgiProcess::wait() noexcept
|
||||
{
|
||||
if (_pid > 0)
|
||||
if (pid_ > 0)
|
||||
{
|
||||
int status;
|
||||
int waitResult = ::waitpid(_pid, &status, WNOHANG);
|
||||
int waitResult = ::waitpid(pid_, &status, WNOHANG);
|
||||
if (waitResult == -1)
|
||||
{
|
||||
Log::error("Error while waiting for CGI process with PID: " + std::to_string(_pid));
|
||||
Log::error("Error while waiting for CGI process with PID: " + std::to_string(pid_));
|
||||
return;
|
||||
}
|
||||
if (waitResult == 0)
|
||||
@ -134,8 +133,13 @@ void CgiProcess::wait() noexcept
|
||||
return;
|
||||
}
|
||||
|
||||
Log::debug("CGI process with PID " + std::to_string(_pid) + " has terminated");
|
||||
;
|
||||
_pid = -1;
|
||||
Log::debug("CGI process with PID " + std::to_string(pid_) + " has terminated with status " + std::to_string(status));
|
||||
status_ = status;
|
||||
pid_ = -1;
|
||||
}
|
||||
}
|
||||
|
||||
int CgiProcess::getExitCode() const noexcept
|
||||
{
|
||||
return status_;
|
||||
}
|
||||
@ -20,11 +20,14 @@ class CgiProcess
|
||||
void kill() const noexcept;
|
||||
void wait() noexcept;
|
||||
|
||||
[[nodiscard]] int getExitCode() const noexcept;
|
||||
|
||||
private:
|
||||
const HttpRequest &request_;
|
||||
CgiHandler &handler_;
|
||||
|
||||
int _pid;
|
||||
int pid_;
|
||||
int status_;
|
||||
// int _cgiFd;
|
||||
|
||||
void spawn();
|
||||
|
||||
@ -1,12 +1,13 @@
|
||||
#include <webserv/http/HttpHeaders.hpp> // for HttpHeaders
|
||||
|
||||
#include <webserv/http/HttpConstants.hpp> // for CRLF
|
||||
#include <webserv/http/HttpHeaders.hpp> // for HttpHeaders
|
||||
#include <webserv/log/Log.hpp>
|
||||
#include <webserv/utils/utils.hpp> // for trim
|
||||
|
||||
#include <algorithm> // for __transform_fn, transform
|
||||
#include <cctype> // for tolower
|
||||
#include <utility> // for pair
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <utility> // for pair
|
||||
|
||||
std::optional<size_t> HttpHeaders::getContentLength() const
|
||||
{
|
||||
@ -94,6 +95,11 @@ void HttpHeaders::parse(const std::string &rawHeaders) noexcept
|
||||
}
|
||||
}
|
||||
|
||||
const std::unordered_map<std::string, std::string> &HttpHeaders::getAll() const noexcept
|
||||
{
|
||||
return headers_;
|
||||
}
|
||||
|
||||
std::string HttpHeaders::toString() const noexcept
|
||||
{
|
||||
std::string result;
|
||||
|
||||
@ -29,6 +29,7 @@ class HttpHeaders
|
||||
[[nodiscard]] std::optional<size_t> getContentLength() const;
|
||||
[[nodiscard]] std::optional<std::string> getContentType() const noexcept;
|
||||
[[nodiscard]] std::optional<std::string> getHost() const noexcept;
|
||||
[[nodiscard]] const std::unordered_map<std::string, std::string> &getAll() const noexcept;
|
||||
|
||||
private:
|
||||
std::unordered_map<std::string, std::string> headers_;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user