httpd

Standard builds of busybox-w32 include the httpd applet to provide a simple web server. Some notable features:

Quick start

The usage message for httpd tells us:

Usage: httpd [-fv[v]] [-c CONFFILE] [-p [IP:]PORT] [-r REALM] [-h HOME]
or httpd -d/-e STRING

Listen for incoming HTTP requests

        -f              Run in foreground
        -v[v]           Verbose
        -p [IP:]PORT    Bind to IP:PORT (default *:80)
        -r REALM        Authentication Realm for Basic Authentication
        -h HOME         Home directory (default .)
        -c FILE         Configuration file (default {/etc,HOME}/httpd.conf)
        -e STRING       HTML encode STRING
        -d STRING       URL decode STRING

If the server is run without any arguments and no configuration file it will serve the contents of the current directory on port 80, the standard port for http. Thus, from a busybox-w32 shell:

~ $ mkdir www
~ $ cd www
~/www $ printf '<html>\nHello world\n</html>\n' >index.html
~/www $ httpd
~/www $ wget -q -O - http://localhost/index.html
<html>
Hello world
</html>
~/www $ pkill httpd

Configuration

When the server first starts, the server root ('home directory' in the usage message) is set using this procedure:

  1. Set it to the current directory.
  2. If the -h command line option is given, use that instead.
  3. If an H: entry is present in the main configuration file, use its value. (Careful now! The location of the main configuration file at this step may depend on the current value of the server root.)

The server looks for its main configuration file in the following places, stopping at the first one that works:

  1. The file specified by the command line option -c. The file path can be absolute or relative to the server root. The file must exist or the server will exit with an error.
  2. /etc/httpd.conf, prefixed with the system drive.
  3. The file httpd.conf in the server root directory.

Local httpd.conf files can also be present in any served directory. These will be parsed when the server receives a request for a file in the directory. Settings in such files are merged with existing settings and only apply for the duration of the request. Local configuration files can't change the server root, though. That would be too confusing!

Configuration files can contain the following types of entry:

   H:/serverroot     # define the server root. It will override -h
   A:172.20.         # Allow address from 172.20.0.0/16
   A:10.0.0.0/25     # Allow any address from 10.0.0.0-10.0.0.127
   A:10.0.0.0/255.255.255.128  # Allow any address that previous set
   A:127.0.0.1       # Allow local loopback connections
   D:*               # Deny from other IP connections
   E404:/path/e404.html # /path/e404.html is the 404 (not found) error page
   I:index.html      # Show index.html when a directory is requested
   /cgi-bin:foo:bar  # Require user foo, pwd bar on urls starting with /cgi-bin/
   /adm:admin:setup  # Require user admin, pwd setup on urls starting with /adm/
   /adm:toor:PaSsWd  # or user toor, pwd PaSsWd on urls starting with /adm/
   .au:audio/basic   # additional mime type for audio.au files
   *.php:/path/php   # run xxx.php through an interpreter

The logic for filtering by IP address is:

Example 1: Allow only specified addresses

   A:172.20.         # Allow any address that begins with 172.20.
   A:10.10.          # Allow any address that begins with 10.10.
   A:127.0.0.1       # Allow local loopback connections
   D:*               # Deny from other IP connections

Example 2: Only deny specified addresses

   D:1.2.3.        # deny from 1.2.3.0 - 1.2.3.255
   D:2.3.4.        # deny from 2.3.4.0 - 2.3.4.255
   A:*             # (optional line added for clarity)

In all cases the parser only checks whether the first character is 'a' or 'd' without regard for case or any other characters before the colon. Thus it's possible to spell out the options in full as Allow or Deny.

The custom error page can be referenced using an absolute path or relative to the server root. It must be a static file (no CGI or script allowed). The error page can only be defined in the main configuration file.

CGI scripts

CGI scripts must reside in the cgi-bin subdirectory of the server root. Here's a simple shell script example:

   #!/bin/sh
   echo "Content-type: text/html"
   echo
   echo "Hello shell"

Anything that busybox-w32 (and Windows) knows how to run is acceptable as a CGI handler:

Script interpreter

Pages can be processed by an external script interpreter before being displayed. A configuration option like the following allows files with the .php suffix to contain PHP scripts:

   *.php:C:/php-8.3.2/php-cgi.exe

A typical PHP installation will have several executables: for this purpose you want the one called php-cgi.exe. Note that the .exe suffix must be provided.

Also note that the PHP configuration file needs to contain this setting:

   cgi.force_redirect = 0

See the PHP page on using cgi.force_redirect for details.

A third thing to note is that the server root must be specified as an absolute path, otherwise PHP won't be able to find the files to be processed. (It's also acceptable to leave the server root unset: it then defaults to the current directory which is handled as an absolute path.)

If all the above details have been heeded it should be possible to serve a .php file like this:

   <html>
   <?php echo "Hello PHP\n"; ?>
   </html>

PHP is a common way of processing web pages. However, it's possible to use a script of some sort instead. As well as the standard CGI environment variables httpd also sets SCRIPT_FILENAME to the absolute path of the file being processed.


Ron Yorston
21st February 2024