#! /usr/local/bin/python

"""Support module for CGI (Common Gateway Interface) scripts.

This module defines a number of utilities for use by CGI scripts
written in Python.


Introduction
------------

A CGI script is invoked by an HTTP server, usually to process user
input submitted through an HTML <FORM> or <ISINPUT> element.

Most often, CGI scripts live in the server's special cgi-bin
directory.  The HTTP server places all sorts of information about the
request (such as the client's hostname, the requested URL, the query
string, and lots of other goodies) in the script's shell environment,
executes the script, and sends the script's output back to the client.

The script's input is connected to the client too, and sometimes the
form data is read this way; at other times the form data is passed via
the "query string" part of the URL.  This module (cgi.py) is intended
to take care of the different cases and provide a simpler interface to
the Python script.  It also provides a number of utilities that help
in debugging scripts, and the latest addition is support for file
uploads from a form (if your browser supports it -- Grail 0.3 and
Netscape 2.0 do).

The output of a CGI script should consist of two sections, separated
by a blank line.  The first section contains a number of headers,
telling the client what kind of data is following.  Python code to
generate a minimal header section looks like this:

	print "Content-type: text/html"	# HTML is following
	print				# blank line, end of headers

The second section is usually HTML, which allows the client software
to display nicely formatted text with header, in-line images, etc.
Here's Python code that prints a simple piece of HTML:

	print "<TITLE>CGI script output</TITLE>"
	print "<H1>This is my first CGI script</H1>"
	print "Hello, world!"

(It may not be fully legal HTML according to the letter of the
standard, but any browser will understand it.)


Using the cgi module
--------------------

Begin by writing "import cgi".  Don't use "from cgi import *" -- the
module defines all sorts of names for its own use or for backward 
compatibility that you don't want in your namespace.

It's best to use the FieldStorage class.  The other classes define in this 
module are provided mostly for backward compatibility.  Instantiate it 
exactly once, without arguments.  This reads the form contents from 
standard input or the environment (depending on the value of various 
environment variables set according to the CGI standard).  Since it may 
consume standard input, it should be instantiated only once.

The FieldStorage instance can be accessed as if it were a Python 
dictionary.  For instance, the following code (which assumes that the 
Content-type header and blank line have already been printed) checks that 
the fields "name" and "addr" are both set to a non-empty string:

	form = cgi.FieldStorage()
	form_ok = 0
	if form.has_key("name") and form.has_key("addr"):
		if form["name"].value != "" and form["addr"].value != "":
			form_ok = 1
	if not form_ok:
		print "<H1>Error</H1>"
		print "Please fill in the name and addr fields."
		return
	...further form processing here...

Here the fields, accessed through form[key], are themselves instances
of FieldStorage (or MiniFieldStorage, depending on the form encoding).

If the submitted form data contains more than one field with the same
name, the object retrieved by form[key] is not a (Mini)FieldStorage
instance but a list of such instances.  If you expect this possibility
(i.e., when your HTML form comtains multiple fields with the same
name), use the type() function to determine whether you have a single
instance or a list of instances.  For example, here's code that
concatenates any number of username fields, separated by commas:

	username = form["username"]
	if type(username) is type([]):
		# Multiple username fields specified
		usernames = ""
		for item in username:
			if usernames:
				# Next item -- insert comma
				usernames = usernames + "," + item.value
			else:
				# First item -- don't insert comma
				usernames = item.value
	else:
		# Single username field specified
		usernames = username.value

If a field represents an uploaded file, the value attribute reads the 
entire file in memory as a string.  This may not be what you want.  You can 
test for an uploaded file by testing either the filename attribute or the 
file attribute.  You can then read the data at leasure from the file 
attribute:

	fileitem = form["userfile"]
	if fileitem.file:
		# It's an uploaded file; count lines
		linecount = 0
		while 1:
			line = fileitem.file.readline()
			if not line: break
			linecount = linecount + 1

The file upload draft standard entertains the possibility of uploading
multiple files from one field (using a recursive multipart/*
encoding).  When this occurs, the item will be a dictionary-like
FieldStorage item.  This can be determined by testing its type
attribute, which should have the value "multipart/form-data" (or
perhaps another string beginning with "multipart/").  It this case, it
can be iterated over recursively just like the top-level form object.

When a form is submitted in the "old" format (as the query string or as a 
single data part of type application/x-www-form-urlencoded), the items 
will actually be instances of the class MiniFieldStorage.  In this case,
the list, file and filename attributes are always None.


Old classes
-----------

These classes, present in earlier versions of the cgi module, are still 
supported for backward compatibility.  New applications should use the
FieldStorage class.

SvFormContentDict: single value form content as dictionary; assumes each 
field name occurs in the form only once.

FormContentDict: multiple value form content as dictionary (the form
items are lists of values).  Useful if your form contains multiple
fields with the same name.

Other classes (FormContent, InterpFormContentDict) are present for
backwards compatibility with really old applications only.  If you still 
use these and would be inconvenienced when they disappeared from a next 
version of this module, drop me a note.


Functions
---------

These are useful if you want more control, or if you want to employ
some of the algorithms implemented in this module in other
circumstances.

parse(fp, [environ, [keep_blank_values, [strict_parsing]]]): parse a
form into a Python dictionary.

parse_qs(qs, [keep_blank_values, [strict_parsing]]): parse a query
string (data of type application/x-www-form-urlencoded).

parse_multipart(fp, pdict): parse input of type multipart/form-data (for 
file uploads).

parse_header(string): parse a header like Content-type into a main
value and a dictionary of parameters.

test(): complete test program.

print_environ(): format the shell environment in HTML.

print_form(form): format a form in HTML.

print_environ_usage(): print a list of useful environment variables in
HTML.

escape(): convert the characters "&", "<" and ">" to HTML-safe
sequences.  Use this if you need to display text that might contain
such characters in HTML.  To translate URLs for inclusion in the HREF
attribute of an <A> tag, use urllib.quote().

log(fmt, ...): write a line to a log file; see docs for initlog().


Caring about security
---------------------

There's one important rule: if you invoke an external program (e.g.
via the os.system() or os.popen() functions), make very sure you don't
pass arbitrary strings received from the client to the shell.  This is
a well-known security hole whereby clever hackers anywhere on the web
can exploit a gullible CGI script to invoke arbitrary shell commands.
Even parts of the URL or field names cannot be trusted, since the
request doesn't have to come from your form!

To be on the safe side, if you must pass a string gotten from a form
to a shell command, you should make sure the string contains only
alphanumeric characters, dashes, underscores, and periods.


Installing your CGI script on a Unix system
-------------------------------------------

Read the documentation for your HTTP server and check with your local
system administrator to find the directory where CGI scripts should be
installed; usually this is in a directory cgi-bin in the server tree.

Make sure that your script is readable and executable by "others"; the
Unix file mode should be 755 (use "chmod 755 filename").  Make sure
that the first line of the script contains "#!" starting in column 1
followed by the pathname of the Python interpreter, for instance:

	#! /usr/local/bin/python

Make sure the Python interpreter exists and is executable by "others".

(Note that it's probably not a good idea to use #! /usr/bin/env python
here, since the Python interpreter may not be on the default path
given to CGI scripts!!!)

Make sure that any files your script needs to read or write are
readable or writable, respectively, by "others" -- their mode should
be 644 for readable and 666 for writable.  This is because, for
security reasons, the HTTP server executes your script as user
"nobody", without any special privileges.  It can only read (write,
execute) files that everybody can read (write, execute).  The current
directory at execution time is also different (it is usually the
server's cgi-bin directory) and the set of environment variables is
also different from what you get at login.  in particular, don't count
on the shell's search path for executables ($PATH) or the Python
module search path ($PYTHONPATH) to be set to anything interesting.

If you need to load modules from a directory which is not on Python's
default module search path, you can change the path in your script,
before importing other modules, e.g.:

	import sys
	sys.path.insert(0, "/usr/home/joe/lib/python")
	sys.path.insert(0, "/usr/local/lib/python")

(This way, the directory inserted last will be searched first!)

Instructions for non-Unix systems will vary; check your HTTP server's
documentation (it will usually have a section on CGI scripts).


Testing your CGI script
-----------------------

Unfortunately, a CGI script will generally not run when you try it
from the command line, and a script that works perfectly from the
command line may fail mysteriously when run from the server.  There's
one reason why you should still test your script from the command
line: if it contains a syntax error, the python interpreter won't
execute it at all, and the HTTP server will most likely send a cryptic
error to the client.

Assuming your script has no syntax errors, yet it does not work, you
have no choice but to read the next section:


Debugging CGI scripts
---------------------

First of all, check for trivial installation errors -- reading the
section above on installing your CGI script carefully can save you a
lot of time.  If you wonder whether you have understood the
installation procedure correctly, try installing a copy of this module
file (cgi.py) as a CGI script.  When invoked as a script, the file
will dump its environment and the contents of the form in HTML form.
Give it the right mode etc, and send it a request.  If it's installed
in the standard cgi-bin directory, it should be possible to send it a
request by entering a URL into your browser of the form:

	http://yourhostname/cgi-bin/cgi.py?name=Joe+Blow&addr=At+Home

If this gives an error of type 404, the server cannot find the script
-- perhaps you need to install it in a different directory.  If it
gives another error (e.g.  500), there's an installation problem that
you should fix before trying to go any further.  If you get a nicely
formatted listing of the environment and form content (in this
example, the fields should be listed as "addr" with value "At Home"
and "name" with value "Joe Blow"), the cgi.py script has been
installed correctly.  If you follow the same procedure for your own
script, you should now be able to debug it.

The next step could be to call the cgi module's test() function from
your script: replace its main code with the single statement

	cgi.test()
	
This should produce the same results as those gotten from installing
the cgi.py file itself.

When an ordinary Python script raises an unhandled exception
(e.g. because of a typo in a module name, a file that can't be opened,
etc.), the Python interpreter prints a nice traceback and exits.
While the Python interpreter will still do this when your CGI script
raises an exception, most likely the traceback will end up in one of
the HTTP server's log file, or be discarded altogether.

Fortunately, once you have managed to get your script to execute
*some* code, it is easy to catch exceptions and cause a traceback to
be printed.  The test() function below in this module is an example.
Here are the rules:

	1. Import the traceback module (before entering the
	   try-except!)
	
	2. Make sure you finish printing the headers and the blank
	   line early
	
	3. Assign sys.stderr to sys.stdout
	
	3. Wrap all remaining code in a try-except statement
	
	4. In the except clause, call traceback.print_exc()

For example:

	import sys
	import traceback
	print "Content-type: text/html"
	print
	sys.stderr = sys.stdout
	try:
		...your code here...
	except:
		print "\n\n<PRE>"
		traceback.print_exc()

Notes: The assignment to sys.stderr is needed because the traceback
prints to sys.stderr.  The print "\n\n<PRE>" statement is necessary to
disable the word wrapping in HTML.

If you suspect that there may be a problem in importing the traceback
module, you can use an even more robust approach (which only uses
built-in modules):

	import sys
	sys.stderr = sys.stdout
	print "Content-type: text/plain"
	print
	...your code here...

This relies on the Python interpreter to print the traceback.  The
content type of the output is set to plain text, which disables all
HTML processing.  If your script works, the raw HTML will be displayed
by your client.  If it raises an exception, most likely after the
first two lines have been printed, a traceback will be displayed.
Because no HTML interpretation is going on, the traceback will
readable.

When all else fails, you may want to insert calls to log() to your
program or even to a copy of the cgi.py file.  Note that this requires
you to set cgi.logfile to the name of a world-writable file before the
first call to log() is made!

Good luck!


Common problems and solutions
-----------------------------

- Most HTTP servers buffer the output from CGI scripts until the
script is completed.  This means that it is not possible to display a
progress report on the client's display while the script is running.

- Check the installation instructions above.

- Check the HTTP server's log files.  ("tail -f logfile" in a separate
window may be useful!)

- Always check a script for syntax errors first, by doing something
like "python script.py".

- When using any of the debugging techniques, don't forget to add
"import sys" to the top of the script.

- When invoking external programs, make sure they can be found.
Usually, this means using absolute path names -- $PATH is usually not
set to a very useful value in a CGI script.

- When reading or writing external files, make sure they can be read
or written by every user on the system.

- Don't try to give a CGI script a set-uid mode.  This doesn't work on
most systems, and is a security liability as well.


History
-------

Michael McLay started this module.  Steve Majewski changed the
interface to SvFormContentDict and FormContentDict.  The multipart
parsing was inspired by code submitted by Andreas Paepcke.  Guido van
Rossum rewrote, reformatted and documented the module and is currently
responsible for its maintenance.


XXX The module is getting pretty heavy with all those docstrings.
Perhaps there should be a slimmed version that doesn't contain all those 
backwards compatible and debugging classes and functions?

"""

