"""Simple HTTP Server.

This module builds on BaseHTTPServer by implementing the standard GET
and HEAD requests in a fairly straightforward manner.

"""


__version__ = "0.3"


import os
import pwd
import sys
import time
import socket
import string
import posixpath
import SocketServer
import BaseHTTPServer


def nobody_uid():
    """Internal routine to get nobody's uid"""
    try:
	nobody = pwd.getpwnam('nobody')[2]
    except pwd.error:
	nobody = 1 + max(map(lambda x: x[2], pwd.getpwall()))
    return nobody

nobody = nobody_uid()


class SimpleHTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):

    """Simple HTTP request handler with GET and HEAD commands.

    This serves files from the current directory and any of its
    subdirectories.  It assumes that all files are plain text files
    unless they have the extension ".html" in which case it assumes
    they are HTML files.

    The GET and HEAD requests are identical except that the HEAD
    request omits the actual contents of the file.

    """

    server_version = "SimpleHTTP/" + __version__

    def do_GET(self):
	"""Serve a GET request."""
	f = self.send_head()
	if f:
	    self.copyfile(f, self.wfile)
	    f.close()

    def do_HEAD(self):
	"""Serve a HEAD request."""
	f = self.send_head()
	if f:
	    f.close()

    def send_head(self):
	"""Common code for GET and HEAD commands.

	This sends the response code and MIME headers.

	Return value is either a file object (which has to be copied
	to the outputfile by the caller unless the command was HEAD,
	and must be closed by the caller under all circumstances), or
	None, in which case the caller has nothing further to do.

	"""
	path = self.translate_path(self.path)
	if os.path.isdir(path):
	    self.send_error(403, "Directory listing not supported")
	    return None
	try:
	    f = open(path)
	except IOError:
	    self.send_error(404, "File not found")
	    return None
	self.send_response(200)
	self.send_header("Content-type", self.guess_type(path))
	self.end_headers()
	return f

    def translate_path(self, path):
	"""Translate a /-separated PATH to the local filename syntax.

	Components that mean special things to the local file system
	(e.g. drive or directory names) are ignored.  (XXX They should
	probably be diagnosed.)

	"""
	path = posixpath.normpath(path)
	words = string.splitfields(path, '/')
	words = filter(None, words)
	path = os.getcwd()
	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

    def copyfile(self, source, outputfile):
	"""Copy all data between two file objects.

	The SOURCE argument is a file object open for reading
	(or anything with a read() method) and the DESTINATION
	argument is a file object open for writing (or
	anything with a write() method).

	The only reason for overriding this would be to change
	the block size or perhaps to replace newlines by CRLF
	-- note however that this the default server uses this
	to copy binary data as well.

	"""

	BLOCKSIZE = 8192
	while 1:
	    data = source.read(BLOCKSIZE)
	    if not data: break
	    outputfile.write(data)

    def guess_type(self, path):
	"""Guess the type of a file.

	Argument is a PATH (a filename).

	Return value is a string of the form type/subtype,
	usable for a MIME Content-type header.

	The default implementation looks the file's extension
	up in the table self.extensions_map, using text/plain
	as a default; however it would be permissible (if
	slow) to look inside the data to make a better guess.

	"""

	base, ext = posixpath.splitext(path)
	if self.extensions_map.has_key(ext):
	    return self.extensions_map[ext]
	ext = string.lower(ext)
	if self.extensions_map.has_key(ext):
	    return self.extensions_map[ext]
	else:
	    return self.extensions_map['']

    extensions_map = {
	    '': 'text/plain',	# Default, *must* be present
	    '.html': 'text/html',
	    '.htm': 'text/html',
	    '.gif': 'image/gif',
	    '.jpg': 'image/jpeg',
	    '.jpeg': 'image/jpeg',
	    }


def test(HandlerClass = SimpleHTTPRequestHandler,
	 ServerClass = SocketServer.TCPServer):
    BaseHTTPServer.test(HandlerClass, ServerClass)


if __name__ == '__main__':
    test()
