diff --git a/webserv/client/Client.cpp b/webserv/client/Client.cpp index c16cbfa..ab7c54a 100644 --- a/webserv/client/Client.cpp +++ b/webserv/client/Client.cpp @@ -140,7 +140,7 @@ void Client::poll() const auto *cgiHandler = dynamic_cast(handler_.get()); if (cgiHandler != nullptr) { - Log::debug("Polling CGI handler for client, fd: " + std::to_string(clientSocket_->getFd())); + // Log::debug("Polling CGI handler for client, fd: " + std::to_string(clientSocket_->getFd())); // CGI handler polling logic if needed cgiHandler->wait(); } diff --git a/webserv/client/Client.hpp b/webserv/client/Client.hpp index e64354d..432b906 100644 --- a/webserv/client/Client.hpp +++ b/webserv/client/Client.hpp @@ -58,9 +58,9 @@ class Client std::unique_ptr httpRequest_; std::unique_ptr httpResponse_; std::unique_ptr router_; - std::unique_ptr handler_ = nullptr; std::unique_ptr clientSocket_; std::unordered_map sockets_; + std::unique_ptr handler_ = nullptr; Server &server_; void writeToCgi(); diff --git a/webserv/handler/AHandler.cpp b/webserv/handler/AHandler.cpp index e119daf..0f640bf 100644 --- a/webserv/handler/AHandler.cpp +++ b/webserv/handler/AHandler.cpp @@ -10,6 +10,10 @@ AHandler::AHandler(const HttpRequest &request, HttpResponse &response) : request_(request), response_(response) {} +AHandler::~AHandler() +{ + cancelTimer(); +} void AHandler::startTimer() { timerSocket_ = std::make_unique(std::chrono::milliseconds(5000)); diff --git a/webserv/handler/AHandler.hpp b/webserv/handler/AHandler.hpp index 9cff463..eaca3af 100644 --- a/webserv/handler/AHandler.hpp +++ b/webserv/handler/AHandler.hpp @@ -10,7 +10,7 @@ class AHandler { public: AHandler(const HttpRequest &request, HttpResponse &response); - virtual ~AHandler() = default; + virtual ~AHandler(); AHandler(const AHandler &other) = delete; AHandler &operator=(const AHandler &other) = delete; diff --git a/webserv/handler/CgiHandler.cpp b/webserv/handler/CgiHandler.cpp index f3ac0ad..a147362 100644 --- a/webserv/handler/CgiHandler.cpp +++ b/webserv/handler/CgiHandler.cpp @@ -1,4 +1,5 @@ #include "webserv/handler/ErrorHandler.hpp" + #include // for Client #include #include // for CgiProcess @@ -8,6 +9,8 @@ #include // for CgiSocket #include // for stoul +#include + CgiHandler::CgiHandler(const HttpRequest &request, HttpResponse &response) : AHandler(request, response), cgiProcess_(nullptr), cgiStdIn_(nullptr), cgiStdOut_(nullptr) { @@ -74,7 +77,7 @@ void CgiHandler::read() { Log::info("CGI process closed stdout, fd: " + std::to_string(cgiStdOut_->getFd())); request_.getClient().removeSocket(cgiStdOut_.get()); - request_.getClient().removeSocket(timerSocket_.get()); + // request_.getClient().removeSocket(timerSocket_.get()); cgiStdOut_ = nullptr; parseCgiOutput(); return; @@ -107,19 +110,20 @@ void CgiHandler::error() { Log::info("CGI process closed stderr, fd: " + std::to_string(cgiStdErr_->getFd())); request_.getClient().removeSocket(cgiStdErr_.get()); - request_.getClient().removeSocket(timerSocket_.get()); // todo maybe this dangerous + // request_.getClient().removeSocket(timerSocket_.get()); // todo maybe this dangerous cgiStdErr_ = nullptr; return; } else { buffer[bytesRead] = '\0'; // NOLINT(cppcoreguidelines-pro-bounds-constant-array-index) - Log::error("CGI stderr output (fd: " + std::to_string(cgiStdErr_->getFd()) + "): " - + std::string(buffer, static_cast(bytesRead))); + Log::error("CGI stderr output (fd: " + std::to_string(cgiStdErr_->getFd()) + + "): " + std::string(buffer, static_cast(bytesRead))); } } -void CgiHandler::setCgiSockets(std::unique_ptr cgiStdIn, std::unique_ptr cgiStdOut, std::unique_ptr cgiStdErr) +void CgiHandler::setCgiSockets(std::unique_ptr cgiStdIn, std::unique_ptr cgiStdOut, + std::unique_ptr cgiStdErr) { cgiStdIn->setCallback([this]() { write(); }); cgiStdOut->setCallback([this]() { read(); }); @@ -221,7 +225,14 @@ void CgiHandler::parseCgiHeaders(std::string &headers) void CgiHandler::handleTimeout() { Log::warning("CGI handler timeout occurred for PID: " + std::to_string(pid_)); - + char buffer[9] = {}; // NOLINT(cppcoreguidelines-avoid-c-arrays) + ssize_t bytesRead = timerSocket_->read(buffer, sizeof(buffer) - 1); + buffer[bytesRead] = '\0'; + if (bytesRead <= 0) + { + // NOLINT(cppcoreguidelines-pro-bounds-constant-array-index) + return; + } // Terminate the CGI process if it's still running if (cgiProcess_) { diff --git a/webserv/socket/TimerSocket.cpp b/webserv/socket/TimerSocket.cpp index bd86811..1162cb3 100644 --- a/webserv/socket/TimerSocket.cpp +++ b/webserv/socket/TimerSocket.cpp @@ -43,4 +43,26 @@ ASocket::Type TimerSocket::getType() const noexcept bool TimerSocket::isActive() const noexcept { return active_; +} + +ssize_t TimerSocket::read(void *buf, size_t len) const +{ + Log::trace(LOCATION); + ssize_t bytesRead = ::read(getFd(), buf, len); + if (bytesRead == -1) + { + throw std::system_error(errno, std::generic_category(), "Socket: Read error"); + } + return bytesRead; +} + +ssize_t TimerSocket::write(const void *buf, size_t len) const +{ + Log::trace(LOCATION); + ssize_t bytesSent = ::write(getFd(), buf, len); + if (bytesSent == -1) + { + throw std::system_error(errno, std::generic_category(), "Socket: Write error"); + } + return bytesSent; } \ No newline at end of file diff --git a/webserv/socket/TimerSocket.hpp b/webserv/socket/TimerSocket.hpp index 2042484..70895fa 100644 --- a/webserv/socket/TimerSocket.hpp +++ b/webserv/socket/TimerSocket.hpp @@ -1,18 +1,23 @@ #pragma once #include "webserv/socket/ASocket.hpp" + #include class TimerSocket : public ASocket { - public: - explicit TimerSocket(std::chrono::milliseconds timeout); - - [[nodiscard]] ASocket::Type getType() const noexcept override; - [[nodiscard]] bool isActive() const noexcept; + public: + explicit TimerSocket(std::chrono::milliseconds timeout); - void activate(); - private: - bool active_ = false; - std::chrono::milliseconds timeout_; + [[nodiscard]] ASocket::Type getType() const noexcept override; + [[nodiscard]] bool isActive() const noexcept; + + ssize_t read(void *buf, size_t len) const override; + ssize_t write(const void *buf, size_t len) const override; + + void activate(); + + private: + bool active_ = false; + std::chrono::milliseconds timeout_; }; \ No newline at end of file