# " <== Emacs font-lock de-bogo-kludgificocity

__version__ = "2.2"


# Imports
# =======

import string
import sys
import os


# Logging support
# ===============

logfile = ""		# Filename to log to, if not empty
logfp = None		# File object to log to, if not None

def initlog(*allargs):
    """Write a log message, if there is a log file.

    Even though this function is called initlog(), you should always
    use log(); log is a variable that is set either to initlog
    (initially), to dolog (once the log file has been opened), or to
    nolog (when logging is disabled).

    The first argument is a format string; the remaining arguments (if
    any) are arguments to the % operator, so e.g.
        log("%s: %s", "a", "b")
    will write "a: b" to the log file, followed by a newline.

    If the global logfp is not None, it should be a file object to
    which log data is written.

    If the global logfp is None, the global logfile may be a string
    giving a filename to open, in append mode.  This file should be
    world writable!!!  If the file can't be opened, logging is
    silently disabled (since there is no safe place where we could
    send an error message).

    """
    global logfp, log
    if logfile and not logfp:
	try:
	    logfp = open(logfile, "a")
	except IOError:
	    pass
    if not logfp:
	log = nolog
    else:
	log = dolog
    apply(log, allargs)

def dolog(fmt, *args):
    """Write a log message to the log file.  See initlog() for docs."""
    logfp.write(fmt%args + "\n")

