#pragma once #include #include #include #include #include // Parsed CGI header block (the body is streamed separately). struct CgiResult { int status = 200; // from a "Status:" header, or 200 if absent std::vector> headers; }; // Forks and execs `argv` with exactly the environment in `env` (each entry // "KEY=value"). The child's stdin is connected to `input_fd` (or /dev/null when // input_fd < 0). Its stdout is parsed as a CGI response: once the header block // up to the first blank line is parsed, `on_headers` is called with it and must // return the stream to receive the body; the remaining bytes are then streamed // there. Splitting it this way lets the caller set HTTP status/headers before // any body is written. Throws std::runtime_error if the child cannot be spawned // or exits non-zero. void run_cgi(const std::vector &argv, const std::vector &env, int input_fd, const std::function &on_headers);