Comanche 20070711

An extremely simple HTTP (web) server written entirely in Python
Comanche is an extremely simple HTTP (web) server written entirely in the Python language. It does not use any of the many Python standard library modules related to HTTP serving, as it was initially written as a learning exercise. At present it does not support CGI or SSL and uses a simple fork-on-demand architecture, but is being actively improved. Read the detailed description for more information.

Comanche is named after an American Indian tribe, like some other web servers you may have heard of (Apache, Cherokee). I don't really know anything about American Indians, but I know a surprising amount about military helicopters, which are sometimes named after tribes as well: I got the name Comanche from Boeing-Sikorsky's RAH-66 Comanche "stealth" armed reconnaissance chopper.

Detailed description

Comanche is a simple, forking web server written in Python. It was written primarily to teach me how to do socket programming in Python, not to be an industrial strength server you might use in the real world. However, I loved writing it and will continue to hack on it in the hopes that one day it will be an industrial strength server you might use in the real world. I want to keep Comanche small, simple and easy to configure (in alignment with my general feelings on software): Comanche is inspired by servers like Acme Lab's thttpd and mini_httpd, and the bozotic HTTP server.

At the moment, Comanche is really only good for two things:

* You could read the code to learn about Python socket programming, the HTTP protocol and forking server architectures.
* You could use it to serve websites and files to an internal network where you know everyone can be trusted not to exploit security flaws and you won't lose a lot of face if your sites go down.

I would recommend against using Comanche in its current state to serve content to the outside world. Its origins as a learning exercise are still very visible. Things like security, stability and performance were not priorities. There are probably situations under which it will break, and there may be exploitable security holes with very nasty consequences. Still, it is by no means a complete shambles and you should certainly try it for internal serving.

Just so you don't download it and get disappointed, here is a list of things that Comanche does currently do:

* Basic HEAD and GET method handling,
* "If-(Un)Modified-Since" condition handling,
* Standard format logging,
* Directory indexing,
* Name based virtual hosting,

and here is a list of things that Comanche does not currently do:

* POST, PUT, DELETE or TRACE method handling,
* Some conditional or partial GET or HEAD handling,
* Any kind of authentication,
* CGI, Fast or otherwise,
* SSL.

I'd like to think it will do all of the above one day.

Complete Instructions

Installation

At the moment Comanche does not have any sort of easy, user friendly installation scripts or anything. This is because I'm lazy and unfamiliar with writing that sort of thing, not because I'm malicious toward noobs or anything. Installation will be quick and painless one day. For now it isn't quick and painless, but it is not exactly long and painful either.

The tarball you get when you download the latest version of Comanche contains three files of Python code (comanche, server.py and handler.py) and one example configuration file (comanche.conf). It's up to you to manually copy these files to wherever you want them, based on the following description of what each one does.

* comanche is a startup script. This is what you run to start Comanche up. It can go pretty much wherever you like, although somewhere in your PATH would be handy, and somewhere like /usr/local/sbin/ would be good Unix style.
* server.py contains code that handles the accepting of incoming connections and the creation of new processes and objects to service them. Note that the comanche file imports a class from this file using the Python line from server import ComancheServer, so you need to put this file somewhere to ensure that works. This means you either put it in the same place as the comanche file (possibly bad style), or you put it somewhere that Python automatically looks for modules.
* handler.py contains code that handles the actual processing of HTTP requests. Note that the serer.py file imports a class from this file using the Python line from handler import Handler, so you need to put this file somewhere to ensure that works. This means you either put it in the same place as the server.py file, or you put it somewhere that Python automatically looks for modules.
* comanche.conf is a configuration file. It can go pretty much wherever you like as it is easy to point Comanche at arbitrarily located config files, though /etc/ or /usr/local/etc/ would be obvious places.

