blob: fd303830cd7cfd6141c78b55a2ce7e1d24eb40dc [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 \
Philip Jenveyd846f1d2009-05-08 02:28:39 +0000184 instead", PendingDeprecationWarning, 2)
Facundo Batistac585df92008-09-03 22:35:50 +0000185 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",
Philip Jenveyd846f1d2009-05-08 02:28:39 +0000191 PendingDeprecationWarning, 2)
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
Fred Drake52481032008-12-04 18:25:17 +0000292def _parseparam(s):
293 while s[:1] == ';':
294 s = s[1:]
295 end = s.find(';')
296 while end > 0 and s.count('"', 0, end) % 2:
297 end = s.find(';', end + 1)
298 if end < 0:
299 end = len(s)
300 f = s[:end]
301 yield f.strip()
302 s = s[end:]
303
Guido van Rossum72755611996-03-06 07:20:06 +0000304def parse_header(line):
Guido van Rossum7aee3841996-03-07 18:00:44 +0000305 """Parse a Content-type like header.
306
307 Return the main content-type and a dictionary of options.
308
309 """
Fred Drake52481032008-12-04 18:25:17 +0000310 parts = _parseparam(';' + line)
311 key = parts.next()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000312 pdict = {}
Fred Drake52481032008-12-04 18:25:17 +0000313 for p in parts:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000314 i = p.find('=')
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000315 if i >= 0:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000316 name = p[:i].strip().lower()
317 value = p[i+1:].strip()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000318 if len(value) >= 2 and value[0] == value[-1] == '"':
319 value = value[1:-1]
Johannes Gijsbers9e15dd62004-08-14 15:39:34 +0000320 value = value.replace('\\\\', '\\').replace('\\"', '"')
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000321 pdict[name] = value
Guido van Rossum7aee3841996-03-07 18:00:44 +0000322 return key, pdict
Guido van Rossum72755611996-03-06 07:20:06 +0000323
324
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000325# Classes for field storage
326# =========================
327
328class MiniFieldStorage:
329
Guido van Rossum0147db01996-03-09 03:16:04 +0000330 """Like FieldStorage, for use when no file uploads are possible."""
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000331
Guido van Rossum7aee3841996-03-07 18:00:44 +0000332 # Dummy attributes
333 filename = None
334 list = None
335 type = None
Guido van Rossum773ab271996-07-23 03:46:24 +0000336 file = None
Guido van Rossum4032c2c1996-03-09 04:04:35 +0000337 type_options = {}
Guido van Rossum7aee3841996-03-07 18:00:44 +0000338 disposition = None
339 disposition_options = {}
340 headers = {}
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000341
Guido van Rossum7aee3841996-03-07 18:00:44 +0000342 def __init__(self, name, value):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000343 """Constructor from field name and value."""
344 self.name = name
345 self.value = value
Guido van Rossum773ab271996-07-23 03:46:24 +0000346 # self.file = StringIO(value)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000347
348 def __repr__(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000349 """Return printable representation."""
Walter Dörwald70a6b492004-02-12 17:35:32 +0000350 return "MiniFieldStorage(%r, %r)" % (self.name, self.value)
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000351
352
353class FieldStorage:
354
Guido van Rossum7aee3841996-03-07 18:00:44 +0000355 """Store a sequence of fields, reading multipart/form-data.
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000356
Guido van Rossum7aee3841996-03-07 18:00:44 +0000357 This class provides naming, typing, files stored on disk, and
358 more. At the top level, it is accessible like a dictionary, whose
359 keys are the field names. (Note: None can occur as a field name.)
360 The items are either a Python list (if there's multiple values) or
361 another FieldStorage or MiniFieldStorage object. If it's a single
362 object, it has the following attributes:
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000363
Guido van Rossum7aee3841996-03-07 18:00:44 +0000364 name: the field name, if specified; otherwise None
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000365
Guido van Rossum7aee3841996-03-07 18:00:44 +0000366 filename: the filename, if specified; otherwise None; this is the
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000367 client side filename, *not* the file name on which it is
368 stored (that's a temporary file you don't deal with)
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000369
Guido van Rossum7aee3841996-03-07 18:00:44 +0000370 value: the value as a *string*; for file uploads, this
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000371 transparently reads the file every time you request the value
Guido van Rossum7aee3841996-03-07 18:00:44 +0000372
373 file: the file(-like) object from which you can read the data;
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000374 None if the data is stored a simple string
Guido van Rossum7aee3841996-03-07 18:00:44 +0000375
376 type: the content-type, or None if not specified
377
378 type_options: dictionary of options specified on the content-type
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000379 line
Guido van Rossum7aee3841996-03-07 18:00:44 +0000380
381 disposition: content-disposition, or None if not specified
382
383 disposition_options: dictionary of corresponding options
384
Armin Rigo3a703b62005-09-19 09:11:04 +0000385 headers: a dictionary(-like) object (sometimes rfc822.Message or a
386 subclass thereof) containing *all* headers
Guido van Rossum7aee3841996-03-07 18:00:44 +0000387
388 The class is subclassable, mostly for the purpose of overriding
389 the make_file() method, which is called internally to come up with
390 a file open for reading and writing. This makes it possible to
391 override the default choice of storing all files in a temporary
392 directory and unlinking them as soon as they have been opened.
393
394 """
395
Guido van Rossum773ab271996-07-23 03:46:24 +0000396 def __init__(self, fp=None, headers=None, outerboundary="",
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000397 environ=os.environ, keep_blank_values=0, strict_parsing=0):
398 """Constructor. Read multipart/* until last part.
Guido van Rossum7aee3841996-03-07 18:00:44 +0000399
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000400 Arguments, all optional:
Guido van Rossum7aee3841996-03-07 18:00:44 +0000401
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000402 fp : file pointer; default: sys.stdin
Guido van Rossumb1b4f941998-05-08 19:55:51 +0000403 (not used when the request method is GET)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000404
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000405 headers : header dictionary-like object; default:
406 taken from environ as per CGI spec
Guido van Rossum7aee3841996-03-07 18:00:44 +0000407
Guido van Rossum773ab271996-07-23 03:46:24 +0000408 outerboundary : terminating multipart boundary
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000409 (for internal use only)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000410
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000411 environ : environment dictionary; default: os.environ
Guido van Rossum773ab271996-07-23 03:46:24 +0000412
413 keep_blank_values: flag indicating whether blank values in
Tim Peters88869f92001-01-14 23:36:06 +0000414 URL encoded forms should be treated as blank strings.
415 A true value indicates that blanks should be retained as
Guido van Rossum773ab271996-07-23 03:46:24 +0000416 blank strings. The default false value indicates that
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000417 blank values are to be ignored and treated as if they were
418 not included.
Guido van Rossum773ab271996-07-23 03:46:24 +0000419
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000420 strict_parsing: flag indicating what to do with parsing errors.
421 If false (the default), errors are silently ignored.
422 If true, errors raise a ValueError exception.
Guido van Rossume08c04c1996-11-11 19:29:11 +0000423
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000424 """
425 method = 'GET'
426 self.keep_blank_values = keep_blank_values
427 self.strict_parsing = strict_parsing
Raymond Hettinger54f02222002-06-01 14:18:47 +0000428 if 'REQUEST_METHOD' in environ:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000429 method = environ['REQUEST_METHOD'].upper()
Facundo Batistaa6a4d502008-06-21 18:58:04 +0000430 self.qs_on_post = None
Guido van Rossum01852831998-06-25 02:40:17 +0000431 if method == 'GET' or method == 'HEAD':
Raymond Hettinger54f02222002-06-01 14:18:47 +0000432 if 'QUERY_STRING' in environ:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000433 qs = environ['QUERY_STRING']
434 elif sys.argv[1:]:
435 qs = sys.argv[1]
436 else:
437 qs = ""
438 fp = StringIO(qs)
439 if headers is None:
440 headers = {'content-type':
441 "application/x-www-form-urlencoded"}
442 if headers is None:
Guido van Rossumcff311a1998-06-11 14:06:59 +0000443 headers = {}
444 if method == 'POST':
445 # Set default content-type for POST to what's traditional
446 headers['content-type'] = "application/x-www-form-urlencoded"
Raymond Hettinger54f02222002-06-01 14:18:47 +0000447 if 'CONTENT_TYPE' in environ:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000448 headers['content-type'] = environ['CONTENT_TYPE']
Facundo Batistaa6a4d502008-06-21 18:58:04 +0000449 if 'QUERY_STRING' in environ:
450 self.qs_on_post = environ['QUERY_STRING']
Raymond Hettinger54f02222002-06-01 14:18:47 +0000451 if 'CONTENT_LENGTH' in environ:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000452 headers['content-length'] = environ['CONTENT_LENGTH']
453 self.fp = fp or sys.stdin
454 self.headers = headers
455 self.outerboundary = outerboundary
Guido van Rossum7aee3841996-03-07 18:00:44 +0000456
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000457 # Process content-disposition header
458 cdisp, pdict = "", {}
Raymond Hettinger54f02222002-06-01 14:18:47 +0000459 if 'content-disposition' in self.headers:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000460 cdisp, pdict = parse_header(self.headers['content-disposition'])
461 self.disposition = cdisp
462 self.disposition_options = pdict
463 self.name = None
Raymond Hettinger54f02222002-06-01 14:18:47 +0000464 if 'name' in pdict:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000465 self.name = pdict['name']
466 self.filename = None
Raymond Hettinger54f02222002-06-01 14:18:47 +0000467 if 'filename' in pdict:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000468 self.filename = pdict['filename']
Guido van Rossum7aee3841996-03-07 18:00:44 +0000469
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000470 # Process content-type header
Barry Warsaw302331a1999-01-08 17:42:03 +0000471 #
472 # Honor any existing content-type header. But if there is no
473 # content-type header, use some sensible defaults. Assume
474 # outerboundary is "" at the outer level, but something non-false
475 # inside a multi-part. The default for an inner part is text/plain,
476 # but for an outer part it should be urlencoded. This should catch
477 # bogus clients which erroneously forget to include a content-type
478 # header.
479 #
480 # See below for what we do if there does exist a content-type header,
481 # but it happens to be something we don't understand.
Raymond Hettinger54f02222002-06-01 14:18:47 +0000482 if 'content-type' in self.headers:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000483 ctype, pdict = parse_header(self.headers['content-type'])
Guido van Rossumce900de1999-06-02 18:44:22 +0000484 elif self.outerboundary or method != 'POST':
Barry Warsaw302331a1999-01-08 17:42:03 +0000485 ctype, pdict = "text/plain", {}
486 else:
487 ctype, pdict = 'application/x-www-form-urlencoded', {}
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000488 self.type = ctype
489 self.type_options = pdict
490 self.innerboundary = ""
Raymond Hettinger54f02222002-06-01 14:18:47 +0000491 if 'boundary' in pdict:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000492 self.innerboundary = pdict['boundary']
493 clen = -1
Raymond Hettinger54f02222002-06-01 14:18:47 +0000494 if 'content-length' in self.headers:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000495 try:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000496 clen = int(self.headers['content-length'])
Skip Montanarodb5d1442002-03-23 05:50:17 +0000497 except ValueError:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000498 pass
499 if maxlen and clen > maxlen:
500 raise ValueError, 'Maximum content length exceeded'
501 self.length = clen
Guido van Rossum7aee3841996-03-07 18:00:44 +0000502
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000503 self.list = self.file = None
504 self.done = 0
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000505 if ctype == 'application/x-www-form-urlencoded':
506 self.read_urlencoded()
507 elif ctype[:10] == 'multipart/':
Guido van Rossumf5745001998-10-20 14:43:02 +0000508 self.read_multi(environ, keep_blank_values, strict_parsing)
Barry Warsaw302331a1999-01-08 17:42:03 +0000509 else:
Guido van Rossum60a3bd81999-06-11 18:26:09 +0000510 self.read_single()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000511
512 def __repr__(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000513 """Return a printable representation."""
Walter Dörwald70a6b492004-02-12 17:35:32 +0000514 return "FieldStorage(%r, %r, %r)" % (
515 self.name, self.filename, self.value)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000516
Guido van Rossum4061cbe2002-09-11 18:20:34 +0000517 def __iter__(self):
518 return iter(self.keys())
519
Guido van Rossum7aee3841996-03-07 18:00:44 +0000520 def __getattr__(self, name):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000521 if name != 'value':
522 raise AttributeError, name
523 if self.file:
524 self.file.seek(0)
525 value = self.file.read()
526 self.file.seek(0)
527 elif self.list is not None:
528 value = self.list
529 else:
530 value = None
531 return value
Guido van Rossum7aee3841996-03-07 18:00:44 +0000532
533 def __getitem__(self, key):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000534 """Dictionary style indexing."""
535 if self.list is None:
536 raise TypeError, "not indexable"
537 found = []
538 for item in self.list:
539 if item.name == key: found.append(item)
540 if not found:
541 raise KeyError, key
542 if len(found) == 1:
543 return found[0]
544 else:
545 return found
Guido van Rossum7aee3841996-03-07 18:00:44 +0000546
Moshe Zadkaa1a4b592000-08-25 21:47:56 +0000547 def getvalue(self, key, default=None):
548 """Dictionary style get() method, including 'value' lookup."""
Raymond Hettinger54f02222002-06-01 14:18:47 +0000549 if key in self:
Moshe Zadkaa1a4b592000-08-25 21:47:56 +0000550 value = self[key]
551 if type(value) is type([]):
Raymond Hettingerf871d832004-12-31 21:59:02 +0000552 return map(attrgetter('value'), value)
Moshe Zadkaa1a4b592000-08-25 21:47:56 +0000553 else:
554 return value.value
555 else:
556 return default
557
Guido van Rossum1bfb3882001-09-05 19:45:34 +0000558 def getfirst(self, key, default=None):
559 """ Return the first value received."""
Raymond Hettinger54f02222002-06-01 14:18:47 +0000560 if key in self:
Guido van Rossum1bfb3882001-09-05 19:45:34 +0000561 value = self[key]
562 if type(value) is type([]):
563 return value[0].value
564 else:
565 return value.value
566 else:
567 return default
568
569 def getlist(self, key):
570 """ Return list of received values."""
Raymond Hettinger54f02222002-06-01 14:18:47 +0000571 if key in self:
Guido van Rossum1bfb3882001-09-05 19:45:34 +0000572 value = self[key]
573 if type(value) is type([]):
Raymond Hettingerf871d832004-12-31 21:59:02 +0000574 return map(attrgetter('value'), value)
Guido van Rossum1bfb3882001-09-05 19:45:34 +0000575 else:
576 return [value.value]
577 else:
578 return []
579
Guido van Rossum7aee3841996-03-07 18:00:44 +0000580 def keys(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000581 """Dictionary style keys() method."""
582 if self.list is None:
583 raise TypeError, "not indexable"
Georg Brandlaff85e22007-09-20 16:06:07 +0000584 return list(set(item.name for item in self.list))
Guido van Rossum7aee3841996-03-07 18:00:44 +0000585
Guido van Rossum0147db01996-03-09 03:16:04 +0000586 def has_key(self, key):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000587 """Dictionary style has_key() method."""
588 if self.list is None:
589 raise TypeError, "not indexable"
Georg Brandlaff85e22007-09-20 16:06:07 +0000590 return any(item.name == key for item in self.list)
Guido van Rossum0147db01996-03-09 03:16:04 +0000591
Raymond Hettinger54f02222002-06-01 14:18:47 +0000592 def __contains__(self, key):
593 """Dictionary style __contains__ method."""
594 if self.list is None:
595 raise TypeError, "not indexable"
Georg Brandlaff85e22007-09-20 16:06:07 +0000596 return any(item.name == key for item in self.list)
Raymond Hettinger54f02222002-06-01 14:18:47 +0000597
Guido van Rossum88b85d41997-01-11 19:21:33 +0000598 def __len__(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000599 """Dictionary style len(x) support."""
600 return len(self.keys())
Guido van Rossum88b85d41997-01-11 19:21:33 +0000601
Georg Brandlaff85e22007-09-20 16:06:07 +0000602 def __nonzero__(self):
603 return bool(self.list)
604
Guido van Rossum7aee3841996-03-07 18:00:44 +0000605 def read_urlencoded(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000606 """Internal: read data in query string format."""
607 qs = self.fp.read(self.length)
Facundo Batistaa6a4d502008-06-21 18:58:04 +0000608 if self.qs_on_post:
609 qs += '&' + self.qs_on_post
Guido van Rossum1946f0d1999-06-04 17:54:39 +0000610 self.list = list = []
Facundo Batistac585df92008-09-03 22:35:50 +0000611 for key, value in urlparse.parse_qsl(qs, self.keep_blank_values,
612 self.strict_parsing):
Guido van Rossum1946f0d1999-06-04 17:54:39 +0000613 list.append(MiniFieldStorage(key, value))
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000614 self.skip_lines()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000615
Guido van Rossum030d2ec1998-12-09 22:16:46 +0000616 FieldStorageClass = None
617
Guido van Rossumf5745001998-10-20 14:43:02 +0000618 def read_multi(self, environ, keep_blank_values, strict_parsing):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000619 """Internal: read a part that is itself multipart."""
Guido van Rossum2e441f72001-07-25 21:00:19 +0000620 ib = self.innerboundary
621 if not valid_boundary(ib):
Walter Dörwald70a6b492004-02-12 17:35:32 +0000622 raise ValueError, 'Invalid boundary in multipart form: %r' % (ib,)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000623 self.list = []
Facundo Batistaa6a4d502008-06-21 18:58:04 +0000624 if self.qs_on_post:
Facundo Batistac585df92008-09-03 22:35:50 +0000625 for key, value in urlparse.parse_qsl(self.qs_on_post,
626 self.keep_blank_values, self.strict_parsing):
Facundo Batistaa6a4d502008-06-21 18:58:04 +0000627 self.list.append(MiniFieldStorage(key, value))
628 FieldStorageClass = None
629
Guido van Rossum030d2ec1998-12-09 22:16:46 +0000630 klass = self.FieldStorageClass or self.__class__
Guido van Rossum2e441f72001-07-25 21:00:19 +0000631 part = klass(self.fp, {}, ib,
Guido van Rossum030d2ec1998-12-09 22:16:46 +0000632 environ, keep_blank_values, strict_parsing)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000633 # Throw first part away
634 while not part.done:
Armin Rigo3a703b62005-09-19 09:11:04 +0000635 headers = rfc822.Message(self.fp)
Guido van Rossum2e441f72001-07-25 21:00:19 +0000636 part = klass(self.fp, headers, ib,
Guido van Rossum030d2ec1998-12-09 22:16:46 +0000637 environ, keep_blank_values, strict_parsing)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000638 self.list.append(part)
639 self.skip_lines()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000640
641 def read_single(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000642 """Internal: read an atomic part."""
643 if self.length >= 0:
644 self.read_binary()
645 self.skip_lines()
646 else:
647 self.read_lines()
648 self.file.seek(0)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000649
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000650 bufsize = 8*1024 # I/O buffering size for copy to file
Guido van Rossum7aee3841996-03-07 18:00:44 +0000651
652 def read_binary(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000653 """Internal: read binary data."""
654 self.file = self.make_file('b')
655 todo = self.length
656 if todo >= 0:
657 while todo > 0:
658 data = self.fp.read(min(todo, self.bufsize))
659 if not data:
660 self.done = -1
661 break
662 self.file.write(data)
663 todo = todo - len(data)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000664
665 def read_lines(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000666 """Internal: read lines until EOF or outerboundary."""
Guido van Rossum52b8c292001-06-29 13:06:06 +0000667 self.file = self.__file = StringIO()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000668 if self.outerboundary:
669 self.read_lines_to_outerboundary()
670 else:
671 self.read_lines_to_eof()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000672
Guido van Rossum52b8c292001-06-29 13:06:06 +0000673 def __write(self, line):
674 if self.__file is not None:
675 if self.__file.tell() + len(line) > 1000:
676 self.file = self.make_file('')
677 self.file.write(self.__file.getvalue())
678 self.__file = None
679 self.file.write(line)
680
Guido van Rossum7aee3841996-03-07 18:00:44 +0000681 def read_lines_to_eof(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000682 """Internal: read lines until EOF."""
683 while 1:
Guido van Rossum9568b732006-08-10 17:41:07 +0000684 line = self.fp.readline(1<<16)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000685 if not line:
686 self.done = -1
687 break
Guido van Rossum52b8c292001-06-29 13:06:06 +0000688 self.__write(line)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000689
690 def read_lines_to_outerboundary(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000691 """Internal: read lines until outerboundary."""
692 next = "--" + self.outerboundary
693 last = next + "--"
694 delim = ""
Guido van Rossum9568b732006-08-10 17:41:07 +0000695 last_line_lfend = True
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000696 while 1:
Guido van Rossum9568b732006-08-10 17:41:07 +0000697 line = self.fp.readline(1<<16)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000698 if not line:
699 self.done = -1
700 break
Guido van Rossum9568b732006-08-10 17:41:07 +0000701 if line[:2] == "--" and last_line_lfend:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000702 strippedline = line.strip()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000703 if strippedline == next:
704 break
705 if strippedline == last:
706 self.done = 1
707 break
708 odelim = delim
709 if line[-2:] == "\r\n":
710 delim = "\r\n"
711 line = line[:-2]
Guido van Rossum9568b732006-08-10 17:41:07 +0000712 last_line_lfend = True
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000713 elif line[-1] == "\n":
714 delim = "\n"
715 line = line[:-1]
Guido van Rossum9568b732006-08-10 17:41:07 +0000716 last_line_lfend = True
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000717 else:
718 delim = ""
Guido van Rossum9568b732006-08-10 17:41:07 +0000719 last_line_lfend = False
Guido van Rossum52b8c292001-06-29 13:06:06 +0000720 self.__write(odelim + line)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000721
722 def skip_lines(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000723 """Internal: skip lines until outer boundary if defined."""
724 if not self.outerboundary or self.done:
725 return
726 next = "--" + self.outerboundary
727 last = next + "--"
Guido van Rossum9568b732006-08-10 17:41:07 +0000728 last_line_lfend = True
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000729 while 1:
Guido van Rossum9568b732006-08-10 17:41:07 +0000730 line = self.fp.readline(1<<16)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000731 if not line:
732 self.done = -1
733 break
Guido van Rossum9568b732006-08-10 17:41:07 +0000734 if line[:2] == "--" and last_line_lfend:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000735 strippedline = line.strip()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000736 if strippedline == next:
737 break
738 if strippedline == last:
739 self.done = 1
740 break
Guido van Rossum9568b732006-08-10 17:41:07 +0000741 last_line_lfend = line.endswith('\n')
Guido van Rossum7aee3841996-03-07 18:00:44 +0000742
Guido van Rossuma5e9fb61997-08-12 18:18:13 +0000743 def make_file(self, binary=None):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000744 """Overridable: return a readable & writable file.
Guido van Rossum7aee3841996-03-07 18:00:44 +0000745
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000746 The file will be used as follows:
747 - data is written to it
748 - seek(0)
749 - data is read from it
Guido van Rossum7aee3841996-03-07 18:00:44 +0000750
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000751 The 'binary' argument is unused -- the file is always opened
752 in binary mode.
Guido van Rossum7aee3841996-03-07 18:00:44 +0000753
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000754 This version opens a temporary file for reading and writing,
755 and immediately deletes (unlinks) it. The trick (on Unix!) is
756 that the file can still be used, but it can't be opened by
757 another process, and it will automatically be deleted when it
758 is closed or when the current process terminates.
Guido van Rossum4032c2c1996-03-09 04:04:35 +0000759
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000760 If you want a more permanent file, you derive a class which
761 overrides this method. If you want a visible temporary file
762 that is nevertheless automatically deleted when the script
763 terminates, try defining a __del__ method in a derived class
764 which unlinks the temporary files you have created.
Guido van Rossum7aee3841996-03-07 18:00:44 +0000765
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000766 """
767 import tempfile
768 return tempfile.TemporaryFile("w+b")
Tim Peters88869f92001-01-14 23:36:06 +0000769
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000770
771
Guido van Rossum4032c2c1996-03-09 04:04:35 +0000772# Backwards Compatibility Classes
773# ===============================
Guido van Rossum9a22de11995-01-12 12:29:47 +0000774
Moshe Zadkaa1a4b592000-08-25 21:47:56 +0000775class FormContentDict(UserDict.UserDict):
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000776 """Form content as dictionary with a list of values per field.
Guido van Rossum72755611996-03-06 07:20:06 +0000777
Guido van Rossum7aee3841996-03-07 18:00:44 +0000778 form = FormContentDict()
779
780 form[key] -> [value, value, ...]
Raymond Hettinger54f02222002-06-01 14:18:47 +0000781 key in form -> Boolean
Guido van Rossum7aee3841996-03-07 18:00:44 +0000782 form.keys() -> [key, key, ...]
783 form.values() -> [[val, val, ...], [val, val, ...], ...]
784 form.items() -> [(key, [val, val, ...]), (key, [val, val, ...]), ...]
785 form.dict == {key: [val, val, ...], ...}
786
787 """
Georg Brandl05b3c452006-09-30 10:58:01 +0000788 def __init__(self, environ=os.environ, keep_blank_values=0, strict_parsing=0):
789 self.dict = self.data = parse(environ=environ,
790 keep_blank_values=keep_blank_values,
791 strict_parsing=strict_parsing)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000792 self.query_string = environ['QUERY_STRING']
Guido van Rossum9a22de11995-01-12 12:29:47 +0000793
794
Guido van Rossum9a22de11995-01-12 12:29:47 +0000795class SvFormContentDict(FormContentDict):
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000796 """Form content as dictionary expecting a single value per field.
Guido van Rossum7aee3841996-03-07 18:00:44 +0000797
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000798 If you only expect a single value for each field, then form[key]
Guido van Rossum7aee3841996-03-07 18:00:44 +0000799 will return that single value. It will raise an IndexError if
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000800 that expectation is not true. If you expect a field to have
Guido van Rossum7aee3841996-03-07 18:00:44 +0000801 possible multiple values, than you can use form.getlist(key) to
802 get all of the values. values() and items() are a compromise:
803 they return single strings where there is a single value, and
804 lists of strings otherwise.
805
806 """
807 def __getitem__(self, key):
Tim Peters88869f92001-01-14 23:36:06 +0000808 if len(self.dict[key]) > 1:
809 raise IndexError, 'expecting a single value'
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000810 return self.dict[key][0]
Guido van Rossum7aee3841996-03-07 18:00:44 +0000811 def getlist(self, key):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000812 return self.dict[key]
Guido van Rossum7aee3841996-03-07 18:00:44 +0000813 def values(self):
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000814 result = []
815 for value in self.dict.values():
816 if len(value) == 1:
817 result.append(value[0])
818 else: result.append(value)
819 return result
Guido van Rossum7aee3841996-03-07 18:00:44 +0000820 def items(self):
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000821 result = []
822 for key, value in self.dict.items():
823 if len(value) == 1:
824 result.append((key, value[0]))
825 else: result.append((key, value))
826 return result
Guido van Rossum9a22de11995-01-12 12:29:47 +0000827
828
Guido van Rossum9a22de11995-01-12 12:29:47 +0000829class InterpFormContentDict(SvFormContentDict):
Tim Peters88869f92001-01-14 23:36:06 +0000830 """This class is present for backwards compatibility only."""
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000831 def __getitem__(self, key):
832 v = SvFormContentDict.__getitem__(self, key)
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000833 if v[0] in '0123456789+-.':
834 try: return int(v)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000835 except ValueError:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000836 try: return float(v)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000837 except ValueError: pass
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000838 return v.strip()
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000839 def values(self):
840 result = []
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000841 for key in self.keys():
842 try:
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000843 result.append(self[key])
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000844 except IndexError:
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000845 result.append(self.dict[key])
846 return result
847 def items(self):
848 result = []
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000849 for key in self.keys():
850 try:
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000851 result.append((key, self[key]))
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000852 except IndexError:
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000853 result.append((key, self.dict[key]))
854 return result
Guido van Rossum9a22de11995-01-12 12:29:47 +0000855
856
Guido van Rossum9a22de11995-01-12 12:29:47 +0000857class FormContent(FormContentDict):
Tim Peters88869f92001-01-14 23:36:06 +0000858 """This class is present for backwards compatibility only."""
Guido van Rossum0147db01996-03-09 03:16:04 +0000859 def values(self, key):
Raymond Hettinger54f02222002-06-01 14:18:47 +0000860 if key in self.dict :return self.dict[key]
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000861 else: return None
Guido van Rossum0147db01996-03-09 03:16:04 +0000862 def indexed_value(self, key, location):
Raymond Hettinger54f02222002-06-01 14:18:47 +0000863 if key in self.dict:
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000864 if len(self.dict[key]) > location:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000865 return self.dict[key][location]
866 else: return None
867 else: return None
Guido van Rossum0147db01996-03-09 03:16:04 +0000868 def value(self, key):
Raymond Hettinger54f02222002-06-01 14:18:47 +0000869 if key in self.dict: return self.dict[key][0]
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000870 else: return None
Guido van Rossum0147db01996-03-09 03:16:04 +0000871 def length(self, key):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000872 return len(self.dict[key])
Guido van Rossum0147db01996-03-09 03:16:04 +0000873 def stripped(self, key):
Raymond Hettinger54f02222002-06-01 14:18:47 +0000874 if key in self.dict: return self.dict[key][0].strip()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000875 else: return None
Guido van Rossum7aee3841996-03-07 18:00:44 +0000876 def pars(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000877 return self.dict
Guido van Rossum9a22de11995-01-12 12:29:47 +0000878
879
Guido van Rossum72755611996-03-06 07:20:06 +0000880# Test/debug code
881# ===============
Guido van Rossum9a22de11995-01-12 12:29:47 +0000882
Guido van Rossum773ab271996-07-23 03:46:24 +0000883def test(environ=os.environ):
Guido van Rossum7aee3841996-03-07 18:00:44 +0000884 """Robust test CGI script, usable as main program.
Guido van Rossum9a22de11995-01-12 12:29:47 +0000885
Guido van Rossum7aee3841996-03-07 18:00:44 +0000886 Write minimal HTTP headers and dump all information provided to
887 the script in HTML form.
888
889 """
Guido van Rossum7aee3841996-03-07 18:00:44 +0000890 print "Content-type: text/html"
891 print
892 sys.stderr = sys.stdout
893 try:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000894 form = FieldStorage() # Replace with other classes to test those
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000895 print_directory()
896 print_arguments()
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000897 print_form(form)
898 print_environ(environ)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000899 print_environ_usage()
900 def f():
901 exec "testing print_exception() -- <I>italics?</I>"
902 def g(f=f):
903 f()
904 print "<H3>What follows is a test, not an actual exception:</H3>"
905 g()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000906 except:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000907 print_exception()
Guido van Rossumf85de8a1996-08-20 20:22:39 +0000908
Guido van Rossum57d51f22000-09-16 21:16:01 +0000909 print "<H1>Second try with a small maxlen...</H1>"
910
Guido van Rossumad164711997-05-13 19:03:23 +0000911 global maxlen
912 maxlen = 50
913 try:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000914 form = FieldStorage() # Replace with other classes to test those
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000915 print_directory()
916 print_arguments()
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000917 print_form(form)
918 print_environ(environ)
Guido van Rossumad164711997-05-13 19:03:23 +0000919 except:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000920 print_exception()
Guido van Rossumad164711997-05-13 19:03:23 +0000921
Guido van Rossumf85de8a1996-08-20 20:22:39 +0000922def print_exception(type=None, value=None, tb=None, limit=None):
923 if type is None:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000924 type, value, tb = sys.exc_info()
Guido van Rossumf85de8a1996-08-20 20:22:39 +0000925 import traceback
926 print
Guido van Rossum7dd06962000-12-27 19:12:58 +0000927 print "<H3>Traceback (most recent call last):</H3>"
Guido van Rossumf85de8a1996-08-20 20:22:39 +0000928 list = traceback.format_tb(tb, limit) + \
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000929 traceback.format_exception_only(type, value)
Guido van Rossumf85de8a1996-08-20 20:22:39 +0000930 print "<PRE>%s<B>%s</B></PRE>" % (
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000931 escape("".join(list[:-1])),
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000932 escape(list[-1]),
933 )
Guido van Rossumf15d1591997-09-29 23:22:12 +0000934 del tb
Guido van Rossum9a22de11995-01-12 12:29:47 +0000935
Guido van Rossum773ab271996-07-23 03:46:24 +0000936def print_environ(environ=os.environ):
Guido van Rossum7aee3841996-03-07 18:00:44 +0000937 """Dump the shell environment as HTML."""
938 keys = environ.keys()
939 keys.sort()
940 print
Guido van Rossum503e50b1996-05-28 22:57:20 +0000941 print "<H3>Shell Environment:</H3>"
Guido van Rossum7aee3841996-03-07 18:00:44 +0000942 print "<DL>"
943 for key in keys:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000944 print "<DT>", escape(key), "<DD>", escape(environ[key])
Tim Peters88869f92001-01-14 23:36:06 +0000945 print "</DL>"
Guido van Rossum7aee3841996-03-07 18:00:44 +0000946 print
Guido van Rossum72755611996-03-06 07:20:06 +0000947
948def print_form(form):
Guido van Rossum7aee3841996-03-07 18:00:44 +0000949 """Dump the contents of a form as HTML."""
950 keys = form.keys()
951 keys.sort()
952 print
Guido van Rossum503e50b1996-05-28 22:57:20 +0000953 print "<H3>Form Contents:</H3>"
Guido van Rossum57d51f22000-09-16 21:16:01 +0000954 if not keys:
955 print "<P>No form fields."
Guido van Rossum7aee3841996-03-07 18:00:44 +0000956 print "<DL>"
957 for key in keys:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000958 print "<DT>" + escape(key) + ":",
959 value = form[key]
Walter Dörwald70a6b492004-02-12 17:35:32 +0000960 print "<i>" + escape(repr(type(value))) + "</i>"
961 print "<DD>" + escape(repr(value))
Guido van Rossum7aee3841996-03-07 18:00:44 +0000962 print "</DL>"
963 print
964
965def print_directory():
966 """Dump the current directory as HTML."""
967 print
968 print "<H3>Current Working Directory:</H3>"
969 try:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000970 pwd = os.getcwd()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000971 except os.error, msg:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000972 print "os.error:", escape(str(msg))
Guido van Rossum7aee3841996-03-07 18:00:44 +0000973 else:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000974 print escape(pwd)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000975 print
Guido van Rossum9a22de11995-01-12 12:29:47 +0000976
Guido van Rossuma8738a51996-03-14 21:30:28 +0000977def print_arguments():
978 print
Guido van Rossum503e50b1996-05-28 22:57:20 +0000979 print "<H3>Command Line Arguments:</H3>"
Guido van Rossuma8738a51996-03-14 21:30:28 +0000980 print
981 print sys.argv
982 print
983
Guido van Rossum9a22de11995-01-12 12:29:47 +0000984def print_environ_usage():
Guido van Rossum7aee3841996-03-07 18:00:44 +0000985 """Dump a list of environment variables used by CGI as HTML."""
986 print """
Guido van Rossum72755611996-03-06 07:20:06 +0000987<H3>These environment variables could have been set:</H3>
988<UL>
Guido van Rossum9a22de11995-01-12 12:29:47 +0000989<LI>AUTH_TYPE
990<LI>CONTENT_LENGTH
991<LI>CONTENT_TYPE
992<LI>DATE_GMT
993<LI>DATE_LOCAL
994<LI>DOCUMENT_NAME
995<LI>DOCUMENT_ROOT
996<LI>DOCUMENT_URI
997<LI>GATEWAY_INTERFACE
998<LI>LAST_MODIFIED
999<LI>PATH
1000<LI>PATH_INFO
1001<LI>PATH_TRANSLATED
1002<LI>QUERY_STRING
1003<LI>REMOTE_ADDR
1004<LI>REMOTE_HOST
1005<LI>REMOTE_IDENT
1006<LI>REMOTE_USER
1007<LI>REQUEST_METHOD
1008<LI>SCRIPT_NAME
1009<LI>SERVER_NAME
1010<LI>SERVER_PORT
1011<LI>SERVER_PROTOCOL
1012<LI>SERVER_ROOT
1013<LI>SERVER_SOFTWARE
1014</UL>
Guido van Rossum7aee3841996-03-07 18:00:44 +00001015In addition, HTTP headers sent by the server may be passed in the
1016environment as well. Here are some common variable names:
1017<UL>
1018<LI>HTTP_ACCEPT
1019<LI>HTTP_CONNECTION
1020<LI>HTTP_HOST
1021<LI>HTTP_PRAGMA
1022<LI>HTTP_REFERER
1023<LI>HTTP_USER_AGENT
1024</UL>
Guido van Rossum9a22de11995-01-12 12:29:47 +00001025"""
1026
Guido van Rossum9a22de11995-01-12 12:29:47 +00001027
Guido van Rossum72755611996-03-06 07:20:06 +00001028# Utilities
1029# =========
Guido van Rossum9a22de11995-01-12 12:29:47 +00001030
Guido van Rossum64c66201997-07-19 20:11:53 +00001031def escape(s, quote=None):
Skip Montanaro97b2fa22005-08-02 02:50:25 +00001032 '''Replace special characters "&", "<" and ">" to HTML-safe sequences.
1033 If the optional flag quote is true, the quotation mark character (")
1034 is also translated.'''
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +00001035 s = s.replace("&", "&amp;") # Must be done first!
1036 s = s.replace("<", "&lt;")
1037 s = s.replace(">", "&gt;")
Guido van Rossum64c66201997-07-19 20:11:53 +00001038 if quote:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +00001039 s = s.replace('"', "&quot;")
Guido van Rossum7aee3841996-03-07 18:00:44 +00001040 return s
Guido van Rossum9a22de11995-01-12 12:29:47 +00001041
Guido van Rossum2e441f72001-07-25 21:00:19 +00001042def valid_boundary(s, _vb_pattern="^[ -~]{0,200}[!-~]$"):
1043 import re
1044 return re.match(_vb_pattern, s)
Guido van Rossum9a22de11995-01-12 12:29:47 +00001045
Guido van Rossum72755611996-03-06 07:20:06 +00001046# Invoke mainline
1047# ===============
1048
1049# Call test() when this file is run as a script (not imported as a module)
Tim Peters88869f92001-01-14 23:36:06 +00001050if __name__ == '__main__':
Guido van Rossum7aee3841996-03-07 18:00:44 +00001051 test()