Files
42_INT_12_webserv/srcs/webserv/cgi_script.cpp
2022-08-08 13:20:06 +02:00

161 lines
3.9 KiB
C++

#include "Webserv.hpp"
bool Webserv::_is_cgi(Client *client)
{
// TODO see how it works with config
if (client->fill_script_path("/cgi-bin/php-cgi"))
return true;
if (client->fill_script_path("/cgi-bin/cgi_cpp.cgi"))
return true;
return false;
}
void Webserv::_exec_cgi(Client *client)
{
char** env;
env = _set_env(client);
_exec_script(client, env);
// _construct_response(client);
for (size_t i = 0; env[i]; i++)
delete[] env[i];
delete[] env;
}
char* Webserv::_dup_env(std::string var, std::string val = "")
{
std::string str;
str = var + "=" + val;
return ( strdup(str.c_str()) );
}
char* Webserv::_dup_env(std::string var, int i)
{
std::string str;
std::string val;
val = ::itos(i);
str = var + "=" + val;
return ( strdup(str.c_str()) );
}
char** Webserv::_set_env(Client *client)
{
char** env = new char*[19];
env[0] = _dup_env("AUTH_TYPE"); // authentification not supported
env[1] = _dup_env("CONTENT_LENGTH" , client->get_rq_body().size());
env[2] = _dup_env("CONTENT_TYPE" , client->get_rq_headers("Content-Type"));
env[3] = _dup_env("GATEWAY_INTERFACE" , "CGI/1.0");
env[4] = _dup_env("PATH_INFO" , client->get_rq_script_info());
env[5] = _dup_env("PATH_TRANSLATED"); // not supported
env[6] = _dup_env("QUERY_STRING" , client->get_rq_query());
env[7] = _dup_env("REMOTE_ADDR" , client->get_cl_ip());
env[8] = _dup_env("REMOTE_HOST" , client->get_rq_headers("Host")); // just test
env[9] = _dup_env("REMOTE_IDENT"); // authentification not supported
env[10] = _dup_env("REMOTE_USER"); // authentification not supported
env[11] = _dup_env("REQUEST_METHOD" , client->get_rq_method_str());
env[12] = _dup_env("SCRIPT_NAME" , client->get_rq_script_path());
env[13] = _dup_env("SERVER_NAME" , client->get_rq_hostname());
env[14] = _dup_env("SERVER_PORT" , client->get_rq_port());
env[15] = _dup_env("SERVER_PROTOCOL" , client->get_rq_version());
env[16] = _dup_env("SERVER_SOFTWARE" , "webser/1.0");
env[17] = _dup_env("REDIRECT_STATUS" , "200");
env[18] = NULL;
return env;
}
void Webserv::_exec_script(Client *client, char **env)
{
#define RD 0
#define WR 1
#define CGI_BUF_SIZE 10
/*1*/ #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]
/*2*/// #define FD_WR_TO_CHLD fdIn
/* */// #define FD_WR_TO_PRNT fdOut
/* */// #define FD_RD_FR_CHLD fdOut
/* */// #define FD_RD_FR_PRNT fdIn
pid_t pid;
char buf[CGI_BUF_SIZE]; // WIP define buffer
char * const * nll = NULL;
std::string response;
std::string body = client->get_rq_body();
/*1*/ int fd_in[2];
/* */ int fd_out[2];
/*2*/// FILE *fIn;
/* */// FILE *fOut;
/* */// long fdIn;
/* */// long fdOut;
/*1*/ pipe(fd_in);
/* */ pipe(fd_out);
/*2*/// fIn = tmpfile();
/* */// fOut = tmpfile();
/* */// fdIn = fileno(fIn);
/* */// fdOut = fileno(fOut);
pid = fork();
if (pid == -1)
std::cerr << "fork crashed" << std::endl;
else if (pid == 0)
{
/*1*/ close(FD_WR_TO_CHLD);
/* */ close(FD_RD_FR_CHLD);
/*2*/
dup2(FD_RD_FR_PRNT, STDIN_FILENO);
dup2(FD_WR_TO_PRNT, STDOUT_FILENO);
execve(client->get_rq_script_path().c_str(), nll, env);
std::cerr << "execve crashed.\n";
}
else
{
/*1*/ close(FD_RD_FR_PRNT);
/* */ close(FD_WR_TO_PRNT);
/*2*/
write(FD_WR_TO_CHLD, body.c_str(), body.size());
close(FD_WR_TO_CHLD);
waitpid(-1, NULL, 0);
/*1*/
/*2*/// lseek(fdOut, 0, SEEK_SET);
memset(buf, '\0', CGI_BUF_SIZE);
while (read(FD_RD_FR_CHLD, buf, CGI_BUF_SIZE - 1) > 0)
{
response += buf;
memset(buf, '\0', CGI_BUF_SIZE);
}
}
if (response.empty())
response = "Status: 500\r\n\r\n";
/*1*/
/*2*/// fclose(fIn);
/* */// fclose(fOut);
/* */// close(fdIn);
/* */// close(fdOut);
// DEBUG
std::cout << "\n______response________\n" << response << "\n________________________\n";
// TODO: see how this must be handled
client->response += response;
}
void Webserv::_construct_client(Client *client)
{
(void)client;
}