def nolog(*allargs):
    """Dummy function, assigned to log when logging is disabled."""
    pass

log = initlog		# The current logging function


# Parsing functions
# =================

def parse(fp=None, environ=os.environ, keep_blank_values=0, strict_parsing=0):
    """Parse a query in the environment or from a file (default stdin)

        Arguments, all optional:

        fp              : file pointer; default: sys.stdin

	environ         : environment dictionary; default: os.environ

        keep_blank_values: flag indicating whether blank values in
            URL encoded forms should be treated as blank strings.  
            A true value inicates that blanks should be retained as 
            blank strings.  The default false value indicates that
	    blank values are to be ignored and treated as if they were
	    not included.

	strict_parsing: flag indicating what to do with parsing errors.
	    If false (the default), errors are silently ignored.
	    If true, errors raise a ValueError exception.
    """
    if not fp:
	fp = sys.stdin
    if not environ.has_key('REQUEST_METHOD'):
	environ['REQUEST_METHOD'] = 'GET'	# For testing stand-alone
    if environ['REQUEST_METHOD'] == 'POST':
	ctype, pdict = parse_header(environ['CONTENT_TYPE'])
	if ctype == 'multipart/form-data':
	    return parse_multipart(fp, pdict)
	elif ctype == 'application/x-www-form-urlencoded':
	    clength = string.atoi(environ['CONTENT_LENGTH'])
	    qs = fp.read(clength)
	else:
	    qs = ''			# Unknown content-type
	if environ.has_key('QUERY_STRING'): 
	    if qs: qs = qs + '&'
	    qs = qs + environ['QUERY_STRING']
	elif sys.argv[1:]: 
	    if qs: qs = qs + '&'
	    qs = qs + sys.argv[1]
	environ['QUERY_STRING'] = qs	# XXX Shouldn't, really
    elif environ.has_key('QUERY_STRING'):
	qs = environ['QUERY_STRING']
    else:
	if sys.argv[1:]:
	    qs = sys.argv[1]
	else:
	    qs = ""
	environ['QUERY_STRING'] = qs	# XXX Shouldn't, really
    return parse_qs(qs, keep_blank_values, strict_parsing)


