History

I wrote this after seeing a small HTTP server that took ~650 lines of C. I thought it would be an interesting challenge to try for a ten-to-one reduction. Not only did I exceed that, but the ~650 line server did not do POST type CGI's, which mine will.

This server (which I name 'ws') has been quite useful. I use it for CGI testing, it's much simpler launching 'ws' with all parameters given on the command line than modifying an Apache conf file and firing the new Apache server up.

Arguments

'ws' takes four arguments on the command line,

ws port_number doc_tree_base cgi_tree_base cgi_location

but they all have defaults. I usually fire it up with

ws 8080 . .

and then fetch plain docs from machine:8080/somedoc.html and CGI's from machine:8080/cgi-bin/somecgi.pl

Both files are in the current directory, whether a file is treated as a plain file or a CGI depends on how it's fetched in the browser.

Note that 8080 is used because you have to be root to bind to port 80, and since 'ws' does not do the 'change uid' that Apache will do, it's better to not run as root.


Note: Closing down the socket when using POST type CGI's

'ws' does not run a CGI as a subprocess, it 'exec's directly to it. While this is fine for GET type CGI's, some browsers have a problem with shutting down the socket when a POST type CGI is used. (Network Error: Connection reset by peer)

A perl solution for this follows (assumes output is in $out):

$| = 1;  # set autoflush on
print "Content-size: @{[length $out]}\nContent-type: text/html\n\n$out";
if(-S STDIN) # 'ws' passes socket, needs it to be shutdown, apache doesn't
  {
  shutdown(STDOUT, 1) or die "$! on shutdown";
  <STDIN>;  # waiting for EOF on socket to keep some browsers happy
  }
exit;
This code will allow a CGI to be run under both 'ws' and Apache. Similar things should work in other languages...