LeftHookRoll
An HTTP/1.0 compliant web server, as specified by RFC1945
Loading...
Searching...
No Matches
CGIManager.hpp
Go to the documentation of this file.
1/**
2 * @file CGIManager.hpp
3 * @brief Declares the CGIManager class responsible for executing CGI scripts and redirecting their input/output.
4 */
5#pragma once
6
7#include <vector>
8#include <string>
9#include <map>
10#include <set>
11#include <unistd.h>
12#include <sys/types.h>
13class Request;
15{
16 public:
17 // Canonical Form
18 CGIManager();
19 CGIManager(const CGIManager& other);
20 CGIManager& operator=(const CGIManager& other);
22
23 //Getters
24 pid_t getPid() const;
25 /**
26 * @return returns read end of the outpipe to add to epoll.
27 */
28 int getOutputFd() const;
29
30 //Behavior
31 /**
32 * @brief Prepares the environment and arguments for executing a CGI script.
33 * @param request the parsed HTTP request.
34 * @param scriptPath the absolute path to the script to be executed.
35 * @param interpreterOverride if non-empty, use this interpreter instead of auto-detecting from extension.
36 */
37 void prepare(const Request& request, const std::string& scriptPath, const std::string& interpreterOverride = "");
38
39 /**
40 * @brief Forks, redirs input file and outpipe, and executes the CGI script.
41 * @param inputFd the fd of the temp file(data store) containing the fully received request body.
42 * @warning this implementation requires that the request body is fully received before executing the CGI script,
43 * we handle large request bodies by writing them to a temp file and passing the fd to the CGI script,
44 * but this also means that we can't start executing the CGI script until we've fully received the request body,
45 * which is a tradeoff we made for simplicity.
46 */
47 void execute(int inputFd);
48
49 /**
50 * @brief Checks if the child process has finished executing (Non-blocking); waitpid with WNOHANG.
51 * @return true if the process exited, false if it is still running.
52 */
53 bool isDone();
54
55 /**
56 * @brief Cleans up all active CGI processes on server shutdown.
57 * Sends SIGTERM to all processes, waits for them to finish, then sends SIGKILL
58 * to any that remain. Prevents zombie processes.
59 */
60 static void cleanupAllProcesses();
61
62 private:
63 //Identity
64 pid_t _pId;
65 //Data
66 int _outPipe[2];
67 std::string _query;
68 std::vector<std::string> _scriptArgv;
69 std::map<std::string, std::string> _env;
70 //Execve Arrays(RAII ts):
73 //Private Helpers
74 void _buildEnvMap(const Request& request, const std::string& scriptPath);
75 void _prepExecveArrays();
76 void _freeExecveArrays();
77 void _closePipes();
78 static void _reapFinishedActivePids();
79 static bool _isSpawnLimitReached();
80
81 static std::set<pid_t> _activePids;
82 static void _registerPid(pid_t pid);
83 static void _unregisterPid(pid_t pid);
84};
int _outPipe[2]
void _freeExecveArrays()
char ** _execveArgv
static void cleanupAllProcesses()
Cleans up all active CGI processes on server shutdown. Sends SIGTERM to all processes,...
static void _registerPid(pid_t pid)
static std::set< pid_t > _activePids
CGIManager & operator=(const CGIManager &other)
pid_t getPid() const
std::map< std::string, std::string > _env
void _buildEnvMap(const Request &request, const std::string &scriptPath)
void prepare(const Request &request, const std::string &scriptPath, const std::string &interpreterOverride="")
Prepares the environment and arguments for executing a CGI script.
std::vector< std::string > _scriptArgv
void execute(int inputFd)
Forks, redirs input file and outpipe, and executes the CGI script.
bool isDone()
Checks if the child process has finished executing (Non-blocking); waitpid with WNOHANG.
void _closePipes()
int getOutputFd() const
static bool _isSpawnLimitReached()
static void _unregisterPid(pid_t pid)
static void _reapFinishedActivePids()
std::string _query
void _prepExecveArrays()
char ** _execveEnvp