body write to CGI now monitored by epoll

+ kermit.jpg :)
This commit is contained in:
lperrey
2022-08-17 23:42:12 +02:00
parent 2613ca2e1a
commit b34e49311b
13 changed files with 302 additions and 193 deletions

View File

@@ -4,98 +4,6 @@
#define MAX_EVENTS 42 // arbitrary
#define TIMEOUT 3000
#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_rfd << "\n";
ret = ::read(client->cgi_pipe_rfd, 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_epoll_error_cgi_fd(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_rfd << "\n";
client->cgi_output = STATUS_500;
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_rfd)
{
if (::close(client->cgi_pipe_rfd) == -1)
std::perror("err close()");
}
client->cgi_pipe_rfd = 0;
_epoll_update(client->get_cl_fd(), EPOLLOUT, EPOLL_CTL_ADD);
}
}
void Webserv::_cgi_epollhup(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_rfd << "\n"; */
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_rfd)
{
if (::close(client->cgi_pipe_rfd) == -1)
std::perror("err close()");
}
client->cgi_pipe_rfd = 0;
_epoll_update(client->get_cl_fd(), EPOLLOUT, EPOLL_CTL_ADD);
}
}
Client *Webserv::_find_cgi_fd(int cgi_fd)
{
std::vector<Client>::iterator it = _clients.begin();
std::vector<Client>::iterator it_end = _clients.end();
while (it != it_end)
{
if (it->cgi_pipe_rfd == cgi_fd)
return (&(*it));
++it;
}
return (NULL);
}
void Webserv::run()
{
std::cerr << "Server started\n";
@@ -104,7 +12,8 @@ void Webserv::run()
int i;
int count_loop = 0;
std::vector<listen_socket>::iterator it_lsocket;
Client *client_cgi = NULL;
Client *client_cgi_output = NULL;
Client *client_cgi_input = NULL;
g_run = true;
while (g_run)
@@ -128,7 +37,8 @@ void Webserv::run()
{
try {
it_lsocket = std::find(_listen_sockets.begin(), _listen_sockets.end(), events[i].data.fd);
client_cgi = _find_cgi_fd(events[i].data.fd);
client_cgi_output = _find_cgi_output_fd(events[i].data.fd);
client_cgi_input = _find_cgi_input_fd(events[i].data.fd);
if (it_lsocket != _listen_sockets.end())
{
if (events[i].events & EPOLLERR || events[i].events & EPOLLHUP)
@@ -136,14 +46,21 @@ void Webserv::run()
else if (events[i].events & EPOLLIN)
_accept_connection(*it_lsocket);
}
else if (client_cgi)
else if (client_cgi_input)
{
if (events[i].events & EPOLLERR || events[i].events & EPOLLHUP)
_handle_epollerr_cgi_input(events[i].events, client_cgi_input);
else if (events[i].events & EPOLLOUT)
_cgi_input_ready(client_cgi_input);
}
else if (client_cgi_output)
{
if (events[i].events & EPOLLERR)
_handle_epoll_error_cgi_fd(events[i].events, client_cgi);
_handle_epollerr_cgi_output(events[i].events, client_cgi_output);
else if (events[i].events & EPOLLIN)
_read_cgi_output(client_cgi);
_read_cgi_output(client_cgi_output);
else if ( (events[i].events & EPOLLHUP) && !(events[i].events & EPOLLIN) )
_cgi_epollhup(events[i].events, client_cgi);
_handle_epollhup_cgi_output(events[i].events, client_cgi_output);
}
else if (std::find(_clients.begin(), _clients.end(), events[i].data.fd) != _clients.end()) // TODO: save the it in var to avoid multiples find()
{