I often use python’s SimpleHTTPServer as an adhoc means for sharing files. As it turns out it’s also a useful tool for dynamically viewing the contents of static site generators like Jekyll (which is what this site is built upon).

The command below is a quick way for one to spawn a webserver that will serve the contents of the current directory.

python -m SimpleHTTPServer

And since python comes pre-installed on most linux distros and on MacOSX, this is a no-nonsense way for serving files.

No dependencies, no installation steps, it just works.

Given this, there are times however, when I wish it had just one extra piece of functionality: the ability to route different url prefixes to different directories.

The script below patches a single function in SimpleHTTPServer’s request handler and makes this possible without adding in any extra dependencies.

server.py

import os
import posixpath
import urllib
import BaseHTTPServer
from SimpleHTTPServer import SimpleHTTPRequestHandler

# modify this to add additional routes
ROUTES = (
    # [url_prefix ,  directory_path]
    ['/media', '/var/www/media'],
    ['',       '/var/www/site']  # empty string for the 'default' match
) 

class RequestHandler(SimpleHTTPRequestHandler):
    
    def translate_path(self, path):
        """translate path given routes"""

        # set default root to cwd
        root = os.getcwd()
        
        # look up routes and set root directory accordingly
        for pattern, rootdir in ROUTES:
            if path.startswith(pattern):
                # found match!
                path = path[len(pattern):]  # consume path up to pattern len
                root = rootdir
                break
        
        # normalize path and prepend root directory
        path = path.split('?',1)[0]
        path = path.split('#',1)[0]
        path = posixpath.normpath(urllib.unquote(path))
        words = path.split('/')
        words = filter(None, words)
        
        path = root
        for word in words:
            drive, word = os.path.splitdrive(word)
            head, word = os.path.split(word)
            if word in (os.curdir, os.pardir):
                continue
            path = os.path.join(path, word)

        return path

if __name__ == '__main__':
    BaseHTTPServer.test(RequestHandler, BaseHTTPServer.HTTPServer)

While not as convenient as the former solution, you can run this script by simply invoking python server.py