2026-08-24
CGI is one of those technologies that quietly shaped the modern web and then got politely shoved into the attic. RFC 3875 is not the invention of CGI — NCSA's HTTPd team, led by Rob McCool, had already sketched it out in 1993. What RFC 3875 does is finally standardize, a full decade later, the de facto contract that thousands of scripts and web servers had already been speaking. It is a rare RFC that documents an accomplished fact rather than proposing a design.
The problem. Early HTTP servers only served static files. To make the web dynamic, someone needed to answer: how does an HTTP server invoke an arbitrary external program, hand it a request, and pipe the program's output back to the client? The answer had to work in any language — Perl, C, shell, Tcl — without linking against the server. CGI's solution is almost aggressively simple: fork a process, put the request in environment variables and stdin, read the response from stdout.
The design decisions. Section 4 defines the meta-variables — the environment variables every CGI script can rely on:
REQUEST_METHOD, QUERY_STRING, CONTENT_TYPE, CONTENT_LENGTHPATH_INFO and PATH_TRANSLATED — the trick that let URLs like /cgi-bin/wiki.pl/FrontPage pass /FrontPage as a script argument, effectively inventing pretty URLs before anyone called them thatSERVER_NAME, SERVER_PROTOCOL, REMOTE_ADDR, REMOTE_USERHTTP_* — any request header, uppercased with dashes converted to underscores. This convention outlived CGI itself; it's still how Rack, WSGI, and countless middleware pass headers around.Request bodies arrive on stdin. The script writes back a small header block (at minimum Content-Type or a Status: line or a Location: redirect), a blank line, then the body. The server splices this into a proper HTTP response. No sockets, no HTTP parsing in the script, no library dependency. You could write a working CGI program in six lines of shell.
Why it mattered. CGI is what turned the web from a document delivery system into an application platform. Every guestbook, every form-mail script, every early PHP page, every 1990s search engine ran through this interface. Perl's dominance in the late 90s is inseparable from CGI: it was the language that let a sysadmin bolt dynamic behavior onto Apache in an afternoon.
Why it died — and didn't. The fork-per-request model is brutal under load. Spinning up a Perl interpreter for every hit made CGI a punchline by 2000. The replacements — mod_perl, FastCGI, WSGI, Rack, PSGI, Servlets, PHP's SAPI, and eventually Node and Go serving HTTP directly — all inherited CGI's vocabulary even as they abandoned its process model. Open any WSGI environ dict in Python today and you'll find REQUEST_METHOD, PATH_INFO, HTTP_HOST. Nginx's fastcgi_params file is a direct translation of Section 4. AWS Lambda's API Gateway event, if you squint, is a JSON re-encoding of the same idea.
The quirky history. RFC 3875 is classified as Informational, not a Standard. By 2004 CGI was already legacy, and the IETF wasn't going to bless it as the future. Ken Coar spent years chasing down every ambiguity the original NCSA spec had left — how exactly do you percent-decode PATH_INFO? What happens with NPH (non-parsed-header) scripts? — and produced a document that is essentially archaeological. It's the RFC as historical marker: this is what we all actually did, written down at last so the next generation can understand why their web framework's request object looks the way it does.
REQUEST_METHOD, PATH_INFO, HTTP_* headers — is the ancestral DNA of every modern web framework's request object.
