Files
42_INT_12_webserv/srcs/webserv/cgi_script.cpp
2022-08-07 22:33:39 +02:00

121 lines
3.1 KiB
C++

#include "Webserv.hpp"
bool Webserv::_is_cgi(Client *client)
{
// TODO see how it works with config
if (client->fill_script_path("php-cgi"))
return true;
if (client->fill_script_path("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);
}
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"); // TODO: define (https://www.rfc-editor.org/rfc/rfc3875#section-4.1.13
// ,https://www.rfc-editor.org/rfc/rfc3875#section-8.2)
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 BUF_SIZE 10
char buf[BUF_SIZE];
int fd_in[2];
int fd_out[2];
char * const * nll = NULL;
std::string response;
std::string body = client->get_rq_body();
pipe(fd_in);
pipe(fd_out);
if (fork() == 0)
{
close(fd_in[WR]);
close(fd_out[RD]);
dup2(fd_in[RD], STDIN_FILENO);
dup2(fd_out[WR], STDOUT_FILENO);
execve(client->get_rq_script_path().c_str(), nll, env);
std::cerr << "execve crashed\n";
}
else
{
close(fd_in[RD]);
close(fd_out[WR]);
// write to stdin of child programm
write(fd_in[WR], body.c_str(), body.size());
close(fd_in[WR]);
waitpid(-1, NULL, 0);
// read stdout of child programm
memset(buf, '\0', BUF_SIZE);
while (read(fd_out[RD], buf, BUF_SIZE) > 0)
{
response += buf;
memset(buf, '\0', BUF_SIZE);
}
}
if (response.empty())
response += "Status: 500\r\n\r\n";
// TODO: see how this must be handled
client->response += response;
}
void Webserv::_construct_client(Client *client)
{
(void)client;
}