"""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 sys
import time
import socket
import string
import posixpath
import SocketServer
import BaseHTTPServer


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()
