Crate outer_cgi

source ·
Expand description

This crate is a thin CGI/FCGI wrapper. It turns your program into an adaptive CGI script; capable of being invoked as CGI or FCGI in a variety of configurations.

This is not a full web framework. It performs minimal validation, and no parsing beyond the bare minimum required to pass one or more CGI-style requests to your handler. Examples of things that outer_cgi does not do:

  • Validate environment variables, beyond checking that GATEWAY_INTERFACE begins with "CGI/", when invoked as a CGI.
  • Parse query strings or cookies.
  • Provide a template engine.
  • Provide any database interfaces.

Here is what it does do:

  • Seamlessly supports operation as either CGI or FCGI.
  • FCGI may either be spawned in the “standard” way (where stdin is a listen socket) or by explicitly binding to either a TCP port or UNIX socket.
  • The UNIX version supports the following additional features:
    • setuid, setgid, and chroot for privilege reduction.
    • Logging to syslog, either out of necessity (from being spawned as FCGI by another process) or by user request.
    • Daemonization.

You write your code as a simple CGI script, using outer_cgi’s replacements for stdin, stdout, and env. outer_cgi then allows the webmaster to deploy your script in whatever configuration is most suitable.

extern crate outer_cgi;
use std::collections::HashMap;
use outer_cgi::IO;

fn handler(io: &mut IO, env: HashMap<String, String>) -> anyhow::Result<i32> {
    io.write_all(format!(r#"Content-type: text/plain; charset=utf-8

Hello World! Your request method was "{}"!
"#, env.get("REQUEST_METHOD").unwrap()).as_bytes())?;
    Ok(0)
}

pub fn main() {
    outer_cgi::main(|_|{}, handler)
}

See the Common Gateway Interface specification for more information.

According to the RFC, the current working directory SHOULD be the directory containing the script. It’s up to the webmaster to ensure this is the case when running as an FCGI.

Traits

  • Wraps the stdin and stdout streams of a standard CGI invocation.

Functions

  • The first (and preferably only) function your program’s main function should call. Handles argument parsing, worker thread spawning, etc. For each request, calls the handler you provide.