blob: 4cf960929950668f4cb0497d9888f496f683216e [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
Armin Rigo3a703b62005-09-19 09:11:04 +000041import mimetools
42import rfc822
Moshe Zadkaa1a4b592000-08-25 21:47:56 +000043import UserDict
Guido van Rossum68937b42007-05-18 00:51:22 +000044from io import StringIO
Guido van Rossum72755611996-03-06 07:20:06 +000045
Guido van Rossuma8423a92001-03-19 13:40:44 +000046__all__ = ["MiniFieldStorage", "FieldStorage", "FormContentDict",
47 "SvFormContentDict", "InterpFormContentDict", "FormContent",
48 "parse", "parse_qs", "parse_qsl", "parse_multipart",
49 "parse_header", "print_exception", "print_environ",
50 "print_form", "print_directory", "print_arguments",
51 "print_environ_usage", "escape"]
Guido van Rossumc204c701996-09-05 19:07:11 +000052
53# Logging support
54# ===============
55
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000056logfile = "" # Filename to log to, if not empty
57logfp = None # File object to log to, if not None
Guido van Rossumc204c701996-09-05 19:07:11 +000058
59def initlog(*allargs):
60 """Write a log message, if there is a log file.
61
62 Even though this function is called initlog(), you should always
63 use log(); log is a variable that is set either to initlog
64 (initially), to dolog (once the log file has been opened), or to
65 nolog (when logging is disabled).
66
67 The first argument is a format string; the remaining arguments (if
68 any) are arguments to the % operator, so e.g.
69 log("%s: %s", "a", "b")
70 will write "a: b" to the log file, followed by a newline.
71
72 If the global logfp is not None, it should be a file object to
73 which log data is written.
74
75 If the global logfp is None, the global logfile may be a string
76 giving a filename to open, in append mode. This file should be
77 world writable!!! If the file can't be opened, logging is
78 silently disabled (since there is no safe place where we could
79 send an error message).
80
81 """
82 global logfp, log
83 if logfile and not logfp:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000084 try:
85 logfp = open(logfile, "a")
86 except IOError:
87 pass
Guido van Rossumc204c701996-09-05 19:07:11 +000088 if not logfp:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000089 log = nolog
Guido van Rossumc204c701996-09-05 19:07:11 +000090 else:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000091 log = dolog
Guido van Rossum68468eb2003-02-27 20:14:51 +000092 log(*allargs)
Guido van Rossumc204c701996-09-05 19:07:11 +000093
94def dolog(fmt, *args):
95 """Write a log message to the log file. See initlog() for docs."""
96 logfp.write(fmt%args + "\n")
97
98def nolog(*allargs):
99 """Dummy function, assigned to log when logging is disabled."""
100 pass
101
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000102log = initlog # The current logging function
Guido van Rossumc204c701996-09-05 19:07:11 +0000103
104
Guido van Rossum72755611996-03-06 07:20:06 +0000105# Parsing functions
106# =================
107
Guido van Rossumad164711997-05-13 19:03:23 +0000108# Maximum input we will accept when REQUEST_METHOD is POST
109# 0 ==> unlimited input
110maxlen = 0
111
Guido van Rossume08c04c1996-11-11 19:29:11 +0000112def parse(fp=None, environ=os.environ, keep_blank_values=0, strict_parsing=0):
Guido van Rossum773ab271996-07-23 03:46:24 +0000113 """Parse a query in the environment or from a file (default stdin)
114
115 Arguments, all optional:
116
117 fp : file pointer; default: sys.stdin
118
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000119 environ : environment dictionary; default: os.environ
Guido van Rossum773ab271996-07-23 03:46:24 +0000120
121 keep_blank_values: flag indicating whether blank values in
Tim Peters88869f92001-01-14 23:36:06 +0000122 URL encoded forms should be treated as blank strings.
123 A true value indicates that blanks should be retained as
Guido van Rossum773ab271996-07-23 03:46:24 +0000124 blank strings. The default false value indicates that
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000125 blank values are to be ignored and treated as if they were
126 not included.
Guido van Rossume08c04c1996-11-11 19:29:11 +0000127
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000128 strict_parsing: flag indicating what to do with parsing errors.
129 If false (the default), errors are silently ignored.
130 If true, errors raise a ValueError exception.
Guido van Rossum773ab271996-07-23 03:46:24 +0000131 """
Raymond Hettingera1449002002-05-31 23:54:44 +0000132 if fp is None:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000133 fp = sys.stdin
Raymond Hettinger54f02222002-06-01 14:18:47 +0000134 if not 'REQUEST_METHOD' in environ:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000135 environ['REQUEST_METHOD'] = 'GET' # For testing stand-alone
Guido van Rossum7aee3841996-03-07 18:00:44 +0000136 if environ['REQUEST_METHOD'] == 'POST':
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000137 ctype, pdict = parse_header(environ['CONTENT_TYPE'])
138 if ctype == 'multipart/form-data':
139 return parse_multipart(fp, pdict)
140 elif ctype == 'application/x-www-form-urlencoded':
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000141 clength = int(environ['CONTENT_LENGTH'])
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000142 if maxlen and clength > maxlen:
143 raise ValueError, 'Maximum content length exceeded'
144 qs = fp.read(clength)
145 else:
146 qs = '' # Unknown content-type
Raymond Hettinger54f02222002-06-01 14:18:47 +0000147 if 'QUERY_STRING' in environ:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000148 if qs: qs = qs + '&'
149 qs = qs + environ['QUERY_STRING']
Tim Peters88869f92001-01-14 23:36:06 +0000150 elif sys.argv[1:]:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000151 if qs: qs = qs + '&'
152 qs = qs + sys.argv[1]
153 environ['QUERY_STRING'] = qs # XXX Shouldn't, really
Raymond Hettinger54f02222002-06-01 14:18:47 +0000154 elif 'QUERY_STRING' in environ:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000155 qs = environ['QUERY_STRING']
Guido van Rossum7aee3841996-03-07 18:00:44 +0000156 else:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000157 if sys.argv[1:]:
158 qs = sys.argv[1]
159 else:
160 qs = ""
161 environ['QUERY_STRING'] = qs # XXX Shouldn't, really
Guido van Rossume08c04c1996-11-11 19:29:11 +0000162 return parse_qs(qs, keep_blank_values, strict_parsing)
Guido van Rossume7808771995-08-07 20:12:09 +0000163
164
Guido van Rossume08c04c1996-11-11 19:29:11 +0000165def parse_qs(qs, keep_blank_values=0, strict_parsing=0):
166 """Parse a query given as a string argument.
Guido van Rossum773ab271996-07-23 03:46:24 +0000167
168 Arguments:
169
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000170 qs: URL-encoded query string to be parsed
Guido van Rossum773ab271996-07-23 03:46:24 +0000171
172 keep_blank_values: flag indicating whether blank values in
Tim Peters88869f92001-01-14 23:36:06 +0000173 URL encoded queries should be treated as blank strings.
174 A true value indicates that blanks should be retained as
Guido van Rossum773ab271996-07-23 03:46:24 +0000175 blank strings. The default false value indicates that
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000176 blank values are to be ignored and treated as if they were
177 not included.
Guido van Rossume08c04c1996-11-11 19:29:11 +0000178
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000179 strict_parsing: flag indicating what to do with parsing errors.
180 If false (the default), errors are silently ignored.
181 If true, errors raise a ValueError exception.
Guido van Rossum773ab271996-07-23 03:46:24 +0000182 """
Guido van Rossum7aee3841996-03-07 18:00:44 +0000183 dict = {}
Guido van Rossum1946f0d1999-06-04 17:54:39 +0000184 for name, value in parse_qsl(qs, keep_blank_values, strict_parsing):
Raymond Hettinger54f02222002-06-01 14:18:47 +0000185 if name in dict:
Moshe Zadkaa1a4b592000-08-25 21:47:56 +0000186 dict[name].append(value)
187 else:
188 dict[name] = [value]
Guido van Rossum1946f0d1999-06-04 17:54:39 +0000189 return dict
190
191def parse_qsl(qs, keep_blank_values=0, strict_parsing=0):
192 """Parse a query given as a string argument.
193
Jeremy Hyltonafde7e22000-09-15 20:06:57 +0000194 Arguments:
Guido van Rossum1946f0d1999-06-04 17:54:39 +0000195
Jeremy Hyltonafde7e22000-09-15 20:06:57 +0000196 qs: URL-encoded query string to be parsed
Guido van Rossum1946f0d1999-06-04 17:54:39 +0000197
Jeremy Hyltonafde7e22000-09-15 20:06:57 +0000198 keep_blank_values: flag indicating whether blank values in
199 URL encoded queries should be treated as blank strings. A
200 true value indicates that blanks should be retained as blank
201 strings. The default false value indicates that blank values
202 are to be ignored and treated as if they were not included.
Guido van Rossum1946f0d1999-06-04 17:54:39 +0000203
Jeremy Hyltonafde7e22000-09-15 20:06:57 +0000204 strict_parsing: flag indicating what to do with parsing errors. If
205 false (the default), errors are silently ignored. If true,
Tim Peters88869f92001-01-14 23:36:06 +0000206 errors raise a ValueError exception.
Guido van Rossum1946f0d1999-06-04 17:54:39 +0000207
Jeremy Hyltonafde7e22000-09-15 20:06:57 +0000208 Returns a list, as G-d intended.
Guido van Rossum1946f0d1999-06-04 17:54:39 +0000209 """
Jeremy Hyltonafde7e22000-09-15 20:06:57 +0000210 pairs = [s2 for s1 in qs.split('&') for s2 in s1.split(';')]
211 r = []
212 for name_value in pairs:
Neil Schemenauer66edb622004-07-19 15:38:11 +0000213 if not name_value and not strict_parsing:
214 continue
Jeremy Hyltonafde7e22000-09-15 20:06:57 +0000215 nv = name_value.split('=', 1)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000216 if len(nv) != 2:
217 if strict_parsing:
Walter Dörwald70a6b492004-02-12 17:35:32 +0000218 raise ValueError, "bad query field: %r" % (name_value,)
Brett Cannon8d9b60f2004-03-21 22:16:15 +0000219 # Handle case of a control-name with no equal sign
220 if keep_blank_values:
221 nv.append('')
222 else:
223 continue
Moshe Zadkaa1a4b592000-08-25 21:47:56 +0000224 if len(nv[1]) or keep_blank_values:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000225 name = urllib.unquote(nv[0].replace('+', ' '))
226 value = urllib.unquote(nv[1].replace('+', ' '))
Moshe Zadkaa1a4b592000-08-25 21:47:56 +0000227 r.append((name, value))
Guido van Rossum1946f0d1999-06-04 17:54:39 +0000228
229 return r
Guido van Rossum9a22de11995-01-12 12:29:47 +0000230
231
Guido van Rossum0147db01996-03-09 03:16:04 +0000232def parse_multipart(fp, pdict):
Guido van Rossum7aee3841996-03-07 18:00:44 +0000233 """Parse multipart input.
Guido van Rossum9a22de11995-01-12 12:29:47 +0000234
Guido van Rossum7aee3841996-03-07 18:00:44 +0000235 Arguments:
236 fp : input file
Johannes Gijsbersc7fc10a2005-01-08 13:56:36 +0000237 pdict: dictionary containing other parameters of content-type header
Guido van Rossum72755611996-03-06 07:20:06 +0000238
Tim Peters88869f92001-01-14 23:36:06 +0000239 Returns a dictionary just like parse_qs(): keys are the field names, each
240 value is a list of values for that field. This is easy to use but not
241 much good if you are expecting megabytes to be uploaded -- in that case,
242 use the FieldStorage class instead which is much more flexible. Note
243 that content-type is the raw, unparsed contents of the content-type
Guido van Rossum0147db01996-03-09 03:16:04 +0000244 header.
Tim Peters88869f92001-01-14 23:36:06 +0000245
246 XXX This does not parse nested multipart parts -- use FieldStorage for
Guido van Rossum0147db01996-03-09 03:16:04 +0000247 that.
Tim Peters88869f92001-01-14 23:36:06 +0000248
249 XXX This should really be subsumed by FieldStorage altogether -- no
Guido van Rossum0147db01996-03-09 03:16:04 +0000250 point in having two implementations of the same parsing algorithm.
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000251 Also, FieldStorage protects itself better against certain DoS attacks
252 by limiting the size of the data read in one chunk. The API here
253 does not support that kind of protection. This also affects parse()
254 since it can call parse_multipart().
Guido van Rossum72755611996-03-06 07:20:06 +0000255
Guido van Rossum7aee3841996-03-07 18:00:44 +0000256 """
Guido van Rossum2e441f72001-07-25 21:00:19 +0000257 boundary = ""
Raymond Hettinger54f02222002-06-01 14:18:47 +0000258 if 'boundary' in pdict:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000259 boundary = pdict['boundary']
Guido van Rossum2e441f72001-07-25 21:00:19 +0000260 if not valid_boundary(boundary):
Walter Dörwald70a6b492004-02-12 17:35:32 +0000261 raise ValueError, ('Invalid boundary in multipart form: %r'
262 % (boundary,))
Tim Petersab9ba272001-08-09 21:40:30 +0000263
Guido van Rossum7aee3841996-03-07 18:00:44 +0000264 nextpart = "--" + boundary
265 lastpart = "--" + boundary + "--"
266 partdict = {}
267 terminator = ""
268
269 while terminator != lastpart:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000270 bytes = -1
271 data = None
272 if terminator:
273 # At start of next part. Read headers first.
Armin Rigo3a703b62005-09-19 09:11:04 +0000274 headers = mimetools.Message(fp)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000275 clength = headers.getheader('content-length')
276 if clength:
277 try:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000278 bytes = int(clength)
279 except ValueError:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000280 pass
281 if bytes > 0:
282 if maxlen and bytes > maxlen:
283 raise ValueError, 'Maximum content length exceeded'
284 data = fp.read(bytes)
285 else:
286 data = ""
287 # Read lines until end of part.
288 lines = []
289 while 1:
290 line = fp.readline()
291 if not line:
292 terminator = lastpart # End outer loop
293 break
294 if line[:2] == "--":
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000295 terminator = line.strip()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000296 if terminator in (nextpart, lastpart):
297 break
298 lines.append(line)
299 # Done with part.
300 if data is None:
301 continue
302 if bytes < 0:
303 if lines:
304 # Strip final line terminator
305 line = lines[-1]
306 if line[-2:] == "\r\n":
307 line = line[:-2]
308 elif line[-1:] == "\n":
309 line = line[:-1]
310 lines[-1] = line
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000311 data = "".join(lines)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000312 line = headers['content-disposition']
313 if not line:
314 continue
315 key, params = parse_header(line)
316 if key != 'form-data':
317 continue
Raymond Hettinger54f02222002-06-01 14:18:47 +0000318 if 'name' in params:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000319 name = params['name']
320 else:
321 continue
Raymond Hettinger54f02222002-06-01 14:18:47 +0000322 if name in partdict:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000323 partdict[name].append(data)
324 else:
325 partdict[name] = [data]
Guido van Rossum72755611996-03-06 07:20:06 +0000326
Guido van Rossum7aee3841996-03-07 18:00:44 +0000327 return partdict
Guido van Rossum9a22de11995-01-12 12:29:47 +0000328
329
Guido van Rossum72755611996-03-06 07:20:06 +0000330def parse_header(line):
Guido van Rossum7aee3841996-03-07 18:00:44 +0000331 """Parse a Content-type like header.
332
333 Return the main content-type and a dictionary of options.
334
335 """
Raymond Hettingerf871d832004-12-31 21:59:02 +0000336 plist = [x.strip() for x in line.split(';')]
Raymond Hettinger46ac8eb2002-06-30 03:39:14 +0000337 key = plist.pop(0).lower()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000338 pdict = {}
339 for p in plist:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000340 i = p.find('=')
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000341 if i >= 0:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000342 name = p[:i].strip().lower()
343 value = p[i+1:].strip()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000344 if len(value) >= 2 and value[0] == value[-1] == '"':
345 value = value[1:-1]
Johannes Gijsbers9e15dd62004-08-14 15:39:34 +0000346 value = value.replace('\\\\', '\\').replace('\\"', '"')
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000347 pdict[name] = value
Guido van Rossum7aee3841996-03-07 18:00:44 +0000348 return key, pdict
Guido van Rossum72755611996-03-06 07:20:06 +0000349
350
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000351# Classes for field storage
352# =========================
353
354class MiniFieldStorage:
355
Guido van Rossum0147db01996-03-09 03:16:04 +0000356 """Like FieldStorage, for use when no file uploads are possible."""
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000357
Guido van Rossum7aee3841996-03-07 18:00:44 +0000358 # Dummy attributes
359 filename = None
360 list = None
361 type = None
Guido van Rossum773ab271996-07-23 03:46:24 +0000362 file = None
Guido van Rossum4032c2c1996-03-09 04:04:35 +0000363 type_options = {}
Guido van Rossum7aee3841996-03-07 18:00:44 +0000364 disposition = None
365 disposition_options = {}
366 headers = {}
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000367
Guido van Rossum7aee3841996-03-07 18:00:44 +0000368 def __init__(self, name, value):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000369 """Constructor from field name and value."""
370 self.name = name
371 self.value = value
Guido van Rossum773ab271996-07-23 03:46:24 +0000372 # self.file = StringIO(value)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000373
374 def __repr__(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000375 """Return printable representation."""
Walter Dörwald70a6b492004-02-12 17:35:32 +0000376 return "MiniFieldStorage(%r, %r)" % (self.name, self.value)
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000377
378
379class FieldStorage:
380
Guido van Rossum7aee3841996-03-07 18:00:44 +0000381 """Store a sequence of fields, reading multipart/form-data.
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000382
Guido van Rossum7aee3841996-03-07 18:00:44 +0000383 This class provides naming, typing, files stored on disk, and
384 more. At the top level, it is accessible like a dictionary, whose
385 keys are the field names. (Note: None can occur as a field name.)
386 The items are either a Python list (if there's multiple values) or
387 another FieldStorage or MiniFieldStorage object. If it's a single
388 object, it has the following attributes:
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000389
Guido van Rossum7aee3841996-03-07 18:00:44 +0000390 name: the field name, if specified; otherwise None
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000391
Guido van Rossum7aee3841996-03-07 18:00:44 +0000392 filename: the filename, if specified; otherwise None; this is the
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000393 client side filename, *not* the file name on which it is
394 stored (that's a temporary file you don't deal with)
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000395
Guido van Rossum7aee3841996-03-07 18:00:44 +0000396 value: the value as a *string*; for file uploads, this
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000397 transparently reads the file every time you request the value
Guido van Rossum7aee3841996-03-07 18:00:44 +0000398
399 file: the file(-like) object from which you can read the data;
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000400 None if the data is stored a simple string
Guido van Rossum7aee3841996-03-07 18:00:44 +0000401
402 type: the content-type, or None if not specified
403
404 type_options: dictionary of options specified on the content-type
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000405 line
Guido van Rossum7aee3841996-03-07 18:00:44 +0000406
407 disposition: content-disposition, or None if not specified
408
409 disposition_options: dictionary of corresponding options
410
Armin Rigo3a703b62005-09-19 09:11:04 +0000411 headers: a dictionary(-like) object (sometimes rfc822.Message or a
412 subclass thereof) containing *all* headers
Guido van Rossum7aee3841996-03-07 18:00:44 +0000413
414 The class is subclassable, mostly for the purpose of overriding
415 the make_file() method, which is called internally to come up with
416 a file open for reading and writing. This makes it possible to
417 override the default choice of storing all files in a temporary
418 directory and unlinking them as soon as they have been opened.
419
420 """
421
Guido van Rossum773ab271996-07-23 03:46:24 +0000422 def __init__(self, fp=None, headers=None, outerboundary="",
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000423 environ=os.environ, keep_blank_values=0, strict_parsing=0):
424 """Constructor. Read multipart/* until last part.
Guido van Rossum7aee3841996-03-07 18:00:44 +0000425
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000426 Arguments, all optional:
Guido van Rossum7aee3841996-03-07 18:00:44 +0000427
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000428 fp : file pointer; default: sys.stdin
Guido van Rossumb1b4f941998-05-08 19:55:51 +0000429 (not used when the request method is GET)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000430
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000431 headers : header dictionary-like object; default:
432 taken from environ as per CGI spec
Guido van Rossum7aee3841996-03-07 18:00:44 +0000433
Guido van Rossum773ab271996-07-23 03:46:24 +0000434 outerboundary : terminating multipart boundary
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000435 (for internal use only)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000436
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000437 environ : environment dictionary; default: os.environ
Guido van Rossum773ab271996-07-23 03:46:24 +0000438
439 keep_blank_values: flag indicating whether blank values in
Tim Peters88869f92001-01-14 23:36:06 +0000440 URL encoded forms should be treated as blank strings.
441 A true value indicates that blanks should be retained as
Guido van Rossum773ab271996-07-23 03:46:24 +0000442 blank strings. The default false value indicates that
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000443 blank values are to be ignored and treated as if they were
444 not included.
Guido van Rossum773ab271996-07-23 03:46:24 +0000445
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000446 strict_parsing: flag indicating what to do with parsing errors.
447 If false (the default), errors are silently ignored.
448 If true, errors raise a ValueError exception.
Guido van Rossume08c04c1996-11-11 19:29:11 +0000449
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000450 """
451 method = 'GET'
452 self.keep_blank_values = keep_blank_values
453 self.strict_parsing = strict_parsing
Raymond Hettinger54f02222002-06-01 14:18:47 +0000454 if 'REQUEST_METHOD' in environ:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000455 method = environ['REQUEST_METHOD'].upper()
Guido van Rossum01852831998-06-25 02:40:17 +0000456 if method == 'GET' or method == 'HEAD':
Raymond Hettinger54f02222002-06-01 14:18:47 +0000457 if 'QUERY_STRING' in environ:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000458 qs = environ['QUERY_STRING']
459 elif sys.argv[1:]:
460 qs = sys.argv[1]
461 else:
462 qs = ""
463 fp = StringIO(qs)
464 if headers is None:
465 headers = {'content-type':
466 "application/x-www-form-urlencoded"}
467 if headers is None:
Guido van Rossumcff311a1998-06-11 14:06:59 +0000468 headers = {}
469 if method == 'POST':
470 # Set default content-type for POST to what's traditional
471 headers['content-type'] = "application/x-www-form-urlencoded"
Raymond Hettinger54f02222002-06-01 14:18:47 +0000472 if 'CONTENT_TYPE' in environ:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000473 headers['content-type'] = environ['CONTENT_TYPE']
Raymond Hettinger54f02222002-06-01 14:18:47 +0000474 if 'CONTENT_LENGTH' in environ:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000475 headers['content-length'] = environ['CONTENT_LENGTH']
476 self.fp = fp or sys.stdin
477 self.headers = headers
478 self.outerboundary = outerboundary
Guido van Rossum7aee3841996-03-07 18:00:44 +0000479
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000480 # Process content-disposition header
481 cdisp, pdict = "", {}
Raymond Hettinger54f02222002-06-01 14:18:47 +0000482 if 'content-disposition' in self.headers:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000483 cdisp, pdict = parse_header(self.headers['content-disposition'])
484 self.disposition = cdisp
485 self.disposition_options = pdict
486 self.name = None
Raymond Hettinger54f02222002-06-01 14:18:47 +0000487 if 'name' in pdict:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000488 self.name = pdict['name']
489 self.filename = None
Raymond Hettinger54f02222002-06-01 14:18:47 +0000490 if 'filename' in pdict:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000491 self.filename = pdict['filename']
Guido van Rossum7aee3841996-03-07 18:00:44 +0000492
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000493 # Process content-type header
Barry Warsaw302331a1999-01-08 17:42:03 +0000494 #
495 # Honor any existing content-type header. But if there is no
496 # content-type header, use some sensible defaults. Assume
497 # outerboundary is "" at the outer level, but something non-false
498 # inside a multi-part. The default for an inner part is text/plain,
499 # but for an outer part it should be urlencoded. This should catch
500 # bogus clients which erroneously forget to include a content-type
501 # header.
502 #
503 # See below for what we do if there does exist a content-type header,
504 # but it happens to be something we don't understand.
Raymond Hettinger54f02222002-06-01 14:18:47 +0000505 if 'content-type' in self.headers:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000506 ctype, pdict = parse_header(self.headers['content-type'])
Guido van Rossumce900de1999-06-02 18:44:22 +0000507 elif self.outerboundary or method != 'POST':
Barry Warsaw302331a1999-01-08 17:42:03 +0000508 ctype, pdict = "text/plain", {}
509 else:
510 ctype, pdict = 'application/x-www-form-urlencoded', {}
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000511 self.type = ctype
512 self.type_options = pdict
513 self.innerboundary = ""
Raymond Hettinger54f02222002-06-01 14:18:47 +0000514 if 'boundary' in pdict:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000515 self.innerboundary = pdict['boundary']
516 clen = -1
Raymond Hettinger54f02222002-06-01 14:18:47 +0000517 if 'content-length' in self.headers:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000518 try:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000519 clen = int(self.headers['content-length'])
Skip Montanarodb5d1442002-03-23 05:50:17 +0000520 except ValueError:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000521 pass
522 if maxlen and clen > maxlen:
523 raise ValueError, 'Maximum content length exceeded'
524 self.length = clen
Guido van Rossum7aee3841996-03-07 18:00:44 +0000525
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000526 self.list = self.file = None
527 self.done = 0
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000528 if ctype == 'application/x-www-form-urlencoded':
529 self.read_urlencoded()
530 elif ctype[:10] == 'multipart/':
Guido van Rossumf5745001998-10-20 14:43:02 +0000531 self.read_multi(environ, keep_blank_values, strict_parsing)
Barry Warsaw302331a1999-01-08 17:42:03 +0000532 else:
Guido van Rossum60a3bd81999-06-11 18:26:09 +0000533 self.read_single()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000534
535 def __repr__(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000536 """Return a printable representation."""
Walter Dörwald70a6b492004-02-12 17:35:32 +0000537 return "FieldStorage(%r, %r, %r)" % (
538 self.name, self.filename, self.value)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000539
Guido van Rossum4061cbe2002-09-11 18:20:34 +0000540 def __iter__(self):
541 return iter(self.keys())
542
Guido van Rossum7aee3841996-03-07 18:00:44 +0000543 def __getattr__(self, name):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000544 if name != 'value':
545 raise AttributeError, name
546 if self.file:
547 self.file.seek(0)
548 value = self.file.read()
549 self.file.seek(0)
550 elif self.list is not None:
551 value = self.list
552 else:
553 value = None
554 return value
Guido van Rossum7aee3841996-03-07 18:00:44 +0000555
556 def __getitem__(self, key):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000557 """Dictionary style indexing."""
558 if self.list is None:
559 raise TypeError, "not indexable"
560 found = []
561 for item in self.list:
562 if item.name == key: found.append(item)
563 if not found:
564 raise KeyError, key
565 if len(found) == 1:
566 return found[0]
567 else:
568 return found
Guido van Rossum7aee3841996-03-07 18:00:44 +0000569
Moshe Zadkaa1a4b592000-08-25 21:47:56 +0000570 def getvalue(self, key, default=None):
571 """Dictionary style get() method, including 'value' lookup."""
Raymond Hettinger54f02222002-06-01 14:18:47 +0000572 if key in self:
Moshe Zadkaa1a4b592000-08-25 21:47:56 +0000573 value = self[key]
574 if type(value) is type([]):
Guido van Rossumc1f779c2007-07-03 08:25:58 +0000575 return [x.value for x in value]
Moshe Zadkaa1a4b592000-08-25 21:47:56 +0000576 else:
577 return value.value
578 else:
579 return default
580
Guido van Rossum1bfb3882001-09-05 19:45:34 +0000581 def getfirst(self, key, default=None):
582 """ Return the first value received."""
Raymond Hettinger54f02222002-06-01 14:18:47 +0000583 if key in self:
Guido van Rossum1bfb3882001-09-05 19:45:34 +0000584 value = self[key]
585 if type(value) is type([]):
586 return value[0].value
587 else:
588 return value.value
589 else:
590 return default
591
592 def getlist(self, key):
593 """ Return list of received values."""
Raymond Hettinger54f02222002-06-01 14:18:47 +0000594 if key in self:
Guido van Rossum1bfb3882001-09-05 19:45:34 +0000595 value = self[key]
596 if type(value) is type([]):
Guido van Rossumc1f779c2007-07-03 08:25:58 +0000597 return [x.value for x in value]
Guido van Rossum1bfb3882001-09-05 19:45:34 +0000598 else:
599 return [value.value]
600 else:
601 return []
602
Guido van Rossum7aee3841996-03-07 18:00:44 +0000603 def keys(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000604 """Dictionary style keys() method."""
605 if self.list is None:
606 raise TypeError, "not indexable"
607 keys = []
608 for item in self.list:
609 if item.name not in keys: keys.append(item.name)
610 return keys
Guido van Rossum7aee3841996-03-07 18:00:44 +0000611
Raymond Hettinger54f02222002-06-01 14:18:47 +0000612 def __contains__(self, key):
613 """Dictionary style __contains__ method."""
614 if self.list is None:
615 raise TypeError, "not indexable"
616 for item in self.list:
617 if item.name == key: return True
618 return False
619
Guido van Rossum88b85d41997-01-11 19:21:33 +0000620 def __len__(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000621 """Dictionary style len(x) support."""
622 return len(self.keys())
Guido van Rossum88b85d41997-01-11 19:21:33 +0000623
Guido van Rossum7aee3841996-03-07 18:00:44 +0000624 def read_urlencoded(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000625 """Internal: read data in query string format."""
626 qs = self.fp.read(self.length)
Guido van Rossum1946f0d1999-06-04 17:54:39 +0000627 self.list = list = []
628 for key, value in parse_qsl(qs, self.keep_blank_values,
629 self.strict_parsing):
630 list.append(MiniFieldStorage(key, value))
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000631 self.skip_lines()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000632
Guido van Rossum030d2ec1998-12-09 22:16:46 +0000633 FieldStorageClass = None
634
Guido van Rossumf5745001998-10-20 14:43:02 +0000635 def read_multi(self, environ, keep_blank_values, strict_parsing):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000636 """Internal: read a part that is itself multipart."""
Guido van Rossum2e441f72001-07-25 21:00:19 +0000637 ib = self.innerboundary
638 if not valid_boundary(ib):
Walter Dörwald70a6b492004-02-12 17:35:32 +0000639 raise ValueError, 'Invalid boundary in multipart form: %r' % (ib,)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000640 self.list = []
Guido van Rossum030d2ec1998-12-09 22:16:46 +0000641 klass = self.FieldStorageClass or self.__class__
Guido van Rossum2e441f72001-07-25 21:00:19 +0000642 part = klass(self.fp, {}, ib,
Guido van Rossum030d2ec1998-12-09 22:16:46 +0000643 environ, keep_blank_values, strict_parsing)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000644 # Throw first part away
645 while not part.done:
Armin Rigo3a703b62005-09-19 09:11:04 +0000646 headers = rfc822.Message(self.fp)
Guido van Rossum2e441f72001-07-25 21:00:19 +0000647 part = klass(self.fp, headers, ib,
Guido van Rossum030d2ec1998-12-09 22:16:46 +0000648 environ, keep_blank_values, strict_parsing)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000649 self.list.append(part)
650 self.skip_lines()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000651
652 def read_single(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000653 """Internal: read an atomic part."""
654 if self.length >= 0:
655 self.read_binary()
656 self.skip_lines()
657 else:
658 self.read_lines()
659 self.file.seek(0)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000660
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000661 bufsize = 8*1024 # I/O buffering size for copy to file
Guido van Rossum7aee3841996-03-07 18:00:44 +0000662
663 def read_binary(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000664 """Internal: read binary data."""
Guido van Rossuma1a68522007-08-28 03:11:34 +0000665 self.file = self.make_file()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000666 todo = self.length
667 if todo >= 0:
668 while todo > 0:
669 data = self.fp.read(min(todo, self.bufsize))
670 if not data:
671 self.done = -1
672 break
673 self.file.write(data)
674 todo = todo - len(data)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000675
676 def read_lines(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000677 """Internal: read lines until EOF or outerboundary."""
Guido van Rossum52b8c292001-06-29 13:06:06 +0000678 self.file = self.__file = StringIO()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000679 if self.outerboundary:
680 self.read_lines_to_outerboundary()
681 else:
682 self.read_lines_to_eof()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000683
Guido van Rossum52b8c292001-06-29 13:06:06 +0000684 def __write(self, line):
685 if self.__file is not None:
686 if self.__file.tell() + len(line) > 1000:
Guido van Rossuma1a68522007-08-28 03:11:34 +0000687 self.file = self.make_file()
688 data = self.__file.getvalue()
689 self.file.write(data)
Guido van Rossum52b8c292001-06-29 13:06:06 +0000690 self.__file = None
691 self.file.write(line)
692
Guido van Rossum7aee3841996-03-07 18:00:44 +0000693 def read_lines_to_eof(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000694 """Internal: read lines until EOF."""
695 while 1:
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000696 line = self.fp.readline(1<<16)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000697 if not line:
698 self.done = -1
699 break
Guido van Rossum52b8c292001-06-29 13:06:06 +0000700 self.__write(line)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000701
702 def read_lines_to_outerboundary(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000703 """Internal: read lines until outerboundary."""
704 next = "--" + self.outerboundary
705 last = next + "--"
706 delim = ""
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000707 last_line_lfend = True
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000708 while 1:
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000709 line = self.fp.readline(1<<16)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000710 if not line:
711 self.done = -1
712 break
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000713 if line[:2] == "--" and last_line_lfend:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000714 strippedline = line.strip()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000715 if strippedline == next:
716 break
717 if strippedline == last:
718 self.done = 1
719 break
720 odelim = delim
721 if line[-2:] == "\r\n":
722 delim = "\r\n"
723 line = line[:-2]
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000724 last_line_lfend = True
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000725 elif line[-1] == "\n":
726 delim = "\n"
727 line = line[:-1]
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000728 last_line_lfend = True
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000729 else:
730 delim = ""
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000731 last_line_lfend = False
Guido van Rossum52b8c292001-06-29 13:06:06 +0000732 self.__write(odelim + line)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000733
734 def skip_lines(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000735 """Internal: skip lines until outer boundary if defined."""
736 if not self.outerboundary or self.done:
737 return
738 next = "--" + self.outerboundary
739 last = next + "--"
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000740 last_line_lfend = True
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000741 while 1:
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000742 line = self.fp.readline(1<<16)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000743 if not line:
744 self.done = -1
745 break
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000746 if line[:2] == "--" and last_line_lfend:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000747 strippedline = line.strip()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000748 if strippedline == next:
749 break
750 if strippedline == last:
751 self.done = 1
752 break
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000753 last_line_lfend = line.endswith('\n')
Guido van Rossum7aee3841996-03-07 18:00:44 +0000754
Guido van Rossuma1a68522007-08-28 03:11:34 +0000755 def make_file(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000756 """Overridable: return a readable & writable file.
Guido van Rossum7aee3841996-03-07 18:00:44 +0000757
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000758 The file will be used as follows:
759 - data is written to it
760 - seek(0)
761 - data is read from it
Guido van Rossum7aee3841996-03-07 18:00:44 +0000762
Guido van Rossuma1a68522007-08-28 03:11:34 +0000763 The file is always opened in text mode.
Guido van Rossum7aee3841996-03-07 18:00:44 +0000764
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000765 This version opens a temporary file for reading and writing,
766 and immediately deletes (unlinks) it. The trick (on Unix!) is
767 that the file can still be used, but it can't be opened by
768 another process, and it will automatically be deleted when it
769 is closed or when the current process terminates.
Guido van Rossum4032c2c1996-03-09 04:04:35 +0000770
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000771 If you want a more permanent file, you derive a class which
772 overrides this method. If you want a visible temporary file
773 that is nevertheless automatically deleted when the script
774 terminates, try defining a __del__ method in a derived class
775 which unlinks the temporary files you have created.
Guido van Rossum7aee3841996-03-07 18:00:44 +0000776
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000777 """
778 import tempfile
Guido van Rossum92bab812007-08-28 03:32:38 +0000779 return tempfile.TemporaryFile("w+", encoding="utf-8", newline="\n")
Tim Peters88869f92001-01-14 23:36:06 +0000780
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000781
782
Guido van Rossum4032c2c1996-03-09 04:04:35 +0000783# Backwards Compatibility Classes
784# ===============================
Guido van Rossum9a22de11995-01-12 12:29:47 +0000785
Moshe Zadkaa1a4b592000-08-25 21:47:56 +0000786class FormContentDict(UserDict.UserDict):
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000787 """Form content as dictionary with a list of values per field.
Guido van Rossum72755611996-03-06 07:20:06 +0000788
Guido van Rossum7aee3841996-03-07 18:00:44 +0000789 form = FormContentDict()
790
791 form[key] -> [value, value, ...]
Raymond Hettinger54f02222002-06-01 14:18:47 +0000792 key in form -> Boolean
Guido van Rossum7aee3841996-03-07 18:00:44 +0000793 form.keys() -> [key, key, ...]
794 form.values() -> [[val, val, ...], [val, val, ...], ...]
795 form.items() -> [(key, [val, val, ...]), (key, [val, val, ...]), ...]
796 form.dict == {key: [val, val, ...], ...}
797
798 """
Thomas Wouters89f507f2006-12-13 04:49:30 +0000799 def __init__(self, environ=os.environ, keep_blank_values=0, strict_parsing=0):
800 self.dict = self.data = parse(environ=environ,
801 keep_blank_values=keep_blank_values,
802 strict_parsing=strict_parsing)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000803 self.query_string = environ['QUERY_STRING']
Guido van Rossum9a22de11995-01-12 12:29:47 +0000804
805
Guido van Rossum9a22de11995-01-12 12:29:47 +0000806class SvFormContentDict(FormContentDict):
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000807 """Form content as dictionary expecting a single value per field.
Guido van Rossum7aee3841996-03-07 18:00:44 +0000808
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000809 If you only expect a single value for each field, then form[key]
Guido van Rossum7aee3841996-03-07 18:00:44 +0000810 will return that single value. It will raise an IndexError if
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000811 that expectation is not true. If you expect a field to have
Guido van Rossum7aee3841996-03-07 18:00:44 +0000812 possible multiple values, than you can use form.getlist(key) to
813 get all of the values. values() and items() are a compromise:
814 they return single strings where there is a single value, and
815 lists of strings otherwise.
816
817 """
818 def __getitem__(self, key):
Tim Peters88869f92001-01-14 23:36:06 +0000819 if len(self.dict[key]) > 1:
820 raise IndexError, 'expecting a single value'
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000821 return self.dict[key][0]
Guido van Rossum7aee3841996-03-07 18:00:44 +0000822 def getlist(self, key):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000823 return self.dict[key]
Guido van Rossum7aee3841996-03-07 18:00:44 +0000824 def values(self):
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000825 result = []
826 for value in self.dict.values():
827 if len(value) == 1:
828 result.append(value[0])
829 else: result.append(value)
830 return result
Guido van Rossum7aee3841996-03-07 18:00:44 +0000831 def items(self):
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000832 result = []
833 for key, value in self.dict.items():
834 if len(value) == 1:
835 result.append((key, value[0]))
836 else: result.append((key, value))
837 return result
Guido van Rossum9a22de11995-01-12 12:29:47 +0000838
839
Guido van Rossum9a22de11995-01-12 12:29:47 +0000840class InterpFormContentDict(SvFormContentDict):
Tim Peters88869f92001-01-14 23:36:06 +0000841 """This class is present for backwards compatibility only."""
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000842 def __getitem__(self, key):
843 v = SvFormContentDict.__getitem__(self, key)
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000844 if v[0] in '0123456789+-.':
845 try: return int(v)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000846 except ValueError:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000847 try: return float(v)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000848 except ValueError: pass
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000849 return v.strip()
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000850 def values(self):
851 result = []
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000852 for key in self.keys():
853 try:
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000854 result.append(self[key])
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000855 except IndexError:
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000856 result.append(self.dict[key])
857 return result
858 def items(self):
859 result = []
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000860 for key in self.keys():
861 try:
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000862 result.append((key, self[key]))
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000863 except IndexError:
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000864 result.append((key, self.dict[key]))
865 return result
Guido van Rossum9a22de11995-01-12 12:29:47 +0000866
867
Guido van Rossum9a22de11995-01-12 12:29:47 +0000868class FormContent(FormContentDict):
Tim Peters88869f92001-01-14 23:36:06 +0000869 """This class is present for backwards compatibility only."""
Guido van Rossum0147db01996-03-09 03:16:04 +0000870 def values(self, key):
Raymond Hettinger54f02222002-06-01 14:18:47 +0000871 if key in self.dict :return self.dict[key]
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000872 else: return None
Guido van Rossum0147db01996-03-09 03:16:04 +0000873 def indexed_value(self, key, location):
Raymond Hettinger54f02222002-06-01 14:18:47 +0000874 if key in self.dict:
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000875 if len(self.dict[key]) > location:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000876 return self.dict[key][location]
877 else: return None
878 else: return None
Guido van Rossum0147db01996-03-09 03:16:04 +0000879 def value(self, key):
Raymond Hettinger54f02222002-06-01 14:18:47 +0000880 if key in self.dict: return self.dict[key][0]
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000881 else: return None
Guido van Rossum0147db01996-03-09 03:16:04 +0000882 def length(self, key):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000883 return len(self.dict[key])
Guido van Rossum0147db01996-03-09 03:16:04 +0000884 def stripped(self, key):
Raymond Hettinger54f02222002-06-01 14:18:47 +0000885 if key in self.dict: return self.dict[key][0].strip()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000886 else: return None
Guido van Rossum7aee3841996-03-07 18:00:44 +0000887 def pars(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000888 return self.dict
Guido van Rossum9a22de11995-01-12 12:29:47 +0000889
890
Guido van Rossum72755611996-03-06 07:20:06 +0000891# Test/debug code
892# ===============
Guido van Rossum9a22de11995-01-12 12:29:47 +0000893
Guido van Rossum773ab271996-07-23 03:46:24 +0000894def test(environ=os.environ):
Guido van Rossum7aee3841996-03-07 18:00:44 +0000895 """Robust test CGI script, usable as main program.
Guido van Rossum9a22de11995-01-12 12:29:47 +0000896
Guido van Rossum7aee3841996-03-07 18:00:44 +0000897 Write minimal HTTP headers and dump all information provided to
898 the script in HTML form.
899
900 """
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000901 print("Content-type: text/html")
902 print()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000903 sys.stderr = sys.stdout
904 try:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000905 form = FieldStorage() # Replace with other classes to test those
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000906 print_directory()
907 print_arguments()
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000908 print_form(form)
909 print_environ(environ)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000910 print_environ_usage()
911 def f():
Georg Brandl7cae87c2006-09-06 06:51:57 +0000912 exec("testing print_exception() -- <I>italics?</I>")
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000913 def g(f=f):
914 f()
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000915 print("<H3>What follows is a test, not an actual exception:</H3>")
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000916 g()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000917 except:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000918 print_exception()
Guido van Rossumf85de8a1996-08-20 20:22:39 +0000919
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000920 print("<H1>Second try with a small maxlen...</H1>")
Guido van Rossum57d51f22000-09-16 21:16:01 +0000921
Guido van Rossumad164711997-05-13 19:03:23 +0000922 global maxlen
923 maxlen = 50
924 try:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000925 form = FieldStorage() # Replace with other classes to test those
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000926 print_directory()
927 print_arguments()
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000928 print_form(form)
929 print_environ(environ)
Guido van Rossumad164711997-05-13 19:03:23 +0000930 except:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000931 print_exception()
Guido van Rossumad164711997-05-13 19:03:23 +0000932
Guido van Rossumf85de8a1996-08-20 20:22:39 +0000933def print_exception(type=None, value=None, tb=None, limit=None):
934 if type is None:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000935 type, value, tb = sys.exc_info()
Guido van Rossumf85de8a1996-08-20 20:22:39 +0000936 import traceback
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000937 print()
938 print("<H3>Traceback (most recent call last):</H3>")
Guido van Rossumf85de8a1996-08-20 20:22:39 +0000939 list = traceback.format_tb(tb, limit) + \
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000940 traceback.format_exception_only(type, value)
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000941 print("<PRE>%s<B>%s</B></PRE>" % (
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000942 escape("".join(list[:-1])),
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000943 escape(list[-1]),
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000944 ))
Guido van Rossumf15d1591997-09-29 23:22:12 +0000945 del tb
Guido van Rossum9a22de11995-01-12 12:29:47 +0000946
Guido van Rossum773ab271996-07-23 03:46:24 +0000947def print_environ(environ=os.environ):
Guido van Rossum7aee3841996-03-07 18:00:44 +0000948 """Dump the shell environment as HTML."""
Guido van Rossuma1a68522007-08-28 03:11:34 +0000949 keys = sorted(environ.keys())
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000950 print()
951 print("<H3>Shell Environment:</H3>")
952 print("<DL>")
Guido van Rossum7aee3841996-03-07 18:00:44 +0000953 for key in keys:
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000954 print("<DT>", escape(key), "<DD>", escape(environ[key]))
955 print("</DL>")
956 print()
Guido van Rossum72755611996-03-06 07:20:06 +0000957
958def print_form(form):
Guido van Rossum7aee3841996-03-07 18:00:44 +0000959 """Dump the contents of a form as HTML."""
Guido van Rossuma1a68522007-08-28 03:11:34 +0000960 keys = sorted(form.keys())
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000961 print()
962 print("<H3>Form Contents:</H3>")
Guido van Rossum57d51f22000-09-16 21:16:01 +0000963 if not keys:
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000964 print("<P>No form fields.")
965 print("<DL>")
Guido van Rossum7aee3841996-03-07 18:00:44 +0000966 for key in keys:
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000967 print("<DT>" + escape(key) + ":", end=' ')
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000968 value = form[key]
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000969 print("<i>" + escape(repr(type(value))) + "</i>")
970 print("<DD>" + escape(repr(value)))
971 print("</DL>")
972 print()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000973
974def print_directory():
975 """Dump the current directory as HTML."""
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000976 print()
977 print("<H3>Current Working Directory:</H3>")
Guido van Rossum7aee3841996-03-07 18:00:44 +0000978 try:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000979 pwd = os.getcwd()
Guido van Rossumb940e112007-01-10 16:19:56 +0000980 except os.error as msg:
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000981 print("os.error:", escape(str(msg)))
Guido van Rossum7aee3841996-03-07 18:00:44 +0000982 else:
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000983 print(escape(pwd))
984 print()
Guido van Rossum9a22de11995-01-12 12:29:47 +0000985
Guido van Rossuma8738a51996-03-14 21:30:28 +0000986def print_arguments():
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000987 print()
988 print("<H3>Command Line Arguments:</H3>")
989 print()
990 print(sys.argv)
991 print()
Guido van Rossuma8738a51996-03-14 21:30:28 +0000992
Guido van Rossum9a22de11995-01-12 12:29:47 +0000993def print_environ_usage():
Guido van Rossum7aee3841996-03-07 18:00:44 +0000994 """Dump a list of environment variables used by CGI as HTML."""
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000995 print("""
Guido van Rossum72755611996-03-06 07:20:06 +0000996<H3>These environment variables could have been set:</H3>
997<UL>
Guido van Rossum9a22de11995-01-12 12:29:47 +0000998<LI>AUTH_TYPE
999<LI>CONTENT_LENGTH
1000<LI>CONTENT_TYPE
1001<LI>DATE_GMT
1002<LI>DATE_LOCAL
1003<LI>DOCUMENT_NAME
1004<LI>DOCUMENT_ROOT
1005<LI>DOCUMENT_URI
1006<LI>GATEWAY_INTERFACE
1007<LI>LAST_MODIFIED
1008<LI>PATH
1009<LI>PATH_INFO
1010<LI>PATH_TRANSLATED
1011<LI>QUERY_STRING
1012<LI>REMOTE_ADDR
1013<LI>REMOTE_HOST
1014<LI>REMOTE_IDENT
1015<LI>REMOTE_USER
1016<LI>REQUEST_METHOD
1017<LI>SCRIPT_NAME
1018<LI>SERVER_NAME
1019<LI>SERVER_PORT
1020<LI>SERVER_PROTOCOL
1021<LI>SERVER_ROOT
1022<LI>SERVER_SOFTWARE
1023</UL>
Guido van Rossum7aee3841996-03-07 18:00:44 +00001024In addition, HTTP headers sent by the server may be passed in the
1025environment as well. Here are some common variable names:
1026<UL>
1027<LI>HTTP_ACCEPT
1028<LI>HTTP_CONNECTION
1029<LI>HTTP_HOST
1030<LI>HTTP_PRAGMA
1031<LI>HTTP_REFERER
1032<LI>HTTP_USER_AGENT
1033</UL>
Guido van Rossumbe19ed72007-02-09 05:37:30 +00001034""")
Guido van Rossum9a22de11995-01-12 12:29:47 +00001035
Guido van Rossum9a22de11995-01-12 12:29:47 +00001036
Guido van Rossum72755611996-03-06 07:20:06 +00001037# Utilities
1038# =========
Guido van Rossum9a22de11995-01-12 12:29:47 +00001039
Guido van Rossum64c66201997-07-19 20:11:53 +00001040def escape(s, quote=None):
Skip Montanaro97b2fa22005-08-02 02:50:25 +00001041 '''Replace special characters "&", "<" and ">" to HTML-safe sequences.
1042 If the optional flag quote is true, the quotation mark character (")
1043 is also translated.'''
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +00001044 s = s.replace("&", "&amp;") # Must be done first!
1045 s = s.replace("<", "&lt;")
1046 s = s.replace(">", "&gt;")
Guido van Rossum64c66201997-07-19 20:11:53 +00001047 if quote:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +00001048 s = s.replace('"', "&quot;")
Guido van Rossum7aee3841996-03-07 18:00:44 +00001049 return s
Guido van Rossum9a22de11995-01-12 12:29:47 +00001050
Guido van Rossum2e441f72001-07-25 21:00:19 +00001051def valid_boundary(s, _vb_pattern="^[ -~]{0,200}[!-~]$"):
1052 import re
1053 return re.match(_vb_pattern, s)
Guido van Rossum9a22de11995-01-12 12:29:47 +00001054
Guido van Rossum72755611996-03-06 07:20:06 +00001055# Invoke mainline
1056# ===============
1057
1058# Call test() when this file is run as a script (not imported as a module)
Tim Peters88869f92001-01-14 23:36:06 +00001059if __name__ == '__main__':
Guido van Rossum7aee3841996-03-07 18:00:44 +00001060 test()