diff --git a/src/CGIHandler.cpp b/src/CGIHandler.cpp index d4af67d..2b94e3e 100644 --- a/src/CGIHandler.cpp +++ b/src/CGIHandler.cpp @@ -66,17 +66,30 @@ HTTPResponse* CGIHandler::processRequest(const HTTPRequest& request) { std::vector argv = _getArgv(request); std::vector envp = _getEnvp(request); pid_t pid = fork(); - if (pid == -1) + if (pid == -1) { + Utils::freeCharVector(argv); + Utils::freeCharVector(envp); throw ForkFailure("Failed to fork process"); - else if (pid == 0) { - _executeChildProcess(request, pipefd, argv, envp); + } else if (pid == 0) { + try { + _executeChildProcess(request, pipefd, argv, envp); + Utils::freeCharVector(argv); + Utils::freeCharVector(envp); + } catch (...) { + Utils::freeCharVector(argv); + Utils::freeCharVector(envp); + throw; + } } else { try { - return _executeParentProcess(pipefd, pid, argv, envp); - } catch (const Exception& e) { + HTTPResponse* response = _executeParentProcess(pipefd, pid); Utils::freeCharVector(argv); Utils::freeCharVector(envp); - throw e; + return response; + } catch (...) { + Utils::freeCharVector(argv); + Utils::freeCharVector(envp); + throw; } } throw ExecutorError("CGI script fatal : out of pid branches !!"); // -Werror @@ -92,12 +105,8 @@ const std::string CGIHandler::_identifyRuntime(const HTTPRequest& request) { return ""; } -HTTPResponse* CGIHandler::_executeParentProcess(int pipefd[2], - pid_t pid, - std::vector argv, - std::vector envp) { +HTTPResponse* CGIHandler::_executeParentProcess(int pipefd[2], pid_t pid) { close(pipefd[1]); // Close the write end of the pipe - fd_set read_fds; FD_ZERO(&read_fds); FD_SET(pipefd[0], &read_fds); @@ -120,19 +129,20 @@ HTTPResponse* CGIHandler::_executeParentProcess(int pipefd[2], } close(pipefd[0]); + // Log the output received from the CGI script + _log.info("CGI script output: " + output); + int status; waitpid(pid, &status, 0); if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { throw RuntimeError("CGI script failed"); } - - // Free only after last throw, where already freed - Utils::freeCharVector(argv); - Utils::freeCharVector(envp); - // Parse output to create HTTPResponse std::size_t headerEndPos = output.find("\r\n\r\n"); + if (headerEndPos == std::string::npos) + throw ExecutorError( + "Invalid CGI response: no header-body separator found"); std::string headerPart = output.substr(0, headerEndPos); std::string bodyContent = output.substr(headerEndPos + 4); // +4 to skip the "\r\n\r\n" @@ -142,11 +152,15 @@ HTTPResponse* CGIHandler::_executeParentProcess(int pipefd[2], std::string line; while (std::getline(headerStream, line)) { std::size_t colonPos = line.find(':'); - if (colonPos != std::string::npos) { - std::string key = line.substr(0, colonPos); - std::string value = line.substr(colonPos + 2); // +2 to skip ": " - headers[key] = value; - } + if (colonPos == std::string::npos) + throw ExecutorError("Invalid CGI response: malformed header line"); + std::string key = line.substr(0, colonPos); + if (key.empty()) + throw ExecutorError("Invalid CGI response: empty header key"); + std::string value = line.substr(colonPos + 2); // +2 to skip ": " + if (value.empty()) + throw ExecutorError("Invalid CGI response: empty header value"); + headers[key] = value; } headers["Content-Length"] = Utils::to_string(bodyContent.size()); return new HTTPResponse(HTTPResponse::OK, headers, bodyContent); diff --git a/src/CGIHandler.hpp b/src/CGIHandler.hpp index 7355012..fea2996 100644 --- a/src/CGIHandler.hpp +++ b/src/CGIHandler.hpp @@ -6,7 +6,7 @@ /* By: agaley +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/04/30 16:11:09 by agaley #+# #+# */ -/* Updated: 2024/06/20 02:57:03 by agaley ### ########lyon.fr */ +/* Updated: 2024/06/25 18:08:07 by agaley ### ########lyon.fr */ /* */ /* ************************************************************************** */ @@ -149,10 +149,7 @@ class CGIHandler { * for the CGI script. * @return HTTPResponse object containing the response from the CGI script. */ - static HTTPResponse* _executeParentProcess(int pipefd[2], - pid_t pid, - std::vector argv, - std::vector envp); + static HTTPResponse* _executeParentProcess(int pipefd[2], pid_t pid); /** * Executes the child process logic for CGI script execution.