Debug in progress, somes fix but not the main problem
This commit is contained in:
@@ -21,6 +21,9 @@ server {
|
|||||||
# error_page 403 ./www/error_pages/error_404.html;
|
# error_page 403 ./www/error_pages/error_404.html;
|
||||||
|
|
||||||
|
|
||||||
|
location /kapouet {
|
||||||
|
root /tmp/www;
|
||||||
|
}
|
||||||
|
|
||||||
location / {
|
location / {
|
||||||
allow_methods GET;
|
allow_methods GET;
|
||||||
@@ -37,6 +40,7 @@ server {
|
|||||||
autoindex on;
|
autoindex on;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
location /cgi-bin {
|
location /cgi-bin {
|
||||||
root ./srcs/cgi-bin/;
|
root ./srcs/cgi-bin/;
|
||||||
cgi_ext out php sh;
|
cgi_ext out php sh;
|
||||||
@@ -44,19 +48,7 @@ server {
|
|||||||
|
|
||||||
location /upload {
|
location /upload {
|
||||||
allow_methods POST;
|
allow_methods POST;
|
||||||
# autoindex on;
|
upload_dir ./www/user_files/;
|
||||||
# root ./www/;
|
|
||||||
# index upload_form_single.html;
|
|
||||||
|
|
||||||
# upload_dir ./www/user_files/;
|
|
||||||
# root doesn’t matter if used only with POST and no CGI
|
|
||||||
}
|
|
||||||
|
|
||||||
location /uploaded {
|
|
||||||
allow_methods GET;
|
|
||||||
autoindex on;
|
|
||||||
# upload_dir ./www/user_files/;
|
|
||||||
root ./www/user_files;
|
|
||||||
# root doesn’t matter if used only with POST and no CGI
|
# root doesn’t matter if used only with POST and no CGI
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,13 +12,13 @@ Client::Client()
|
|||||||
request_complete(false),
|
request_complete(false),
|
||||||
assigned_server(NULL),
|
assigned_server(NULL),
|
||||||
assigned_location(NULL),
|
assigned_location(NULL),
|
||||||
cgi_state(0),
|
cgi_state(CGI_NO_CGI),
|
||||||
cgi_pipe_w_to_child(0),
|
cgi_pipe_w_to_child(-1),
|
||||||
cgi_pipe_r_from_child(0),
|
cgi_pipe_r_from_child(-1),
|
||||||
cgi_pipe_w_to_parent(0),
|
cgi_pipe_w_to_parent(-1),
|
||||||
cgi_pipe_r_from_parent(0),
|
cgi_pipe_r_from_parent(-1),
|
||||||
cgi_pid(0),
|
cgi_pid(0),
|
||||||
_fd(0),
|
_fd(-1),
|
||||||
_port(""),
|
_port(""),
|
||||||
_ip(""),
|
_ip(""),
|
||||||
_lsocket(NULL)
|
_lsocket(NULL)
|
||||||
@@ -33,11 +33,11 @@ Client::Client(int afd, listen_socket *lsocket, std::string aport, std::string a
|
|||||||
request_complete(false),
|
request_complete(false),
|
||||||
assigned_server(NULL),
|
assigned_server(NULL),
|
||||||
assigned_location(NULL),
|
assigned_location(NULL),
|
||||||
cgi_state(0),
|
cgi_state(CGI_NO_CGI),
|
||||||
cgi_pipe_w_to_child(0),
|
cgi_pipe_w_to_child(-1),
|
||||||
cgi_pipe_r_from_child(0),
|
cgi_pipe_r_from_child(-1),
|
||||||
cgi_pipe_w_to_parent(0),
|
cgi_pipe_w_to_parent(-1),
|
||||||
cgi_pipe_r_from_parent(0),
|
cgi_pipe_r_from_parent(-1),
|
||||||
cgi_pid(0),
|
cgi_pid(0),
|
||||||
_fd(afd),
|
_fd(afd),
|
||||||
_port(aport),
|
_port(aport),
|
||||||
@@ -272,11 +272,11 @@ void Client::clear_script()
|
|||||||
|
|
||||||
void Client::clear_cgi_vars()
|
void Client::clear_cgi_vars()
|
||||||
{
|
{
|
||||||
cgi_state = false;
|
cgi_state = CGI_NO_CGI;
|
||||||
cgi_pipe_w_to_child = 0;
|
cgi_pipe_w_to_child = -1;
|
||||||
cgi_pipe_r_from_child = 0;
|
cgi_pipe_r_from_child = -1;
|
||||||
cgi_pipe_w_to_parent = 0;
|
cgi_pipe_w_to_parent = -1;
|
||||||
cgi_pipe_r_from_parent = 0;
|
cgi_pipe_r_from_parent = -1;
|
||||||
cgi_pid = 0;
|
cgi_pid = 0;
|
||||||
cgi_output.clear();
|
cgi_output.clear();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,8 +45,8 @@ enum cgi_states
|
|||||||
CGI_NO_CGI = 0,
|
CGI_NO_CGI = 0,
|
||||||
CGI_WAIT_TO_EXEC,
|
CGI_WAIT_TO_EXEC,
|
||||||
CGI_READY_TO_EXEC,
|
CGI_READY_TO_EXEC,
|
||||||
CGI_WAIT_FOR_OUTPUT,
|
CGI_OUTPUT_READING,
|
||||||
CGI_OUTPUT_READY
|
CGI_OUTPUT_COMPLETE
|
||||||
};
|
};
|
||||||
|
|
||||||
class Client
|
class Client
|
||||||
@@ -69,7 +69,7 @@ class Client
|
|||||||
const LocationConfig *assigned_location;
|
const LocationConfig *assigned_location;
|
||||||
|
|
||||||
// CGI variables
|
// CGI variables
|
||||||
int cgi_state;
|
cgi_states cgi_state;
|
||||||
int cgi_pipe_w_to_child;
|
int cgi_pipe_w_to_child;
|
||||||
int cgi_pipe_r_from_child;
|
int cgi_pipe_r_from_child;
|
||||||
int cgi_pipe_w_to_parent;
|
int cgi_pipe_w_to_parent;
|
||||||
|
|||||||
@@ -109,8 +109,6 @@ class Webserv
|
|||||||
void _close_all_clients();
|
void _close_all_clients();
|
||||||
void _close_all_clients_fd();
|
void _close_all_clients_fd();
|
||||||
void _close_all_clients_cgi_pipes();
|
void _close_all_clients_cgi_pipes();
|
||||||
void _close_cgi_pipe_r_from_child(int fd);
|
|
||||||
void _close_all_cgi_pipe_r_from_child();
|
|
||||||
void _close_all_listen_sockets();
|
void _close_all_listen_sockets();
|
||||||
void _reopen_lsocket(std::vector<listen_socket>::iterator it);
|
void _reopen_lsocket(std::vector<listen_socket>::iterator it);
|
||||||
void _handle_epoll_error_lsocket(uint32_t events, std::vector<listen_socket>::iterator it);
|
void _handle_epoll_error_lsocket(uint32_t events, std::vector<listen_socket>::iterator it);
|
||||||
@@ -134,7 +132,8 @@ class Webserv
|
|||||||
void _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_output(Client *client, std::string & output);
|
||||||
void _check_script_status(Client *client, std::string & output);
|
void _check_script_status(Client *client, std::string & output);
|
||||||
size_t _check_script_fields(const std::string & output, size_t status);
|
unsigned int
|
||||||
|
_check_script_fields(const std::string & output, unsigned int status);
|
||||||
void _check_fields_duplicates(Client *client, std::string & output);
|
void _check_fields_duplicates(Client *client, std::string & output);
|
||||||
void _add_script_body_length_header(std::string & output);
|
void _add_script_body_length_header(std::string & output);
|
||||||
void _remove_body_leading_empty_lines(std::string & output);
|
void _remove_body_leading_empty_lines(std::string & output);
|
||||||
|
|||||||
@@ -70,16 +70,27 @@ void Webserv::_cgi_open_pipes(Client *client)
|
|||||||
{
|
{
|
||||||
#define R 0
|
#define R 0
|
||||||
#define W 1
|
#define W 1
|
||||||
|
int pipe_fd[2];
|
||||||
|
|
||||||
int fd_in[2];
|
if (::pipe(pipe_fd) == -1)
|
||||||
int fd_out[2];
|
{
|
||||||
::pipe(fd_in);
|
std::perror("err pipe");
|
||||||
::pipe(fd_out);
|
client->status = 500;
|
||||||
|
}
|
||||||
|
client->cgi_pipe_r_from_parent = pipe_fd[R];
|
||||||
|
client->cgi_pipe_w_to_child = pipe_fd[W];
|
||||||
|
|
||||||
client->cgi_pipe_r_from_parent = fd_in[R];
|
if (::pipe(pipe_fd) == -1)
|
||||||
client->cgi_pipe_w_to_child = fd_in[W];
|
{
|
||||||
client->cgi_pipe_r_from_child = fd_out[R];
|
std::perror("err pipe");
|
||||||
client->cgi_pipe_w_to_parent = fd_out[W];
|
if (::close(client->cgi_pipe_r_from_parent) == -1)
|
||||||
|
std::perror("err close()");
|
||||||
|
if (::close(client->cgi_pipe_w_to_child) == -1)
|
||||||
|
std::perror("err close()");
|
||||||
|
client->status = 500;
|
||||||
|
}
|
||||||
|
client->cgi_pipe_r_from_child = pipe_fd[R];
|
||||||
|
client->cgi_pipe_w_to_parent = pipe_fd[W];
|
||||||
|
|
||||||
// epoll add for writing body to child
|
// epoll add for writing body to child
|
||||||
_epoll_update(client->cgi_pipe_w_to_child, EPOLLOUT, EPOLL_CTL_ADD);
|
_epoll_update(client->cgi_pipe_w_to_child, EPOLLOUT, EPOLL_CTL_ADD);
|
||||||
@@ -181,7 +192,11 @@ void Webserv::_exec_script(Client *client, char *env[])
|
|||||||
|
|
||||||
pid = fork();
|
pid = fork();
|
||||||
if (pid == -1)
|
if (pid == -1)
|
||||||
|
{
|
||||||
std::perror("err fork()");
|
std::perror("err fork()");
|
||||||
|
client->status = 500;
|
||||||
|
_close_client_cgi_pipes(client);
|
||||||
|
}
|
||||||
else if (pid == 0) // child
|
else if (pid == 0) // child
|
||||||
{
|
{
|
||||||
std::signal(SIGPIPE, SIG_DFL);
|
std::signal(SIGPIPE, SIG_DFL);
|
||||||
@@ -189,19 +204,13 @@ void Webserv::_exec_script(Client *client, char *env[])
|
|||||||
|
|
||||||
if (dup2(client->cgi_pipe_r_from_parent, STDIN_FILENO) == -1)
|
if (dup2(client->cgi_pipe_r_from_parent, STDIN_FILENO) == -1)
|
||||||
{
|
{
|
||||||
std::perror("err dup2()");
|
std::perror("err dup2() STDIN_FILENO");
|
||||||
if (::close(client->cgi_pipe_r_from_parent) == -1) // Valgind debug, not essential
|
|
||||||
std::perror("err close");
|
|
||||||
if (::close(client->cgi_pipe_w_to_parent) == -1) // Valgind debug, not essential
|
|
||||||
std::perror("err close");
|
|
||||||
throw ExecFail();
|
throw ExecFail();
|
||||||
}
|
}
|
||||||
if (dup2(client->cgi_pipe_w_to_parent, STDOUT_FILENO) == -1)
|
if (dup2(client->cgi_pipe_w_to_parent, STDOUT_FILENO) == -1)
|
||||||
{
|
{
|
||||||
std::perror("err dup2()");
|
std::perror("err dup2() STDOUT_FILENO");
|
||||||
if (::close(client->cgi_pipe_r_from_parent) == -1) // Valgind debug, not essential
|
if (::close(STDIN_FILENO) == -1) // Valgind debug, not essential
|
||||||
std::perror("err close");
|
|
||||||
if (::close(client->cgi_pipe_w_to_parent) == -1) // Valgind debug, not essential
|
|
||||||
std::perror("err close");
|
std::perror("err close");
|
||||||
throw ExecFail();
|
throw ExecFail();
|
||||||
}
|
}
|
||||||
@@ -210,8 +219,8 @@ void Webserv::_exec_script(Client *client, char *env[])
|
|||||||
if (::close(_epfd) == -1)
|
if (::close(_epfd) == -1)
|
||||||
std::perror("err close");
|
std::perror("err close");
|
||||||
|
|
||||||
path = client->get_rq_script_path(); // Wut ? Only relative path ?
|
path = client->get_rq_script_path();
|
||||||
/*DEBUG*/std::cerr << "execve:[" << path << "]\n";
|
std::cerr << "execve:[" << path << "]\n"; // DEBUG
|
||||||
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
|
||||||
{
|
{
|
||||||
std::perror("err execve()");
|
std::perror("err execve()");
|
||||||
@@ -230,18 +239,17 @@ void Webserv::_exec_script(Client *client, char *env[])
|
|||||||
std::perror("err close");
|
std::perror("err close");
|
||||||
if (::close(client->cgi_pipe_w_to_child) == -1)
|
if (::close(client->cgi_pipe_w_to_child) == -1)
|
||||||
std::perror("err close");
|
std::perror("err close");
|
||||||
|
|
||||||
// add client->cgi_pipe_r_from_child to epoll,
|
// add client->cgi_pipe_r_from_child to epoll,
|
||||||
_epoll_update(client->cgi_pipe_r_from_child, EPOLLIN, EPOLL_CTL_ADD);
|
_epoll_update(client->cgi_pipe_r_from_child, EPOLLIN, EPOLL_CTL_ADD);
|
||||||
// stop monitoring client->fd until the cgi-script as done is job
|
// stop monitoring client->fd until the cgi-script as done is job
|
||||||
_epoll_update(client->get_cl_fd(), 0, EPOLL_CTL_DEL);
|
_epoll_update(client->get_cl_fd(), 0, EPOLL_CTL_DEL);
|
||||||
|
|
||||||
client->cgi_pid = pid;
|
client->cgi_pid = pid;
|
||||||
client->cgi_state = CGI_WAIT_FOR_OUTPUT;
|
client->cgi_state = CGI_OUTPUT_READING;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define STATUS_500 std::string("Status: 500" CRLF CRLF);
|
|
||||||
|
|
||||||
void Webserv::_check_script_output(Client *client, std::string & output)
|
void Webserv::_check_script_output(Client *client, std::string & output)
|
||||||
{
|
{
|
||||||
@@ -282,17 +290,16 @@ void Webserv::_check_script_status(Client *client, std::string & output)
|
|||||||
client->status = 200;
|
client->status = 200;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Webserv::_check_script_fields(const std::string & output, size_t status)
|
unsigned int Webserv::_check_script_fields(const std::string & output, unsigned int status)
|
||||||
{
|
{
|
||||||
std::string headers;
|
std::string headers;
|
||||||
std::string body;
|
std::string body;
|
||||||
size_t pos;
|
size_t pos;
|
||||||
|
|
||||||
std::cerr << "0\n";
|
std::cerr << "_check_script_fields()\n";
|
||||||
pos = output.find(CRLF CRLF);
|
pos = output.find(CRLF CRLF);
|
||||||
if (pos == NPOS) // there is not empty line
|
if (pos == NPOS) // there is not empty line
|
||||||
return 500;
|
return 500;
|
||||||
std::cerr << "1\n";
|
|
||||||
headers = output.substr(0, pos);
|
headers = output.substr(0, pos);
|
||||||
body = output.substr(pos + CRLF_SIZE * 2);
|
body = output.substr(pos + CRLF_SIZE * 2);
|
||||||
headers = str_tolower(headers);
|
headers = str_tolower(headers);
|
||||||
@@ -301,18 +308,14 @@ std::cerr << "1\n";
|
|||||||
{
|
{
|
||||||
if (!body.empty()) // there is body
|
if (!body.empty()) // there is body
|
||||||
return 500;
|
return 500;
|
||||||
std::cerr << "2\n";
|
|
||||||
if (headers.find("location") == NPOS) // there is no location field
|
if (headers.find("location") == NPOS) // there is no location field
|
||||||
return 500;
|
return 500;
|
||||||
std::cerr << "3\n";
|
|
||||||
}
|
}
|
||||||
else if (headers.find("location") != NPOS) // there is a location field
|
else if (headers.find("location") != NPOS) // there is a location field
|
||||||
{
|
{
|
||||||
if (body.empty()) // there is no body
|
if (body.empty()) // there is no body
|
||||||
return 500;
|
return 500;
|
||||||
std::cerr << "4\n";
|
|
||||||
}
|
}
|
||||||
std::cerr << "5\n";
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,31 +3,28 @@
|
|||||||
|
|
||||||
|
|
||||||
#define BUFSIZE 8192 // (8Ko)
|
#define BUFSIZE 8192 // (8Ko)
|
||||||
#define STATUS_500 std::string("Status: 500" CRLF CRLF);
|
|
||||||
void Webserv::_read_cgi_output(Client *client)
|
void Webserv::_read_cgi_output(Client *client)
|
||||||
{
|
{
|
||||||
char buf[BUFSIZE];
|
char buf[BUFSIZE];
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
std::cerr << "_read_cgi_output()" << "\n";
|
std::cerr << "_read_cgi_output()" << "\n"; // Debug
|
||||||
std::cerr << "cgi_pid = " << client->cgi_pid << "\n";
|
std::cerr << "cgi_pid = " << client->cgi_pid << "\n"; // Debug
|
||||||
std::cerr << "client fd = " << client->get_cl_fd() << "\n";
|
std::cerr << "client fd = " << client->get_cl_fd() << "\n"; // Debug
|
||||||
std::cerr << "cgi fd = " << client->cgi_pipe_r_from_child << "\n";
|
std::cerr << "cgi fd = " << client->cgi_pipe_r_from_child << "\n"; // Debug
|
||||||
|
|
||||||
ret = ::read(client->cgi_pipe_r_from_child, buf, BUFSIZE);
|
ret = ::read(client->cgi_pipe_r_from_child, buf, BUFSIZE);
|
||||||
std::cerr << "cgi read ret = " << ret << "\n";
|
std::cerr << "cgi read ret = " << ret << "\n"; // Debug
|
||||||
if (ret == -1)
|
if (ret == -1)
|
||||||
{
|
{
|
||||||
std::perror("err read(cgi_fd)");
|
std::perror("err read(cgi_fd)");
|
||||||
client->cgi_output = STATUS_500;
|
client->status = 500;
|
||||||
|
client->cgi_state = CGI_NO_CGI;
|
||||||
}
|
}
|
||||||
else if (ret == 0)
|
else if (ret == 0)
|
||||||
std::cerr << "Madame s'il vous plait, du Ketchup pour mon hamburger" << " (AKA:ret=0)" << "\n";
|
std::cerr << "Madame s'il vous plait, du Ketchup pour mon hamburger" << " (AKA:ret=0)" << "\n"; // :)
|
||||||
else
|
else
|
||||||
{
|
|
||||||
std::cerr << "NORMAL BEHAVIOR I THINK!\n"; // debug
|
|
||||||
client->cgi_output.append(buf, ret);
|
client->cgi_output.append(buf, ret);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void Webserv::_handle_epollerr_cgi_output(uint32_t events, Client *client)
|
void Webserv::_handle_epollerr_cgi_output(uint32_t events, Client *client)
|
||||||
{
|
{
|
||||||
@@ -37,7 +34,8 @@ void Webserv::_handle_epollerr_cgi_output(uint32_t events, Client *client)
|
|||||||
std::cerr << "client fd = " << client->get_cl_fd() << "\n";
|
std::cerr << "client fd = " << client->get_cl_fd() << "\n";
|
||||||
std::cerr << "cgi fd = " << client->cgi_pipe_r_from_child << "\n";
|
std::cerr << "cgi fd = " << client->cgi_pipe_r_from_child << "\n";
|
||||||
|
|
||||||
client->cgi_output = STATUS_500;
|
client->status = 500;
|
||||||
|
client->cgi_state = CGI_NO_CGI;
|
||||||
|
|
||||||
// Common with EPOLLHUP
|
// Common with EPOLLHUP
|
||||||
pid_t wait_ret;
|
pid_t wait_ret;
|
||||||
@@ -45,14 +43,11 @@ void Webserv::_handle_epollerr_cgi_output(uint32_t events, Client *client)
|
|||||||
std::cerr << "cgi EPOLLERR waitpid ret = " << wait_ret << "\n";
|
std::cerr << "cgi EPOLLERR waitpid ret = " << wait_ret << "\n";
|
||||||
if (wait_ret == client->cgi_pid)
|
if (wait_ret == client->cgi_pid)
|
||||||
{
|
{
|
||||||
if (client->cgi_pipe_r_from_child)
|
_epoll_update(client->cgi_pipe_r_from_child, 0, EPOLL_CTL_DEL);
|
||||||
{
|
|
||||||
if (::close(client->cgi_pipe_r_from_child) == -1)
|
if (::close(client->cgi_pipe_r_from_child) == -1)
|
||||||
std::perror("err close()");
|
std::perror("err close()");
|
||||||
}
|
client->cgi_pipe_r_from_child = -1;
|
||||||
client->cgi_pipe_r_from_child = 0;
|
|
||||||
_epoll_update(client->get_cl_fd(), EPOLLOUT, EPOLL_CTL_ADD);
|
_epoll_update(client->get_cl_fd(), EPOLLOUT, EPOLL_CTL_ADD);
|
||||||
client->cgi_state = CGI_OUTPUT_READY;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -73,14 +68,12 @@ void Webserv::_handle_epollhup_cgi_output(uint32_t events, Client *client)
|
|||||||
// std::cerr << "cgi EPOLLHUP waitpid ret = " << wait_ret << "\n";
|
// std::cerr << "cgi EPOLLHUP waitpid ret = " << wait_ret << "\n";
|
||||||
if (wait_ret == client->cgi_pid)
|
if (wait_ret == client->cgi_pid)
|
||||||
{
|
{
|
||||||
if (client->cgi_pipe_r_from_child)
|
_epoll_update(client->cgi_pipe_r_from_child, 0, EPOLL_CTL_DEL);
|
||||||
{
|
|
||||||
if (::close(client->cgi_pipe_r_from_child) == -1)
|
if (::close(client->cgi_pipe_r_from_child) == -1)
|
||||||
std::perror("err close()");
|
std::perror("err close()");
|
||||||
}
|
client->cgi_pipe_r_from_child = -1;
|
||||||
client->cgi_pipe_r_from_child = 0;
|
|
||||||
_epoll_update(client->get_cl_fd(), EPOLLOUT, EPOLL_CTL_ADD);
|
_epoll_update(client->get_cl_fd(), EPOLLOUT, EPOLL_CTL_ADD);
|
||||||
client->cgi_state = CGI_OUTPUT_READY;
|
client->cgi_state = CGI_OUTPUT_COMPLETE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,9 +88,8 @@ void Webserv::_handle_epollerr_cgi_input(uint32_t events, Client *client)
|
|||||||
{
|
{
|
||||||
(void)events;
|
(void)events;
|
||||||
|
|
||||||
client->cgi_output = STATUS_500;
|
client->status = 500;
|
||||||
|
client->cgi_state = CGI_NO_CGI;
|
||||||
client->cgi_state = CGI_OUTPUT_READY;
|
|
||||||
_close_client_cgi_pipes(client);
|
_close_client_cgi_pipes(client);
|
||||||
_epoll_update(client->get_cl_fd(), EPOLLOUT, EPOLL_CTL_ADD);
|
_epoll_update(client->get_cl_fd(), EPOLLOUT, EPOLL_CTL_ADD);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ void Webserv::_close_client(int fd)
|
|||||||
if (::close(fd) == -1)
|
if (::close(fd) == -1)
|
||||||
std::perror("err close()");
|
std::perror("err close()");
|
||||||
_close_client_cgi_pipes(&(*it));
|
_close_client_cgi_pipes(&(*it));
|
||||||
|
// it->clear(); // PISTE, debug normalement superflu
|
||||||
_clients.erase(it);
|
_clients.erase(it);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -24,23 +25,38 @@ void Webserv::_close_client(int fd)
|
|||||||
void Webserv::_close_client_cgi_pipes(Client *client)
|
void Webserv::_close_client_cgi_pipes(Client *client)
|
||||||
{
|
{
|
||||||
if (client->cgi_state)
|
if (client->cgi_state)
|
||||||
{
|
{ // No need to reset the fd to -1 normaly
|
||||||
std::cerr << "close cgi-pipes" << "\n";
|
std::cerr << "close cgi-pipes" << "\n";
|
||||||
if (::close(client->cgi_pipe_w_to_child) == -1)
|
if (::close(client->cgi_pipe_w_to_child) == -1)
|
||||||
std::perror("err close()");
|
std::perror("err close()");
|
||||||
|
// client->cgi_pipe_w_to_child = -1;
|
||||||
|
|
||||||
if (::close(client->cgi_pipe_r_from_child) == -1)
|
if (::close(client->cgi_pipe_r_from_child) == -1)
|
||||||
std::perror("err close()");
|
std::perror("err close()");
|
||||||
|
// client->cgi_pipe_r_from_child = -1;
|
||||||
|
|
||||||
if (::close(client->cgi_pipe_w_to_parent) == -1)
|
if (::close(client->cgi_pipe_w_to_parent) == -1)
|
||||||
std::perror("err close()");
|
std::perror("err close()");
|
||||||
|
// client->cgi_pipe_w_to_parent = -1;
|
||||||
|
|
||||||
if (::close(client->cgi_pipe_r_from_parent) == -1)
|
if (::close(client->cgi_pipe_r_from_parent) == -1)
|
||||||
std::perror("err close()");
|
std::perror("err close()");
|
||||||
|
// client->cgi_pipe_r_from_parent = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Webserv::_close_all_clients()
|
void Webserv::_close_all_clients()
|
||||||
{
|
{
|
||||||
_close_all_clients_fd();
|
_close_all_clients_fd();
|
||||||
|
|
||||||
_clients.clear();
|
_clients.clear();
|
||||||
|
// REMPLACEMENT ->
|
||||||
|
/* while (!_clients.empty())
|
||||||
|
{
|
||||||
|
std::cerr << "_clients.pop_back() " << &_clients.back() << "\n";
|
||||||
|
_clients.back().clear();
|
||||||
|
_clients.pop_back();
|
||||||
|
} */
|
||||||
}
|
}
|
||||||
|
|
||||||
void Webserv::_close_all_clients_fd()
|
void Webserv::_close_all_clients_fd()
|
||||||
|
|||||||
@@ -25,8 +25,6 @@ void Webserv::_request(Client *client)
|
|||||||
}
|
}
|
||||||
else if (ret == READ_COMPLETE)
|
else if (ret == READ_COMPLETE)
|
||||||
{
|
{
|
||||||
if (client->body_complete && client->get_rq_multi_bodys().empty()) // DEBUG
|
|
||||||
std::cerr << "______BODY\n" << client->get_rq_body() << "\n______\n"; // DEBUG
|
|
||||||
_epoll_update(client->get_cl_fd(), EPOLLOUT, EPOLL_CTL_MOD);
|
_epoll_update(client->get_cl_fd(), EPOLLOUT, EPOLL_CTL_MOD);
|
||||||
client->request_complete = true;
|
client->request_complete = true;
|
||||||
}
|
}
|
||||||
@@ -53,13 +51,10 @@ int Webserv::_read_request(Client *client)
|
|||||||
// ::print_special(client->raw_request);
|
// ::print_special(client->raw_request);
|
||||||
// std::cerr << "__raw_request__\n" << client->raw_request << "\n______\n"; // DEBUG
|
// std::cerr << "__raw_request__\n" << client->raw_request << "\n______\n"; // DEBUG
|
||||||
|
|
||||||
print_special(client->raw_request);
|
// print_special(client->raw_request);
|
||||||
|
|
||||||
std::cerr << "client header complete: " << client->header_complete << "\n"; // DEBUG
|
|
||||||
|
|
||||||
if (!client->header_complete)
|
if (!client->header_complete)
|
||||||
{
|
{
|
||||||
std::cout << "Header not complete\n"; // debug
|
|
||||||
client->parse_request_headers(_servers);
|
client->parse_request_headers(_servers);
|
||||||
if (client->status)
|
if (client->status)
|
||||||
return READ_COMPLETE;
|
return READ_COMPLETE;
|
||||||
@@ -78,7 +73,6 @@ int Webserv::_read_request(Client *client)
|
|||||||
}
|
}
|
||||||
if (client->header_complete)
|
if (client->header_complete)
|
||||||
{
|
{
|
||||||
std::cerr << "Client header Complete\n";
|
|
||||||
// client->read_body_size += ret; // Not accurate, part of body could have been read with headers, unused for now
|
// client->read_body_size += ret; // Not accurate, part of body could have been read with headers, unused for now
|
||||||
client->parse_request_body();
|
client->parse_request_body();
|
||||||
if (client->status || client->body_complete)
|
if (client->status || client->body_complete)
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ void Webserv::_response(Client *client)
|
|||||||
|| client->status == 400 // TODO: Refactoring
|
|| client->status == 400 // TODO: Refactoring
|
||||||
|| client->status == 408
|
|| client->status == 408
|
||||||
|| client->status == 413)
|
|| client->status == 413)
|
||||||
|
// || client->cgi_state == CGI_OUTPUT_COMPLETE) // DEBUG
|
||||||
_close_client(client->get_cl_fd());
|
_close_client(client->get_cl_fd());
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -48,8 +49,8 @@ int Webserv::_send_response(Client *client)
|
|||||||
if (!client->status)
|
if (!client->status)
|
||||||
{
|
{
|
||||||
_construct_response(client);
|
_construct_response(client);
|
||||||
if (client->cgi_state == CGI_WAIT_FOR_OUTPUT
|
if (client->cgi_state == CGI_WAIT_TO_EXEC
|
||||||
|| client->cgi_state == CGI_WAIT_TO_EXEC)
|
|| client->cgi_state == CGI_OUTPUT_READING)
|
||||||
return SEND_IN_PROGRESS;
|
return SEND_IN_PROGRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,6 +73,11 @@ int Webserv::_send_response(Client *client)
|
|||||||
std::cerr << "SEND RET 0 for client.fd =" << client->get_cl_fd() << "\n"; // DEBUG
|
std::cerr << "SEND RET 0 for client.fd =" << client->get_cl_fd() << "\n"; // DEBUG
|
||||||
return SEND_CLOSE;
|
return SEND_CLOSE;
|
||||||
}
|
}
|
||||||
|
if (ret < (int)client->response.size())
|
||||||
|
{
|
||||||
|
std::cerr << "send() as not send all data, IT CAN HAPPEN !" << "\n"; // DEBUG
|
||||||
|
throw ExecFail(); // DEBUG, TODO, A ENLEVER ABSOLEMENT, WHILE TEMP =D
|
||||||
|
}
|
||||||
// /* Debug */ std::cerr << "ret send() = " << ret << "\n"; // DEBUG
|
// /* Debug */ std::cerr << "ret send() = " << ret << "\n"; // DEBUG
|
||||||
|
|
||||||
return SEND_COMPLETE;
|
return SEND_COMPLETE;
|
||||||
@@ -99,16 +105,26 @@ void Webserv::_construct_response(Client *client)
|
|||||||
if (client->cgi_state == CGI_READY_TO_EXEC)
|
if (client->cgi_state == CGI_READY_TO_EXEC)
|
||||||
{
|
{
|
||||||
std::string body = client->get_rq_body();
|
std::string body = client->get_rq_body();
|
||||||
::write(client->cgi_pipe_w_to_child, body.c_str(), body.size());
|
std::cerr << "client.fd for write body =" << client->get_cl_fd() << "\n"; // DEBUG
|
||||||
|
std::cerr << "client.cgi_pipe_w_to_child for write body =" << client->cgi_pipe_w_to_child << "\n"; // DEBUG
|
||||||
|
if (::write(client->cgi_pipe_w_to_child, body.c_str(), body.size()) == -1)
|
||||||
|
{
|
||||||
|
std::perror("err write()");
|
||||||
|
_close_client_cgi_pipes(client);
|
||||||
|
client->status = 500;
|
||||||
|
client->cgi_state = CGI_NO_CGI;
|
||||||
|
return;
|
||||||
|
}
|
||||||
_exec_cgi(client);
|
_exec_cgi(client);
|
||||||
}
|
}
|
||||||
else if (client->cgi_state == CGI_OUTPUT_READY)
|
else if (client->cgi_state == CGI_OUTPUT_COMPLETE)
|
||||||
{
|
{
|
||||||
// /*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 "[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(client->cgi_output); std::cout << B_PURPLE "-----------" RESET "\n\n";
|
// /*DEBUG*/ std::cout << "\n" B_PURPLE "[script output]:" RESET "\n"; ::print_special(client->cgi_output); std::cout << B_PURPLE "-----------" RESET "\n\n";
|
||||||
_check_script_output(client, client->cgi_output); // FD_CGI : adjust for client->cgi_output;
|
_check_script_output(client, client->cgi_output); // FD_CGI : adjust for client->cgi_output;
|
||||||
if (client->status < 400)
|
if (client->status < 400 || client->status >= 600)
|
||||||
client->response += client->cgi_output;
|
client->response += client->cgi_output;
|
||||||
|
// client->cgi_state = CGI_NO_CGI; // Not indispensable, reset when client.clear()
|
||||||
// /*DEBUG*/ std::cout << "\n" B_PURPLE "[response + output]:" RESET "\n"; ::print_special(client->response); std::cout << B_PURPLE "-----------" RESET "\n\n";
|
// /*DEBUG*/ std::cout << "\n" B_PURPLE "[response + output]:" RESET "\n"; ::print_special(client->response); std::cout << B_PURPLE "-----------" RESET "\n\n";
|
||||||
}
|
}
|
||||||
else if (_is_cgi(client, path))
|
else if (_is_cgi(client, path))
|
||||||
|
|||||||
@@ -12,8 +12,9 @@ void Webserv::run()
|
|||||||
int i;
|
int i;
|
||||||
int count_loop = 0;
|
int count_loop = 0;
|
||||||
std::vector<listen_socket>::iterator it_lsocket;
|
std::vector<listen_socket>::iterator it_lsocket;
|
||||||
Client *client_cgi_output = NULL;
|
std::vector<Client>::iterator it_client;
|
||||||
Client *client_cgi_input = NULL;
|
Client *client_cgi_input = NULL;
|
||||||
|
Client *client_cgi_output = NULL;
|
||||||
|
|
||||||
g_run = true;
|
g_run = true;
|
||||||
while (g_run)
|
while (g_run)
|
||||||
@@ -37,8 +38,10 @@ void Webserv::run()
|
|||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
it_lsocket = std::find(_listen_sockets.begin(), _listen_sockets.end(), events[i].data.fd);
|
it_lsocket = std::find(_listen_sockets.begin(), _listen_sockets.end(), events[i].data.fd);
|
||||||
client_cgi_output = _find_cgi_output_fd(events[i].data.fd);
|
it_client = std::find(_clients.begin(), _clients.end(), events[i].data.fd);
|
||||||
client_cgi_input = _find_cgi_input_fd(events[i].data.fd);
|
client_cgi_input = _find_cgi_input_fd(events[i].data.fd);
|
||||||
|
client_cgi_output = _find_cgi_output_fd(events[i].data.fd);
|
||||||
|
|
||||||
if (it_lsocket != _listen_sockets.end())
|
if (it_lsocket != _listen_sockets.end())
|
||||||
{
|
{
|
||||||
if (events[i].events & EPOLLERR || events[i].events & EPOLLHUP)
|
if (events[i].events & EPOLLERR || events[i].events & EPOLLHUP)
|
||||||
@@ -46,6 +49,15 @@ void Webserv::run()
|
|||||||
else if (events[i].events & EPOLLIN)
|
else if (events[i].events & EPOLLIN)
|
||||||
_accept_connection(*it_lsocket);
|
_accept_connection(*it_lsocket);
|
||||||
}
|
}
|
||||||
|
else if (it_client != _clients.end())
|
||||||
|
{
|
||||||
|
if (events[i].events & EPOLLERR || events[i].events & EPOLLHUP)
|
||||||
|
_handle_epoll_error_client(events[i].events, events[i].data.fd);
|
||||||
|
else if (events[i].events & EPOLLIN)
|
||||||
|
_request( &(*it_client) );
|
||||||
|
else if (events[i].events & EPOLLOUT)
|
||||||
|
_response( &(*it_client) );
|
||||||
|
}
|
||||||
else if (client_cgi_input)
|
else if (client_cgi_input)
|
||||||
{
|
{
|
||||||
if (events[i].events & EPOLLERR || events[i].events & EPOLLHUP)
|
if (events[i].events & EPOLLERR || events[i].events & EPOLLHUP)
|
||||||
@@ -62,14 +74,9 @@ void Webserv::run()
|
|||||||
else if ( (events[i].events & EPOLLHUP) && !(events[i].events & EPOLLIN) )
|
else if ( (events[i].events & EPOLLHUP) && !(events[i].events & EPOLLIN) )
|
||||||
_handle_epollhup_cgi_output(events[i].events, client_cgi_output);
|
_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()
|
else
|
||||||
{
|
{
|
||||||
if (events[i].events & EPOLLERR || events[i].events & EPOLLHUP)
|
std::cerr << "NOTHING FOR FD = " << events[i].data.fd << "\n"; // DEBUG
|
||||||
_handle_epoll_error_client(events[i].events, events[i].data.fd);
|
|
||||||
else if (events[i].events & EPOLLIN)
|
|
||||||
_request( &(*std::find(_clients.begin(), _clients.end(), events[i].data.fd)) );
|
|
||||||
else if (events[i].events & EPOLLOUT)
|
|
||||||
_response( &(*std::find(_clients.begin(), _clients.end(), events[i].data.fd)) );
|
|
||||||
}
|
}
|
||||||
++i;
|
++i;
|
||||||
if (!g_run)
|
if (!g_run)
|
||||||
|
|||||||
1
urls.txt
1
urls.txt
@@ -6,4 +6,3 @@ http://localhost:4040/test
|
|||||||
http://localhost:4040/test/test_deeper/
|
http://localhost:4040/test/test_deeper/
|
||||||
http://localhost:4040/test/test_deeper/super_deep/
|
http://localhost:4040/test/test_deeper/super_deep/
|
||||||
http://localhost:4040/test/index1.html
|
http://localhost:4040/test/index1.html
|
||||||
|
|
||||||
|
|||||||
1
urls_cgi.txt
Normal file
1
urls_cgi.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
http://localhost:4040/cgi-bin/cgi_cpp_empty.out?fname=John&lname=Doe
|
||||||
BIN
www/user_files/pepe.jpg
Normal file
BIN
www/user_files/pepe.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 54 KiB |
Reference in New Issue
Block a user