As you can see, you could very well just leave everything in the directory you untarred them to and run it from there (e.g., put everything in /usr/local/comanche/), and in fact this is what I would recommend doing for the time being, because it is easy and Comanche is not yet the kind of software you take seriously enough to scatter throughout your filesystem. Obviously there are much neater ways of doing it (putting server.py and handler.py somewhere under your Python's site-packages directory, etc.) and maybe one day there will be a nice install script to do this for you.

Configuration

Comanche is supposed to be easy to configure. To this end, you technically don't have to configure it - everything has a default setting and if you just run the comanche file in the tarball you downloaded, it will at try to use these defaults. If these defaults match your needs (they probably don't, but may), you are good to go. If not, you have two ways to override the defaults:

 * You can use command line options when you run comanche, or,
 * You can use a configuration file

You can also use a combination of these two methods, i.e. you can set some options on the command line and some from a file. The ``chain of command'' is that command line options will override any options specified in a configuration file, and any options in the configuration file which are not overridden by a command line option will override the defaults. Note that not every option can be set from the command line, as some are somewhat impractical.

The configuration file format used by Comanche is that understood by the Python standard library's ConfigParser module. Each file is divided into sections, each section is made up of option-value pairs. Section names appear between square brackets, options are set (one per line) with option=value lines. Blank lines and lines beginning with # are ignored. The files look something like this:

[Section 1]
option1=value1
option2=value2
option3=value3
[Section 2]
option1=value1
option2=value2


You can view Comanche's default configuration file to get a clearer idea.

Here is a list of all the options Comanche currently supports and how you can set them using command line options or a configuration file.

* Listening address
* Listening port
* Timeout duration
* Document base directory
* Index files
* Log file
* Chroot directory
* Low privilege user
* MIME types

Listening address

Comanche can listen on any network address you like. By default, Comanche listens on the address 127.0.0.1, the local ``loopback'' address. This is because I think using Comanche to serve the outside world is currently a bad idea, and so it should require a concerted effort to do it. Note that a single Comanche process can currently only listen on one address at a time. Until this changes, you can just start one process per address.

You can specify a listening address on the command line with a -a listeningaddress switch, where listeningaddress is either an IPV4 address in dotted quad form or a hostname which resolves to the address of a network interface on the local machine.

You can specify a listening address in a configuration file with a address=listeningaddress line in the "Main server configuration" section of the file, where listeningaddress is either an IPV4 address in dotted quad form or a hostname which resolves to the address of a network interface on the local machine.

Listening port