def parse_qs(qs, keep_blank_values=0, strict_parsing=0):
    """Parse a query given as a string argument.

        Arguments:

	qs: URL-encoded query string to be parsed

        keep_blank_values: flag indicating whether blank values in
            URL encoded queries should be treated as blank strings.  
            A true value inicates that blanks should be retained as 
            blank strings.  The default false value indicates that
	    blank values are to be ignored and treated as if they were
	    not included.

	strict_parsing: flag indicating what to do with parsing errors.
	    If false (the default), errors are silently ignored.
	    If true, errors raise a ValueError exception.
    """
    import urllib, regsub
    name_value_pairs = string.splitfields(qs, '&')
    dict = {}
    for name_value in name_value_pairs:
	nv = string.splitfields(name_value, '=')
	if len(nv) != 2:
	    if strict_parsing:
		raise ValueError, "bad query field: %s" % `name_value`
	    continue
	name = urllib.unquote(regsub.gsub('+', ' ', nv[0]))
	value = urllib.unquote(regsub.gsub('+', ' ', nv[1]))
        if len(value) or keep_blank_values:
	    if dict.has_key (name):
		dict[name].append(value)
	    else:
		dict[name] = [value]
    return dict


def parse_multipart(fp, pdict):
    """Parse multipart input.

    Arguments:
    fp   : input file
    pdict: dictionary containing other parameters of conten-type header

    Returns a dictionary just like parse_qs(): keys are the field names, each 
    value is a list of values for that field.  This is easy to use but not 
    much good if you are expecting megabytes to be uploaded -- in that case, 
    use the FieldStorage class instead which is much more flexible.  Note 
    that content-type is the raw, unparsed contents of the content-type 
    header.
    
    XXX This does not parse nested multipart parts -- use FieldStorage for 
    that.
    
    XXX This should really be subsumed by FieldStorage altogether -- no 
    point in having two implementations of the same parsing algorithm.

    """
    import mimetools
    if pdict.has_key('boundary'):
	boundary = pdict['boundary']
    else:
	boundary = ""
    nextpart = "--" + boundary
    lastpart = "--" + boundary + "--"
    partdict = {}
    terminator = ""

    while terminator != lastpart:
	bytes = -1
	data = None
	if terminator:
	    # At start of next part.  Read headers first.
	    headers = mimetools.Message(fp)
	    clength = headers.getheader('content-length')
	    if clength:
		try:
		    bytes = string.atoi(clength)
		except string.atoi_error:
		    pass
	    if bytes > 0:
		data = fp.read(bytes)
	    else:
		data = ""
	# Read lines until end of part.
	lines = []
	while 1:
	    line = fp.readline()
	    if not line:
		terminator = lastpart # End outer loop
		break
	    if line[:2] == "--":
		terminator = string.strip(line)
		if terminator in (nextpart, lastpart):
		    break
	    lines.append(line)
	# Done with part.
	if data is None:
	    continue
	if bytes < 0:
	    if lines:
		# Strip final line terminator
		line = lines[-1]
		if line[-2:] == "\r\n":
		    line = line[:-2]
		elif line[-1:] == "\n":
		    line = line[:-1]
		lines[-1] = line
		data = string.joinfields(lines, "")
	line = headers['content-disposition']
	if not line:
	    continue
	key, params = parse_header(line)
	if key != 'form-data':
	    continue
	if params.has_key('name'):
	    name = params['name']
	else:
	    continue
	if partdict.has_key(name):
	    partdict[name].append(data)
	else:
	    partdict[name] = [data]

    return partdict


