#! /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
# =================

# Maximum input we will accept when REQUEST_METHOD is POST
# 0 ==> unlimited input
maxlen = 0

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'])
	    if maxlen and clength > maxlen:
		raise ValueError, 'Maximum content length exceeded'
	    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:
		if maxlen and bytes > maxlen:
		    raise ValueError, 'Maximum content length exceeded'
		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
	    if maxlen and clen > maxlen:
		raise ValueError, 'Maximum content length exceeded'
	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()

    # Second try with a small maxlen...
    global maxlen
    maxlen = 50
    try:
	form = FieldStorage()	# Replace with other classes to test those
	print_form(form)
	print_environ(environ)
	print_directory()
	print_arguments()
	print_environ_usage()
    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()
