README.md @master — view markup · raw · history · blame
melvil
EARLY AND EXPERIMENTAL
Melvil is the HTTP server interface I think I'd want to use. It's very slow at present, and still quite early, but it's at least a proof-of-concept of something I think should exist.
Basic Use
The Melvil server does nothing but pass HTTP requests and responses between other servers: it is, in effect, a mechanism for establishing reverse proxies.
The server is invoked with a single optional argument, and it continues running in the foreground until it is killed with standard Unix signals. The argument is a directory, and if that directory exists, it switches to that directory before continuing. It then reads configuration from that directory and will continuously forward requests based on that configuration.
The configuration directory contains zero or more subdirectories, each of which describes a given request filter and forwarding mechanism. The subdirectory may contain several specifically named files, whose contents specify a forwarding system:
path: which request paths to match; defaults to "*"
domain: which request subdomains to match; defaults to "*"
mode: how to forward the request; defaults to "http"
host: which host to forward to; defaults to "localhost"
port: which port to forward to; defaults to "80"
conf: which path to forward to; defaults to "/dev/null"
resp: which HTTP response to issue; defaults to 303
These are interpreted as follows:
-
The
path
anddomain
fields tell us which requests to forward: both of them default to accepting anything, and both of them allow their values to have the wildcard character*
. -
The
mode
field tells us how to forward requests. There are three possible forwarding modes:- If the mode is
http
, then Melvil will forward the HTTP request to the server listening on the hosthost
and the portport
. - If the mode is
melvil
, then Melvil will recursively check the configuration directory atconf
. - If the mode is
redir
, then Melvil will respond with an HTTP response code as indicated inresp
and redirect to the host as indicated inhost
.
- If the mode is
In the future, there might be more modes, such as a fastcgi
mode
which points to a Unix socket or a static
mode which serves
static files, but this is enough to test the idea.
Example Setups
A simple-but-interesting configuration, which forwards requests
for example.com
to localhost:5001
, redirects www.example.com
to
example.com
, forwards requests for blog.example.com
to
example.tumblr.com
, and redirects everything else to localhost:5000
.
$ # create the example.com config, which forwards to a
$ # local HTTP server listening on port 5001
$ mkdir 00-base
$ echo example.com >00-base/domain
$ echo 5001 >00-base/port
$
$ # redirect www.example.com to example.com
$ mkdir 00-www
$ echo www.example.com >00-www/domain
$ echo redir >00-www/mode
$ echo example.com >00-www/host
$
$ # create the configuration for the blog subdomain
$ mkdir 00-blog
$ echo blog.example.com >00-blog/domain
$ echo example.tumblr.com >00-blog/host
$
$ # and now create the fallthrough case
$ mkdir 99-default
$ echo mode >99-default
$ echo 5000 >99-default/port
Notice that we only need to specify a few pieces of information for each case, because we can often use the defaults for various fields, so each "configuration" is usually a directory with two or maybe three files.
Because configuration is specified as a directory, rather than as a single file, we can use properties of the Unix file system as a simple ACL-like mechanism. For example, a system administrator can set up a user-owned configuration directory for each user, and then use a global configuration directory to forward requests to that user on a per-subdomain basis:
$ mkdir -p /etc/melvil
$ for U in $USERS; do
> # find the user's home directory
> HOMEDIR=`cat /etc/passwd | grep ${U} | cut -d ':' -f 6`
>
> # add a configuration directory to each user
> mkdir -p ${HOMEDIR}/melvil
> chown ${U} ${HOMEDIR}/melvil
>
> # add a new forwarding rule for each user
> mkdir -p /etc/melvil/${U}-local
>
> # make ${U}.example.com forward to the user's melvil configuration
> echo "${U}.example.com" >/melvil/user-${U}/domain
> echo "melvil" >/melvil/user-${U}/mode
> echo "${HOMEDIR}/melvil" >/melvil/user-${U}/conf
> done
$ melvil /etc/melvil
Now, if a given user wants to set up a local HTTP server that produces dynamic content, they can add the appropriate forwarding configuration to their own directory, but they cannot modify other users' configurations or the global configuration.
Even if you're running a single server, but want to have multiple services on it, this can be a convenient way to set up reverse proxy servers without needing root access.