def parse_header(line):
    """Parse a Content-type like header.

    Return the main content-type and a dictionary of options.

    """
    plist = map(string.strip, string.splitfields(line, ';'))
    key = string.lower(plist[0])
    del plist[0]
    pdict = {}
    for p in plist:
	i = string.find(p, '=')
	if i >= 0:
	    name = string.lower(string.strip(p[:i]))
	    value = string.strip(p[i+1:])
	    if len(value) >= 2 and value[0] == value[-1] == '"':
		value = value[1:-1]
	    pdict[name] = value
    return key, pdict


# Classes for field storage
# =========================

class MiniFieldStorage:

    """Like FieldStorage, for use when no file uploads are possible."""

    # Dummy attributes
    filename = None
    list = None
    type = None
    file = None
    type_options = {}
    disposition = None
    disposition_options = {}
    headers = {}

    def __init__(self, name, value):
	"""Constructor from field name and value."""
	from StringIO import StringIO
	self.name = name
	self.value = value
        # self.file = StringIO(value)

    def __repr__(self):
	"""Return printable representation."""
	return "MiniFieldStorage(%s, %s)" % (`self.name`, `self.value`)


class FieldStorage:

    """Store a sequence of fields, reading multipart/form-data.

    This class provides naming, typing, files stored on disk, and
    more.  At the top level, it is accessible like a dictionary, whose
    keys are the field names.  (Note: None can occur as a field name.)
    The items are either a Python list (if there's multiple values) or
    another FieldStorage or MiniFieldStorage object.  If it's a single
    object, it has the following attributes:

    name: the field name, if specified; otherwise None

    filename: the filename, if specified; otherwise None; this is the
	client side filename, *not* the file name on which it is
	stored (that's a temporary file you don't deal with)

    value: the value as a *string*; for file uploads, this
	transparently reads the file every time you request the value

    file: the file(-like) object from which you can read the data;
	None if the data is stored a simple string

    type: the content-type, or None if not specified

    type_options: dictionary of options specified on the content-type
	line

    disposition: content-disposition, or None if not specified

    disposition_options: dictionary of corresponding options

    headers: a dictionary(-like) object (sometimes rfc822.Message or a
	subclass thereof) containing *all* headers

    The class is subclassable, mostly for the purpose of overriding
    the make_file() method, which is called internally to come up with
    a file open for reading and writing.  This makes it possible to
    override the default choice of storing all files in a temporary
    directory and unlinking them as soon as they have been opened.

    """

    def __init__(self, fp=None, headers=None, outerboundary="",
		 environ=os.environ, keep_blank_values=0, strict_parsing=0):
	"""Constructor.  Read multipart/* until last part.

	Arguments, all optional:

	fp      	: file pointer; default: sys.stdin

	headers 	: header dictionary-like object; default:
	    taken from environ as per CGI spec

        outerboundary   : terminating multipart boundary
	    (for internal use only)

	environ         : environment dictionary; default: os.environ

        keep_blank_values: flag indicating whether blank values in
            URL encoded forms should be treated as blank strings.  
            A true value inicates that blanks should be retained as 
            blank strings.  The default false value indicates that
	    blank values are to be ignored and treated as if they were
	    not included.

	strict_parsing: flag indicating what to do with parsing errors.
	    If false (the default), errors are silently ignored.
	    If true, errors raise a ValueError exception.

	"""
	method = None
	self.keep_blank_values = keep_blank_values
	self.strict_parsing = strict_parsing
	if environ.has_key('REQUEST_METHOD'):
	    method = string.upper(environ['REQUEST_METHOD'])
	if not fp and method == 'GET':
	    qs = None
	    if environ.has_key('QUERY_STRING'):
		qs = environ['QUERY_STRING']
	    from StringIO import StringIO
	    fp = StringIO(qs or "")
	    if headers is None:
		headers = {'content-type':
			   "application/x-www-form-urlencoded"}
	if headers is None:
	    headers = {}
	    if environ.has_key('CONTENT_TYPE'):
		headers['content-type'] = environ['CONTENT_TYPE']
	    if environ.has_key('CONTENT_LENGTH'):
		headers['content-length'] = environ['CONTENT_LENGTH']
	self.fp = fp or sys.stdin
	self.headers = headers
	self.outerboundary = outerboundary

	# Process content-disposition header
	cdisp, pdict = "", {}
	if self.headers.has_key('content-disposition'):
	    cdisp, pdict = parse_header(self.headers['content-disposition'])
	self.disposition = cdisp
	self.disposition_options = pdict
	self.name = None
	if pdict.has_key('name'):
	    self.name = pdict['name']
	self.filename = None
	if pdict.has_key('filename'):
	    self.filename = pdict['filename']

	# Process content-type header
	ctype, pdict = "text/plain", {}
	if self.headers.has_key('content-type'):
	    ctype, pdict = parse_header(self.headers['content-type'])
	self.type = ctype
	self.type_options = pdict
	self.innerboundary = ""
	if pdict.has_key('boundary'):
	    self.innerboundary = pdict['boundary']
	clen = -1
	if self.headers.has_key('content-length'):
	    try:
		clen = string.atoi(self.headers['content-length'])
	    except:
		pass
	self.length = clen

	self.list = self.file = None
	self.done = 0
	self.lines = []
	if ctype == 'application/x-www-form-urlencoded':
	    self.read_urlencoded()
	elif ctype[:10] == 'multipart/':
	    self.read_multi()
	else:
	    self.read_single()

    def __repr__(self):
	"""Return a printable representation."""
	return "FieldStorage(%s, %s, %s)" % (
		`self.name`, `self.filename`, `self.value`)

    def __getattr__(self, name):
	if name != 'value':
	    raise AttributeError, name
	if self.file:
	    self.file.seek(0)
	    value = self.file.read()
	    self.file.seek(0)
	elif self.list is not None:
	    value = self.list
	else:
	    value = None
	return value

    def __getitem__(self, key):
	"""Dictionary style indexing."""
	if self.list is None:
	    raise TypeError, "not indexable"
	found = []
	for item in self.list:
	    if item.name == key: found.append(item)
	if not found:
	    raise KeyError, key
	if len(found) == 1:
	    return found[0]
	else:
	    return found

    def keys(self):
	"""Dictionary style keys() method."""
	if self.list is None:
	    raise TypeError, "not indexable"
	keys = []
	for item in self.list:
	    if item.name not in keys: keys.append(item.name)
	return keys

    def has_key(self, key):
	"""Dictionary style has_key() method."""
	if self.list is None:
	    raise TypeError, "not indexable"
	for item in self.list:
	    if item.name == key: return 1
	return 0

    def __len__(self):
	"""Dictionary style len(x) support."""
	return len(self.keys())

    def read_urlencoded(self):
	"""Internal: read data in query string format."""
	qs = self.fp.read(self.length)
	dict = parse_qs(qs, self.keep_blank_values, self.strict_parsing)
	self.list = []
	for key, valuelist in dict.items():
	    for value in valuelist:
		self.list.append(MiniFieldStorage(key, value))
	self.skip_lines()

    def read_multi(self):
	"""Internal: read a part that is itself multipart."""
	import rfc822
	self.list = []
	part = self.__class__(self.fp, {}, self.innerboundary)
	# Throw first part away
	while not part.done:
	    headers = rfc822.Message(self.fp)
	    part = self.__class__(self.fp, headers, self.innerboundary)
	    self.list.append(part)
	self.skip_lines()

    def read_single(self):
	"""Internal: read an atomic part."""
	if self.length >= 0:
	    self.read_binary()
	    self.skip_lines()
	else:
	    self.read_lines()
	self.file.seek(0)

    bufsize = 8*1024		# I/O buffering size for copy to file

    def read_binary(self):
	"""Internal: read binary data."""
	self.file = self.make_file('b')
	todo = self.length
	if todo >= 0:
	    while todo > 0:
		data = self.fp.read(min(todo, self.bufsize))
		if not data:
		    self.done = -1
		    break
		self.file.write(data)
		todo = todo - len(data)

    def read_lines(self):
	"""Internal: read lines until EOF or outerboundary."""
	self.file = self.make_file('')
	if self.outerboundary:
	    self.read_lines_to_outerboundary()
	else:
	    self.read_lines_to_eof()

    def read_lines_to_eof(self):
	"""Internal: read lines until EOF."""
	while 1:
	    line = self.fp.readline()
	    if not line:
		self.done = -1
		break
	    self.lines.append(line)
	    self.file.write(line)

    def read_lines_to_outerboundary(self):
	"""Internal: read lines until outerboundary."""
	next = "--" + self.outerboundary
	last = next + "--"
	delim = ""
	while 1:
	    line = self.fp.readline()
	    if not line:
		self.done = -1
		break
	    self.lines.append(line)
	    if line[:2] == "--":
		strippedline = string.strip(line)
		if strippedline == next:
		    break
		if strippedline == last:
		    self.done = 1
		    break
	    odelim = delim
	    if line[-2:] == "\r\n":
		delim = "\r\n"
		line = line[:-2]
	    elif line[-1] == "\n":
		delim = "\n"
		line = line[:-1]
	    else:
		delim = ""
	    self.file.write(odelim + line)

    def skip_lines(self):
	"""Internal: skip lines until outer boundary if defined."""
	if not self.outerboundary or self.done:
	    return
	next = "--" + self.outerboundary
	last = next + "--"
	while 1:
	    line = self.fp.readline()
	    if not line:
		self.done = -1
		break
	    self.lines.append(line)
	    if line[:2] == "--":
		strippedline = string.strip(line)
		if strippedline == next:
		    break
		if strippedline == last:
		    self.done = 1
		    break

    def make_file(self, binary):
	"""Overridable: return a readable & writable file.

	The file will be used as follows:
	- data is written to it
	- seek(0)
	- data is read from it

	The 'binary' argument is 'b' if the file should be created in
	binary mode (on non-Unix systems), '' otherwise.

	This version opens a temporary file for reading and writing,
	and immediately deletes (unlinks) it.  The trick (on Unix!) is
	that the file can still be used, but it can't be opened by
	another process, and it will automatically be deleted when it
	is closed or when the current process terminates.

	If you want a more permanent file, you derive a class which
	overrides this method.  If you want a visible temporary file
	that is nevertheless automatically deleted when the script
	terminates, try defining a __del__ method in a derived class
	which unlinks the temporary files you have created.

	"""
	import tempfile
	tfn = tempfile.mktemp()
	f = open(tfn, "w%s+" % binary)
	os.unlink(tfn)
	return f


