Files
42_INT_12_webserv/srcs/webserv/cgi_epoll.cpp
2022-08-17 23:42:12 +02:00

130 lines
3.4 KiB
C++

#include "Webserv.hpp"
#define BUFSIZE 8192 // (8Ko)
#define STATUS_500 std::string("Status: 500" CRLF CRLF);
void Webserv::_read_cgi_output(Client *client)
{
char buf[BUFSIZE];
ssize_t ret;
std::cerr << "_read_cgi_output()" << "\n";
std::cerr << "cgi_pid = " << client->cgi_pid << "\n";
std::cerr << "client fd = " << client->get_cl_fd() << "\n";
std::cerr << "cgi fd = " << client->cgi_pipe_r_from_child << "\n";
ret = ::read(client->cgi_pipe_r_from_child, buf, BUFSIZE);
std::cerr << "cgi read ret = " << ret << "\n";
if (ret == -1)
{
std::perror("err read(cgi_fd)");
client->cgi_output = STATUS_500;
}
else if (ret == 0)
std::cerr << "Madame s'il vous plait, du Ketchup pour mon hamburger" << " (AKA:ret=0)" << "\n";
else
{
std::cerr << "NORMAL BEHAVIOR I THINK!\n"; // debug
client->cgi_output.append(buf, ret);
}
}
void Webserv::_handle_epollerr_cgi_output(uint32_t events, Client *client)
{
(void)events;
std::cerr << "cgi EPOLLERR" << "\n";
std::cerr << "cgi_pid = " << client->cgi_pid << "\n";
std::cerr << "client fd = " << client->get_cl_fd() << "\n";
std::cerr << "cgi fd = " << client->cgi_pipe_r_from_child << "\n";
client->cgi_output = STATUS_500;
// Common with EPOLLHUP
pid_t wait_ret;
wait_ret = ::waitpid(client->cgi_pid, NULL, WNOHANG);
std::cerr << "cgi EPOLLERR waitpid ret = " << wait_ret << "\n";
if (wait_ret == client->cgi_pid)
{
if (client->cgi_pipe_r_from_child)
{
if (::close(client->cgi_pipe_r_from_child) == -1)
std::perror("err close()");
}
client->cgi_pipe_r_from_child = 0;
_epoll_update(client->get_cl_fd(), EPOLLOUT, EPOLL_CTL_ADD);
client->cgi_state = CGI_OUTPUT_READY;
}
}
void Webserv::_handle_epollhup_cgi_output(uint32_t events, Client *client)
{
(void)events;
(void)client;
/* std::cerr << "cgi EPOLLHUP" << "\n";
std::cerr << "cgi_pid = " << client->cgi_pid << "\n";
std::cerr << "client fd = " << client->get_cl_fd() << "\n";
std::cerr << "cgi fd = " << client->cgi_pipe_r_from_child << "\n"; */
// Common with EPOLLERR
pid_t wait_ret;
wait_ret = ::waitpid(client->cgi_pid, NULL, WNOHANG);
// std::cerr << "cgi EPOLLHUP waitpid ret = " << wait_ret << "\n";
if (wait_ret == client->cgi_pid)
{
if (client->cgi_pipe_r_from_child)
{
if (::close(client->cgi_pipe_r_from_child) == -1)
std::perror("err close()");
}
client->cgi_pipe_r_from_child = 0;
_epoll_update(client->get_cl_fd(), EPOLLOUT, EPOLL_CTL_ADD);
client->cgi_state = CGI_OUTPUT_READY;
}
}
void Webserv::_cgi_input_ready(Client *client)
{
client->cgi_state = CGI_READY_TO_EXEC;
_epoll_update(client->cgi_pipe_w_to_child, 0, EPOLL_CTL_DEL);
_epoll_update(client->get_cl_fd(), EPOLLOUT, EPOLL_CTL_ADD);
}
void Webserv::_handle_epollerr_cgi_input(uint32_t events, Client *client)
{
(void)events;
client->cgi_output = STATUS_500;
client->cgi_state = CGI_OUTPUT_READY;
_close_client_cgi_pipes(client);
_epoll_update(client->get_cl_fd(), EPOLLOUT, EPOLL_CTL_ADD);
}
Client *Webserv::_find_cgi_output_fd(int fd)
{
std::vector<Client>::iterator it = _clients.begin();
std::vector<Client>::iterator it_end = _clients.end();
while (it != it_end)
{
if (it->cgi_pipe_r_from_child == fd)
return (&(*it));
++it;
}
return (NULL);
}
Client *Webserv::_find_cgi_input_fd(int fd)
{
std::vector<Client>::iterator it = _clients.begin();
std::vector<Client>::iterator it_end = _clients.end();
while (it != it_end)
{
if (it->cgi_pipe_w_to_child == fd)
return (&(*it));
++it;
}
return (NULL);
}