From 67cf7a1c3ab6693c5b32479e975a129663fd6a4e Mon Sep 17 00:00:00 2001 From: adjoly Date: Thu, 15 May 2025 14:25:45 +0200 Subject: [PATCH 1/4] =?UTF-8?q?=E3=80=8C=F0=9F=8F=97=EF=B8=8F=E3=80=8D=20w?= =?UTF-8?q?ip:=20started=20working=20on=20cgi=20finally?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- exemples/test.toml | 2 +- includes/help.hpp | 3 +- includes/requests/ARequest.hpp | 2 +- includes/requests/Cgi.hpp | 24 ++++++---- src/requests_handling/Cgi.cpp | 85 ++++++++++++++++++++++++++++------ src/server/Server.cpp | 7 +-- 6 files changed, 94 insertions(+), 29 deletions(-) diff --git a/exemples/test.toml b/exemples/test.toml index d031313..ac1d78c 100644 --- a/exemples/test.toml +++ b/exemples/test.toml @@ -12,7 +12,7 @@ port = 8080 [server.location./] methods = { "GET" } -root = "/sgoinfre/goinfre/Perso/mmoussou" +root = "/home/adjoly" dirlist = true client_max_body_size = "10M" index = "banger.html" diff --git a/includes/help.hpp b/includes/help.hpp index 6c8da1f..3ec8d7d 100644 --- a/includes/help.hpp +++ b/includes/help.hpp @@ -6,7 +6,7 @@ /* By: adjoly +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/04/10 13:43:54 by adjoly #+# #+# */ -/* Updated: 2025/05/08 12:05:38 by adjoly ### ########.fr */ +/* Updated: 2025/05/15 12:02:30 by adjoly ### ########.fr */ /* */ /* ************************************************************************** */ @@ -18,5 +18,6 @@ #define SAMPLE_CONF_PATH "/etc/webserv/default.conf" #endif #define WEBSRV_VERSION "v0.2" +#define WEBSRV_NAME "webserv" bool help(int, char **); diff --git a/includes/requests/ARequest.hpp b/includes/requests/ARequest.hpp index 925af3f..61ea316 100644 --- a/includes/requests/ARequest.hpp +++ b/includes/requests/ARequest.hpp @@ -6,7 +6,7 @@ /* By: mmoussou +#+ +:+ +#+ */ +/* By: gadelbes +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ -/* Created: 2025/03/24 14:17:34 by adjoly #+# #+# */ -/* Updated: 2025/04/30 09:36:02 by adjoly ### ########.fr */ +/* Created: 2025/04/24 13:46:34 by gadelbes #+# #+# */ +/* Updated: 2025/05/15 13:45:20 by adjoly ### ########.fr */ /* */ /* ************************************************************************** */ #pragma once -#include +#include "server/AResource.hpp" +#include #include +#include + #include #include namespace webserv { -class Cgi { +class Cgi : public server::AClientResource { public: - Cgi(http::ARequest *, config::Server *); + Cgi(http::ARequest *, config::Route *); ~Cgi(void); std::string getEnv(std::string &); - void setEnv(std::string &, std::string); + void setEnv(const std::string, std::string); void process(void); @@ -33,8 +36,11 @@ class Cgi { private: void _initEnvp(void); + char **_genEnv(void); + std::map _envp; - config::Server *_conf; - http::IMessage *_request; + config::Route *_conf; + http::ARequest *_request; }; + }; // namespace webserv diff --git a/src/requests_handling/Cgi.cpp b/src/requests_handling/Cgi.cpp index 6ce13f8..488e705 100644 --- a/src/requests_handling/Cgi.cpp +++ b/src/requests_handling/Cgi.cpp @@ -3,23 +3,54 @@ /* ::: :::::::: */ /* Cgi.cpp :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: adjoly +#+ +:+ +#+ */ +/* By: gadelbes +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ -/* Created: 2025/04/24 13:46:34 by adjoly #+# #+# */ -/* Updated: 2025/04/30 09:49:32 by adjoly ### ########.fr */ +/* Created: 2025/04/24 13:46:34 by gadelbes #+# #+# */ +/* Updated: 2025/05/15 12:46:38 by adjoly ### ########.fr */ /* */ /* ************************************************************************** */ -#include "requests/default.hpp" +#include "requests/Cgi.hpp" +#include "help.hpp" +#include using namespace webserv; -Cgi::Cgi(http::ARequest *req, config::Server *conf) : _conf(conf), _request(req) { +Cgi::Cgi(http::ARequest *req, config::Route *conf) + : _conf(conf), _request(req) { _initEnvp(); } -void Cgi::_initEnvp(void) { - //_envp[] = ""; +void Cgi::_initEnvp(void) { + std::stringstream str; + str << WEBSRV_NAME << "/" << WEBSRV_VERSION; + setEnv("SERVER_SOFTWARE", str.str()); + setEnv("SERVER_NAME", _request->getHeader("Host")); + setEnv("SERVER_PROTOCOL", _request->getProtocol()); + // setEnv("SERVER_PORT", _request->get); // TODO need to get the port by a + // way i dont know yet + + setEnv("GATEWAY_INTERFACE", "CGI/1.1"); + + // setEnv("PATH_TRANSLATED", ); // TODO wtf should i put here i dont fcking + // know setEnv("PATH_INFO", ); // TODO wut make no sense + + str.clear(); + str << _request->getBody().length(); + setEnv("CONTENT_LENGH", str.str()); + setEnv("CONTENT_TYPE", _request->getHeader("Content-Type")); + // setEnv("REMOTE_ADDR", _request->get) // TODO don't have it yet need to be + // passed to the requset :sob: + setEnv("HTTP_ACCEPT", _request->getHeader("Accept")); + setEnv("HTTP_ACCEPT_LANGUAGE", _request->getHeader("Accept-Language")); + setEnv("HTTP_COOKIE", _request->getHeader("Cookie")); + setEnv("HTTP_HOST", _request->getHeader("Host")); + setEnv("HTTP_REFERER", _request->getHeader("Referer")); + setEnv("HTTP_USER_AGENT", _request->getHeader("User-Agent")); + + setEnv("SCRIPT_NAME", _request->getTarget()); + + setEnv("QUERY_STRING", _request->getUrl().getQueryString()); } std::string Cgi::getEnv(std::string &key) { @@ -30,20 +61,46 @@ std::string Cgi::getEnv(std::string &key) { return ""; } -void Cgi::setEnv(std::string &key, std::string value) { +void Cgi::setEnv(const std::string key, std::string value) { _envp[key] = value; } -void Cgi::process() { - int pipefd[2]; - int forkPid; +void Cgi::process() { + int pipefd[2]; + int forkPid; if (pipe(pipefd) <= -1) { - //throw error + // throw error } forkPid = fork(); if (forkPid == 0) { - // in fork - } + int fd = open("kanel/cheminfichier", + O_RDONLY); // chemin vers ce que je dois ouvrir + if (fd == -1) + // throw erreur + dup2(fd, 0); + dup2(pipefd[1], 1); + close(fd); + close(pipefd[0]); + close(pipefd[1]); + + std::string cgipath = "kanel/chemincgi"; // chemin du cgi + char *envp[] = {getEnv("REQUEST_METHOD"), getEnv("?"), getEnv("TYPE"), + getEnv("LENGTH"), NULL}; + execve(cgipath, NULL, env); + // throw si execve echou + } else if (forkPid >= 1) { + close(pipefd[1]); + + int nb; + waitpid(forkPid, &nb, 0); + + char buffer[4096] // jsp quoi mettre le temps + while (read(pipefd[0], buffer, sizeof(buffer))) { + // tranfert donnees + } + close(pipefd[0]); + } else + throw error; } diff --git a/src/server/Server.cpp b/src/server/Server.cpp index a4c1508..0f4a611 100644 --- a/src/server/Server.cpp +++ b/src/server/Server.cpp @@ -6,7 +6,7 @@ /* By: adjoly +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/04/11 16:11:40 by adjoly #+# #+# */ -/* Updated: 2025/05/02 13:30:50 by mmoussou ### ########.fr */ +/* Updated: 2025/05/14 23:58:55 by adjoly ### ########.fr */ /* */ /* ************************************************************************** */ @@ -187,14 +187,15 @@ void Server::_run(void) { _log->error("client does not exist"); continue; } - if (client->requestParsed() == true && !client->isReadyToClose()) { + if (client->requestParsed() == true && + !client->isReadyToClose()) { client->answer(); continue; } if (client->isReadyToClose()) { _client_data.erase(std::find(_client_data.begin(), - _client_data.end(), client)); + _client_data.end(), client)); delete client; for (auto it = range(_client_fds)) { if (_client_fds[i].fd == (*it).fd) { From 8762963315a8c4e55d58c7bf0f747d4fe4a93b57 Mon Sep 17 00:00:00 2001 From: adjoly Date: Fri, 16 May 2025 16:59:31 +0200 Subject: [PATCH 2/4] =?UTF-8?q?=E3=80=8C=F0=9F=8F=97=EF=B8=8F=E3=80=8D=20w?= =?UTF-8?q?ip:=20genEnv=20done=20and=20process=20in=20progress?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- includes/config/Route.hpp | 20 +++++++- includes/requests/Cgi.hpp | 16 +++++-- includes/server/ResourceManager.hpp | 4 +- src/requests_handling/Cgi.cpp | 74 ++++++++++++++--------------- 4 files changed, 68 insertions(+), 46 deletions(-) diff --git a/includes/config/Route.hpp b/includes/config/Route.hpp index 9bb02fe..d49e5ff 100644 --- a/includes/config/Route.hpp +++ b/includes/config/Route.hpp @@ -6,7 +6,7 @@ /* By: adjoly +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/03/19 14:59:41 by adjoly #+# #+# */ -/* Updated: 2025/05/09 11:06:38 by adjoly ### ########.fr */ +/* Updated: 2025/05/16 12:08:03 by adjoly ### ########.fr */ /* */ /* ************************************************************************** */ @@ -20,6 +20,7 @@ #include #include #include +#include namespace webserv { namespace config { @@ -39,6 +40,23 @@ class Route { std::string getUpRoot(void) { return _up_root; } std::string getIndex(void) { return _index; } std::map *getCgi(void) { return _cgi; } + std::string getCgiPath(const std::string file) { + if (_cgi == not_nullptr) + return ""; + size_t pos = file.find_last_of("."); + + if (pos == file.length()) + return ""; + std::string ext = file.substr(pos + 1); + + for (auto it = prange(_cgi)) { + if (ext == it->first) { + return it->second; + } + } + return ""; + } + bool *getMethods(void) { return _methods; } diff --git a/includes/requests/Cgi.hpp b/includes/requests/Cgi.hpp index 8feb745..d78490b 100644 --- a/includes/requests/Cgi.hpp +++ b/includes/requests/Cgi.hpp @@ -6,7 +6,7 @@ /* By: gadelbes +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/04/24 13:46:34 by gadelbes #+# #+# */ -/* Updated: 2025/05/15 13:45:20 by adjoly ### ########.fr */ +/* Updated: 2025/05/16 12:26:18 by adjoly ### ########.fr */ /* */ /* ************************************************************************** */ @@ -36,11 +36,19 @@ class Cgi : public server::AClientResource { private: void _initEnvp(void); + /** + * @brief Can be used to convert the _envp to a char** usable in execve + * + * @return A newly allocated char** with the env from _envp + */ char **_genEnv(void); - std::map _envp; - config::Route *_conf; - http::ARequest *_request; + std::string _script_path; // The full path of the script to be executed + std::string _cgi_path; + + std::map _envp; // The envp filled with _initEnvp + config::Route *_conf; // The configuration for the route used + http::ARequest *_request; // The requests that will be used for the cgi }; }; // namespace webserv diff --git a/includes/server/ResourceManager.hpp b/includes/server/ResourceManager.hpp index ccc6c15..d9db7c7 100644 --- a/includes/server/ResourceManager.hpp +++ b/includes/server/ResourceManager.hpp @@ -6,7 +6,7 @@ /* By: adjoly +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/05/12 17:13:39 by adjoly #+# #+# */ -/* Updated: 2025/05/13 10:14:27 by adjoly ### ########.fr */ +/* Updated: 2025/05/16 10:18:25 by adjoly ### ########.fr */ /* */ /* ************************************************************************** */ @@ -77,7 +77,7 @@ class ResourceManager { delete (*it); _res.erase(it); } - // TODO throw or not - to see + // NOTE: throw or not - to see } protected: diff --git a/src/requests_handling/Cgi.cpp b/src/requests_handling/Cgi.cpp index 488e705..ca48219 100644 --- a/src/requests_handling/Cgi.cpp +++ b/src/requests_handling/Cgi.cpp @@ -6,41 +6,52 @@ /* By: gadelbes +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/04/24 13:46:34 by gadelbes #+# #+# */ -/* Updated: 2025/05/15 12:46:38 by adjoly ### ########.fr */ +/* Updated: 2025/05/16 12:30:10 by adjoly ### ########.fr */ /* */ /* ************************************************************************** */ -#include "requests/Cgi.hpp" -#include "help.hpp" +#include +#include +#include +#include + +#include #include using namespace webserv; +// WARN: construtor will probably be changed and practicly do nothing Cgi::Cgi(http::ARequest *req, config::Route *conf) : _conf(conf), _request(req) { _initEnvp(); + _cgi_path = _conf->getCgiPath(req->getTarget()); + if (_cgi_path == "") { + // TODO: need to make something + } } void Cgi::_initEnvp(void) { std::stringstream str; str << WEBSRV_NAME << "/" << WEBSRV_VERSION; setEnv("SERVER_SOFTWARE", str.str()); + str.clear(); setEnv("SERVER_NAME", _request->getHeader("Host")); setEnv("SERVER_PROTOCOL", _request->getProtocol()); - // setEnv("SERVER_PORT", _request->get); // TODO need to get the port by a + // setEnv("SERVER_PORT", _request->get); // TODO: need to get the port by a // way i dont know yet setEnv("GATEWAY_INTERFACE", "CGI/1.1"); - // setEnv("PATH_TRANSLATED", ); // TODO wtf should i put here i dont fcking - // know setEnv("PATH_INFO", ); // TODO wut make no sense + // setEnv("PATH_TRANSLATED", ); // TODO: wtf should i put here i dont fcking + // know + // setEnv("PATH_INFO", ); // TODO: wut make no sense - str.clear(); str << _request->getBody().length(); setEnv("CONTENT_LENGH", str.str()); + str.clear(); setEnv("CONTENT_TYPE", _request->getHeader("Content-Type")); - // setEnv("REMOTE_ADDR", _request->get) // TODO don't have it yet need to be - // passed to the requset :sob: + // setEnv("REMOTE_ADDR", _request->get) // TODO: don't have it yet need to + // be passed to the requset :sob: setEnv("HTTP_ACCEPT", _request->getHeader("Accept")); setEnv("HTTP_ACCEPT_LANGUAGE", _request->getHeader("Accept-Language")); setEnv("HTTP_COOKIE", _request->getHeader("Cookie")); @@ -65,42 +76,27 @@ void Cgi::setEnv(const std::string key, std::string value) { _envp[key] = value; } +char **Cgi::_genEnv(void) { + char **newEnv = new char *[_envp.size() + 1]; + size_t i = 0; + + for (auto it = range(_envp), i++) { + std::string str = it->first + "=" + it->second; + char *tmp = new char[str.size() + 1]; + std::strcpy(tmp, str.c_str()); + newEnv[i] = tmp; + } + + return newEnv; +} + void Cgi::process() { int pipefd[2]; int forkPid; if (pipe(pipefd) <= -1) { - // throw error + // TODO: error handling } forkPid = fork(); - if (forkPid == 0) { - int fd = open("kanel/cheminfichier", - O_RDONLY); // chemin vers ce que je dois ouvrir - if (fd == -1) - // throw erreur - dup2(fd, 0); - dup2(pipefd[1], 1); - close(fd); - close(pipefd[0]); - close(pipefd[1]); - - std::string cgipath = "kanel/chemincgi"; // chemin du cgi - char *envp[] = {getEnv("REQUEST_METHOD"), getEnv("?"), getEnv("TYPE"), - getEnv("LENGTH"), NULL}; - execve(cgipath, NULL, env); - // throw si execve echou - } else if (forkPid >= 1) { - close(pipefd[1]); - - int nb; - waitpid(forkPid, &nb, 0); - - char buffer[4096] // jsp quoi mettre le temps - while (read(pipefd[0], buffer, sizeof(buffer))) { - // tranfert donnees - } - close(pipefd[0]); - } else - throw error; } From 7d53470dd0f735d4f94e34289fd4568340466f29 Mon Sep 17 00:00:00 2001 From: adjoly Date: Mon, 19 May 2025 11:42:24 +0200 Subject: [PATCH 3/4] =?UTF-8?q?=E3=80=8C=F0=9F=8F=97=EF=B8=8F=E3=80=8D=20w?= =?UTF-8?q?ip:=20process=20fork=20should=20be=20nearly=20complete?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- includes/requests/Cgi.hpp | 5 ++++- src/requests_handling/Cgi.cpp | 42 ++++++++++++++++++++++++++++++----- 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/includes/requests/Cgi.hpp b/includes/requests/Cgi.hpp index d78490b..f3274ac 100644 --- a/includes/requests/Cgi.hpp +++ b/includes/requests/Cgi.hpp @@ -6,7 +6,7 @@ /* By: gadelbes +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/04/24 13:46:34 by gadelbes #+# #+# */ -/* Updated: 2025/05/16 12:26:18 by adjoly ### ########.fr */ +/* Updated: 2025/05/19 11:07:07 by adjoly ### ########.fr */ /* */ /* ************************************************************************** */ @@ -49,6 +49,9 @@ class Cgi : public server::AClientResource { std::map _envp; // The envp filled with _initEnvp config::Route *_conf; // The configuration for the route used http::ARequest *_request; // The requests that will be used for the cgi + + int stdin_pipe[2]; // The pipefd for the stdin of the cgi + int stdout_pipe[2]; // The pipefd for the stdout of the cgi }; }; // namespace webserv diff --git a/src/requests_handling/Cgi.cpp b/src/requests_handling/Cgi.cpp index ca48219..0904da2 100644 --- a/src/requests_handling/Cgi.cpp +++ b/src/requests_handling/Cgi.cpp @@ -6,17 +6,22 @@ /* By: gadelbes +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/04/24 13:46:34 by gadelbes #+# #+# */ -/* Updated: 2025/05/16 12:30:10 by adjoly ### ########.fr */ +/* Updated: 2025/05/19 11:41:28 by adjoly ### ########.fr */ /* */ /* ************************************************************************** */ +#include #include +#include #include #include #include #include +#include #include +#include +#include using namespace webserv; @@ -90,13 +95,38 @@ char **Cgi::_genEnv(void) { return newEnv; } -void Cgi::process() { - int pipefd[2]; - int forkPid; +void Cgi::process(void) { + int pipefd[2]; + pid_t forkPid; - if (pipe(pipefd) <= -1) { - // TODO: error handling + if (pipe(pipefd) == -1) { + throw; + // TODO: error handling pipe fail } forkPid = fork(); + if (forkPid < 0) { + throw; + // TODO: fork fail + } else if (forkPid == 0) { + dup2(pipefd[1], STDOUT_FILENO); + close(pipefd[1]); + close(pipefd[0]); + + char *argv[] = {const_cast(_cgi_path.c_str()), + const_cast(_script_path.c_str()), NULL}; + char **env = _genEnv(); + + if (execve(_cgi_path.c_str(), argv, env) == -1) { + std::stringstream str; + str << "how did you do that ???? : "; + str << errno; + _log->error(str.str()); + for (int i = 0; env[i] != NULL; i++) + delete env[i]; + delete env; + exit(EXIT_FAILURE); + } + } + waitpid(forkPid, NULL, 0); } From d1fcaafb477dd1e5181355cf2c90642b03c925e4 Mon Sep 17 00:00:00 2001 From: adjoly Date: Wed, 21 May 2025 09:51:34 +0200 Subject: [PATCH 4/4] =?UTF-8?q?=E3=80=8C=F0=9F=8F=97=EF=B8=8F=E3=80=8D=20w?= =?UTF-8?q?ip:=20should=20be=20working=20(kinda)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- includes/requests/Cgi.hpp | 52 ++++++++++++++++++--- src/requests_handling/Cgi.cpp | 86 +++++++++++++++++++++++------------ src/server/Server.cpp | 2 +- 3 files changed, 104 insertions(+), 36 deletions(-) diff --git a/includes/requests/Cgi.hpp b/includes/requests/Cgi.hpp index f3274ac..2194a9c 100644 --- a/includes/requests/Cgi.hpp +++ b/includes/requests/Cgi.hpp @@ -6,7 +6,7 @@ /* By: gadelbes +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/04/24 13:46:34 by gadelbes #+# #+# */ -/* Updated: 2025/05/19 11:07:07 by adjoly ### ########.fr */ +/* Updated: 2025/05/20 20:01:38 by adjoly ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,10 +15,12 @@ #include "server/AResource.hpp" #include #include +#include #include #include #include +#include namespace webserv { @@ -27,13 +29,46 @@ class Cgi : public server::AClientResource { Cgi(http::ARequest *, config::Route *); ~Cgi(void); - std::string getEnv(std::string &); - void setEnv(const std::string, std::string); + int getFdOut(void) const { return _stdout_pipe[0]; } + /** + * @brief Can be used to prepare the Cgi execution + * + * @note To be used after the main fd is in POLLOUT state + */ + void prepare(void); + + /** + * @brief Can be used to know if the prepare function has already been + * called + */ + bool isPrepared(void) { return _prepared; } + + /** + * @brief Can be used to process the Cgi script + */ void process(void); + /** + * @brief Can be used to check if the Cgi have been executed + * + * @note Need to be used after the process() function and checked before + * using str() + */ + bool isProcessed(void) { return _executed; } + + /** + * @brief Can be used to get the output of the Cgi + * + * @note Need to be used after the outfd is in POLLIN state + */ + std::string str(void); + protected: private: + bool _prepared; + bool _executed; + void _initEnvp(void); /** @@ -43,15 +78,18 @@ class Cgi : public server::AClientResource { */ char **_genEnv(void); + std::string _getEnv(std::string &) const; + void _setEnv(const std::string, std::string); + std::string _script_path; // The full path of the script to be executed - std::string _cgi_path; + std::string _cgi_path; std::map _envp; // The envp filled with _initEnvp - config::Route *_conf; // The configuration for the route used + config::Route *_conf; // The configuration for the route used http::ARequest *_request; // The requests that will be used for the cgi - int stdin_pipe[2]; // The pipefd for the stdin of the cgi - int stdout_pipe[2]; // The pipefd for the stdout of the cgi + int _stdin_pipe[2]; // The pipefd for the stdin of the cgi + int _stdout_pipe[2]; // The pipefd for the stdout of the cgi }; }; // namespace webserv diff --git a/src/requests_handling/Cgi.cpp b/src/requests_handling/Cgi.cpp index 0904da2..ea5c2be 100644 --- a/src/requests_handling/Cgi.cpp +++ b/src/requests_handling/Cgi.cpp @@ -6,7 +6,7 @@ /* By: gadelbes +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/04/24 13:46:34 by gadelbes #+# #+# */ -/* Updated: 2025/05/19 11:41:28 by adjoly ### ########.fr */ +/* Updated: 2025/05/21 09:50:23 by adjoly ### ########.fr */ /* */ /* ************************************************************************** */ @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -27,49 +28,51 @@ using namespace webserv; // WARN: construtor will probably be changed and practicly do nothing Cgi::Cgi(http::ARequest *req, config::Route *conf) - : _conf(conf), _request(req) { + : _prepared(false), _executed(false), _conf(conf), _request(req) { _initEnvp(); _cgi_path = _conf->getCgiPath(req->getTarget()); if (_cgi_path == "") { - // TODO: need to make something + throw; + // TODO: need to make something probably will be checked before by + // client } } void Cgi::_initEnvp(void) { std::stringstream str; str << WEBSRV_NAME << "/" << WEBSRV_VERSION; - setEnv("SERVER_SOFTWARE", str.str()); + _setEnv("SERVER_SOFTWARE", str.str()); str.clear(); - setEnv("SERVER_NAME", _request->getHeader("Host")); - setEnv("SERVER_PROTOCOL", _request->getProtocol()); + _setEnv("SERVER_NAME", _request->getHeader("Host")); + _setEnv("SERVER_PROTOCOL", _request->getProtocol()); // setEnv("SERVER_PORT", _request->get); // TODO: need to get the port by a // way i dont know yet - setEnv("GATEWAY_INTERFACE", "CGI/1.1"); + _setEnv("GATEWAY_INTERFACE", "CGI/1.1"); // setEnv("PATH_TRANSLATED", ); // TODO: wtf should i put here i dont fcking // know // setEnv("PATH_INFO", ); // TODO: wut make no sense str << _request->getBody().length(); - setEnv("CONTENT_LENGH", str.str()); + _setEnv("CONTENT_LENGH", str.str()); str.clear(); - setEnv("CONTENT_TYPE", _request->getHeader("Content-Type")); + _setEnv("CONTENT_TYPE", _request->getHeader("Content-Type")); // setEnv("REMOTE_ADDR", _request->get) // TODO: don't have it yet need to // be passed to the requset :sob: - setEnv("HTTP_ACCEPT", _request->getHeader("Accept")); - setEnv("HTTP_ACCEPT_LANGUAGE", _request->getHeader("Accept-Language")); - setEnv("HTTP_COOKIE", _request->getHeader("Cookie")); - setEnv("HTTP_HOST", _request->getHeader("Host")); - setEnv("HTTP_REFERER", _request->getHeader("Referer")); - setEnv("HTTP_USER_AGENT", _request->getHeader("User-Agent")); + _setEnv("HTTP_ACCEPT", _request->getHeader("Accept")); + _setEnv("HTTP_ACCEPT_LANGUAGE", _request->getHeader("Accept-Language")); + _setEnv("HTTP_COOKIE", _request->getHeader("Cookie")); + _setEnv("HTTP_HOST", _request->getHeader("Host")); + _setEnv("HTTP_REFERER", _request->getHeader("Referer")); + _setEnv("HTTP_USER_AGENT", _request->getHeader("User-Agent")); - setEnv("SCRIPT_NAME", _request->getTarget()); + _setEnv("SCRIPT_NAME", _request->getTarget()); - setEnv("QUERY_STRING", _request->getUrl().getQueryString()); + _setEnv("QUERY_STRING", _request->getUrl().getQueryString()); } -std::string Cgi::getEnv(std::string &key) { +std::string Cgi::_getEnv(std::string &key) const { auto it = _envp.find(key); if (it != _envp.end()) { return it->second; @@ -77,7 +80,7 @@ std::string Cgi::getEnv(std::string &key) { return ""; } -void Cgi::setEnv(const std::string key, std::string value) { +void Cgi::_setEnv(const std::string key, std::string value) { _envp[key] = value; } @@ -95,23 +98,31 @@ char **Cgi::_genEnv(void) { return newEnv; } -void Cgi::process(void) { - int pipefd[2]; - pid_t forkPid; - - if (pipe(pipefd) == -1) { +void Cgi::prepare(void) { + if (pipe(_stdin_pipe) == -1 && pipe(_stdout_pipe) == -1) { throw; - // TODO: error handling pipe fail + // TODO: need to make a better throw } + _fd->fd = _stdin_pipe[1]; + _fd->events = POLLOUT; + _prepared = true; +} + +void Cgi::process(void) { + pid_t forkPid; forkPid = fork(); if (forkPid < 0) { throw; // TODO: fork fail } else if (forkPid == 0) { - dup2(pipefd[1], STDOUT_FILENO); - close(pipefd[1]); - close(pipefd[0]); + dup2(_stdin_pipe[0], STDIN_FILENO); + close(_stdin_pipe[0]); + close(_stdin_pipe[1]); + + dup2(_stdout_pipe[1], STDOUT_FILENO); + close(_stdout_pipe[0]); + close(_stdout_pipe[1]); char *argv[] = {const_cast(_cgi_path.c_str()), const_cast(_script_path.c_str()), NULL}; @@ -128,5 +139,24 @@ void Cgi::process(void) { exit(EXIT_FAILURE); } } + close(_stdin_pipe[0]); + close(_stdout_pipe[1]); waitpid(forkPid, NULL, 0); + _executed = true; +} + +std::string Cgi::str(void) { + std::string str; + int max = _conf->getMaxBody(); + char buffer[1024]; + + while (max) { + ssize_t count = read(_stdout_pipe[0], buffer, sizeof(buffer)); + if (count > 0) + str.append(buffer); + else + break; + } + str.append("\0"); + return str; } diff --git a/src/server/Server.cpp b/src/server/Server.cpp index 0f4a611..13e1c6a 100644 --- a/src/server/Server.cpp +++ b/src/server/Server.cpp @@ -6,7 +6,7 @@ /* By: adjoly +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/04/11 16:11:40 by adjoly #+# #+# */ -/* Updated: 2025/05/14 23:58:55 by adjoly ### ########.fr */ +/* Updated: 2025/05/19 15:11:00 by adjoly ### ########.fr */ /* */ /* ************************************************************************** */