# Backwards Compatibility Classes
# ===============================

class FormContentDict:
    """Basic (multiple values per field) form content as dictionary.

    form = FormContentDict()

    form[key] -> [value, value, ...]
    form.has_key(key) -> Boolean
    form.keys() -> [key, key, ...]
    form.values() -> [[val, val, ...], [val, val, ...], ...]
    form.items() ->  [(key, [val, val, ...]), (key, [val, val, ...]), ...]
    form.dict == {key: [val, val, ...], ...}

    """
    def __init__(self, environ=os.environ):
        self.dict = parse(environ=environ)
	self.query_string = environ['QUERY_STRING']
    def __getitem__(self,key):
	return self.dict[key]
    def keys(self):
	return self.dict.keys()
    def has_key(self, key):
	return self.dict.has_key(key)
    def values(self):
	return self.dict.values()
    def items(self):
	return self.dict.items() 
    def __len__( self ):
	return len(self.dict)


class SvFormContentDict(FormContentDict):
    """Strict single-value expecting form content as dictionary.

    IF you only expect a single value for each field, then form[key]
    will return that single value.  It will raise an IndexError if
    that expectation is not true.  IF you expect a field to have
    possible multiple values, than you can use form.getlist(key) to
    get all of the values.  values() and items() are a compromise:
    they return single strings where there is a single value, and
    lists of strings otherwise.

    """
    def __getitem__(self, key):
	if len(self.dict[key]) > 1: 
	    raise IndexError, 'expecting a single value' 
	return self.dict[key][0]
    def getlist(self, key):
	return self.dict[key]
    def values(self):
	lis = []
	for each in self.dict.values(): 
	    if len( each ) == 1 : 
		lis.append(each[0])
	    else: lis.append(each)
	return lis
    def items(self):
	lis = []
	for key,value in self.dict.items():
	    if len(value) == 1 :
		lis.append((key, value[0]))
	    else:	lis.append((key, value))
	return lis


