merging small fixes andmore telnet tests
This commit is contained in:
@@ -107,6 +107,9 @@ class Webserv
|
||||
void _close_client(int fd);
|
||||
void _close_all_clients();
|
||||
void _close_all_clients_fd();
|
||||
void _close_all_clients_cgi_fd();
|
||||
void _close_cgi_pipe_rfd(int fd);
|
||||
void _close_all_cgi_pipe_rfd();
|
||||
void _close_all_listen_sockets();
|
||||
void _reopen_lsocket(std::vector<listen_socket>::iterator it);
|
||||
void _handle_epoll_error_lsocket(uint32_t events, std::vector<listen_socket>::iterator it);
|
||||
@@ -121,18 +124,27 @@ class Webserv
|
||||
// cgi.cpp
|
||||
bool _is_cgi(Client *client, std::string path);
|
||||
size_t _cgi_pos(Client *client, std::string &path, size_t pos);
|
||||
std::string _exec_cgi(Client *client);
|
||||
void _exec_cgi(Client *client);
|
||||
void _set_env_vector(Client *client, std::vector<std::string> &env_vector);
|
||||
void _set_env_cstr(char *env_cstr[], std::vector<std::string> &env_vector);
|
||||
std::string _dup_env(std::string var, std::string val);
|
||||
std::string _dup_env(std::string var, int i);
|
||||
std::string _exec_script(Client *client, char *env[]);
|
||||
void _exec_script(Client *client, char *env[]);
|
||||
void _check_script_output(Client *client, std::string & output);
|
||||
void _check_script_status(Client *client, std::string & output);
|
||||
void _check_script_fields(Client *client, std::string & output);
|
||||
void _add_script_body_length_header(std::string & output);
|
||||
void _remove_body_leading_empty_lines(std::string & output);
|
||||
|
||||
|
||||
|
||||
Client *_find_cgi_fd(int cgi_fd);
|
||||
void _read_cgi_output(Client *client);
|
||||
void _handle_epoll_error_cgi_fd(uint32_t events, Client *client);
|
||||
void _cgi_epollhup(uint32_t events, Client *client);
|
||||
|
||||
|
||||
|
||||
///////////////////////
|
||||
class ExecFail : public std::exception
|
||||
{
|
||||
|
||||
@@ -66,9 +66,8 @@ size_t Webserv::_cgi_pos(Client *client, std::string &path, size_t pos)
|
||||
return NPOS;
|
||||
}
|
||||
|
||||
std::string Webserv::_exec_cgi(Client *client)
|
||||
void Webserv::_exec_cgi(Client *client)
|
||||
{
|
||||
std::string script_output;
|
||||
char* env_cstr[19] = {NULL};
|
||||
std::vector<std::string> env_vector;
|
||||
env_vector.reserve(18);
|
||||
@@ -77,12 +76,11 @@ std::string Webserv::_exec_cgi(Client *client)
|
||||
_set_env_vector(client, env_vector);
|
||||
try {
|
||||
_set_env_cstr(env_cstr, env_vector);
|
||||
script_output = _exec_script(client, env_cstr);
|
||||
_exec_script(client, env_cstr);
|
||||
|
||||
while (env_cstr[i] != NULL)
|
||||
delete[] env_cstr[i++];
|
||||
|
||||
return script_output;
|
||||
return;
|
||||
}
|
||||
catch (const Webserv::ExecFail& e)
|
||||
{
|
||||
@@ -125,7 +123,7 @@ void Webserv::_set_env_vector(Client *client, std::vector<std::string> &env_vect
|
||||
env_vector.push_back(_dup_env("QUERY_STRING" , client->get_rq_query()));
|
||||
env_vector.push_back(_dup_env("REMOTE_ADDR" , client->get_cl_ip()));
|
||||
env_vector.push_back(_dup_env("REMOTE_HOST" , client->get_cl_ip())); // equal to REMOTE_ADDR or empty
|
||||
env_vector.push_back(_dup_env("REMOTE_IDENT")); // authentification not supported
|
||||
env_vector.push_back(_dup_env("REMOTE_IDENT")); // authentification not supported
|
||||
env_vector.push_back(_dup_env("REMOTE_USER")); // authentification not supported
|
||||
env_vector.push_back(_dup_env("REQUEST_METHOD" , client->get_rq_method_str()));
|
||||
env_vector.push_back(_dup_env("SCRIPT_NAME" , client->get_rq_script_path())); // LUKE: To Check
|
||||
@@ -151,43 +149,17 @@ void Webserv::_set_env_cstr(char *env_cstr[], std::vector<std::string> &env_vect
|
||||
env_cstr[i] = NULL;
|
||||
}
|
||||
|
||||
/* void Webserv::_set_env_cstr(char *env_cstr[], std::vector<std::string> &env_vector)
|
||||
{
|
||||
env_cstr[0] = const_cast<char*>(env_vector[0].c_str());
|
||||
env_cstr[1] = const_cast<char*>(env_vector[1].c_str());
|
||||
env_cstr[2] = const_cast<char*>(env_vector[2].c_str());
|
||||
env_cstr[3] = const_cast<char*>(env_vector[3].c_str());
|
||||
env_cstr[4] = const_cast<char*>(env_vector[4].c_str());
|
||||
env_cstr[5] = const_cast<char*>(env_vector[5].c_str());
|
||||
env_cstr[6] = const_cast<char*>(env_vector[6].c_str());
|
||||
env_cstr[7] = const_cast<char*>(env_vector[7].c_str());
|
||||
env_cstr[8] = const_cast<char*>(env_vector[8].c_str());
|
||||
env_cstr[9] = const_cast<char*>(env_vector[9].c_str());
|
||||
env_cstr[10] = const_cast<char*>(env_vector[10].c_str());
|
||||
env_cstr[11] = const_cast<char*>(env_vector[11].c_str());
|
||||
env_cstr[12] = const_cast<char*>(env_vector[12].c_str());
|
||||
env_cstr[13] = const_cast<char*>(env_vector[13].c_str());
|
||||
env_cstr[14] = const_cast<char*>(env_vector[14].c_str());
|
||||
env_cstr[15] = const_cast<char*>(env_vector[15].c_str());
|
||||
env_cstr[16] = const_cast<char*>(env_vector[16].c_str());
|
||||
env_cstr[17] = const_cast<char*>(env_vector[17].c_str());
|
||||
env_cstr[18] = NULL;
|
||||
} */
|
||||
|
||||
#define STATUS_500 std::string("Status: 500" CRLF CRLF);
|
||||
|
||||
std::string Webserv::_exec_script(Client *client, char *env[])
|
||||
void Webserv::_exec_script(Client *client, char *env[])
|
||||
{
|
||||
#define RD 0
|
||||
#define WR 1
|
||||
#define CGI_BUF_SIZE 10
|
||||
#define FD_WR_TO_CHLD fd_in[WR]
|
||||
#define FD_WR_TO_PRNT fd_out[WR]
|
||||
#define FD_RD_FR_CHLD fd_out[RD]
|
||||
#define FD_RD_FR_PRNT fd_in[RD]
|
||||
|
||||
pid_t pid;
|
||||
char buf[CGI_BUF_SIZE]; // WIP define buffer
|
||||
char * const nll[1] = {NULL};
|
||||
std::string script_output;
|
||||
std::string body = client->get_rq_body();
|
||||
@@ -195,12 +167,12 @@ std::string Webserv::_exec_script(Client *client, char *env[])
|
||||
int fd_out[2];
|
||||
std::string path;
|
||||
|
||||
pipe(fd_in);
|
||||
pipe(fd_out);
|
||||
::pipe(fd_in);
|
||||
::pipe(fd_out);
|
||||
|
||||
pid = fork();
|
||||
if (pid == -1)
|
||||
perror("err fork()");
|
||||
std::perror("err fork()");
|
||||
else if (pid == 0) // child
|
||||
{
|
||||
std::signal(SIGPIPE, SIG_DFL);
|
||||
@@ -212,14 +184,14 @@ std::string Webserv::_exec_script(Client *client, char *env[])
|
||||
::close(FD_RD_FR_CHLD);
|
||||
if (dup2(FD_RD_FR_PRNT, STDIN_FILENO) == -1)
|
||||
{
|
||||
perror("err dup2()");
|
||||
std::perror("err dup2()");
|
||||
::close(FD_RD_FR_PRNT); // Valgind debug, not essential
|
||||
::close(FD_WR_TO_PRNT); // Valgind debug, not essential
|
||||
throw ExecFail();
|
||||
}
|
||||
if (dup2(FD_WR_TO_PRNT, STDOUT_FILENO) == -1)
|
||||
{
|
||||
perror("err dup2()");
|
||||
std::perror("err dup2()");
|
||||
::close(FD_RD_FR_PRNT); // Valgind debug, not essential
|
||||
::close(FD_WR_TO_PRNT); // Valgind debug, not essential
|
||||
throw ExecFail();
|
||||
@@ -230,9 +202,9 @@ std::string Webserv::_exec_script(Client *client, char *env[])
|
||||
|
||||
path = "." + client->get_rq_script_path(); // Wut ? Only relative path ?
|
||||
/*DEBUG*/std::cerr << "execve:[" << path << "]\n";
|
||||
if (execve(path.c_str(), nll, env) == -1) // replace path for debug error forcing
|
||||
if (::execve(path.c_str(), nll, env) == -1) // replace path for debug error forcing
|
||||
{
|
||||
perror("err execve()");
|
||||
std::perror("err execve()");
|
||||
::close(STDIN_FILENO); // Valgind debug, not essential
|
||||
::close(STDOUT_FILENO); // Valgind debug, not essential
|
||||
throw ExecFail();
|
||||
@@ -240,41 +212,32 @@ std::string Webserv::_exec_script(Client *client, char *env[])
|
||||
}
|
||||
else //parent
|
||||
{
|
||||
close(FD_RD_FR_PRNT);
|
||||
close(FD_WR_TO_PRNT);
|
||||
write(FD_WR_TO_CHLD, body.c_str(), body.size());
|
||||
close(FD_WR_TO_CHLD);
|
||||
waitpid(-1, NULL, 0);
|
||||
// We could maybe,
|
||||
::close(FD_RD_FR_PRNT);
|
||||
::close(FD_WR_TO_PRNT);
|
||||
::write(FD_WR_TO_CHLD, body.c_str(), body.size()); // move this before the fork ?
|
||||
::close(FD_WR_TO_CHLD);
|
||||
|
||||
// add FD_RD_FR_CHLD to epoll,
|
||||
// return to the main loop,
|
||||
// read FD_RD_FR_CHLD each time epoll say its ready,
|
||||
// then try waitpid() with WNOHANG after each read.
|
||||
// when waitpid() tell us its finish (or maybe when epoll return EPOLLHUP)
|
||||
// then actually parse the script_output and send it to the client.
|
||||
_epoll_update(FD_RD_FR_CHLD, EPOLLIN, EPOLL_CTL_ADD);
|
||||
// stop monitoring client->fd until the cgi-script as done is job
|
||||
_epoll_update(client->get_cl_fd(), 0, EPOLL_CTL_DEL);
|
||||
|
||||
ssize_t ret = 1;
|
||||
while (ret > 0)
|
||||
{
|
||||
ret = read(FD_RD_FR_CHLD, buf, CGI_BUF_SIZE);
|
||||
if (ret == -1)
|
||||
{
|
||||
std::perror("err recv()");
|
||||
script_output = STATUS_500;
|
||||
break;
|
||||
}
|
||||
script_output.append(buf, ret);
|
||||
}
|
||||
close(FD_RD_FR_CHLD);
|
||||
client->cgi_pipe_rfd = FD_RD_FR_CHLD;
|
||||
client->cgi_pid = pid;
|
||||
}
|
||||
if (script_output.empty())
|
||||
script_output = STATUS_500;
|
||||
|
||||
return script_output;
|
||||
}
|
||||
|
||||
#define STATUS_500 std::string("Status: 500" CRLF CRLF);
|
||||
|
||||
void Webserv::_check_script_output(Client *client, std::string & output)
|
||||
{
|
||||
size_t pos;
|
||||
pos = client->cgi_output.find(CRLF CRLF);
|
||||
if (pos == 0 || pos == NPOS)
|
||||
{
|
||||
client->status = 500;;
|
||||
return;
|
||||
}
|
||||
_check_script_status(client, output);
|
||||
if (client->status >= 400 && client->status < 600)
|
||||
return;
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
void Webserv::_close_client(int fd)
|
||||
{
|
||||
std::vector<Client>::iterator it = _clients.begin();
|
||||
while (it != _clients.end())
|
||||
std::vector<Client>::iterator it_end = _clients.end();
|
||||
while (it != it_end)
|
||||
{
|
||||
if (*it == fd)
|
||||
{
|
||||
@@ -27,20 +28,39 @@ void Webserv::_close_all_clients()
|
||||
|
||||
void Webserv::_close_all_clients_fd()
|
||||
{
|
||||
_close_all_clients_cgi_fd();
|
||||
std::vector<Client>::iterator it = _clients.begin();
|
||||
std::vector<Client>::iterator it_end = _clients.end();
|
||||
while (it != it_end)
|
||||
{
|
||||
// _epoll_update(_clients.back().fd, 0, EPOLL_CTL_DEL); // normalement superflu, DEBUG
|
||||
std::cerr << "close fd " << _clients.back().get_cl_fd() << "\n";
|
||||
if (::close(_clients.back().get_cl_fd()) == -1)
|
||||
std::cerr << "close fd " << it->get_cl_fd() << "\n";
|
||||
if (::close(it->get_cl_fd()) == -1)
|
||||
std::perror("err close()");
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
void Webserv::_close_all_listen_sockets()
|
||||
void Webserv::_close_all_clients_cgi_fd()
|
||||
{
|
||||
std::vector<Client>::iterator it = _clients.begin();
|
||||
std::vector<Client>::iterator it_end = _clients.end();
|
||||
while (it != it_end)
|
||||
{
|
||||
// _epoll_update(_clients.back().fd, 0, EPOLL_CTL_DEL); // normalement superflu, DEBUG
|
||||
if (it->cgi_pipe_rfd)
|
||||
{
|
||||
std::cerr << "close cgi-fd " << it->cgi_pipe_rfd << "\n";
|
||||
if (::close(it->cgi_pipe_rfd) == -1)
|
||||
std::perror("err close()");
|
||||
}
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Webserv::_close_all_listen_sockets()
|
||||
{ // TODO : change like clients (clear in place of pop_back)
|
||||
while (!_listen_sockets.empty())
|
||||
{
|
||||
// _epoll_update(_listen_sockets.back().fd, 0, EPOLL_CTL_DEL); // normalement superflu, DEBUG
|
||||
@@ -116,5 +136,8 @@ void Webserv::_handle_epoll_error_client(uint32_t events, int fd)
|
||||
std::cerr << "EPOLLERR on client fd " << fd << "\n"; // DEBUG
|
||||
if (events & EPOLLHUP)
|
||||
std::cerr << "EPOLLHUP on client fd " << fd << "\n"; // DEBUG
|
||||
_close_client(fd);
|
||||
if (std::find(_clients.begin(), _clients.end(), fd) != _clients.end())
|
||||
std::cerr << "Found the client in _clients" << "\n"; // DEBUG
|
||||
|
||||
_close_client(fd); // " EPOLLHUP on client fd 8 " en boucle quand on mattraque un peu les CGI, donc il ne le trouve pas dans _clients. Etrange.
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
enum send_return
|
||||
{
|
||||
SEND_IN_PROGRESS, // unused
|
||||
SEND_IN_PROGRESS,
|
||||
SEND_COMPLETE,
|
||||
SEND_CLOSE,
|
||||
};
|
||||
@@ -40,16 +40,33 @@ int Webserv::_send_response(Client *client)
|
||||
|
||||
std::cerr << "send()\n";
|
||||
|
||||
_append_base_headers(client);
|
||||
if (!client->status)
|
||||
_construct_response(client);
|
||||
if (client->response.empty())
|
||||
{
|
||||
_append_base_headers(client);
|
||||
if (!client->status)
|
||||
{
|
||||
_construct_response(client);
|
||||
if (client->cgi_pipe_rfd)
|
||||
return SEND_IN_PROGRESS;
|
||||
}
|
||||
}
|
||||
else if (!client->cgi_output.empty())
|
||||
{
|
||||
// /*DEBUG*/ std::cout << "\n" B_PURPLE "[response]:" RESET "\n"; ::print_special(client->response); std::cout << B_PURPLE "-----------" RESET "\n\n";
|
||||
// /*DEBUG*/ std::cout << "\n" B_PURPLE "[script output]:" RESET "\n"; ::print_special(script_output); std::cout << B_PURPLE "-----------" RESET "\n\n";
|
||||
_check_script_output(client, client->cgi_output); // FD_CGI : adjust for client->cgi_output;
|
||||
if (client->status < 400)
|
||||
client->response += client->cgi_output;
|
||||
// /*DEBUG*/ std::cout << "\n" B_PURPLE "[response + output]:" RESET "\n"; ::print_special(client->response); std::cout << B_PURPLE "-----------" RESET "\n\n";
|
||||
}
|
||||
|
||||
_insert_status_line(client);
|
||||
if (client->status >= 400)
|
||||
_error_html_response(client);
|
||||
|
||||
//*DEBUG*/ std::cout << "\n" B_PURPLE "[response + output + headers]:" RESET "\n"; ::print_special(client->response); std::cout << "\n" B_PURPLE "-----------" RESET "\n\n";
|
||||
|
||||
std::cerr << "client->response.size() = " << client->response.size() << "\n"; // DEBUG
|
||||
// /* Debug */ std::cerr << "client->response.size() = " << client->response.size() << "\n"; // DEBUG
|
||||
ret = ::send(client->get_cl_fd(), client->response.c_str(), client->response.size(), 0);
|
||||
if (ret == -1)
|
||||
{
|
||||
@@ -62,7 +79,7 @@ int Webserv::_send_response(Client *client)
|
||||
std::cerr << "SEND RET 0 for client.fd =" << client->get_cl_fd() << "\n"; // DEBUG
|
||||
return SEND_CLOSE;
|
||||
}
|
||||
std::cerr << "ret send() = " << ret << "\n"; // DEBUG
|
||||
// /* Debug */ std::cerr << "ret send() = " << ret << "\n"; // DEBUG
|
||||
|
||||
return SEND_COMPLETE;
|
||||
}
|
||||
@@ -89,14 +106,7 @@ void Webserv::_construct_response(Client *client)
|
||||
path = _replace_url_root(client, client->get_rq_abs_path());
|
||||
if (_is_cgi(client, path))
|
||||
{
|
||||
script_output = _exec_cgi(client);
|
||||
//*DEBUG*/ std::cout << "\n" B_PURPLE "[response]:" RESET "\n"; ::print_special(client->response); std::cout << B_PURPLE "-----------" RESET "\n\n";
|
||||
//*DEBUG*/ std::cout << "\n" B_PURPLE "[script output]:" RESET "\n"; ::print_special(script_output); std::cout << B_PURPLE "-----------" RESET "\n\n";
|
||||
_check_script_output(client, script_output);
|
||||
if (client->status < 400)
|
||||
client->response += script_output;
|
||||
//*DEBUG*/ std::cout << "\n" B_PURPLE "[response + output]:" RESET "\n"; ::print_special(client->response); std::cout << B_PURPLE "-----------" RESET "\n\n";
|
||||
|
||||
_exec_cgi(client);
|
||||
return;
|
||||
}
|
||||
_process_method(client, path);
|
||||
@@ -104,7 +114,7 @@ void Webserv::_construct_response(Client *client)
|
||||
|
||||
void Webserv::_process_method(Client *client, std::string &path)
|
||||
{
|
||||
std::cerr << "allow_methods = " << http_methods_to_str(client->assigned_location->allow_methods) << "\n"; // debug
|
||||
// std::cerr << "allow_methods = " << http_methods_to_str(client->assigned_location->allow_methods) << "\n"; // debug
|
||||
std::cerr << "Path again: " << path << '\n'; // debug
|
||||
|
||||
switch (client->get_rq_method())
|
||||
@@ -122,13 +132,13 @@ void Webserv::_process_method(Client *client, std::string &path)
|
||||
|
||||
std::string Webserv::_replace_url_root(Client *client, std::string path)
|
||||
{
|
||||
std::cerr << "assigned_location->path = " << client->assigned_location->path << "\n"; // debug
|
||||
std::cerr << "path before = " << path << "\n"; // DEBUG
|
||||
// /* Debug */ std::cerr << "assigned_location->path = " << client->assigned_location->path << "\n"; // debug
|
||||
// /* Debug */ std::cerr << "path before = " << path << "\n"; // DEBUG
|
||||
if (client->assigned_location->path == "/")
|
||||
path.insert(0, client->assigned_location->root);
|
||||
else
|
||||
path.replace(0, client->assigned_location->path.size(), client->assigned_location->root);
|
||||
std::cerr << "path after = " << path << "\n"; // DEBUG
|
||||
// /* Debug */ std::cerr << "path after = " << path << "\n"; // DEBUG
|
||||
return path;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,95 @@
|
||||
#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
|
||||
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";
|
||||
@@ -11,13 +100,15 @@ void Webserv::run()
|
||||
int nfds;
|
||||
int i;
|
||||
int count_loop = 0;
|
||||
std::vector<listen_socket>::iterator it_socket;
|
||||
std::vector<listen_socket>::iterator it_lsocket;
|
||||
Client *client_cgi = NULL;
|
||||
|
||||
g_run = true;
|
||||
while (g_run)
|
||||
{
|
||||
std::cerr << ++count_loop << "----loop epoll()\n";
|
||||
std::cerr << ++count_loop << "----loop epoll() ";
|
||||
nfds = ::epoll_wait(_epfd, events, MAX_EVENTS, TIMEOUT);
|
||||
std::cerr << "(nfds=" << nfds << ")\n";
|
||||
if (nfds == -1)
|
||||
{
|
||||
int errno_copy = errno;
|
||||
@@ -33,15 +124,25 @@ void Webserv::run()
|
||||
while (i < nfds)
|
||||
{
|
||||
try {
|
||||
it_socket = std::find(_listen_sockets.begin(), _listen_sockets.end(), events[i].data.fd);
|
||||
if (it_socket != _listen_sockets.end())
|
||||
it_lsocket = std::find(_listen_sockets.begin(), _listen_sockets.end(), events[i].data.fd);
|
||||
client_cgi = _find_cgi_fd(events[i].data.fd);
|
||||
if (it_lsocket != _listen_sockets.end())
|
||||
{
|
||||
if (events[i].events & EPOLLERR || events[i].events & EPOLLHUP)
|
||||
_handle_epoll_error_lsocket(events[i].events, it_socket);
|
||||
_handle_epoll_error_lsocket(events[i].events, it_lsocket);
|
||||
else if (events[i].events & EPOLLIN)
|
||||
_accept_connection(*it_socket);
|
||||
_accept_connection(*it_lsocket);
|
||||
}
|
||||
else
|
||||
else if (client_cgi)
|
||||
{
|
||||
if (events[i].events & EPOLLERR)
|
||||
_handle_epoll_error_cgi_fd(events[i].events, client_cgi);
|
||||
else if (events[i].events & EPOLLIN)
|
||||
_read_cgi_output(client_cgi);
|
||||
else if ( (events[i].events & EPOLLHUP) && !(events[i].events & EPOLLIN) )
|
||||
_cgi_epollhup(events[i].events, client_cgi);
|
||||
}
|
||||
else if (std::find(_clients.begin(), _clients.end(), events[i].data.fd) != _clients.end()) // TODO: save the it in var to avoid multiples find()
|
||||
{
|
||||
if (events[i].events & EPOLLERR || events[i].events & EPOLLHUP)
|
||||
_handle_epoll_error_client(events[i].events, events[i].data.fd);
|
||||
|
||||
Reference in New Issue
Block a user