Fennel wiki: CGI

Some people regard CGI as outmoded or obsolete, but it can be a great way to add a little bit of dynamicity to an otherwise static web site.

CGI launches a new process for every HTTP request that hits a given script. The HTTP headers are exposed as environment variables (available using os.getenv) and the HTTP request body is provided to the process over stdin. The response (HTTP headers and body) is written to stdout. That's all there is to it; no complex configuration or daemons required.

The fennel-lang.org codebase uses a makefile to generate static HTML at build time and then uses CGI scripts to save off data like survey responses or conference signups. This data is then pulled back to a development laptop using rsync and then the summary HTML is regenerated and uploaded back to the site with another rsync.

This is much less dynamic than most web applications, but it's very simple and nearly foolproof. If you don't need anything fancier, maybe it will work for you too.

(let [contents (io.read "*all")
      ;; we could use os.time but it only has second-level resolution which
      ;; means there is a very slight chance of conflict for two requests.
      date (io.popen "date --rfc-3339=ns")
      id (: (date:read "*a") :sub 1 -2)]
  (with-open [raw (io.open (.. "responses/" id ".raw") :w)]
    (raw:write contents))
  (print "status: 301 redirect")
  (print "Location: /survey/thanks.html\n"))

Note that not all HTTP servers support CGI; in particular nginx lacks this feature.

For a more detailed look at how static HTML and CGI can work together, see this blog post about the Fennel survey