class InterpFormContentDict(SvFormContentDict):
    """This class is present for backwards compatibility only.""" 
    def __getitem__( self, key ):
	v = SvFormContentDict.__getitem__( self, key )
	if v[0] in string.digits+'+-.' : 
	    try:  return  string.atoi( v ) 
	    except ValueError:
		try:	return string.atof( v )
		except ValueError: pass
	return string.strip(v)
    def values( self ):
	lis = [] 
	for key in self.keys():
	    try:
		lis.append( self[key] )
	    except IndexError:
		lis.append( self.dict[key] )
	return lis
    def items( self ):
	lis = [] 
	for key in self.keys():
	    try:
		lis.append( (key, self[key]) )
	    except IndexError:
		lis.append( (key, self.dict[key]) )
	return lis


class FormContent(FormContentDict):
    """This class is present for backwards compatibility only.""" 
    def values(self, key):
	if self.dict.has_key(key) :return self.dict[key]
	else: return None
    def indexed_value(self, key, location):
	if self.dict.has_key(key):
	    if len (self.dict[key]) > location:
		return self.dict[key][location]
	    else: return None
	else: return None
    def value(self, key):
	if self.dict.has_key(key): return self.dict[key][0]
	else: return None
    def length(self, key):
	return len(self.dict[key])
    def stripped(self, key):
	if self.dict.has_key(key): return string.strip(self.dict[key][0])
	else: return None
    def pars(self):
	return self.dict