Comanche can listen on any port number you like, though you should remember that you'll need to start Comanche as root in order to bind a socket to any address less than or equal to 1024. Port 80 is the standard for HTTP servers, and this is the Comanche default. Web browsers automatically attempt to connect to addresses on port 80 and if you use any other port, users will have to type that number into their browser to get to your sites. If you aren't able to serve on port 80 for whatever reason (e.g., because you can't get root privileges or because your ISP blocks incoming connections to port 80), port 8080 is the de facto standard ``backup'' port for web serving. Note that a single Comanche process can currently only listen on one port at a time. Until this changes, you can just start one process per port.

You can specify a port number on the command line with a -p portnumber switch.

You can specify a port number in a configuration file with a port=portnumber line in the "Main server configuration" section of the file.

Timeout duration

In version 1.1 of the HTTP protocol, the standard thing to do is to leave a connection between a browser and a web server open after serving the initial request, in case the browser wants to make another request shortly after (e.g. to request an image in a page after requesting the page itself). The connection is only actually closed down when no requests have been received after a certain period (or if the browser closes the connection from its end). This improves performance over version 1.0 of HTTP, where each individual request required setting up and then tearing down a separate connection. By default, Comanche will close a connection after 3 seconds of not receiving any requests. Maybe you want to wait more or less time.

You can specify a timeout duration in a configuration file with a timeout=duration (duration is an integer number of seconds) line in the "Main server configuration" section of the file.

Document base directory

Comanche needs to know where to find the files that clients ask it for. The term document base is given to the directory which contains all the fils and directories which a server is able to serve. URIs are structured like filepaths, and Comanche will interpret these paths relative to the document base. IMPORTANT NOTE: If you set Comanche up to chroot to some directory then, obviously, the document base directory needs to be inside the chroot directory and, less obviously, you should set your document base directory as described below RELATIVE to your chroot directory. E.g., if you are chrooting Comanche into /var/www/ and your document base is /var/www/htdocs, then you should tell Comanche to chroot to /var/www and to use htdocs as its document base.

You can specify a document base directory on the command line with a -b /path/to/docbase switch.

You can specify a document base directory in a configuration file with a docbase=/path/to/docbase line in the "Main server configuration" section of the file.

Name based virtual hosting

Comanche is capable of doing simple name based virtual hosting. This allows you to host many different websites with different addresses using the same server. By default, virtual hosting is turned off, but if you turn it on then when Comanche receives a request, it will examine the ``Host'' header sent with the request, which tells it the address of the host the browser is trying to connect to, e.g., www.example.com. Comanche will then look for a directory called www.example.com in its document root, and will look for any requested files relative to that directory. In other words, to use name based virtual hosting, Comanche's document root should be populated with directories whose names are hostnames, and each of these directories is the document root for a website hosted at that name.

You can turn name based virtual hosting on on the command line with a -v switch.

You can turn name based virtual hosting on in a configuration file with a virthost=yes line in the "Main server configuration" section of the file.

Index files

By default, if Comanche receives a request for a directory, it will look in that directory for a file called index.html or index.htm, in that order, and serve the first the first one it finds. You might like it to check for other filenames too, or to check in a different order, or whatever. Note that if Comanche can't find any of the files in this list, it will send a HTML index of the directory's content.

You can specify a comma separated list of index file names in a configuration file with a indexfiles=filename1,filename2,filename3 line (of course, you can use more or less than three names as you wish) in the "Main server configuration" section of the file.

Log file

Comanche will log every request to an external file, in a common format (the same format Apache uses by default, so most log analysis programs will work with Comanche logs). It needs to know which file to use for logging. By default, it uses /var/www/comanche_log. IMPORTANT NOTE: Comanche opens its log file before it chroots, so, unlike the document base directory setting, you should set your logfile to the absolute path of the file you want, not the path relative to the chroot point.

You can specify a log file on the command line with a -l /path/to/logfile switch.

You can specify a log file in a configuration file with a logfile=/path/to/logfile switch.

Chroot directory

Comanche can use the chroot system call on POSIX systems to redefine the root of the filesystem for Comanche processes. This is a handy security measure. If an attacker is able to somehow get Comanche to execute rm -rf / on your machine, then the damage will be substantially less if Comanche is only able to access a small subset of your filesystem rather than everything. You should use this feature. If you don't want to use this feature, just ask Comanche to chroot to /, which is the same as not chrooting at all.

Low privilege user

Comanche can use the setuid system call on POSIX systems to change the user it runs as after it has finished binding sockets to addresses and ports. This is a handy security measure: you can initially run Comanche as root, so that you have the authority to bind to port 80, but then change to a different user with lower privileges, so that security compromises are not as secure. If an attacker is able to somehow get Comanche to execute rm -rf / on your machine, the damage will be substantially less if Comanche is running as a user who does not have permission to delete anything useful than if it running as root. You should use this feature.

Daemon mode

By default, Comanche runs as a ``daemon''. This means that if you start it from a shell, the program will be started ``in the background'' and you'll immediately get your shell prompt back. Comanche will not print any output (unless there is a problem starting up) and will continue run in the background until you shut it down, even if you exit the shell. If you want to, you can tell it not to run in daemon mode: you'll be left with a silent, non-responsive shell until you press Ctrl+C. This is handy for testing configurations.

You can tell Comanche not to run in daemon mode on the command line with a -d switch.

You can tell Comanche not to run in daemon mode in a configuration file with a daemon=no line in the "Main server configuration" section of the file.

Server name

Whenever a HTTP server responds to a browser's request, part of the information it sends back is a short string identifying the name of the server, perhaps the version number and even some of the expansion modules installed in the server. By default, Comanche tells the world its name and version number. This information is almost universally ignored, because almost nobody cares. However, one time it does get used is when malicious people or programs scan web servers looking for those running software which has known security holes in it. So maybe you want to tell the world you are running the server "abc123", so no automatic scanner will ever target you. To be honest, this option is actually pretty useless, but it doesn't hurt anybody.

You can specify a server name in a configuration file with a server=servername line in the ``Main server configuration'' section of the file.

MIME types

When a HTTP server sends a file to a browser, it also sends an indication of what kind of file it is sending, so that the browser knows whether to try to display it as a website, open it in an audio or video player, or ask the user where they would like to save it. It does this by telling the browser the ``MIME type'' of the file. MIME types have the general form category/detail, e.g., some common MIME types for image files are image/gif and image/jpeg. Of course, the server doesn't actually know what kind of file a file is, so it just guesses based on the file's extension. The server needs some idea of which file extensions correspond to the various MIME types.

Mappings from file extensions to MIME types can only be done in a configuration file, not from the command line. The "MIME types" section of a configuration file is devoted to this task. Each option-value pair in that section should be of the form extension=mimetype. As an example, the following mappings are present by default:

[MIME types]
html=text/html
css=text/css
gif=image/gif
jpg=image/jpeg
png=image/png
mp3=audio/mpeg
mpg=video/mpeg
txt=text/plain

You can add as many MIME types as you wish.

Starting it up

Starting Comanche up is simply a matter of running the comanche file which came in the downloaded tarball, with appropriate command line options if desired. This file is a script which takes care of details like opening log files, chrooting and changing user, daemonising the process, etc. You can set your machine up to run this script on boot in the usual ways (e.g., /etc/rc.local on BSD systems) if you want Comanche to be started automatically. At the moment, you have to run Comanche as root no matter what options you set - yes, this can be reasonably considered a bug and yes, it will be fixed soon.

Shutting it down

If you send a SIGTERM signal (using the kill command) to the main Comanche process (the first one started, which forks all others), it will catch it and try to shut things down smoothly. Requests which are currently being handled should still be completed (i.e. this is a ``graceful shutdown'', in Apache lingo). Comanche does not currently write the pid of the main thread to a file anywhere, so finding the pid to send the SIGTERM means looking at ps output. I will probably change this next release, as it's a bit of a pain.

If you are running Comanche in non-daemon mode, the SIGINT generated by a Ctrl+C will be caught and handled in the same way as SIGTERMs are handled above.

There is currently no way to ``restart'' Comanche. A SIGHUP just causes a graceful shutdown like a SIGTERM or SIGINT. A form of restart, in which config files are re-read, may turn up soonish.

last updated on:
June 11th, 2009, 13:50 GMT
price:
FREE!
developed by:
Luke Maurits
license type:
BSD License 
category:
ROOT \ Internet \ HTTP (WWW)

FREE!

In a hurry? Add it to your Download Basket!

user rating

UNRATED
0.0/5
 

0/5

What's New in This Release:
  • Any requests involving URIs with "double dots" (..) in them generate a 404 error. This solves a serious security issue in previous releases where files that were below the chroot directory but above the document base could still be downloaded. If a Comanche server was not chrooted, every file on the system was exposed! File access should now be truly limited to the document base.
  • Any requests involving URIs which resolve to a directory but do not end in a slash trigger a redirect to the URI ending with a /. This makes directory indexing a little less fragile, and seems to be a standard practice (e.g., Apache and the AcmeLabs servers do it).
  • "If-Modified-Since" and "If-Unmodified-Since" values in request headers are now handled.
  • The StringIO module was replace with the cStringIO module, as this may provide a (probably slight) performance increase.
read full changelog

Add your review!

SUBMIT