10a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#! /usr/local/bin/python 20a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 30a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# NOTE: the above "/usr/local/bin/python" is NOT a mistake. It is 40a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# intentionally NOT "/usr/bin/env python". On many systems 50a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# (e.g. Solaris), /usr/local/bin is not in $PATH as passed to CGI 60a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# scripts, and /usr/local/bin is the default directory where Python is 70a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# installed, so /usr/bin/env would be unable to find python. Granted, 80a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# binary installations by Linux vendors often install Python in 90a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# /usr/bin. So let those vendors patch cgi.py to match their choice 100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# of installation. 110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao"""Support module for CGI (Common Gateway Interface) scripts. 130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 140a8c90248264a8b26970b4473770bcc3df8515fJosh GaoThis module defines a number of utilities for use by CGI scripts 150a8c90248264a8b26970b4473770bcc3df8515fJosh Gaowritten in Python. 160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao""" 170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# XXX Perhaps there should be a slimmed version that doesn't contain 190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# all those backwards compatible and debugging classes and functions? 200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# History 220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# ------- 230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# 240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Michael McLay started this module. Steve Majewski changed the 250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# interface to SvFormContentDict and FormContentDict. The multipart 260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# parsing was inspired by code submitted by Andreas Paepcke. Guido van 270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Rossum rewrote, reformatted and documented the module and is currently 280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# responsible for its maintenance. 290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# 300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao__version__ = "2.6" 320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Imports 350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# ======= 360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 370a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom operator import attrgetter 380a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport sys 390a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport os 400a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport UserDict 410a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport urlparse 420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 430a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom warnings import filterwarnings, catch_warnings, warn 440a8c90248264a8b26970b4473770bcc3df8515fJosh Gaowith catch_warnings(): 450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if sys.py3kwarning: 460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao filterwarnings("ignore", ".*mimetools has been removed", 470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao DeprecationWarning) 480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao filterwarnings("ignore", ".*rfc822 has been removed", 490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao DeprecationWarning) 500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao import mimetools 510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao import rfc822 520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 530a8c90248264a8b26970b4473770bcc3df8515fJosh Gaotry: 540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao from cStringIO import StringIO 550a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoexcept ImportError: 560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao from StringIO import StringIO 570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao__all__ = ["MiniFieldStorage", "FieldStorage", "FormContentDict", 590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao "SvFormContentDict", "InterpFormContentDict", "FormContent", 600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao "parse", "parse_qs", "parse_qsl", "parse_multipart", 610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao "parse_header", "print_exception", "print_environ", 620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao "print_form", "print_directory", "print_arguments", 630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao "print_environ_usage", "escape"] 640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Logging support 660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# =============== 670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 680a8c90248264a8b26970b4473770bcc3df8515fJosh Gaologfile = "" # Filename to log to, if not empty 690a8c90248264a8b26970b4473770bcc3df8515fJosh Gaologfp = None # File object to log to, if not None 700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 710a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef initlog(*allargs): 720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Write a log message, if there is a log file. 730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao Even though this function is called initlog(), you should always 750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao use log(); log is a variable that is set either to initlog 760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao (initially), to dolog (once the log file has been opened), or to 770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao nolog (when logging is disabled). 780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao The first argument is a format string; the remaining arguments (if 800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao any) are arguments to the % operator, so e.g. 810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao log("%s: %s", "a", "b") 820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao will write "a: b" to the log file, followed by a newline. 830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao If the global logfp is not None, it should be a file object to 850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao which log data is written. 860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao If the global logfp is None, the global logfile may be a string 880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao giving a filename to open, in append mode. This file should be 890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao world writable!!! If the file can't be opened, logging is 900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao silently disabled (since there is no safe place where we could 910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao send an error message). 920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """ 940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao global logfp, log 950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if logfile and not logfp: 960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao try: 970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao logfp = open(logfile, "a") 980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao except IOError: 990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao pass 1000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if not logfp: 1010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao log = nolog 1020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: 1030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao log = dolog 1040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao log(*allargs) 1050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1060a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef dolog(fmt, *args): 1070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Write a log message to the log file. See initlog() for docs.""" 1080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao logfp.write(fmt%args + "\n") 1090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1100a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef nolog(*allargs): 1110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Dummy function, assigned to log when logging is disabled.""" 1120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao pass 1130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1140a8c90248264a8b26970b4473770bcc3df8515fJosh Gaolog = initlog # The current logging function 1150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Parsing functions 1180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# ================= 1190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Maximum input we will accept when REQUEST_METHOD is POST 1210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# 0 ==> unlimited input 1220a8c90248264a8b26970b4473770bcc3df8515fJosh Gaomaxlen = 0 1230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1240a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef parse(fp=None, environ=os.environ, keep_blank_values=0, strict_parsing=0): 1250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Parse a query in the environment or from a file (default stdin) 1260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao Arguments, all optional: 1280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao fp : file pointer; default: sys.stdin 1300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao environ : environment dictionary; default: os.environ 1320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao keep_blank_values: flag indicating whether blank values in 1340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao percent-encoded forms should be treated as blank strings. 1350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao A true value indicates that blanks should be retained as 1360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao blank strings. The default false value indicates that 1370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao blank values are to be ignored and treated as if they were 1380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao not included. 1390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao strict_parsing: flag indicating what to do with parsing errors. 1410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao If false (the default), errors are silently ignored. 1420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao If true, errors raise a ValueError exception. 1430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """ 1440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if fp is None: 1450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao fp = sys.stdin 1460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if not 'REQUEST_METHOD' in environ: 1470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao environ['REQUEST_METHOD'] = 'GET' # For testing stand-alone 1480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if environ['REQUEST_METHOD'] == 'POST': 1490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ctype, pdict = parse_header(environ['CONTENT_TYPE']) 1500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if ctype == 'multipart/form-data': 1510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return parse_multipart(fp, pdict) 1520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao elif ctype == 'application/x-www-form-urlencoded': 1530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao clength = int(environ['CONTENT_LENGTH']) 1540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if maxlen and clength > maxlen: 1550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao raise ValueError, 'Maximum content length exceeded' 1560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao qs = fp.read(clength) 1570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: 1580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao qs = '' # Unknown content-type 1590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if 'QUERY_STRING' in environ: 1600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if qs: qs = qs + '&' 1610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao qs = qs + environ['QUERY_STRING'] 1620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao elif sys.argv[1:]: 1630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if qs: qs = qs + '&' 1640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao qs = qs + sys.argv[1] 1650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao environ['QUERY_STRING'] = qs # XXX Shouldn't, really 1660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao elif 'QUERY_STRING' in environ: 1670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao qs = environ['QUERY_STRING'] 1680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: 1690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if sys.argv[1:]: 1700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao qs = sys.argv[1] 1710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: 1720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao qs = "" 1730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao environ['QUERY_STRING'] = qs # XXX Shouldn't, really 1740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return urlparse.parse_qs(qs, keep_blank_values, strict_parsing) 1750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# parse query string function called from urlparse, 1780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# this is done in order to maintain backward compatiblity. 1790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1800a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef parse_qs(qs, keep_blank_values=0, strict_parsing=0): 1810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Parse a query given as a string argument.""" 1820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao warn("cgi.parse_qs is deprecated, use urlparse.parse_qs instead", 1830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao PendingDeprecationWarning, 2) 1840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return urlparse.parse_qs(qs, keep_blank_values, strict_parsing) 1850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1870a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef parse_qsl(qs, keep_blank_values=0, strict_parsing=0): 1880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Parse a query given as a string argument.""" 1890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao warn("cgi.parse_qsl is deprecated, use urlparse.parse_qsl instead", 1900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao PendingDeprecationWarning, 2) 1910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return urlparse.parse_qsl(qs, keep_blank_values, strict_parsing) 1920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1930a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef parse_multipart(fp, pdict): 1940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Parse multipart input. 1950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao Arguments: 1970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao fp : input file 1980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao pdict: dictionary containing other parameters of content-type header 1990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao Returns a dictionary just like parse_qs(): keys are the field names, each 2010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao value is a list of values for that field. This is easy to use but not 2020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao much good if you are expecting megabytes to be uploaded -- in that case, 2030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao use the FieldStorage class instead which is much more flexible. Note 2040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao that content-type is the raw, unparsed contents of the content-type 2050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao header. 2060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao XXX This does not parse nested multipart parts -- use FieldStorage for 2080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao that. 2090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao XXX This should really be subsumed by FieldStorage altogether -- no 2110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao point in having two implementations of the same parsing algorithm. 2120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao Also, FieldStorage protects itself better against certain DoS attacks 2130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao by limiting the size of the data read in one chunk. The API here 2140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao does not support that kind of protection. This also affects parse() 2150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao since it can call parse_multipart(). 2160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """ 2180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao boundary = "" 2190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if 'boundary' in pdict: 2200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao boundary = pdict['boundary'] 2210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if not valid_boundary(boundary): 2220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao raise ValueError, ('Invalid boundary in multipart form: %r' 2230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao % (boundary,)) 2240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao nextpart = "--" + boundary 2260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao lastpart = "--" + boundary + "--" 2270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao partdict = {} 2280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao terminator = "" 2290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao while terminator != lastpart: 2310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao bytes = -1 2320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao data = None 2330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if terminator: 2340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # At start of next part. Read headers first. 2350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao headers = mimetools.Message(fp) 2360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao clength = headers.getheader('content-length') 2370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if clength: 2380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao try: 2390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao bytes = int(clength) 2400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao except ValueError: 2410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao pass 2420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if bytes > 0: 2430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if maxlen and bytes > maxlen: 2440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao raise ValueError, 'Maximum content length exceeded' 2450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao data = fp.read(bytes) 2460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: 2470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao data = "" 2480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # Read lines until end of part. 2490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao lines = [] 2500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao while 1: 2510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao line = fp.readline() 2520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if not line: 2530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao terminator = lastpart # End outer loop 2540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao break 2550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if line[:2] == "--": 2560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao terminator = line.strip() 2570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if terminator in (nextpart, lastpart): 2580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao break 2590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao lines.append(line) 2600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # Done with part. 2610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if data is None: 2620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao continue 2630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if bytes < 0: 2640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if lines: 2650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # Strip final line terminator 2660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao line = lines[-1] 2670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if line[-2:] == "\r\n": 2680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao line = line[:-2] 2690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao elif line[-1:] == "\n": 2700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao line = line[:-1] 2710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao lines[-1] = line 2720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao data = "".join(lines) 2730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao line = headers['content-disposition'] 2740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if not line: 2750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao continue 2760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao key, params = parse_header(line) 2770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if key != 'form-data': 2780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao continue 2790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if 'name' in params: 2800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao name = params['name'] 2810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: 2820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao continue 2830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if name in partdict: 2840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao partdict[name].append(data) 2850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: 2860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao partdict[name] = [data] 2870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return partdict 2890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2910a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef _parseparam(s): 2920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao while s[:1] == ';': 2930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao s = s[1:] 2940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao end = s.find(';') 2950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao while end > 0 and (s.count('"', 0, end) - s.count('\\"', 0, end)) % 2: 2960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao end = s.find(';', end + 1) 2970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if end < 0: 2980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao end = len(s) 2990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao f = s[:end] 3000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao yield f.strip() 3010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao s = s[end:] 3020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3030a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef parse_header(line): 3040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Parse a Content-type like header. 3050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao Return the main content-type and a dictionary of options. 3070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """ 3090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao parts = _parseparam(';' + line) 3100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao key = parts.next() 3110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao pdict = {} 3120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao for p in parts: 3130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao i = p.find('=') 3140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if i >= 0: 3150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao name = p[:i].strip().lower() 3160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao value = p[i+1:].strip() 3170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if len(value) >= 2 and value[0] == value[-1] == '"': 3180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao value = value[1:-1] 3190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao value = value.replace('\\\\', '\\').replace('\\"', '"') 3200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao pdict[name] = value 3210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return key, pdict 3220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Classes for field storage 3250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# ========================= 3260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3270a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass MiniFieldStorage: 3280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Like FieldStorage, for use when no file uploads are possible.""" 3300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # Dummy attributes 3320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao filename = None 3330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao list = None 3340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao type = None 3350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao file = None 3360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao type_options = {} 3370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao disposition = None 3380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao disposition_options = {} 3390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao headers = {} 3400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def __init__(self, name, value): 3420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Constructor from field name and value.""" 3430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.name = name 3440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.value = value 3450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # self.file = StringIO(value) 3460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def __repr__(self): 3480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Return printable representation.""" 3490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return "MiniFieldStorage(%r, %r)" % (self.name, self.value) 3500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3520a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass FieldStorage: 3530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Store a sequence of fields, reading multipart/form-data. 3550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao This class provides naming, typing, files stored on disk, and 3570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao more. At the top level, it is accessible like a dictionary, whose 3580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao keys are the field names. (Note: None can occur as a field name.) 3590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao The items are either a Python list (if there's multiple values) or 3600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao another FieldStorage or MiniFieldStorage object. If it's a single 3610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao object, it has the following attributes: 3620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao name: the field name, if specified; otherwise None 3640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao filename: the filename, if specified; otherwise None; this is the 3660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao client side filename, *not* the file name on which it is 3670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao stored (that's a temporary file you don't deal with) 3680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao value: the value as a *string*; for file uploads, this 3700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao transparently reads the file every time you request the value 3710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao file: the file(-like) object from which you can read the data; 3730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao None if the data is stored a simple string 3740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao type: the content-type, or None if not specified 3760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao type_options: dictionary of options specified on the content-type 3780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao line 3790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao disposition: content-disposition, or None if not specified 3810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao disposition_options: dictionary of corresponding options 3830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao headers: a dictionary(-like) object (sometimes rfc822.Message or a 3850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao subclass thereof) containing *all* headers 3860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao The class is subclassable, mostly for the purpose of overriding 3880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao the make_file() method, which is called internally to come up with 3890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao a file open for reading and writing. This makes it possible to 3900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao override the default choice of storing all files in a temporary 3910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao directory and unlinking them as soon as they have been opened. 3920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """ 3940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def __init__(self, fp=None, headers=None, outerboundary="", 3960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao environ=os.environ, keep_blank_values=0, strict_parsing=0): 3970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Constructor. Read multipart/* until last part. 3980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao Arguments, all optional: 4000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 4010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao fp : file pointer; default: sys.stdin 4020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao (not used when the request method is GET) 4030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 4040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao headers : header dictionary-like object; default: 4050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao taken from environ as per CGI spec 4060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 4070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao outerboundary : terminating multipart boundary 4080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao (for internal use only) 4090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 4100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao environ : environment dictionary; default: os.environ 4110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 4120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao keep_blank_values: flag indicating whether blank values in 4130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao percent-encoded forms should be treated as blank strings. 4140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao A true value indicates that blanks should be retained as 4150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao blank strings. The default false value indicates that 4160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao blank values are to be ignored and treated as if they were 4170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao not included. 4180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 4190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao strict_parsing: flag indicating what to do with parsing errors. 4200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao If false (the default), errors are silently ignored. 4210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao If true, errors raise a ValueError exception. 4220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 4230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """ 4240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao method = 'GET' 4250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.keep_blank_values = keep_blank_values 4260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.strict_parsing = strict_parsing 4270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if 'REQUEST_METHOD' in environ: 4280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao method = environ['REQUEST_METHOD'].upper() 4290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.qs_on_post = None 4300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if method == 'GET' or method == 'HEAD': 4310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if 'QUERY_STRING' in environ: 4320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao qs = environ['QUERY_STRING'] 4330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao elif sys.argv[1:]: 4340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao qs = sys.argv[1] 4350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: 4360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao qs = "" 4370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao fp = StringIO(qs) 4380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if headers is None: 4390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao headers = {'content-type': 4400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao "application/x-www-form-urlencoded"} 4410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if headers is None: 4420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao headers = {} 4430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if method == 'POST': 4440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # Set default content-type for POST to what's traditional 4450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao headers['content-type'] = "application/x-www-form-urlencoded" 4460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if 'CONTENT_TYPE' in environ: 4470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao headers['content-type'] = environ['CONTENT_TYPE'] 4480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if 'QUERY_STRING' in environ: 4490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.qs_on_post = environ['QUERY_STRING'] 4500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if 'CONTENT_LENGTH' in environ: 4510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao headers['content-length'] = environ['CONTENT_LENGTH'] 4520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.fp = fp or sys.stdin 4530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.headers = headers 4540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.outerboundary = outerboundary 4550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 4560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # Process content-disposition header 4570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao cdisp, pdict = "", {} 4580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if 'content-disposition' in self.headers: 4590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao cdisp, pdict = parse_header(self.headers['content-disposition']) 4600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.disposition = cdisp 4610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.disposition_options = pdict 4620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.name = None 4630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if 'name' in pdict: 4640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.name = pdict['name'] 4650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.filename = None 4660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if 'filename' in pdict: 4670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.filename = pdict['filename'] 4680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 4690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # Process content-type header 4700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # 4710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # Honor any existing content-type header. But if there is no 4720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # content-type header, use some sensible defaults. Assume 4730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # outerboundary is "" at the outer level, but something non-false 4740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # inside a multi-part. The default for an inner part is text/plain, 4750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # but for an outer part it should be urlencoded. This should catch 4760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # bogus clients which erroneously forget to include a content-type 4770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # header. 4780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # 4790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # See below for what we do if there does exist a content-type header, 4800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # but it happens to be something we don't understand. 4810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if 'content-type' in self.headers: 4820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ctype, pdict = parse_header(self.headers['content-type']) 4830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao elif self.outerboundary or method != 'POST': 4840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ctype, pdict = "text/plain", {} 4850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: 4860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ctype, pdict = 'application/x-www-form-urlencoded', {} 4870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.type = ctype 4880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.type_options = pdict 4890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.innerboundary = "" 4900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if 'boundary' in pdict: 4910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.innerboundary = pdict['boundary'] 4920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao clen = -1 4930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if 'content-length' in self.headers: 4940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao try: 4950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao clen = int(self.headers['content-length']) 4960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao except ValueError: 4970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao pass 4980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if maxlen and clen > maxlen: 4990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao raise ValueError, 'Maximum content length exceeded' 5000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.length = clen 5010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 5020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.list = self.file = None 5030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.done = 0 5040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if ctype == 'application/x-www-form-urlencoded': 5050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.read_urlencoded() 5060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao elif ctype[:10] == 'multipart/': 5070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.read_multi(environ, keep_blank_values, strict_parsing) 5080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: 5090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.read_single() 5100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 5110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def __repr__(self): 5120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Return a printable representation.""" 5130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return "FieldStorage(%r, %r, %r)" % ( 5140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.name, self.filename, self.value) 5150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 5160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def __iter__(self): 5170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return iter(self.keys()) 5180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 5190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def __getattr__(self, name): 5200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if name != 'value': 5210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao raise AttributeError, name 5220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if self.file: 5230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.file.seek(0) 5240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao value = self.file.read() 5250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.file.seek(0) 5260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao elif self.list is not None: 5270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao value = self.list 5280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: 5290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao value = None 5300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return value 5310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 5320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def __getitem__(self, key): 5330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Dictionary style indexing.""" 5340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if self.list is None: 5350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao raise TypeError, "not indexable" 5360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao found = [] 5370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao for item in self.list: 5380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if item.name == key: found.append(item) 5390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if not found: 5400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao raise KeyError, key 5410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if len(found) == 1: 5420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return found[0] 5430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: 5440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return found 5450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 5460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def getvalue(self, key, default=None): 5470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Dictionary style get() method, including 'value' lookup.""" 5480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if key in self: 5490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao value = self[key] 5500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if type(value) is type([]): 5510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return map(attrgetter('value'), value) 5520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: 5530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return value.value 5540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: 5550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return default 5560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 5570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def getfirst(self, key, default=None): 5580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """ Return the first value received.""" 5590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if key in self: 5600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao value = self[key] 5610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if type(value) is type([]): 5620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return value[0].value 5630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: 5640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return value.value 5650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: 5660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return default 5670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 5680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def getlist(self, key): 5690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """ Return list of received values.""" 5700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if key in self: 5710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao value = self[key] 5720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if type(value) is type([]): 5730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return map(attrgetter('value'), value) 5740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: 5750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return [value.value] 5760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: 5770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return [] 5780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 5790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def keys(self): 5800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Dictionary style keys() method.""" 5810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if self.list is None: 5820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao raise TypeError, "not indexable" 5830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return list(set(item.name for item in self.list)) 5840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 5850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def has_key(self, key): 5860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Dictionary style has_key() method.""" 5870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if self.list is None: 5880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao raise TypeError, "not indexable" 5890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return any(item.name == key for item in self.list) 5900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 5910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def __contains__(self, key): 5920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Dictionary style __contains__ method.""" 5930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if self.list is None: 5940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao raise TypeError, "not indexable" 5950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return any(item.name == key for item in self.list) 5960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 5970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def __len__(self): 5980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Dictionary style len(x) support.""" 5990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return len(self.keys()) 6000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 6010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def __nonzero__(self): 6020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return bool(self.list) 6030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 6040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def read_urlencoded(self): 6050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Internal: read data in query string format.""" 6060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao qs = self.fp.read(self.length) 6070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if self.qs_on_post: 6080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao qs += '&' + self.qs_on_post 6090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.list = list = [] 6100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao for key, value in urlparse.parse_qsl(qs, self.keep_blank_values, 6110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.strict_parsing): 6120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao list.append(MiniFieldStorage(key, value)) 6130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.skip_lines() 6140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 6150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao FieldStorageClass = None 6160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 6170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def read_multi(self, environ, keep_blank_values, strict_parsing): 6180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Internal: read a part that is itself multipart.""" 6190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ib = self.innerboundary 6200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if not valid_boundary(ib): 6210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao raise ValueError, 'Invalid boundary in multipart form: %r' % (ib,) 6220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.list = [] 6230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if self.qs_on_post: 6240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao for key, value in urlparse.parse_qsl(self.qs_on_post, 6250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.keep_blank_values, self.strict_parsing): 6260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.list.append(MiniFieldStorage(key, value)) 6270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao FieldStorageClass = None 6280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 6290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao klass = self.FieldStorageClass or self.__class__ 6300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao part = klass(self.fp, {}, ib, 6310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao environ, keep_blank_values, strict_parsing) 6320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # Throw first part away 6330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao while not part.done: 6340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao headers = rfc822.Message(self.fp) 6350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao part = klass(self.fp, headers, ib, 6360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao environ, keep_blank_values, strict_parsing) 6370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.list.append(part) 6380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.skip_lines() 6390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 6400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def read_single(self): 6410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Internal: read an atomic part.""" 6420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if self.length >= 0: 6430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.read_binary() 6440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.skip_lines() 6450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: 6460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.read_lines() 6470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.file.seek(0) 6480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 6490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao bufsize = 8*1024 # I/O buffering size for copy to file 6500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 6510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def read_binary(self): 6520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Internal: read binary data.""" 6530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.file = self.make_file('b') 6540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao todo = self.length 6550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if todo >= 0: 6560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao while todo > 0: 6570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao data = self.fp.read(min(todo, self.bufsize)) 6580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if not data: 6590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.done = -1 6600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao break 6610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.file.write(data) 6620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao todo = todo - len(data) 6630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 6640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def read_lines(self): 6650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Internal: read lines until EOF or outerboundary.""" 6660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.file = self.__file = StringIO() 6670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if self.outerboundary: 6680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.read_lines_to_outerboundary() 6690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: 6700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.read_lines_to_eof() 6710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 6720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def __write(self, line): 6730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if self.__file is not None: 6740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if self.__file.tell() + len(line) > 1000: 6750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.file = self.make_file('') 6760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.file.write(self.__file.getvalue()) 6770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.__file = None 6780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.file.write(line) 6790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 6800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def read_lines_to_eof(self): 6810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Internal: read lines until EOF.""" 6820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao while 1: 6830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao line = self.fp.readline(1<<16) 6840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if not line: 6850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.done = -1 6860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao break 6870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.__write(line) 6880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 6890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def read_lines_to_outerboundary(self): 6900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Internal: read lines until outerboundary.""" 6910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao next = "--" + self.outerboundary 6920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao last = next + "--" 6930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao delim = "" 6940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao last_line_lfend = True 6950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao while 1: 6960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao line = self.fp.readline(1<<16) 6970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if not line: 6980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.done = -1 6990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao break 7000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if line[:2] == "--" and last_line_lfend: 7010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao strippedline = line.strip() 7020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if strippedline == next: 7030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao break 7040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if strippedline == last: 7050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.done = 1 7060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao break 7070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao odelim = delim 7080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if line[-2:] == "\r\n": 7090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao delim = "\r\n" 7100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao line = line[:-2] 7110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao last_line_lfend = True 7120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao elif line[-1] == "\n": 7130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao delim = "\n" 7140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao line = line[:-1] 7150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao last_line_lfend = True 7160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: 7170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao delim = "" 7180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao last_line_lfend = False 7190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.__write(odelim + line) 7200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 7210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def skip_lines(self): 7220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Internal: skip lines until outer boundary if defined.""" 7230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if not self.outerboundary or self.done: 7240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return 7250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao next = "--" + self.outerboundary 7260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao last = next + "--" 7270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao last_line_lfend = True 7280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao while 1: 7290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao line = self.fp.readline(1<<16) 7300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if not line: 7310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.done = -1 7320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao break 7330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if line[:2] == "--" and last_line_lfend: 7340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao strippedline = line.strip() 7350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if strippedline == next: 7360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao break 7370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if strippedline == last: 7380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.done = 1 7390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao break 7400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao last_line_lfend = line.endswith('\n') 7410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 7420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def make_file(self, binary=None): 7430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Overridable: return a readable & writable file. 7440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 7450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao The file will be used as follows: 7460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao - data is written to it 7470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao - seek(0) 7480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao - data is read from it 7490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 7500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao The 'binary' argument is unused -- the file is always opened 7510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao in binary mode. 7520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 7530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao This version opens a temporary file for reading and writing, 7540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao and immediately deletes (unlinks) it. The trick (on Unix!) is 7550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao that the file can still be used, but it can't be opened by 7560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao another process, and it will automatically be deleted when it 7570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao is closed or when the current process terminates. 7580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 7590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao If you want a more permanent file, you derive a class which 7600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao overrides this method. If you want a visible temporary file 7610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao that is nevertheless automatically deleted when the script 7620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao terminates, try defining a __del__ method in a derived class 7630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao which unlinks the temporary files you have created. 7640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 7650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """ 7660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao import tempfile 7670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return tempfile.TemporaryFile("w+b") 7680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 7690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 7700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 7710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Backwards Compatibility Classes 7720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# =============================== 7730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 7740a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass FormContentDict(UserDict.UserDict): 7750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Form content as dictionary with a list of values per field. 7760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 7770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao form = FormContentDict() 7780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 7790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao form[key] -> [value, value, ...] 7800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao key in form -> Boolean 7810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao form.keys() -> [key, key, ...] 7820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao form.values() -> [[val, val, ...], [val, val, ...], ...] 7830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao form.items() -> [(key, [val, val, ...]), (key, [val, val, ...]), ...] 7840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao form.dict == {key: [val, val, ...], ...} 7850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 7860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """ 7870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def __init__(self, environ=os.environ, keep_blank_values=0, strict_parsing=0): 7880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.dict = self.data = parse(environ=environ, 7890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao keep_blank_values=keep_blank_values, 7900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao strict_parsing=strict_parsing) 7910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.query_string = environ['QUERY_STRING'] 7920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 7930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 7940a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass SvFormContentDict(FormContentDict): 7950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Form content as dictionary expecting a single value per field. 7960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 7970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao If you only expect a single value for each field, then form[key] 7980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao will return that single value. It will raise an IndexError if 7990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao that expectation is not true. If you expect a field to have 8000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao possible multiple values, than you can use form.getlist(key) to 8010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao get all of the values. values() and items() are a compromise: 8020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao they return single strings where there is a single value, and 8030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao lists of strings otherwise. 8040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 8050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """ 8060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def __getitem__(self, key): 8070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if len(self.dict[key]) > 1: 8080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao raise IndexError, 'expecting a single value' 8090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return self.dict[key][0] 8100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def getlist(self, key): 8110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return self.dict[key] 8120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def values(self): 8130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao result = [] 8140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao for value in self.dict.values(): 8150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if len(value) == 1: 8160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao result.append(value[0]) 8170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: result.append(value) 8180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return result 8190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def items(self): 8200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao result = [] 8210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao for key, value in self.dict.items(): 8220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if len(value) == 1: 8230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao result.append((key, value[0])) 8240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: result.append((key, value)) 8250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return result 8260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 8270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 8280a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass InterpFormContentDict(SvFormContentDict): 8290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """This class is present for backwards compatibility only.""" 8300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def __getitem__(self, key): 8310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao v = SvFormContentDict.__getitem__(self, key) 8320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if v[0] in '0123456789+-.': 8330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao try: return int(v) 8340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao except ValueError: 8350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao try: return float(v) 8360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao except ValueError: pass 8370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return v.strip() 8380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def values(self): 8390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao result = [] 8400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao for key in self.keys(): 8410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao try: 8420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao result.append(self[key]) 8430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao except IndexError: 8440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao result.append(self.dict[key]) 8450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return result 8460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def items(self): 8470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao result = [] 8480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao for key in self.keys(): 8490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao try: 8500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao result.append((key, self[key])) 8510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao except IndexError: 8520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao result.append((key, self.dict[key])) 8530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return result 8540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 8550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 8560a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass FormContent(FormContentDict): 8570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """This class is present for backwards compatibility only.""" 8580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def values(self, key): 8590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if key in self.dict :return self.dict[key] 8600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: return None 8610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def indexed_value(self, key, location): 8620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if key in self.dict: 8630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if len(self.dict[key]) > location: 8640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return self.dict[key][location] 8650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: return None 8660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: return None 8670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def value(self, key): 8680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if key in self.dict: return self.dict[key][0] 8690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: return None 8700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def length(self, key): 8710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return len(self.dict[key]) 8720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def stripped(self, key): 8730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if key in self.dict: return self.dict[key][0].strip() 8740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: return None 8750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def pars(self): 8760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return self.dict 8770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 8780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 8790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Test/debug code 8800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# =============== 8810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 8820a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef test(environ=os.environ): 8830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Robust test CGI script, usable as main program. 8840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 8850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao Write minimal HTTP headers and dump all information provided to 8860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao the script in HTML form. 8870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 8880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """ 8890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao print "Content-type: text/html" 8900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao print 8910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao sys.stderr = sys.stdout 8920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao try: 8930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao form = FieldStorage() # Replace with other classes to test those 8940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao print_directory() 8950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao print_arguments() 8960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao print_form(form) 8970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao print_environ(environ) 8980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao print_environ_usage() 8990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def f(): 9000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao exec "testing print_exception() -- <I>italics?</I>" 9010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def g(f=f): 9020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao f() 9030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao print "<H3>What follows is a test, not an actual exception:</H3>" 9040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao g() 9050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao except: 9060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao print_exception() 9070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 9080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao print "<H1>Second try with a small maxlen...</H1>" 9090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 9100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao global maxlen 9110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao maxlen = 50 9120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao try: 9130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao form = FieldStorage() # Replace with other classes to test those 9140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao print_directory() 9150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao print_arguments() 9160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao print_form(form) 9170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao print_environ(environ) 9180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao except: 9190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao print_exception() 9200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 9210a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef print_exception(type=None, value=None, tb=None, limit=None): 9220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if type is None: 9230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao type, value, tb = sys.exc_info() 9240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao import traceback 9250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao print 9260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao print "<H3>Traceback (most recent call last):</H3>" 9270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao list = traceback.format_tb(tb, limit) + \ 9280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao traceback.format_exception_only(type, value) 9290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao print "<PRE>%s<B>%s</B></PRE>" % ( 9300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao escape("".join(list[:-1])), 9310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao escape(list[-1]), 9320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ) 9330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao del tb 9340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 9350a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef print_environ(environ=os.environ): 9360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Dump the shell environment as HTML.""" 9370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao keys = environ.keys() 9380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao keys.sort() 9390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao print 9400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao print "<H3>Shell Environment:</H3>" 9410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao print "<DL>" 9420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao for key in keys: 9430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao print "<DT>", escape(key), "<DD>", escape(environ[key]) 9440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao print "</DL>" 9450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao print 9460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 9470a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef print_form(form): 9480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Dump the contents of a form as HTML.""" 9490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao keys = form.keys() 9500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao keys.sort() 9510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao print 9520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao print "<H3>Form Contents:</H3>" 9530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if not keys: 9540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao print "<P>No form fields." 9550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao print "<DL>" 9560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao for key in keys: 9570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao print "<DT>" + escape(key) + ":", 9580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao value = form[key] 9590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao print "<i>" + escape(repr(type(value))) + "</i>" 9600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao print "<DD>" + escape(repr(value)) 9610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao print "</DL>" 9620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao print 9630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 9640a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef print_directory(): 9650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Dump the current directory as HTML.""" 9660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao print 9670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao print "<H3>Current Working Directory:</H3>" 9680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao try: 9690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao pwd = os.getcwd() 9700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao except os.error, msg: 9710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao print "os.error:", escape(str(msg)) 9720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: 9730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao print escape(pwd) 9740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao print 9750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 9760a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef print_arguments(): 9770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao print 9780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao print "<H3>Command Line Arguments:</H3>" 9790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao print 9800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao print sys.argv 9810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao print 9820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 9830a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef print_environ_usage(): 9840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Dump a list of environment variables used by CGI as HTML.""" 9850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao print """ 9860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao<H3>These environment variables could have been set:</H3> 9870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao<UL> 9880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao<LI>AUTH_TYPE 9890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao<LI>CONTENT_LENGTH 9900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao<LI>CONTENT_TYPE 9910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao<LI>DATE_GMT 9920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao<LI>DATE_LOCAL 9930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao<LI>DOCUMENT_NAME 9940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao<LI>DOCUMENT_ROOT 9950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao<LI>DOCUMENT_URI 9960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao<LI>GATEWAY_INTERFACE 9970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao<LI>LAST_MODIFIED 9980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao<LI>PATH 9990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao<LI>PATH_INFO 10000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao<LI>PATH_TRANSLATED 10010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao<LI>QUERY_STRING 10020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao<LI>REMOTE_ADDR 10030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao<LI>REMOTE_HOST 10040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao<LI>REMOTE_IDENT 10050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao<LI>REMOTE_USER 10060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao<LI>REQUEST_METHOD 10070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao<LI>SCRIPT_NAME 10080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao<LI>SERVER_NAME 10090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao<LI>SERVER_PORT 10100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao<LI>SERVER_PROTOCOL 10110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao<LI>SERVER_ROOT 10120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao<LI>SERVER_SOFTWARE 10130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao</UL> 10140a8c90248264a8b26970b4473770bcc3df8515fJosh GaoIn addition, HTTP headers sent by the server may be passed in the 10150a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoenvironment as well. Here are some common variable names: 10160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao<UL> 10170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao<LI>HTTP_ACCEPT 10180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao<LI>HTTP_CONNECTION 10190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao<LI>HTTP_HOST 10200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao<LI>HTTP_PRAGMA 10210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao<LI>HTTP_REFERER 10220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao<LI>HTTP_USER_AGENT 10230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao</UL> 10240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao""" 10250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 10260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 10270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Utilities 10280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# ========= 10290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 10300a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef escape(s, quote=None): 10310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao '''Replace special characters "&", "<" and ">" to HTML-safe sequences. 10320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao If the optional flag quote is true, the quotation mark character (") 10330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao is also translated.''' 10340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao s = s.replace("&", "&") # Must be done first! 10350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao s = s.replace("<", "<") 10360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao s = s.replace(">", ">") 10370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if quote: 10380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao s = s.replace('"', """) 10390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return s 10400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 10410a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef valid_boundary(s, _vb_pattern="^[ -~]{0,200}[!-~]$"): 10420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao import re 10430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return re.match(_vb_pattern, s) 10440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 10450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Invoke mainline 10460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# =============== 10470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 10480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Call test() when this file is run as a script (not imported as a module) 10490a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoif __name__ == '__main__': 10500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao test() 1051