marty 0.1.1

Great Scott! Rust helpers for CGI—map RFC 3875 to hyper, glue tower services, and hit 88 mph without a flux capacitor. Evolved from mknet/cgi-rs.
docs.rs failed to build marty-0.1.1
Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
Visit the last successful build: marty-0.1.0

Marty

“Roads? Where we’re going, we don’t need roads.”
— Doc Brown, Back to the Future (and yet: sometimes all you need is one process per request—and we call that CGI.)

Marty is the new name on crates.io for Rust helpers around the Common Gateway Interface (RFC 3875). The line starts with cbgbt/cgi-rs (the original project), continues in the mknet/cgi-rs fork, and lands here—with more Huey Lewis, more 88 mph, and the firm belief that your next HTTP stack does not need a DeLorean, only solid types.

This repository: github.com/mknet/marty.

Lineage (who did what, no time paradox)

Stage Repository
Original cgi-rs github.com/cbgbt/cgi-rs
Maintained fork github.com/mknet/cgi-rs
Crates.io & this tree github.com/mknet/marty

Great Scott — what is this?

A CGI server launches (classically) a script as its own process for each incoming request. Think of it as a trip to another timeline: clean isolation, gone when the work is done, and the next request gets a fresh timeline.

For typical HTTP services, CGI’s role has long been superseded by models that keep long-lived worker processes around (“where we’re going, we keep the server running”). That buys you latency and throughput. CGI is still useful when you want very low idle footprint and are willing to trade some throughput for a simple resource story (one request, one process)—low power mode for Hill Valley instead of constant fire from the Mr. Fusion equivalent.


Crates in the ecosystem (status: evolving from cgi-rs)

The cbgbt/cgi-rs / mknet/cgi-rs workspace is split into several crates. The story continues on crates.io under Marty; the exact layout in mknet/marty follows the port.

Theme Idea
Core CGI environment → hyper::Request / hyper::Response
Tower / Axum Same crate: enable marty feature tower for serve_cgi + marty::tower (full Router / routing stacks as CGI)
Dev server Example-only TCP harness: examples/_http-cgi-server (_http-cgi-server crate)
Examples 01_basic — static CGIResponse, synchronous main (no Tower); sample-cgi-script — Axum + tower + sessions + SQLite

This repository is a Cargo workspace mirroring mknet/cgi-rs develop: the marty/ crate replaces cgi-rs and, with the tower feature, integrates the old tower-cgi behaviour inside marty::tower (no separate Tower crate in this tree). For local demos, examples/_http-cgi-server/ (cargo run -p _http-cgi-server) is a minimal HTTP+CGI test harness—not production software. The sample-cgi-script lives at examples/sample-cgi-script/ (marty with features = ["tower"]). examples/01_basic/ is the smallest demo: default marty only, synchronous main, writes a fixed body via CGIResponse::write_response_to_output (cargo run -p example-01-basic). Smoke test (build → cgi-bin/_http-cgi-serverHurl assertions in examples/01_basic/smoke.hurl): install just and hurl, then from the repo root run just smoke-01-basic (needs python3 for the Cargo target path when copying the binary). Run the larger sample with cargo run -p sample-cgi-script.

If you return from the future and suddenly need Windows: upstream still listed that as a limitation—check the current README in the repo before you bet the farm on 1955.


Tower / Axum: “I guess you guys aren’t ready for that yet”

This pattern comes straight from the cgi-rs README (cbgbt/cgi-rs original; same text in the mknet/cgi-rs fork): a Tower Service—for example an Axum Router—is run behind marty’s serve_cgi when the tower feature is enabled:

// marty = { version = "…", features = ["tower"] }
use axum::{routing::get, Router};
use marty::serve_cgi;

#[tokio::main]
async fn main() {
    let app = Router::new().route("/", get(|| async { "Hello, World!" }));
    serve_cgi(app).await.unwrap();
}

Operation: Like the Enchantment Under the Sea dance—steady tempo, one route at a time, and no panicking before the first note.


Core: CGI → Hyper (meta-variables & request)

The core crate (historically cgi_rs, on crates.io as marty) maps the CGI environment to hyper::Request / hyper::Response so you can keep building with the rest of the Hyper ecosystem—without your code unraveling like alternate 1985.

Current limitations (per upstream docs: cbgbt/cgi-rs, mknet/cgi-rs)

  • Focused on utilities for CGI scripts, not a full CGI server in the crate sense.
  • Only “Document”-style responses.
  • Only a subset of CGI environment variables are hoisted into requests.
  • No Windows (in the referenced upstream state).

Example: parse an HTTP request from the CGI environment

// Target API on crates.io; until the port lands you may still see `cgi_rs::…`.
use hyper::{Request, Body};
use marty::CGIRequest;

fn main() {
    // In a real CGI environment the server sets these variables (and more).
    std::env::set_var("REQUEST_METHOD", "GET");
    std::env::set_var("CONTENT_LENGTH", "0");
    std::env::set_var("REQUEST_URI", "/");

    let cgi_request: Request<Body> = CGIRequest::from_env()
        .and_then(Request::try_from)
        .unwrap();
}

Note: While the public API is still being ported 1:1 from cgi_rs, your checkout may temporarily still show cgi_rs::…. The goal is a single marty:: path on crates.io.

Example: meta-variables (RFC 3875)

You can always read environment variables raw—the core also offers a structured way to fetch and parse CGI meta-variables:

fn main() {
    let method = marty::MetaVariableKind::RequestMethod
        .try_from_env()
        .unwrap();
    assert_eq!(method.as_str().unwrap(), "GET");
}

If REQUEST_METHOD is missing, that is the wrong almanac in the suitcase: double-check your server configuration before you fix the timeline.


License

Apache License, Version 2.0 — see LICENSE-APACHE in this repository (same text as upstream mknet/cgi-rs / cbgbt/cgi-rs).


Acknowledgements / Easter eggs

  • Doc would yell “1.21 gigawatts!”—here you often need fewer watts, but you do need solid types.
  • Marty might forget to git revert Johnny B. Goode—you should still ship versions and a changelog.
  • If something will not compile: cargo clean, then try again—like the second attempt at the flux capacitor wiring harness.

“If you put your mind to it, you can accomplish anything.” — George McFly (and a halfway decent README.md).