blob: 33b91bfbd235847d4ef11a9f7875d898e31fa3cd [file] [log] [blame]
Guido van Rossum51914632000-10-03 13:51:09 +00001#! /usr/local/bin/python
Guido van Rossum1c9daa81995-09-18 21:52:37 +00002
Guido van Rossum467d7232001-02-13 13:13:33 +00003# NOTE: the above "/usr/local/bin/python" is NOT a mistake. It is
4# intentionally NOT "/usr/bin/env python". On many systems
5# (e.g. Solaris), /usr/local/bin is not in $PATH as passed to CGI
6# scripts, and /usr/local/bin is the default directory where Python is
7# installed, so /usr/bin/env would be unable to find python. Granted,
8# binary installations by Linux vendors often install Python in
9# /usr/bin. So let those vendors patch cgi.py to match their choice
10# of installation.
11
Guido van Rossum72755611996-03-06 07:20:06 +000012"""Support module for CGI (Common Gateway Interface) scripts.
Guido van Rossum1c9daa81995-09-18 21:52:37 +000013
Guido van Rossum7aee3841996-03-07 18:00:44 +000014This module defines a number of utilities for use by CGI scripts
15written in Python.
Guido van Rossum72755611996-03-06 07:20:06 +000016"""
17
Jeremy Hyltonc253d9a2000-08-03 20:57:44 +000018# XXX Perhaps there should be a slimmed version that doesn't contain
19# all those backwards compatible and debugging classes and functions?
Guido van Rossum98d9fd32000-02-28 15:12:25 +000020
21# History
22# -------
Tim Peters88869f92001-01-14 23:36:06 +000023#
Guido van Rossum98d9fd32000-02-28 15:12:25 +000024# Michael McLay started this module. Steve Majewski changed the
25# interface to SvFormContentDict and FormContentDict. The multipart
26# parsing was inspired by code submitted by Andreas Paepcke. Guido van
27# Rossum rewrote, reformatted and documented the module and is currently
28# responsible for its maintenance.
Tim Peters88869f92001-01-14 23:36:06 +000029#
Guido van Rossum98d9fd32000-02-28 15:12:25 +000030
Guido van Rossum52b8c292001-06-29 13:06:06 +000031__version__ = "2.6"
Guido van Rossum0147db01996-03-09 03:16:04 +000032
Guido van Rossum72755611996-03-06 07:20:06 +000033
34# Imports
35# =======
36
Raymond Hettingerf871d832004-12-31 21:59:02 +000037from operator import attrgetter
Guido van Rossum72755611996-03-06 07:20:06 +000038import sys
39import os
Guido van Rossuma5e9fb61997-08-12 18:18:13 +000040import urllib
Moshe Zadkaa1a4b592000-08-25 21:47:56 +000041import UserDict
Facundo Batistac585df92008-09-03 22:35:50 +000042import urlparse
43
44from warnings import filterwarnings, catch_warnings, warn
Brett Cannon1eaf0742008-09-02 01:25:16 +000045with catch_warnings():
46 if sys.py3kwarning:
47 filterwarnings("ignore", ".*mimetools has been removed",
48 DeprecationWarning)
Brett Cannon721b1452008-08-16 22:00:27 +000049 import mimetools
Brett Cannon1eaf0742008-09-02 01:25:16 +000050 if sys.py3kwarning:
51 filterwarnings("ignore", ".*rfc822 has been removed", DeprecationWarning)
Brett Cannon721b1452008-08-16 22:00:27 +000052 import rfc822
53
Raymond Hettingera6172712004-12-31 19:15:26 +000054try:
55 from cStringIO import StringIO
56except ImportError:
57 from StringIO import StringIO
Guido van Rossum72755611996-03-06 07:20:06 +000058
Guido van Rossuma8423a92001-03-19 13:40:44 +000059__all__ = ["MiniFieldStorage", "FieldStorage", "FormContentDict",
60 "SvFormContentDict", "InterpFormContentDict", "FormContent",
61 "parse", "parse_qs", "parse_qsl", "parse_multipart",
62 "parse_header", "print_exception", "print_environ",
63 "print_form", "print_directory", "print_arguments",
64 "print_environ_usage", "escape"]
Guido van Rossumc204c701996-09-05 19:07:11 +000065
66# Logging support
67# ===============
68
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000069logfile = "" # Filename to log to, if not empty
70logfp = None # File object to log to, if not None
Guido van Rossumc204c701996-09-05 19:07:11 +000071
72def initlog(*allargs):
73 """Write a log message, if there is a log file.
74
75 Even though this function is called initlog(), you should always
76 use log(); log is a variable that is set either to initlog
77 (initially), to dolog (once the log file has been opened), or to
78 nolog (when logging is disabled).
79
80 The first argument is a format string; the remaining arguments (if
81 any) are arguments to the % operator, so e.g.
82 log("%s: %s", "a", "b")
83 will write "a: b" to the log file, followed by a newline.
84
85 If the global logfp is not None, it should be a file object to
86 which log data is written.
87
88 If the global logfp is None, the global logfile may be a string
89 giving a filename to open, in append mode. This file should be
90 world writable!!! If the file can't be opened, logging is
91 silently disabled (since there is no safe place where we could
92 send an error message).
93
94 """
95 global logfp, log
96 if logfile and not logfp:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000097 try:
98 logfp = open(logfile, "a")
99 except IOError:
100 pass
Guido van Rossumc204c701996-09-05 19:07:11 +0000101 if not logfp:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000102 log = nolog
Guido van Rossumc204c701996-09-05 19:07:11 +0000103 else:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000104 log = dolog
Guido van Rossum68468eb2003-02-27 20:14:51 +0000105 log(*allargs)
Guido van Rossumc204c701996-09-05 19:07:11 +0000106
107def dolog(fmt, *args):
108 """Write a log message to the log file. See initlog() for docs."""
109 logfp.write(fmt%args + "\n")
110
111def nolog(*allargs):
112 """Dummy function, assigned to log when logging is disabled."""
113 pass
114
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000115log = initlog # The current logging function
Guido van Rossumc204c701996-09-05 19:07:11 +0000116
117
Guido van Rossum72755611996-03-06 07:20:06 +0000118# Parsing functions
119# =================
120
Guido van Rossumad164711997-05-13 19:03:23 +0000121# Maximum input we will accept when REQUEST_METHOD is POST
122# 0 ==> unlimited input
123maxlen = 0
124
Guido van Rossume08c04c1996-11-11 19:29:11 +0000125def parse(fp=None, environ=os.environ, keep_blank_values=0, strict_parsing=0):
Guido van Rossum773ab271996-07-23 03:46:24 +0000126 """Parse a query in the environment or from a file (default stdin)
127
128 Arguments, all optional:
129
130 fp : file pointer; default: sys.stdin
131
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000132 environ : environment dictionary; default: os.environ
Guido van Rossum773ab271996-07-23 03:46:24 +0000133
134 keep_blank_values: flag indicating whether blank values in
Tim Peters88869f92001-01-14 23:36:06 +0000135 URL encoded forms should be treated as blank strings.
136 A true value indicates that blanks should be retained as
Guido van Rossum773ab271996-07-23 03:46:24 +0000137 blank strings. The default false value indicates that
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000138 blank values are to be ignored and treated as if they were
139 not included.
Guido van Rossume08c04c1996-11-11 19:29:11 +0000140
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000141 strict_parsing: flag indicating what to do with parsing errors.
142 If false (the default), errors are silently ignored.
143 If true, errors raise a ValueError exception.
Guido van Rossum773ab271996-07-23 03:46:24 +0000144 """
Raymond Hettingera1449002002-05-31 23:54:44 +0000145 if fp is None:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000146 fp = sys.stdin
Raymond Hettinger54f02222002-06-01 14:18:47 +0000147 if not 'REQUEST_METHOD' in environ:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000148 environ['REQUEST_METHOD'] = 'GET' # For testing stand-alone
Guido van Rossum7aee3841996-03-07 18:00:44 +0000149 if environ['REQUEST_METHOD'] == 'POST':
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000150 ctype, pdict = parse_header(environ['CONTENT_TYPE'])
151 if ctype == 'multipart/form-data':
152 return parse_multipart(fp, pdict)
153 elif ctype == 'application/x-www-form-urlencoded':
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000154 clength = int(environ['CONTENT_LENGTH'])
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000155 if maxlen and clength > maxlen:
156 raise ValueError, 'Maximum content length exceeded'
157 qs = fp.read(clength)
158 else:
159 qs = '' # Unknown content-type
Raymond Hettinger54f02222002-06-01 14:18:47 +0000160 if 'QUERY_STRING' in environ:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000161 if qs: qs = qs + '&'
162 qs = qs + environ['QUERY_STRING']
Tim Peters88869f92001-01-14 23:36:06 +0000163 elif sys.argv[1:]:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000164 if qs: qs = qs + '&'
165 qs = qs + sys.argv[1]
166 environ['QUERY_STRING'] = qs # XXX Shouldn't, really
Raymond Hettinger54f02222002-06-01 14:18:47 +0000167 elif 'QUERY_STRING' in environ:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000168 qs = environ['QUERY_STRING']
Guido van Rossum7aee3841996-03-07 18:00:44 +0000169 else:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000170 if sys.argv[1:]:
171 qs = sys.argv[1]
172 else:
173 qs = ""
174 environ['QUERY_STRING'] = qs # XXX Shouldn't, really
Guido van Rossume08c04c1996-11-11 19:29:11 +0000175 return parse_qs(qs, keep_blank_values, strict_parsing)
Guido van Rossume7808771995-08-07 20:12:09 +0000176
177
Facundo Batistac585df92008-09-03 22:35:50 +0000178# parse query string function called from urlparse,
179# this is done in order to maintain backward compatiblity.
180
Guido van Rossume08c04c1996-11-11 19:29:11 +0000181def parse_qs(qs, keep_blank_values=0, strict_parsing=0):
Facundo Batistac585df92008-09-03 22:35:50 +0000182 """Parse a query given as a string argument."""
183 warn("cgi.parse_qs is deprecated, use urlparse.parse_qs \
184 instead",PendingDeprecationWarning)
185 return urlparse.parse_qs(qs, keep_blank_values, strict_parsing)
Guido van Rossum773ab271996-07-23 03:46:24 +0000186
Guido van Rossum1946f0d1999-06-04 17:54:39 +0000187
188def parse_qsl(qs, keep_blank_values=0, strict_parsing=0):
Facundo Batistac585df92008-09-03 22:35:50 +0000189 """Parse a query given as a string argument."""
190 warn("cgi.parse_qsl is deprecated, use urlparse.parse_qsl instead",
191 PendingDeprecationWarning)
Facundo Batistaace0bcf2008-09-08 00:20:28 +0000192 return urlparse.parse_qsl(qs, keep_blank_values, strict_parsing)
Guido van Rossum9a22de11995-01-12 12:29:47 +0000193
Guido van Rossum0147db01996-03-09 03:16:04 +0000194def parse_multipart(fp, pdict):
Guido van Rossum7aee3841996-03-07 18:00:44 +0000195 """Parse multipart input.
Guido van Rossum9a22de11995-01-12 12:29:47 +0000196
Guido van Rossum7aee3841996-03-07 18:00:44 +0000197 Arguments:
198 fp : input file
Johannes Gijsbersc7fc10a2005-01-08 13:56:36 +0000199 pdict: dictionary containing other parameters of content-type header
Guido van Rossum72755611996-03-06 07:20:06 +0000200
Tim Peters88869f92001-01-14 23:36:06 +0000201 Returns a dictionary just like parse_qs(): keys are the field names, each
202 value is a list of values for that field. This is easy to use but not
203 much good if you are expecting megabytes to be uploaded -- in that case,
204 use the FieldStorage class instead which is much more flexible. Note
205 that content-type is the raw, unparsed contents of the content-type
Guido van Rossum0147db01996-03-09 03:16:04 +0000206 header.
Tim Peters88869f92001-01-14 23:36:06 +0000207
208 XXX This does not parse nested multipart parts -- use FieldStorage for
Guido van Rossum0147db01996-03-09 03:16:04 +0000209 that.
Tim Peters88869f92001-01-14 23:36:06 +0000210
211 XXX This should really be subsumed by FieldStorage altogether -- no
Guido van Rossum0147db01996-03-09 03:16:04 +0000212 point in having two implementations of the same parsing algorithm.
Guido van Rossum9568b732006-08-10 17:41:07 +0000213 Also, FieldStorage protects itself better against certain DoS attacks
214 by limiting the size of the data read in one chunk. The API here
215 does not support that kind of protection. This also affects parse()
216 since it can call parse_multipart().
Guido van Rossum72755611996-03-06 07:20:06 +0000217
Guido van Rossum7aee3841996-03-07 18:00:44 +0000218 """
Guido van Rossum2e441f72001-07-25 21:00:19 +0000219 boundary = ""
Raymond Hettinger54f02222002-06-01 14:18:47 +0000220 if 'boundary' in pdict:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000221 boundary = pdict['boundary']
Guido van Rossum2e441f72001-07-25 21:00:19 +0000222 if not valid_boundary(boundary):
Walter Dörwald70a6b492004-02-12 17:35:32 +0000223 raise ValueError, ('Invalid boundary in multipart form: %r'
224 % (boundary,))
Tim Petersab9ba272001-08-09 21:40:30 +0000225
Guido van Rossum7aee3841996-03-07 18:00:44 +0000226 nextpart = "--" + boundary
227 lastpart = "--" + boundary + "--"
228 partdict = {}
229 terminator = ""
230
231 while terminator != lastpart:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000232 bytes = -1
233 data = None
234 if terminator:
235 # At start of next part. Read headers first.
Armin Rigo3a703b62005-09-19 09:11:04 +0000236 headers = mimetools.Message(fp)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000237 clength = headers.getheader('content-length')
238 if clength:
239 try:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000240 bytes = int(clength)
241 except ValueError:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000242 pass
243 if bytes > 0:
244 if maxlen and bytes > maxlen:
245 raise ValueError, 'Maximum content length exceeded'
246 data = fp.read(bytes)
247 else:
248 data = ""
249 # Read lines until end of part.
250 lines = []
251 while 1:
252 line = fp.readline()
253 if not line:
254 terminator = lastpart # End outer loop
255 break
256 if line[:2] == "--":
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000257 terminator = line.strip()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000258 if terminator in (nextpart, lastpart):
259 break
260 lines.append(line)
261 # Done with part.
262 if data is None:
263 continue
264 if bytes < 0:
265 if lines:
266 # Strip final line terminator
267 line = lines[-1]
268 if line[-2:] == "\r\n":
269 line = line[:-2]
270 elif line[-1:] == "\n":
271 line = line[:-1]
272 lines[-1] = line
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000273 data = "".join(lines)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000274 line = headers['content-disposition']
275 if not line:
276 continue
277 key, params = parse_header(line)
278 if key != 'form-data':
279 continue
Raymond Hettinger54f02222002-06-01 14:18:47 +0000280 if 'name' in params:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000281 name = params['name']
282 else:
283 continue
Raymond Hettinger54f02222002-06-01 14:18:47 +0000284 if name in partdict:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000285 partdict[name].append(data)
286 else:
287 partdict[name] = [data]
Guido van Rossum72755611996-03-06 07:20:06 +0000288
Guido van Rossum7aee3841996-03-07 18:00:44 +0000289 return partdict
Guido van Rossum9a22de11995-01-12 12:29:47 +0000290
291
Guido van Rossum72755611996-03-06 07:20:06 +0000292def parse_header(line):
Guido van Rossum7aee3841996-03-07 18:00:44 +0000293 """Parse a Content-type like header.
294
295 Return the main content-type and a dictionary of options.
296
297 """
Raymond Hettingerf871d832004-12-31 21:59:02 +0000298 plist = [x.strip() for x in line.split(';')]
Raymond Hettinger46ac8eb2002-06-30 03:39:14 +0000299 key = plist.pop(0).lower()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000300 pdict = {}
301 for p in plist:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000302 i = p.find('=')
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000303 if i >= 0:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000304 name = p[:i].strip().lower()
305 value = p[i+1:].strip()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000306 if len(value) >= 2 and value[0] == value[-1] == '"':
307 value = value[1:-1]
Johannes Gijsbers9e15dd62004-08-14 15:39:34 +0000308 value = value.replace('\\\\', '\\').replace('\\"', '"')
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000309 pdict[name] = value
Guido van Rossum7aee3841996-03-07 18:00:44 +0000310 return key, pdict
Guido van Rossum72755611996-03-06 07:20:06 +0000311
312
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000313# Classes for field storage
314# =========================
315
316class MiniFieldStorage:
317
Guido van Rossum0147db01996-03-09 03:16:04 +0000318 """Like FieldStorage, for use when no file uploads are possible."""
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000319
Guido van Rossum7aee3841996-03-07 18:00:44 +0000320 # Dummy attributes
321 filename = None
322 list = None
323 type = None
Guido van Rossum773ab271996-07-23 03:46:24 +0000324 file = None
Guido van Rossum4032c2c1996-03-09 04:04:35 +0000325 type_options = {}
Guido van Rossum7aee3841996-03-07 18:00:44 +0000326 disposition = None
327 disposition_options = {}
328 headers = {}
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000329
Guido van Rossum7aee3841996-03-07 18:00:44 +0000330 def __init__(self, name, value):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000331 """Constructor from field name and value."""
332 self.name = name
333 self.value = value
Guido van Rossum773ab271996-07-23 03:46:24 +0000334 # self.file = StringIO(value)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000335
336 def __repr__(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000337 """Return printable representation."""
Walter Dörwald70a6b492004-02-12 17:35:32 +0000338 return "MiniFieldStorage(%r, %r)" % (self.name, self.value)
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000339
340
341class FieldStorage:
342
Guido van Rossum7aee3841996-03-07 18:00:44 +0000343 """Store a sequence of fields, reading multipart/form-data.
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000344
Guido van Rossum7aee3841996-03-07 18:00:44 +0000345 This class provides naming, typing, files stored on disk, and
346 more. At the top level, it is accessible like a dictionary, whose
347 keys are the field names. (Note: None can occur as a field name.)
348 The items are either a Python list (if there's multiple values) or
349 another FieldStorage or MiniFieldStorage object. If it's a single
350 object, it has the following attributes:
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000351
Guido van Rossum7aee3841996-03-07 18:00:44 +0000352 name: the field name, if specified; otherwise None
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000353
Guido van Rossum7aee3841996-03-07 18:00:44 +0000354 filename: the filename, if specified; otherwise None; this is the
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000355 client side filename, *not* the file name on which it is
356 stored (that's a temporary file you don't deal with)
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000357
Guido van Rossum7aee3841996-03-07 18:00:44 +0000358 value: the value as a *string*; for file uploads, this
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000359 transparently reads the file every time you request the value
Guido van Rossum7aee3841996-03-07 18:00:44 +0000360
361 file: the file(-like) object from which you can read the data;
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000362 None if the data is stored a simple string
Guido van Rossum7aee3841996-03-07 18:00:44 +0000363
364 type: the content-type, or None if not specified
365
366 type_options: dictionary of options specified on the content-type
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000367 line
Guido van Rossum7aee3841996-03-07 18:00:44 +0000368
369 disposition: content-disposition, or None if not specified
370
371 disposition_options: dictionary of corresponding options
372
Armin Rigo3a703b62005-09-19 09:11:04 +0000373 headers: a dictionary(-like) object (sometimes rfc822.Message or a
374 subclass thereof) containing *all* headers
Guido van Rossum7aee3841996-03-07 18:00:44 +0000375
376 The class is subclassable, mostly for the purpose of overriding
377 the make_file() method, which is called internally to come up with
378 a file open for reading and writing. This makes it possible to
379 override the default choice of storing all files in a temporary
380 directory and unlinking them as soon as they have been opened.
381
382 """
383
Guido van Rossum773ab271996-07-23 03:46:24 +0000384 def __init__(self, fp=None, headers=None, outerboundary="",
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000385 environ=os.environ, keep_blank_values=0, strict_parsing=0):
386 """Constructor. Read multipart/* until last part.
Guido van Rossum7aee3841996-03-07 18:00:44 +0000387
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000388 Arguments, all optional:
Guido van Rossum7aee3841996-03-07 18:00:44 +0000389
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000390 fp : file pointer; default: sys.stdin
Guido van Rossumb1b4f941998-05-08 19:55:51 +0000391 (not used when the request method is GET)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000392
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000393 headers : header dictionary-like object; default:
394 taken from environ as per CGI spec
Guido van Rossum7aee3841996-03-07 18:00:44 +0000395
Guido van Rossum773ab271996-07-23 03:46:24 +0000396 outerboundary : terminating multipart boundary
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000397 (for internal use only)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000398
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000399 environ : environment dictionary; default: os.environ
Guido van Rossum773ab271996-07-23 03:46:24 +0000400
401 keep_blank_values: flag indicating whether blank values in
Tim Peters88869f92001-01-14 23:36:06 +0000402 URL encoded forms should be treated as blank strings.
403 A true value indicates that blanks should be retained as
Guido van Rossum773ab271996-07-23 03:46:24 +0000404 blank strings. The default false value indicates that
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000405 blank values are to be ignored and treated as if they were
406 not included.
Guido van Rossum773ab271996-07-23 03:46:24 +0000407
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000408 strict_parsing: flag indicating what to do with parsing errors.
409 If false (the default), errors are silently ignored.
410 If true, errors raise a ValueError exception.
Guido van Rossume08c04c1996-11-11 19:29:11 +0000411
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000412 """
413 method = 'GET'
414 self.keep_blank_values = keep_blank_values
415 self.strict_parsing = strict_parsing
Raymond Hettinger54f02222002-06-01 14:18:47 +0000416 if 'REQUEST_METHOD' in environ:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000417 method = environ['REQUEST_METHOD'].upper()
Facundo Batistaa6a4d502008-06-21 18:58:04 +0000418 self.qs_on_post = None
Guido van Rossum01852831998-06-25 02:40:17 +0000419 if method == 'GET' or method == 'HEAD':
Raymond Hettinger54f02222002-06-01 14:18:47 +0000420 if 'QUERY_STRING' in environ:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000421 qs = environ['QUERY_STRING']
422 elif sys.argv[1:]:
423 qs = sys.argv[1]
424 else:
425 qs = ""
426 fp = StringIO(qs)
427 if headers is None:
428 headers = {'content-type':
429 "application/x-www-form-urlencoded"}
430 if headers is None:
Guido van Rossumcff311a1998-06-11 14:06:59 +0000431 headers = {}
432 if method == 'POST':
433 # Set default content-type for POST to what's traditional
434 headers['content-type'] = "application/x-www-form-urlencoded"
Raymond Hettinger54f02222002-06-01 14:18:47 +0000435 if 'CONTENT_TYPE' in environ:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000436 headers['content-type'] = environ['CONTENT_TYPE']
Facundo Batistaa6a4d502008-06-21 18:58:04 +0000437 if 'QUERY_STRING' in environ:
438 self.qs_on_post = environ['QUERY_STRING']
Raymond Hettinger54f02222002-06-01 14:18:47 +0000439 if 'CONTENT_LENGTH' in environ:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000440 headers['content-length'] = environ['CONTENT_LENGTH']
441 self.fp = fp or sys.stdin
442 self.headers = headers
443 self.outerboundary = outerboundary
Guido van Rossum7aee3841996-03-07 18:00:44 +0000444
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000445 # Process content-disposition header
446 cdisp, pdict = "", {}
Raymond Hettinger54f02222002-06-01 14:18:47 +0000447 if 'content-disposition' in self.headers:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000448 cdisp, pdict = parse_header(self.headers['content-disposition'])
449 self.disposition = cdisp
450 self.disposition_options = pdict
451 self.name = None
Raymond Hettinger54f02222002-06-01 14:18:47 +0000452 if 'name' in pdict:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000453 self.name = pdict['name']
454 self.filename = None
Raymond Hettinger54f02222002-06-01 14:18:47 +0000455 if 'filename' in pdict:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000456 self.filename = pdict['filename']
Guido van Rossum7aee3841996-03-07 18:00:44 +0000457
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000458 # Process content-type header
Barry Warsaw302331a1999-01-08 17:42:03 +0000459 #
460 # Honor any existing content-type header. But if there is no
461 # content-type header, use some sensible defaults. Assume
462 # outerboundary is "" at the outer level, but something non-false
463 # inside a multi-part. The default for an inner part is text/plain,
464 # but for an outer part it should be urlencoded. This should catch
465 # bogus clients which erroneously forget to include a content-type
466 # header.
467 #
468 # See below for what we do if there does exist a content-type header,
469 # but it happens to be something we don't understand.
Raymond Hettinger54f02222002-06-01 14:18:47 +0000470 if 'content-type' in self.headers:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000471 ctype, pdict = parse_header(self.headers['content-type'])
Guido van Rossumce900de1999-06-02 18:44:22 +0000472 elif self.outerboundary or method != 'POST':
Barry Warsaw302331a1999-01-08 17:42:03 +0000473 ctype, pdict = "text/plain", {}
474 else:
475 ctype, pdict = 'application/x-www-form-urlencoded', {}
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000476 self.type = ctype
477 self.type_options = pdict
478 self.innerboundary = ""
Raymond Hettinger54f02222002-06-01 14:18:47 +0000479 if 'boundary' in pdict:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000480 self.innerboundary = pdict['boundary']
481 clen = -1
Raymond Hettinger54f02222002-06-01 14:18:47 +0000482 if 'content-length' in self.headers:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000483 try:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000484 clen = int(self.headers['content-length'])
Skip Montanarodb5d1442002-03-23 05:50:17 +0000485 except ValueError:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000486 pass
487 if maxlen and clen > maxlen:
488 raise ValueError, 'Maximum content length exceeded'
489 self.length = clen
Guido van Rossum7aee3841996-03-07 18:00:44 +0000490
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000491 self.list = self.file = None
492 self.done = 0
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000493 if ctype == 'application/x-www-form-urlencoded':
494 self.read_urlencoded()
495 elif ctype[:10] == 'multipart/':
Guido van Rossumf5745001998-10-20 14:43:02 +0000496 self.read_multi(environ, keep_blank_values, strict_parsing)
Barry Warsaw302331a1999-01-08 17:42:03 +0000497 else:
Guido van Rossum60a3bd81999-06-11 18:26:09 +0000498 self.read_single()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000499
500 def __repr__(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000501 """Return a printable representation."""
Walter Dörwald70a6b492004-02-12 17:35:32 +0000502 return "FieldStorage(%r, %r, %r)" % (
503 self.name, self.filename, self.value)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000504
Guido van Rossum4061cbe2002-09-11 18:20:34 +0000505 def __iter__(self):
506 return iter(self.keys())
507
Guido van Rossum7aee3841996-03-07 18:00:44 +0000508 def __getattr__(self, name):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000509 if name != 'value':
510 raise AttributeError, name
511 if self.file:
512 self.file.seek(0)
513 value = self.file.read()
514 self.file.seek(0)
515 elif self.list is not None:
516 value = self.list
517 else:
518 value = None
519 return value
Guido van Rossum7aee3841996-03-07 18:00:44 +0000520
521 def __getitem__(self, key):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000522 """Dictionary style indexing."""
523 if self.list is None:
524 raise TypeError, "not indexable"
525 found = []
526 for item in self.list:
527 if item.name == key: found.append(item)
528 if not found:
529 raise KeyError, key
530 if len(found) == 1:
531 return found[0]
532 else:
533 return found
Guido van Rossum7aee3841996-03-07 18:00:44 +0000534
Moshe Zadkaa1a4b592000-08-25 21:47:56 +0000535 def getvalue(self, key, default=None):
536 """Dictionary style get() method, including 'value' lookup."""
Raymond Hettinger54f02222002-06-01 14:18:47 +0000537 if key in self:
Moshe Zadkaa1a4b592000-08-25 21:47:56 +0000538 value = self[key]
539 if type(value) is type([]):
Raymond Hettingerf871d832004-12-31 21:59:02 +0000540 return map(attrgetter('value'), value)
Moshe Zadkaa1a4b592000-08-25 21:47:56 +0000541 else:
542 return value.value
543 else:
544 return default
545
Guido van Rossum1bfb3882001-09-05 19:45:34 +0000546 def getfirst(self, key, default=None):
547 """ Return the first value received."""
Raymond Hettinger54f02222002-06-01 14:18:47 +0000548 if key in self:
Guido van Rossum1bfb3882001-09-05 19:45:34 +0000549 value = self[key]
550 if type(value) is type([]):
551 return value[0].value
552 else:
553 return value.value
554 else:
555 return default
556
557 def getlist(self, key):
558 """ Return list of received values."""
Raymond Hettinger54f02222002-06-01 14:18:47 +0000559 if key in self:
Guido van Rossum1bfb3882001-09-05 19:45:34 +0000560 value = self[key]
561 if type(value) is type([]):
Raymond Hettingerf871d832004-12-31 21:59:02 +0000562 return map(attrgetter('value'), value)
Guido van Rossum1bfb3882001-09-05 19:45:34 +0000563 else:
564 return [value.value]
565 else:
566 return []
567
Guido van Rossum7aee3841996-03-07 18:00:44 +0000568 def keys(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000569 """Dictionary style keys() method."""
570 if self.list is None:
571 raise TypeError, "not indexable"
Georg Brandlaff85e22007-09-20 16:06:07 +0000572 return list(set(item.name for item in self.list))
Guido van Rossum7aee3841996-03-07 18:00:44 +0000573
Guido van Rossum0147db01996-03-09 03:16:04 +0000574 def has_key(self, key):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000575 """Dictionary style has_key() method."""
576 if self.list is None:
577 raise TypeError, "not indexable"
Georg Brandlaff85e22007-09-20 16:06:07 +0000578 return any(item.name == key for item in self.list)
Guido van Rossum0147db01996-03-09 03:16:04 +0000579
Raymond Hettinger54f02222002-06-01 14:18:47 +0000580 def __contains__(self, key):
581 """Dictionary style __contains__ method."""
582 if self.list is None:
583 raise TypeError, "not indexable"
Georg Brandlaff85e22007-09-20 16:06:07 +0000584 return any(item.name == key for item in self.list)
Raymond Hettinger54f02222002-06-01 14:18:47 +0000585
Guido van Rossum88b85d41997-01-11 19:21:33 +0000586 def __len__(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000587 """Dictionary style len(x) support."""
588 return len(self.keys())
Guido van Rossum88b85d41997-01-11 19:21:33 +0000589
Georg Brandlaff85e22007-09-20 16:06:07 +0000590 def __nonzero__(self):
591 return bool(self.list)
592
Guido van Rossum7aee3841996-03-07 18:00:44 +0000593 def read_urlencoded(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000594 """Internal: read data in query string format."""
595 qs = self.fp.read(self.length)
Facundo Batistaa6a4d502008-06-21 18:58:04 +0000596 if self.qs_on_post:
597 qs += '&' + self.qs_on_post
Guido van Rossum1946f0d1999-06-04 17:54:39 +0000598 self.list = list = []
Facundo Batistac585df92008-09-03 22:35:50 +0000599 for key, value in urlparse.parse_qsl(qs, self.keep_blank_values,
600 self.strict_parsing):
Guido van Rossum1946f0d1999-06-04 17:54:39 +0000601 list.append(MiniFieldStorage(key, value))
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000602 self.skip_lines()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000603
Guido van Rossum030d2ec1998-12-09 22:16:46 +0000604 FieldStorageClass = None
605
Guido van Rossumf5745001998-10-20 14:43:02 +0000606 def read_multi(self, environ, keep_blank_values, strict_parsing):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000607 """Internal: read a part that is itself multipart."""
Guido van Rossum2e441f72001-07-25 21:00:19 +0000608 ib = self.innerboundary
609 if not valid_boundary(ib):
Walter Dörwald70a6b492004-02-12 17:35:32 +0000610 raise ValueError, 'Invalid boundary in multipart form: %r' % (ib,)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000611 self.list = []
Facundo Batistaa6a4d502008-06-21 18:58:04 +0000612 if self.qs_on_post:
Facundo Batistac585df92008-09-03 22:35:50 +0000613 for key, value in urlparse.parse_qsl(self.qs_on_post,
614 self.keep_blank_values, self.strict_parsing):
Facundo Batistaa6a4d502008-06-21 18:58:04 +0000615 self.list.append(MiniFieldStorage(key, value))
616 FieldStorageClass = None
617
Guido van Rossum030d2ec1998-12-09 22:16:46 +0000618 klass = self.FieldStorageClass or self.__class__
Guido van Rossum2e441f72001-07-25 21:00:19 +0000619 part = klass(self.fp, {}, ib,
Guido van Rossum030d2ec1998-12-09 22:16:46 +0000620 environ, keep_blank_values, strict_parsing)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000621 # Throw first part away
622 while not part.done:
Armin Rigo3a703b62005-09-19 09:11:04 +0000623 headers = rfc822.Message(self.fp)
Guido van Rossum2e441f72001-07-25 21:00:19 +0000624 part = klass(self.fp, headers, ib,
Guido van Rossum030d2ec1998-12-09 22:16:46 +0000625 environ, keep_blank_values, strict_parsing)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000626 self.list.append(part)
627 self.skip_lines()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000628
629 def read_single(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000630 """Internal: read an atomic part."""
631 if self.length >= 0:
632 self.read_binary()
633 self.skip_lines()
634 else:
635 self.read_lines()
636 self.file.seek(0)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000637
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000638 bufsize = 8*1024 # I/O buffering size for copy to file
Guido van Rossum7aee3841996-03-07 18:00:44 +0000639
640 def read_binary(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000641 """Internal: read binary data."""
642 self.file = self.make_file('b')
643 todo = self.length
644 if todo >= 0:
645 while todo > 0:
646 data = self.fp.read(min(todo, self.bufsize))
647 if not data:
648 self.done = -1
649 break
650 self.file.write(data)
651 todo = todo - len(data)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000652
653 def read_lines(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000654 """Internal: read lines until EOF or outerboundary."""
Guido van Rossum52b8c292001-06-29 13:06:06 +0000655 self.file = self.__file = StringIO()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000656 if self.outerboundary:
657 self.read_lines_to_outerboundary()
658 else:
659 self.read_lines_to_eof()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000660
Guido van Rossum52b8c292001-06-29 13:06:06 +0000661 def __write(self, line):
662 if self.__file is not None:
663 if self.__file.tell() + len(line) > 1000:
664 self.file = self.make_file('')
665 self.file.write(self.__file.getvalue())
666 self.__file = None
667 self.file.write(line)
668
Guido van Rossum7aee3841996-03-07 18:00:44 +0000669 def read_lines_to_eof(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000670 """Internal: read lines until EOF."""
671 while 1:
Guido van Rossum9568b732006-08-10 17:41:07 +0000672 line = self.fp.readline(1<<16)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000673 if not line:
674 self.done = -1
675 break
Guido van Rossum52b8c292001-06-29 13:06:06 +0000676 self.__write(line)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000677
678 def read_lines_to_outerboundary(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000679 """Internal: read lines until outerboundary."""
680 next = "--" + self.outerboundary
681 last = next + "--"
682 delim = ""
Guido van Rossum9568b732006-08-10 17:41:07 +0000683 last_line_lfend = True
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000684 while 1:
Guido van Rossum9568b732006-08-10 17:41:07 +0000685 line = self.fp.readline(1<<16)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000686 if not line:
687 self.done = -1
688 break
Guido van Rossum9568b732006-08-10 17:41:07 +0000689 if line[:2] == "--" and last_line_lfend:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000690 strippedline = line.strip()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000691 if strippedline == next:
692 break
693 if strippedline == last:
694 self.done = 1
695 break
696 odelim = delim
697 if line[-2:] == "\r\n":
698 delim = "\r\n"
699 line = line[:-2]
Guido van Rossum9568b732006-08-10 17:41:07 +0000700 last_line_lfend = True
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000701 elif line[-1] == "\n":
702 delim = "\n"
703 line = line[:-1]
Guido van Rossum9568b732006-08-10 17:41:07 +0000704 last_line_lfend = True
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000705 else:
706 delim = ""
Guido van Rossum9568b732006-08-10 17:41:07 +0000707 last_line_lfend = False
Guido van Rossum52b8c292001-06-29 13:06:06 +0000708 self.__write(odelim + line)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000709
710 def skip_lines(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000711 """Internal: skip lines until outer boundary if defined."""
712 if not self.outerboundary or self.done:
713 return
714 next = "--" + self.outerboundary
715 last = next + "--"
Guido van Rossum9568b732006-08-10 17:41:07 +0000716 last_line_lfend = True
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000717 while 1:
Guido van Rossum9568b732006-08-10 17:41:07 +0000718 line = self.fp.readline(1<<16)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000719 if not line:
720 self.done = -1
721 break
Guido van Rossum9568b732006-08-10 17:41:07 +0000722 if line[:2] == "--" and last_line_lfend:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000723 strippedline = line.strip()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000724 if strippedline == next:
725 break
726 if strippedline == last:
727 self.done = 1
728 break
Guido van Rossum9568b732006-08-10 17:41:07 +0000729 last_line_lfend = line.endswith('\n')
Guido van Rossum7aee3841996-03-07 18:00:44 +0000730
Guido van Rossuma5e9fb61997-08-12 18:18:13 +0000731 def make_file(self, binary=None):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000732 """Overridable: return a readable & writable file.
Guido van Rossum7aee3841996-03-07 18:00:44 +0000733
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000734 The file will be used as follows:
735 - data is written to it
736 - seek(0)
737 - data is read from it
Guido van Rossum7aee3841996-03-07 18:00:44 +0000738
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000739 The 'binary' argument is unused -- the file is always opened
740 in binary mode.
Guido van Rossum7aee3841996-03-07 18:00:44 +0000741
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000742 This version opens a temporary file for reading and writing,
743 and immediately deletes (unlinks) it. The trick (on Unix!) is
744 that the file can still be used, but it can't be opened by
745 another process, and it will automatically be deleted when it
746 is closed or when the current process terminates.
Guido van Rossum4032c2c1996-03-09 04:04:35 +0000747
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000748 If you want a more permanent file, you derive a class which
749 overrides this method. If you want a visible temporary file
750 that is nevertheless automatically deleted when the script
751 terminates, try defining a __del__ method in a derived class
752 which unlinks the temporary files you have created.
Guido van Rossum7aee3841996-03-07 18:00:44 +0000753
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000754 """
755 import tempfile
756 return tempfile.TemporaryFile("w+b")
Tim Peters88869f92001-01-14 23:36:06 +0000757
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000758
759
Guido van Rossum4032c2c1996-03-09 04:04:35 +0000760# Backwards Compatibility Classes
761# ===============================
Guido van Rossum9a22de11995-01-12 12:29:47 +0000762
Moshe Zadkaa1a4b592000-08-25 21:47:56 +0000763class FormContentDict(UserDict.UserDict):
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000764 """Form content as dictionary with a list of values per field.
Guido van Rossum72755611996-03-06 07:20:06 +0000765
Guido van Rossum7aee3841996-03-07 18:00:44 +0000766 form = FormContentDict()
767
768 form[key] -> [value, value, ...]
Raymond Hettinger54f02222002-06-01 14:18:47 +0000769 key in form -> Boolean
Guido van Rossum7aee3841996-03-07 18:00:44 +0000770 form.keys() -> [key, key, ...]
771 form.values() -> [[val, val, ...], [val, val, ...], ...]
772 form.items() -> [(key, [val, val, ...]), (key, [val, val, ...]), ...]
773 form.dict == {key: [val, val, ...], ...}
774
775 """
Georg Brandl05b3c452006-09-30 10:58:01 +0000776 def __init__(self, environ=os.environ, keep_blank_values=0, strict_parsing=0):
777 self.dict = self.data = parse(environ=environ,
778 keep_blank_values=keep_blank_values,
779 strict_parsing=strict_parsing)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000780 self.query_string = environ['QUERY_STRING']
Guido van Rossum9a22de11995-01-12 12:29:47 +0000781
782
Guido van Rossum9a22de11995-01-12 12:29:47 +0000783class SvFormContentDict(FormContentDict):
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000784 """Form content as dictionary expecting a single value per field.
Guido van Rossum7aee3841996-03-07 18:00:44 +0000785
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000786 If you only expect a single value for each field, then form[key]
Guido van Rossum7aee3841996-03-07 18:00:44 +0000787 will return that single value. It will raise an IndexError if
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000788 that expectation is not true. If you expect a field to have
Guido van Rossum7aee3841996-03-07 18:00:44 +0000789 possible multiple values, than you can use form.getlist(key) to
790 get all of the values. values() and items() are a compromise:
791 they return single strings where there is a single value, and
792 lists of strings otherwise.
793
794 """
795 def __getitem__(self, key):
Tim Peters88869f92001-01-14 23:36:06 +0000796 if len(self.dict[key]) > 1:
797 raise IndexError, 'expecting a single value'
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000798 return self.dict[key][0]
Guido van Rossum7aee3841996-03-07 18:00:44 +0000799 def getlist(self, key):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000800 return self.dict[key]
Guido van Rossum7aee3841996-03-07 18:00:44 +0000801 def values(self):
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000802 result = []
803 for value in self.dict.values():
804 if len(value) == 1:
805 result.append(value[0])
806 else: result.append(value)
807 return result
Guido van Rossum7aee3841996-03-07 18:00:44 +0000808 def items(self):
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000809 result = []
810 for key, value in self.dict.items():
811 if len(value) == 1:
812 result.append((key, value[0]))
813 else: result.append((key, value))
814 return result
Guido van Rossum9a22de11995-01-12 12:29:47 +0000815
816
Guido van Rossum9a22de11995-01-12 12:29:47 +0000817class InterpFormContentDict(SvFormContentDict):
Tim Peters88869f92001-01-14 23:36:06 +0000818 """This class is present for backwards compatibility only."""
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000819 def __getitem__(self, key):
820 v = SvFormContentDict.__getitem__(self, key)
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000821 if v[0] in '0123456789+-.':
822 try: return int(v)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000823 except ValueError:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000824 try: return float(v)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000825 except ValueError: pass
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000826 return v.strip()
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000827 def values(self):
828 result = []
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000829 for key in self.keys():
830 try:
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000831 result.append(self[key])
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000832 except IndexError:
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000833 result.append(self.dict[key])
834 return result
835 def items(self):
836 result = []
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000837 for key in self.keys():
838 try:
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000839 result.append((key, self[key]))
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000840 except IndexError:
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000841 result.append((key, self.dict[key]))
842 return result
Guido van Rossum9a22de11995-01-12 12:29:47 +0000843
844
Guido van Rossum9a22de11995-01-12 12:29:47 +0000845class FormContent(FormContentDict):
Tim Peters88869f92001-01-14 23:36:06 +0000846 """This class is present for backwards compatibility only."""
Guido van Rossum0147db01996-03-09 03:16:04 +0000847 def values(self, key):
Raymond Hettinger54f02222002-06-01 14:18:47 +0000848 if key in self.dict :return self.dict[key]
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000849 else: return None
Guido van Rossum0147db01996-03-09 03:16:04 +0000850 def indexed_value(self, key, location):
Raymond Hettinger54f02222002-06-01 14:18:47 +0000851 if key in self.dict:
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000852 if len(self.dict[key]) > location:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000853 return self.dict[key][location]
854 else: return None
855 else: return None
Guido van Rossum0147db01996-03-09 03:16:04 +0000856 def value(self, key):
Raymond Hettinger54f02222002-06-01 14:18:47 +0000857 if key in self.dict: return self.dict[key][0]
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000858 else: return None
Guido van Rossum0147db01996-03-09 03:16:04 +0000859 def length(self, key):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000860 return len(self.dict[key])
Guido van Rossum0147db01996-03-09 03:16:04 +0000861 def stripped(self, key):
Raymond Hettinger54f02222002-06-01 14:18:47 +0000862 if key in self.dict: return self.dict[key][0].strip()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000863 else: return None
Guido van Rossum7aee3841996-03-07 18:00:44 +0000864 def pars(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000865 return self.dict
Guido van Rossum9a22de11995-01-12 12:29:47 +0000866
867
Guido van Rossum72755611996-03-06 07:20:06 +0000868# Test/debug code
869# ===============
Guido van Rossum9a22de11995-01-12 12:29:47 +0000870
Guido van Rossum773ab271996-07-23 03:46:24 +0000871def test(environ=os.environ):
Guido van Rossum7aee3841996-03-07 18:00:44 +0000872 """Robust test CGI script, usable as main program.
Guido van Rossum9a22de11995-01-12 12:29:47 +0000873
Guido van Rossum7aee3841996-03-07 18:00:44 +0000874 Write minimal HTTP headers and dump all information provided to
875 the script in HTML form.
876
877 """
Guido van Rossum7aee3841996-03-07 18:00:44 +0000878 print "Content-type: text/html"
879 print
880 sys.stderr = sys.stdout
881 try:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000882 form = FieldStorage() # Replace with other classes to test those
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000883 print_directory()
884 print_arguments()
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000885 print_form(form)
886 print_environ(environ)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000887 print_environ_usage()
888 def f():
889 exec "testing print_exception() -- <I>italics?</I>"
890 def g(f=f):
891 f()
892 print "<H3>What follows is a test, not an actual exception:</H3>"
893 g()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000894 except:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000895 print_exception()
Guido van Rossumf85de8a1996-08-20 20:22:39 +0000896
Guido van Rossum57d51f22000-09-16 21:16:01 +0000897 print "<H1>Second try with a small maxlen...</H1>"
898
Guido van Rossumad164711997-05-13 19:03:23 +0000899 global maxlen
900 maxlen = 50
901 try:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000902 form = FieldStorage() # Replace with other classes to test those
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000903 print_directory()
904 print_arguments()
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000905 print_form(form)
906 print_environ(environ)
Guido van Rossumad164711997-05-13 19:03:23 +0000907 except:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000908 print_exception()
Guido van Rossumad164711997-05-13 19:03:23 +0000909
Guido van Rossumf85de8a1996-08-20 20:22:39 +0000910def print_exception(type=None, value=None, tb=None, limit=None):
911 if type is None:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000912 type, value, tb = sys.exc_info()
Guido van Rossumf85de8a1996-08-20 20:22:39 +0000913 import traceback
914 print
Guido van Rossum7dd06962000-12-27 19:12:58 +0000915 print "<H3>Traceback (most recent call last):</H3>"
Guido van Rossumf85de8a1996-08-20 20:22:39 +0000916 list = traceback.format_tb(tb, limit) + \
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000917 traceback.format_exception_only(type, value)
Guido van Rossumf85de8a1996-08-20 20:22:39 +0000918 print "<PRE>%s<B>%s</B></PRE>" % (
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000919 escape("".join(list[:-1])),
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000920 escape(list[-1]),
921 )
Guido van Rossumf15d1591997-09-29 23:22:12 +0000922 del tb
Guido van Rossum9a22de11995-01-12 12:29:47 +0000923
Guido van Rossum773ab271996-07-23 03:46:24 +0000924def print_environ(environ=os.environ):
Guido van Rossum7aee3841996-03-07 18:00:44 +0000925 """Dump the shell environment as HTML."""
926 keys = environ.keys()
927 keys.sort()
928 print
Guido van Rossum503e50b1996-05-28 22:57:20 +0000929 print "<H3>Shell Environment:</H3>"
Guido van Rossum7aee3841996-03-07 18:00:44 +0000930 print "<DL>"
931 for key in keys:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000932 print "<DT>", escape(key), "<DD>", escape(environ[key])
Tim Peters88869f92001-01-14 23:36:06 +0000933 print "</DL>"
Guido van Rossum7aee3841996-03-07 18:00:44 +0000934 print
Guido van Rossum72755611996-03-06 07:20:06 +0000935
936def print_form(form):
Guido van Rossum7aee3841996-03-07 18:00:44 +0000937 """Dump the contents of a form as HTML."""
938 keys = form.keys()
939 keys.sort()
940 print
Guido van Rossum503e50b1996-05-28 22:57:20 +0000941 print "<H3>Form Contents:</H3>"
Guido van Rossum57d51f22000-09-16 21:16:01 +0000942 if not keys:
943 print "<P>No form fields."
Guido van Rossum7aee3841996-03-07 18:00:44 +0000944 print "<DL>"
945 for key in keys:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000946 print "<DT>" + escape(key) + ":",
947 value = form[key]
Walter Dörwald70a6b492004-02-12 17:35:32 +0000948 print "<i>" + escape(repr(type(value))) + "</i>"
949 print "<DD>" + escape(repr(value))
Guido van Rossum7aee3841996-03-07 18:00:44 +0000950 print "</DL>"
951 print
952
953def print_directory():
954 """Dump the current directory as HTML."""
955 print
956 print "<H3>Current Working Directory:</H3>"
957 try:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000958 pwd = os.getcwd()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000959 except os.error, msg:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000960 print "os.error:", escape(str(msg))
Guido van Rossum7aee3841996-03-07 18:00:44 +0000961 else:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000962 print escape(pwd)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000963 print
Guido van Rossum9a22de11995-01-12 12:29:47 +0000964
Guido van Rossuma8738a51996-03-14 21:30:28 +0000965def print_arguments():
966 print
Guido van Rossum503e50b1996-05-28 22:57:20 +0000967 print "<H3>Command Line Arguments:</H3>"
Guido van Rossuma8738a51996-03-14 21:30:28 +0000968 print
969 print sys.argv
970 print
971
Guido van Rossum9a22de11995-01-12 12:29:47 +0000972def print_environ_usage():
Guido van Rossum7aee3841996-03-07 18:00:44 +0000973 """Dump a list of environment variables used by CGI as HTML."""
974 print """
Guido van Rossum72755611996-03-06 07:20:06 +0000975<H3>These environment variables could have been set:</H3>
976<UL>
Guido van Rossum9a22de11995-01-12 12:29:47 +0000977<LI>AUTH_TYPE
978<LI>CONTENT_LENGTH
979<LI>CONTENT_TYPE
980<LI>DATE_GMT
981<LI>DATE_LOCAL
982<LI>DOCUMENT_NAME
983<LI>DOCUMENT_ROOT
984<LI>DOCUMENT_URI
985<LI>GATEWAY_INTERFACE
986<LI>LAST_MODIFIED
987<LI>PATH
988<LI>PATH_INFO
989<LI>PATH_TRANSLATED
990<LI>QUERY_STRING
991<LI>REMOTE_ADDR
992<LI>REMOTE_HOST
993<LI>REMOTE_IDENT
994<LI>REMOTE_USER
995<LI>REQUEST_METHOD
996<LI>SCRIPT_NAME
997<LI>SERVER_NAME
998<LI>SERVER_PORT
999<LI>SERVER_PROTOCOL
1000<LI>SERVER_ROOT
1001<LI>SERVER_SOFTWARE
1002</UL>
Guido van Rossum7aee3841996-03-07 18:00:44 +00001003In addition, HTTP headers sent by the server may be passed in the
1004environment as well. Here are some common variable names:
1005<UL>
1006<LI>HTTP_ACCEPT
1007<LI>HTTP_CONNECTION
1008<LI>HTTP_HOST
1009<LI>HTTP_PRAGMA
1010<LI>HTTP_REFERER
1011<LI>HTTP_USER_AGENT
1012</UL>
Guido van Rossum9a22de11995-01-12 12:29:47 +00001013"""
1014
Guido van Rossum9a22de11995-01-12 12:29:47 +00001015
Guido van Rossum72755611996-03-06 07:20:06 +00001016# Utilities
1017# =========
Guido van Rossum9a22de11995-01-12 12:29:47 +00001018
Guido van Rossum64c66201997-07-19 20:11:53 +00001019def escape(s, quote=None):
Skip Montanaro97b2fa22005-08-02 02:50:25 +00001020 '''Replace special characters "&", "<" and ">" to HTML-safe sequences.
1021 If the optional flag quote is true, the quotation mark character (")
1022 is also translated.'''
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +00001023 s = s.replace("&", "&amp;") # Must be done first!
1024 s = s.replace("<", "&lt;")
1025 s = s.replace(">", "&gt;")
Guido van Rossum64c66201997-07-19 20:11:53 +00001026 if quote:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +00001027 s = s.replace('"', "&quot;")
Guido van Rossum7aee3841996-03-07 18:00:44 +00001028 return s
Guido van Rossum9a22de11995-01-12 12:29:47 +00001029
Guido van Rossum2e441f72001-07-25 21:00:19 +00001030def valid_boundary(s, _vb_pattern="^[ -~]{0,200}[!-~]$"):
1031 import re
1032 return re.match(_vb_pattern, s)
Guido van Rossum9a22de11995-01-12 12:29:47 +00001033
Guido van Rossum72755611996-03-06 07:20:06 +00001034# Invoke mainline
1035# ===============
1036
1037# Call test() when this file is run as a script (not imported as a module)
Tim Peters88869f92001-01-14 23:36:06 +00001038if __name__ == '__main__':
Guido van Rossum7aee3841996-03-07 18:00:44 +00001039 test()