# Test/debug code
# ===============

def test(environ=os.environ):
    """Robust test CGI script, usable as main program.

    Write minimal HTTP headers and dump all information provided to
    the script in HTML form.

    """
    import traceback
    print "Content-type: text/html"
    print
    sys.stderr = sys.stdout
    try:
	form = FieldStorage()	# Replace with other classes to test those
	print_form(form)
        print_environ(environ)
	print_directory()
	print_arguments()
	print_environ_usage()
	def f():
	    exec "testing print_exception() -- <I>italics?</I>"
	def g(f=f):
	    f()
	print "<H3>What follows is a test, not an actual exception:</H3>"
	g()
    except:
	print_exception()

def print_exception(type=None, value=None, tb=None, limit=None):
    if type is None:
	type, value, tb = sys.exc_type, sys.exc_value, sys.exc_traceback
    import traceback
    print
    print "<H3>Traceback (innermost last):</H3>"
    list = traceback.format_tb(tb, limit) + \
	   traceback.format_exception_only(type, value)
    print "<PRE>%s<B>%s</B></PRE>" % (
	escape(string.join(list[:-1], "")),
	escape(list[-1]),
	)

def print_environ(environ=os.environ):
    """Dump the shell environment as HTML."""
    keys = environ.keys()
    keys.sort()
    print
    print "<H3>Shell Environment:</H3>"
    print "<DL>"
    for key in keys:
	print "<DT>", escape(key), "<DD>", escape(environ[key])
    print "</DL>" 
    print

def print_form(form):
    """Dump the contents of a form as HTML."""
    keys = form.keys()
    keys.sort()
    print
    print "<H3>Form Contents:</H3>"
    print "<DL>"
    for key in keys:
	print "<DT>" + escape(key) + ":",
	value = form[key]
	print "<i>" + escape(`type(value)`) + "</i>"
	print "<DD>" + escape(`value`)
    print "</DL>"
    print

def print_directory():
    """Dump the current directory as HTML."""
    print
    print "<H3>Current Working Directory:</H3>"
    try:
	pwd = os.getcwd()
    except os.error, msg:
	print "os.error:", escape(str(msg))
    else:
	print escape(pwd)
    print

def print_arguments():
    print
    print "<H3>Command Line Arguments:</H3>"
    print
    print sys.argv
    print

def print_environ_usage():
    """Dump a list of environment variables used by CGI as HTML."""
    print """
<H3>These environment variables could have been set:</H3>
<UL>
<LI>AUTH_TYPE
<LI>CONTENT_LENGTH
<LI>CONTENT_TYPE
<LI>DATE_GMT
<LI>DATE_LOCAL
<LI>DOCUMENT_NAME
<LI>DOCUMENT_ROOT
<LI>DOCUMENT_URI
<LI>GATEWAY_INTERFACE
<LI>LAST_MODIFIED
<LI>PATH
<LI>PATH_INFO
<LI>PATH_TRANSLATED
<LI>QUERY_STRING
<LI>REMOTE_ADDR
<LI>REMOTE_HOST
<LI>REMOTE_IDENT
<LI>REMOTE_USER
<LI>REQUEST_METHOD
<LI>SCRIPT_NAME
<LI>SERVER_NAME
<LI>SERVER_PORT
<LI>SERVER_PROTOCOL
<LI>SERVER_ROOT
<LI>SERVER_SOFTWARE
</UL>
In addition, HTTP headers sent by the server may be passed in the
environment as well.  Here are some common variable names:
<UL>
<LI>HTTP_ACCEPT
<LI>HTTP_CONNECTION
<LI>HTTP_HOST
<LI>HTTP_PRAGMA
<LI>HTTP_REFERER
<LI>HTTP_USER_AGENT
</UL>
"""


# Utilities
# =========

def escape(s):
    """Replace special characters '&', '<' and '>' by SGML entities."""
    import regsub
    s = regsub.gsub("&", "&amp;", s)	# Must be done first!
    s = regsub.gsub("<", "&lt;", s)
    s = regsub.gsub(">", "&gt;", s)
    return s


# Invoke mainline
# ===============

# Call test() when this file is run as a script (not imported as a module)
if __name__ == '__main__': 
    test()
