feat: implement CGI process management with wait and kill functionality
This commit is contained in:
parent
b8e3e16f3d
commit
60405f03d5
@ -1,3 +1,4 @@
|
|||||||
|
#include "webserv/handler/CgiHandler.hpp"
|
||||||
#include "webserv/socket/ASocket.hpp"
|
#include "webserv/socket/ASocket.hpp"
|
||||||
#include "webserv/socket/CgiSocket.hpp"
|
#include "webserv/socket/CgiSocket.hpp"
|
||||||
|
|
||||||
@ -118,12 +119,20 @@ void Client::removeCgiSocket(CgiSocket *cgiSocket)
|
|||||||
|
|
||||||
void Client::poll() const
|
void Client::poll() const
|
||||||
{
|
{
|
||||||
|
auto * cgiHandler = dynamic_cast<CgiHandler *>(handler_.get());
|
||||||
|
if (cgiHandler != nullptr)
|
||||||
|
{
|
||||||
|
Log::debug("Polling CGI handler for client, fd: " + std::to_string(clientSocket_->getFd()));
|
||||||
|
// CGI handler polling logic if needed
|
||||||
|
cgiHandler->wait();
|
||||||
|
}
|
||||||
if (httpResponse_->isComplete())
|
if (httpResponse_->isComplete())
|
||||||
{
|
{
|
||||||
Log::info("Response is ready to be sent to client, fd: " + std::to_string(clientSocket_->getFd()));
|
Log::info("Response is ready to be sent to client, fd: " + std::to_string(clientSocket_->getFd()));
|
||||||
clientSocket_->setCallback([this]() { respond(); });
|
clientSocket_->setCallback([this]() { respond(); });
|
||||||
server_.writable(clientSocket_->getFd());
|
server_.writable(clientSocket_->getFd());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::respond() const
|
void Client::respond() const
|
||||||
|
|||||||
@ -57,9 +57,6 @@ class Client
|
|||||||
std::unique_ptr<Router> router_;
|
std::unique_ptr<Router> router_;
|
||||||
std::unique_ptr<AHandler> handler_ = nullptr;
|
std::unique_ptr<AHandler> handler_ = nullptr;
|
||||||
std::unique_ptr<ClientSocket> clientSocket_;
|
std::unique_ptr<ClientSocket> clientSocket_;
|
||||||
std::unique_ptr<CgiSocket> cgiStdIn_ = nullptr;
|
|
||||||
std::unique_ptr<CgiSocket> cgiStdOut_ = nullptr;
|
|
||||||
|
|
||||||
std::unordered_map<int, ASocket *> sockets_;
|
std::unordered_map<int, ASocket *> sockets_;
|
||||||
|
|
||||||
Server &server_;
|
Server &server_;
|
||||||
|
|||||||
@ -19,6 +19,7 @@ void CgiHandler::handle()
|
|||||||
// Initialize CGI process
|
// Initialize CGI process
|
||||||
cgiProcess_ = std::make_unique<CgiProcess>(request_, *this);
|
cgiProcess_ = std::make_unique<CgiProcess>(request_, *this);
|
||||||
|
|
||||||
|
|
||||||
Log::info("CGI process started and sockets registered");
|
Log::info("CGI process started and sockets registered");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,3 +97,17 @@ void CgiHandler::setCgiSockets(std::unique_ptr<CgiSocket> cgiStdIn, std::unique_
|
|||||||
|
|
||||||
// TODO add to handler
|
// TODO add to handler
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CgiHandler::wait() noexcept
|
||||||
|
{
|
||||||
|
if (cgiProcess_)
|
||||||
|
{
|
||||||
|
cgiProcess_->wait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CgiHandler::setPid(int pid)
|
||||||
|
{
|
||||||
|
pid_ = pid;
|
||||||
|
|
||||||
|
}
|
||||||
@ -20,13 +20,17 @@ class CgiHandler : public AHandler
|
|||||||
~CgiHandler() = default;
|
~CgiHandler() = default;
|
||||||
|
|
||||||
void handle() override;
|
void handle() override;
|
||||||
|
void wait() noexcept;
|
||||||
void setCgiSockets(std::unique_ptr<CgiSocket> cgiStdIn, std::unique_ptr<CgiSocket> cgiStdOut);
|
void setCgiSockets(std::unique_ptr<CgiSocket> cgiStdIn, std::unique_ptr<CgiSocket> cgiStdOut);
|
||||||
|
void setPid(int pid);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
constexpr static size_t bufferSize_ = 8192; // TODO: remove duplicate definition and move to configmanager
|
constexpr static size_t bufferSize_ = 8192; // TODO: remove duplicate definition and move to configmanager
|
||||||
std::unique_ptr<CgiProcess> cgiProcess_;
|
std::unique_ptr<CgiProcess> cgiProcess_;
|
||||||
std::unique_ptr<CgiSocket> cgiStdIn_;
|
std::unique_ptr<CgiSocket> cgiStdIn_;
|
||||||
std::unique_ptr<CgiSocket> cgiStdOut_;
|
std::unique_ptr<CgiSocket> cgiStdOut_;
|
||||||
|
int pid_ = -1;
|
||||||
|
|
||||||
|
|
||||||
void write();
|
void write();
|
||||||
void read();
|
void read();
|
||||||
|
|||||||
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <csignal>
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
@ -81,5 +83,37 @@ void CgiProcess::spawn()
|
|||||||
// request_.getClient().setCgiSockets(std::move(cgiStdIn), std::move(cgiStdOut)); // move the sockets to the
|
// request_.getClient().setCgiSockets(std::move(cgiStdIn), std::move(cgiStdOut)); // move the sockets to the
|
||||||
// client
|
// client
|
||||||
handler_.setCgiSockets(std::move(cgiStdIn), std::move(cgiStdOut));
|
handler_.setCgiSockets(std::move(cgiStdIn), std::move(cgiStdOut));
|
||||||
|
handler_.setPid(_pid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CgiProcess::kill() const noexcept
|
||||||
|
{
|
||||||
|
if (_pid > 0)
|
||||||
|
{
|
||||||
|
::kill(_pid, SIGKILL);
|
||||||
|
Log::debug("Killed CGI process with PID: " + std::to_string(_pid));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CgiProcess::wait() noexcept
|
||||||
|
{
|
||||||
|
if (_pid > 0)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
int waitResult =::waitpid(_pid, &status, WNOHANG);
|
||||||
|
if (waitResult == -1)
|
||||||
|
{
|
||||||
|
Log::error("Error while waiting for CGI process with PID: " + std::to_string(_pid));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (waitResult == 0)
|
||||||
|
{
|
||||||
|
// Still running
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log::debug("CGI process with PID " + std::to_string(_pid) + " has terminated");
|
||||||
|
_pid = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -15,6 +15,8 @@ class CgiProcess
|
|||||||
CgiProcess &operator=(CgiProcess &&other) noexcept = delete;
|
CgiProcess &operator=(CgiProcess &&other) noexcept = delete;
|
||||||
|
|
||||||
~CgiProcess() = default;
|
~CgiProcess() = default;
|
||||||
|
void kill() const noexcept;
|
||||||
|
void wait() noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const HttpRequest &request_;
|
const HttpRequest &request_;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user