src/cgi.h
browsing at commit = 55fa1ac0b398c748c7e2421b855a1606790cafc9
#pragma once
#include <functional>
#include <ostream>
#include <string>
#include <utility>
#include <vector>
// Parsed CGI header block (the body is streamed separately).
struct CgiResult {
int status = 200; // from a "Status:" header, or 200 if absent
std::vector<std::pair<std::string, std::string>> 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<std::string> &argv,
const std::vector<std::string> &env, int input_fd,
const std::function<std::ostream &(const CgiResult &)> &on_headers);