diff --git a/htdocs/site-3/index.php b/htdocs/site-3/index.php index 4ee9e65..8dba1c0 100644 --- a/htdocs/site-3/index.php +++ b/htdocs/site-3/index.php @@ -1,6 +1,10 @@ diff --git a/webserv/handler/CgiHandler.cpp b/webserv/handler/CgiHandler.cpp index 21d8eff..18ced50 100644 --- a/webserv/handler/CgiHandler.cpp +++ b/webserv/handler/CgiHandler.cpp @@ -5,6 +5,7 @@ #include // for HttpResponse #include // for Log #include // for CgiSocket +#include // for stoul CgiHandler::CgiHandler(const HttpRequest &request, HttpResponse &response) : AHandler(request, response), cgiProcess_(nullptr), cgiStdIn_(nullptr), cgiStdOut_(nullptr) @@ -19,7 +20,6 @@ void CgiHandler::handle() // Initialize CGI process cgiProcess_ = std::make_unique(request_, *this); - Log::info("CGI process started and sockets registered"); } @@ -72,14 +72,13 @@ void CgiHandler::read() Log::info("CGI process closed stdout, fd: " + std::to_string(cgiStdOut_->getFd())); request_.getClient().removeCgiSocket(cgiStdOut_.get()); cgiStdOut_ = nullptr; - response_.addHeader("Content-Type", "text/html"); - response_.setComplete(); + parseCgiOutput(); return; } else { buffer[bytesRead] = '\0'; // NOLINT(cppcoreguidelines-pro-bounds-constant-array-index) - response_.appendBody(std::string(buffer, static_cast(bytesRead))); + appendToBuffer(buffer, static_cast(bytesRead)); Log::debug("Read " + std::to_string(bytesRead) + " bytes from CGI stdout, fd: " + std::to_string(cgiStdOut_->getFd())); } @@ -109,5 +108,63 @@ void CgiHandler::wait() noexcept void CgiHandler::setPid(int pid) { pid_ = pid; +} +void CgiHandler::parseCgiOutput() +{ + Log::trace(LOCATION); + + // Parse the headers from the buffer + size_t headerEnd = std::string(buffer_.begin(), buffer_.end()).find("\r\n\r\n"); + if (headerEnd == std::string::npos) + { + Log::debug("CGI output headers not complete yet"); + return; + } + // Parse the headers + std::string headers(buffer_.begin(), buffer_.begin() + static_cast(headerEnd)); + Log::debug("CGI output headers: " + headers); + parseCgiHeaders(headers); + + buffer_.erase(buffer_.begin(), buffer_.begin() + static_cast(headerEnd) + 4); + parseCgiBody(); +} + +void CgiHandler::parseCgiHeaders(std::string &headers) +{ + Log::trace(LOCATION); + size_t start = 0; + size_t end = headers.find("\r\n"); + while (end != std::string::npos) + { + std::string header = headers.substr(start, end - start); + Log::debug("CGI header: " + header); + size_t colonPos = header.find(':'); + if (colonPos != std::string::npos) + { + std::string name = header.substr(0, colonPos); + std::string value = header.substr(colonPos + 1); + name = utils::trim(name); + value = utils::trim(value); + response_.addHeader(name, value); + } + start = end + 2; + end = headers.find("\r\n", start); + } +} + +void CgiHandler::parseCgiBody() +{ + Log::trace(LOCATION); + + // Append the body to the response + response_.appendBody(buffer_); + response_.setComplete(); + buffer_.clear(); +} + +void CgiHandler::appendToBuffer(const char *data, size_t length) +{ + Log::trace(LOCATION); + buffer_.insert(buffer_.end(), data, data + length); } \ No newline at end of file diff --git a/webserv/handler/CgiHandler.hpp b/webserv/handler/CgiHandler.hpp index 602d5eb..3c9c9b4 100644 --- a/webserv/handler/CgiHandler.hpp +++ b/webserv/handler/CgiHandler.hpp @@ -26,9 +26,16 @@ class CgiHandler : public AHandler private: constexpr static size_t bufferSize_ = 8192; // TODO: remove duplicate definition and move to configmanager + std::vector buffer_; + std::unique_ptr cgiProcess_; std::unique_ptr cgiStdIn_; std::unique_ptr cgiStdOut_; + void parseCgiOutput(); + void parseCgiHeaders(std::string &headers); + void parseCgiBody(); + void appendToBuffer(const char *data, size_t length); + int pid_ = -1;