#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; }