blob: 268aea0c4c90e139d6cc1bb1a60c129670dda31e [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
Guido van Rossuma5e9fb61997-08-12 18:18:13 +000041import mimetools
42import rfc822
Moshe Zadkaa1a4b592000-08-25 21:47:56 +000043import UserDict
Raymond Hettingera6172712004-12-31 19:15:26 +000044try:
45 from cStringIO import StringIO
46except ImportError:
47 from StringIO import StringIO
Guido van Rossum72755611996-03-06 07:20:06 +000048
Guido van Rossuma8423a92001-03-19 13:40:44 +000049__all__ = ["MiniFieldStorage", "FieldStorage", "FormContentDict",
50 "SvFormContentDict", "InterpFormContentDict", "FormContent",
51 "parse", "parse_qs", "parse_qsl", "parse_multipart",
52 "parse_header", "print_exception", "print_environ",
53 "print_form", "print_directory", "print_arguments",
54 "print_environ_usage", "escape"]
Guido van Rossumc204c701996-09-05 19:07:11 +000055
56# Logging support
57# ===============
58
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000059logfile = "" # Filename to log to, if not empty
60logfp = None # File object to log to, if not None
Guido van Rossumc204c701996-09-05 19:07:11 +000061
62def initlog(*allargs):
63 """Write a log message, if there is a log file.
64
65 Even though this function is called initlog(), you should always
66 use log(); log is a variable that is set either to initlog
67 (initially), to dolog (once the log file has been opened), or to
68 nolog (when logging is disabled).
69
70 The first argument is a format string; the remaining arguments (if
71 any) are arguments to the % operator, so e.g.
72 log("%s: %s", "a", "b")
73 will write "a: b" to the log file, followed by a newline.
74
75 If the global logfp is not None, it should be a file object to
76 which log data is written.
77
78 If the global logfp is None, the global logfile may be a string
79 giving a filename to open, in append mode. This file should be
80 world writable!!! If the file can't be opened, logging is
81 silently disabled (since there is no safe place where we could
82 send an error message).
83
84 """
85 global logfp, log
86 if logfile and not logfp:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000087 try:
88 logfp = open(logfile, "a")
89 except IOError:
90 pass
Guido van Rossumc204c701996-09-05 19:07:11 +000091 if not logfp:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000092 log = nolog
Guido van Rossumc204c701996-09-05 19:07:11 +000093 else:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000094 log = dolog
Guido van Rossum68468eb2003-02-27 20:14:51 +000095 log(*allargs)
Guido van Rossumc204c701996-09-05 19:07:11 +000096
97def dolog(fmt, *args):
98 """Write a log message to the log file. See initlog() for docs."""
99 logfp.write(fmt%args + "\n")
100
101def nolog(*allargs):
102 """Dummy function, assigned to log when logging is disabled."""
103 pass
104
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000105log = initlog # The current logging function
Guido van Rossumc204c701996-09-05 19:07:11 +0000106
107
Guido van Rossum72755611996-03-06 07:20:06 +0000108# Parsing functions
109# =================
110
Guido van Rossumad164711997-05-13 19:03:23 +0000111# Maximum input we will accept when REQUEST_METHOD is POST
112# 0 ==> unlimited input
113maxlen = 0
114
Guido van Rossume08c04c1996-11-11 19:29:11 +0000115def parse(fp=None, environ=os.environ, keep_blank_values=0, strict_parsing=0):
Guido van Rossum773ab271996-07-23 03:46:24 +0000116 """Parse a query in the environment or from a file (default stdin)
117
118 Arguments, all optional:
119
120 fp : file pointer; default: sys.stdin
121
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000122 environ : environment dictionary; default: os.environ
Guido van Rossum773ab271996-07-23 03:46:24 +0000123
124 keep_blank_values: flag indicating whether blank values in
Tim Peters88869f92001-01-14 23:36:06 +0000125 URL encoded forms should be treated as blank strings.
126 A true value indicates that blanks should be retained as
Guido van Rossum773ab271996-07-23 03:46:24 +0000127 blank strings. The default false value indicates that
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000128 blank values are to be ignored and treated as if they were
129 not included.
Guido van Rossume08c04c1996-11-11 19:29:11 +0000130
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000131 strict_parsing: flag indicating what to do with parsing errors.
132 If false (the default), errors are silently ignored.
133 If true, errors raise a ValueError exception.
Guido van Rossum773ab271996-07-23 03:46:24 +0000134 """
Raymond Hettingera1449002002-05-31 23:54:44 +0000135 if fp is None:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000136 fp = sys.stdin
Raymond Hettinger54f02222002-06-01 14:18:47 +0000137 if not 'REQUEST_METHOD' in environ:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000138 environ['REQUEST_METHOD'] = 'GET' # For testing stand-alone
Guido van Rossum7aee3841996-03-07 18:00:44 +0000139 if environ['REQUEST_METHOD'] == 'POST':
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000140 ctype, pdict = parse_header(environ['CONTENT_TYPE'])
141 if ctype == 'multipart/form-data':
142 return parse_multipart(fp, pdict)
143 elif ctype == 'application/x-www-form-urlencoded':
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000144 clength = int(environ['CONTENT_LENGTH'])
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000145 if maxlen and clength > maxlen:
146 raise ValueError, 'Maximum content length exceeded'
147 qs = fp.read(clength)
148 else:
149 qs = '' # Unknown content-type
Raymond Hettinger54f02222002-06-01 14:18:47 +0000150 if 'QUERY_STRING' in environ:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000151 if qs: qs = qs + '&'
152 qs = qs + environ['QUERY_STRING']
Tim Peters88869f92001-01-14 23:36:06 +0000153 elif sys.argv[1:]:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000154 if qs: qs = qs + '&'
155 qs = qs + sys.argv[1]
156 environ['QUERY_STRING'] = qs # XXX Shouldn't, really
Raymond Hettinger54f02222002-06-01 14:18:47 +0000157 elif 'QUERY_STRING' in environ:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000158 qs = environ['QUERY_STRING']
Guido van Rossum7aee3841996-03-07 18:00:44 +0000159 else:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000160 if sys.argv[1:]:
161 qs = sys.argv[1]
162 else:
163 qs = ""
164 environ['QUERY_STRING'] = qs # XXX Shouldn't, really
Guido van Rossume08c04c1996-11-11 19:29:11 +0000165 return parse_qs(qs, keep_blank_values, strict_parsing)
Guido van Rossume7808771995-08-07 20:12:09 +0000166
167
Guido van Rossume08c04c1996-11-11 19:29:11 +0000168def parse_qs(qs, keep_blank_values=0, strict_parsing=0):
169 """Parse a query given as a string argument.
Guido van Rossum773ab271996-07-23 03:46:24 +0000170
171 Arguments:
172
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000173 qs: URL-encoded query string to be parsed
Guido van Rossum773ab271996-07-23 03:46:24 +0000174
175 keep_blank_values: flag indicating whether blank values in
Tim Peters88869f92001-01-14 23:36:06 +0000176 URL encoded queries should be treated as blank strings.
177 A true value indicates that blanks should be retained as
Guido van Rossum773ab271996-07-23 03:46:24 +0000178 blank strings. The default false value indicates that
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000179 blank values are to be ignored and treated as if they were
180 not included.
Guido van Rossume08c04c1996-11-11 19:29:11 +0000181
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000182 strict_parsing: flag indicating what to do with parsing errors.
183 If false (the default), errors are silently ignored.
184 If true, errors raise a ValueError exception.
Guido van Rossum773ab271996-07-23 03:46:24 +0000185 """
Guido van Rossum7aee3841996-03-07 18:00:44 +0000186 dict = {}
Guido van Rossum1946f0d1999-06-04 17:54:39 +0000187 for name, value in parse_qsl(qs, keep_blank_values, strict_parsing):
Raymond Hettinger54f02222002-06-01 14:18:47 +0000188 if name in dict:
Moshe Zadkaa1a4b592000-08-25 21:47:56 +0000189 dict[name].append(value)
190 else:
191 dict[name] = [value]
Guido van Rossum1946f0d1999-06-04 17:54:39 +0000192 return dict
193
194def parse_qsl(qs, keep_blank_values=0, strict_parsing=0):
195 """Parse a query given as a string argument.
196
Jeremy Hyltonafde7e22000-09-15 20:06:57 +0000197 Arguments:
Guido van Rossum1946f0d1999-06-04 17:54:39 +0000198
Jeremy Hyltonafde7e22000-09-15 20:06:57 +0000199 qs: URL-encoded query string to be parsed
Guido van Rossum1946f0d1999-06-04 17:54:39 +0000200
Jeremy Hyltonafde7e22000-09-15 20:06:57 +0000201 keep_blank_values: flag indicating whether blank values in
202 URL encoded queries should be treated as blank strings. A
203 true value indicates that blanks should be retained as blank
204 strings. The default false value indicates that blank values
205 are to be ignored and treated as if they were not included.
Guido van Rossum1946f0d1999-06-04 17:54:39 +0000206
Jeremy Hyltonafde7e22000-09-15 20:06:57 +0000207 strict_parsing: flag indicating what to do with parsing errors. If
208 false (the default), errors are silently ignored. If true,
Tim Peters88869f92001-01-14 23:36:06 +0000209 errors raise a ValueError exception.
Guido van Rossum1946f0d1999-06-04 17:54:39 +0000210
Jeremy Hyltonafde7e22000-09-15 20:06:57 +0000211 Returns a list, as G-d intended.
Guido van Rossum1946f0d1999-06-04 17:54:39 +0000212 """
Jeremy Hyltonafde7e22000-09-15 20:06:57 +0000213 pairs = [s2 for s1 in qs.split('&') for s2 in s1.split(';')]
214 r = []
215 for name_value in pairs:
Neil Schemenauer66edb622004-07-19 15:38:11 +0000216 if not name_value and not strict_parsing:
217 continue
Jeremy Hyltonafde7e22000-09-15 20:06:57 +0000218 nv = name_value.split('=', 1)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000219 if len(nv) != 2:
220 if strict_parsing:
Walter Dörwald70a6b492004-02-12 17:35:32 +0000221 raise ValueError, "bad query field: %r" % (name_value,)
Brett Cannon8d9b60f2004-03-21 22:16:15 +0000222 # Handle case of a control-name with no equal sign
223 if keep_blank_values:
224 nv.append('')
225 else:
226 continue
Moshe Zadkaa1a4b592000-08-25 21:47:56 +0000227 if len(nv[1]) or keep_blank_values:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000228 name = urllib.unquote(nv[0].replace('+', ' '))
229 value = urllib.unquote(nv[1].replace('+', ' '))
Moshe Zadkaa1a4b592000-08-25 21:47:56 +0000230 r.append((name, value))
Guido van Rossum1946f0d1999-06-04 17:54:39 +0000231
232 return r
Guido van Rossum9a22de11995-01-12 12:29:47 +0000233
234
Guido van Rossum0147db01996-03-09 03:16:04 +0000235def parse_multipart(fp, pdict):
Guido van Rossum7aee3841996-03-07 18:00:44 +0000236 """Parse multipart input.
Guido van Rossum9a22de11995-01-12 12:29:47 +0000237
Guido van Rossum7aee3841996-03-07 18:00:44 +0000238 Arguments:
239 fp : input file
Guido van Rossum7aee3841996-03-07 18:00:44 +0000240 pdict: dictionary containing other parameters of conten-type header
Guido van Rossum72755611996-03-06 07:20:06 +0000241
Tim Peters88869f92001-01-14 23:36:06 +0000242 Returns a dictionary just like parse_qs(): keys are the field names, each
243 value is a list of values for that field. This is easy to use but not
244 much good if you are expecting megabytes to be uploaded -- in that case,
245 use the FieldStorage class instead which is much more flexible. Note
246 that content-type is the raw, unparsed contents of the content-type
Guido van Rossum0147db01996-03-09 03:16:04 +0000247 header.
Tim Peters88869f92001-01-14 23:36:06 +0000248
249 XXX This does not parse nested multipart parts -- use FieldStorage for
Guido van Rossum0147db01996-03-09 03:16:04 +0000250 that.
Tim Peters88869f92001-01-14 23:36:06 +0000251
252 XXX This should really be subsumed by FieldStorage altogether -- no
Guido van Rossum0147db01996-03-09 03:16:04 +0000253 point in having two implementations of the same parsing algorithm.
Guido van Rossum72755611996-03-06 07:20:06 +0000254
Guido van Rossum7aee3841996-03-07 18:00:44 +0000255 """
Guido van Rossum2e441f72001-07-25 21:00:19 +0000256 boundary = ""
Raymond Hettinger54f02222002-06-01 14:18:47 +0000257 if 'boundary' in pdict:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000258 boundary = pdict['boundary']
Guido van Rossum2e441f72001-07-25 21:00:19 +0000259 if not valid_boundary(boundary):
Walter Dörwald70a6b492004-02-12 17:35:32 +0000260 raise ValueError, ('Invalid boundary in multipart form: %r'
261 % (boundary,))
Tim Petersab9ba272001-08-09 21:40:30 +0000262
Guido van Rossum7aee3841996-03-07 18:00:44 +0000263 nextpart = "--" + boundary
264 lastpart = "--" + boundary + "--"
265 partdict = {}
266 terminator = ""
267
268 while terminator != lastpart:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000269 bytes = -1
270 data = None
271 if terminator:
272 # At start of next part. Read headers first.
273 headers = mimetools.Message(fp)
274 clength = headers.getheader('content-length')
275 if clength:
276 try:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000277 bytes = int(clength)
278 except ValueError:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000279 pass
280 if bytes > 0:
281 if maxlen and bytes > maxlen:
282 raise ValueError, 'Maximum content length exceeded'
283 data = fp.read(bytes)
284 else:
285 data = ""
286 # Read lines until end of part.
287 lines = []
288 while 1:
289 line = fp.readline()
290 if not line:
291 terminator = lastpart # End outer loop
292 break
293 if line[:2] == "--":
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000294 terminator = line.strip()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000295 if terminator in (nextpart, lastpart):
296 break
297 lines.append(line)
298 # Done with part.
299 if data is None:
300 continue
301 if bytes < 0:
302 if lines:
303 # Strip final line terminator
304 line = lines[-1]
305 if line[-2:] == "\r\n":
306 line = line[:-2]
307 elif line[-1:] == "\n":
308 line = line[:-1]
309 lines[-1] = line
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000310 data = "".join(lines)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000311 line = headers['content-disposition']
312 if not line:
313 continue
314 key, params = parse_header(line)
315 if key != 'form-data':
316 continue
Raymond Hettinger54f02222002-06-01 14:18:47 +0000317 if 'name' in params:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000318 name = params['name']
319 else:
320 continue
Raymond Hettinger54f02222002-06-01 14:18:47 +0000321 if name in partdict:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000322 partdict[name].append(data)
323 else:
324 partdict[name] = [data]
Guido van Rossum72755611996-03-06 07:20:06 +0000325
Guido van Rossum7aee3841996-03-07 18:00:44 +0000326 return partdict
Guido van Rossum9a22de11995-01-12 12:29:47 +0000327
328
Guido van Rossum72755611996-03-06 07:20:06 +0000329def parse_header(line):
Guido van Rossum7aee3841996-03-07 18:00:44 +0000330 """Parse a Content-type like header.
331
332 Return the main content-type and a dictionary of options.
333
334 """
Raymond Hettingerf871d832004-12-31 21:59:02 +0000335 plist = [x.strip() for x in line.split(';')]
Raymond Hettinger46ac8eb2002-06-30 03:39:14 +0000336 key = plist.pop(0).lower()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000337 pdict = {}
338 for p in plist:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000339 i = p.find('=')
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000340 if i >= 0:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000341 name = p[:i].strip().lower()
342 value = p[i+1:].strip()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000343 if len(value) >= 2 and value[0] == value[-1] == '"':
344 value = value[1:-1]
Johannes Gijsbers9e15dd62004-08-14 15:39:34 +0000345 value = value.replace('\\\\', '\\').replace('\\"', '"')
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000346 pdict[name] = value
Guido van Rossum7aee3841996-03-07 18:00:44 +0000347 return key, pdict
Guido van Rossum72755611996-03-06 07:20:06 +0000348
349
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000350# Classes for field storage
351# =========================
352
353class MiniFieldStorage:
354
Guido van Rossum0147db01996-03-09 03:16:04 +0000355 """Like FieldStorage, for use when no file uploads are possible."""
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000356
Guido van Rossum7aee3841996-03-07 18:00:44 +0000357 # Dummy attributes
358 filename = None
359 list = None
360 type = None
Guido van Rossum773ab271996-07-23 03:46:24 +0000361 file = None
Guido van Rossum4032c2c1996-03-09 04:04:35 +0000362 type_options = {}
Guido van Rossum7aee3841996-03-07 18:00:44 +0000363 disposition = None
364 disposition_options = {}
365 headers = {}
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000366
Guido van Rossum7aee3841996-03-07 18:00:44 +0000367 def __init__(self, name, value):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000368 """Constructor from field name and value."""
369 self.name = name
370 self.value = value
Guido van Rossum773ab271996-07-23 03:46:24 +0000371 # self.file = StringIO(value)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000372
373 def __repr__(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000374 """Return printable representation."""
Walter Dörwald70a6b492004-02-12 17:35:32 +0000375 return "MiniFieldStorage(%r, %r)" % (self.name, self.value)
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000376
377
378class FieldStorage:
379
Guido van Rossum7aee3841996-03-07 18:00:44 +0000380 """Store a sequence of fields, reading multipart/form-data.
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000381
Guido van Rossum7aee3841996-03-07 18:00:44 +0000382 This class provides naming, typing, files stored on disk, and
383 more. At the top level, it is accessible like a dictionary, whose
384 keys are the field names. (Note: None can occur as a field name.)
385 The items are either a Python list (if there's multiple values) or
386 another FieldStorage or MiniFieldStorage object. If it's a single
387 object, it has the following attributes:
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000388
Guido van Rossum7aee3841996-03-07 18:00:44 +0000389 name: the field name, if specified; otherwise None
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000390
Guido van Rossum7aee3841996-03-07 18:00:44 +0000391 filename: the filename, if specified; otherwise None; this is the
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000392 client side filename, *not* the file name on which it is
393 stored (that's a temporary file you don't deal with)
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000394
Guido van Rossum7aee3841996-03-07 18:00:44 +0000395 value: the value as a *string*; for file uploads, this
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000396 transparently reads the file every time you request the value
Guido van Rossum7aee3841996-03-07 18:00:44 +0000397
398 file: the file(-like) object from which you can read the data;
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000399 None if the data is stored a simple string
Guido van Rossum7aee3841996-03-07 18:00:44 +0000400
401 type: the content-type, or None if not specified
402
403 type_options: dictionary of options specified on the content-type
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000404 line
Guido van Rossum7aee3841996-03-07 18:00:44 +0000405
406 disposition: content-disposition, or None if not specified
407
408 disposition_options: dictionary of corresponding options
409
410 headers: a dictionary(-like) object (sometimes rfc822.Message or a
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000411 subclass thereof) containing *all* headers
Guido van Rossum7aee3841996-03-07 18:00:44 +0000412
413 The class is subclassable, mostly for the purpose of overriding
414 the make_file() method, which is called internally to come up with
415 a file open for reading and writing. This makes it possible to
416 override the default choice of storing all files in a temporary
417 directory and unlinking them as soon as they have been opened.
418
419 """
420
Guido van Rossum773ab271996-07-23 03:46:24 +0000421 def __init__(self, fp=None, headers=None, outerboundary="",
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000422 environ=os.environ, keep_blank_values=0, strict_parsing=0):
423 """Constructor. Read multipart/* until last part.
Guido van Rossum7aee3841996-03-07 18:00:44 +0000424
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000425 Arguments, all optional:
Guido van Rossum7aee3841996-03-07 18:00:44 +0000426
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000427 fp : file pointer; default: sys.stdin
Guido van Rossumb1b4f941998-05-08 19:55:51 +0000428 (not used when the request method is GET)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000429
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000430 headers : header dictionary-like object; default:
431 taken from environ as per CGI spec
Guido van Rossum7aee3841996-03-07 18:00:44 +0000432
Guido van Rossum773ab271996-07-23 03:46:24 +0000433 outerboundary : terminating multipart boundary
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000434 (for internal use only)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000435
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000436 environ : environment dictionary; default: os.environ
Guido van Rossum773ab271996-07-23 03:46:24 +0000437
438 keep_blank_values: flag indicating whether blank values in
Tim Peters88869f92001-01-14 23:36:06 +0000439 URL encoded forms should be treated as blank strings.
440 A true value indicates that blanks should be retained as
Guido van Rossum773ab271996-07-23 03:46:24 +0000441 blank strings. The default false value indicates that
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000442 blank values are to be ignored and treated as if they were
443 not included.
Guido van Rossum773ab271996-07-23 03:46:24 +0000444
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000445 strict_parsing: flag indicating what to do with parsing errors.
446 If false (the default), errors are silently ignored.
447 If true, errors raise a ValueError exception.
Guido van Rossume08c04c1996-11-11 19:29:11 +0000448
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000449 """
450 method = 'GET'
451 self.keep_blank_values = keep_blank_values
452 self.strict_parsing = strict_parsing
Raymond Hettinger54f02222002-06-01 14:18:47 +0000453 if 'REQUEST_METHOD' in environ:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000454 method = environ['REQUEST_METHOD'].upper()
Guido van Rossum01852831998-06-25 02:40:17 +0000455 if method == 'GET' or method == 'HEAD':
Raymond Hettinger54f02222002-06-01 14:18:47 +0000456 if 'QUERY_STRING' in environ:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000457 qs = environ['QUERY_STRING']
458 elif sys.argv[1:]:
459 qs = sys.argv[1]
460 else:
461 qs = ""
462 fp = StringIO(qs)
463 if headers is None:
464 headers = {'content-type':
465 "application/x-www-form-urlencoded"}
466 if headers is None:
Guido van Rossumcff311a1998-06-11 14:06:59 +0000467 headers = {}
468 if method == 'POST':
469 # Set default content-type for POST to what's traditional
470 headers['content-type'] = "application/x-www-form-urlencoded"
Raymond Hettinger54f02222002-06-01 14:18:47 +0000471 if 'CONTENT_TYPE' in environ:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000472 headers['content-type'] = environ['CONTENT_TYPE']
Raymond Hettinger54f02222002-06-01 14:18:47 +0000473 if 'CONTENT_LENGTH' in environ:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000474 headers['content-length'] = environ['CONTENT_LENGTH']
475 self.fp = fp or sys.stdin
476 self.headers = headers
477 self.outerboundary = outerboundary
Guido van Rossum7aee3841996-03-07 18:00:44 +0000478
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000479 # Process content-disposition header
480 cdisp, pdict = "", {}
Raymond Hettinger54f02222002-06-01 14:18:47 +0000481 if 'content-disposition' in self.headers:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000482 cdisp, pdict = parse_header(self.headers['content-disposition'])
483 self.disposition = cdisp
484 self.disposition_options = pdict
485 self.name = None
Raymond Hettinger54f02222002-06-01 14:18:47 +0000486 if 'name' in pdict:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000487 self.name = pdict['name']
488 self.filename = None
Raymond Hettinger54f02222002-06-01 14:18:47 +0000489 if 'filename' in pdict:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000490 self.filename = pdict['filename']
Guido van Rossum7aee3841996-03-07 18:00:44 +0000491
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000492 # Process content-type header
Barry Warsaw302331a1999-01-08 17:42:03 +0000493 #
494 # Honor any existing content-type header. But if there is no
495 # content-type header, use some sensible defaults. Assume
496 # outerboundary is "" at the outer level, but something non-false
497 # inside a multi-part. The default for an inner part is text/plain,
498 # but for an outer part it should be urlencoded. This should catch
499 # bogus clients which erroneously forget to include a content-type
500 # header.
501 #
502 # See below for what we do if there does exist a content-type header,
503 # but it happens to be something we don't understand.
Raymond Hettinger54f02222002-06-01 14:18:47 +0000504 if 'content-type' in self.headers:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000505 ctype, pdict = parse_header(self.headers['content-type'])
Guido van Rossumce900de1999-06-02 18:44:22 +0000506 elif self.outerboundary or method != 'POST':
Barry Warsaw302331a1999-01-08 17:42:03 +0000507 ctype, pdict = "text/plain", {}
508 else:
509 ctype, pdict = 'application/x-www-form-urlencoded', {}
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000510 self.type = ctype
511 self.type_options = pdict
512 self.innerboundary = ""
Raymond Hettinger54f02222002-06-01 14:18:47 +0000513 if 'boundary' in pdict:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000514 self.innerboundary = pdict['boundary']
515 clen = -1
Raymond Hettinger54f02222002-06-01 14:18:47 +0000516 if 'content-length' in self.headers:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000517 try:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000518 clen = int(self.headers['content-length'])
Skip Montanarodb5d1442002-03-23 05:50:17 +0000519 except ValueError:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000520 pass
521 if maxlen and clen > maxlen:
522 raise ValueError, 'Maximum content length exceeded'
523 self.length = clen
Guido van Rossum7aee3841996-03-07 18:00:44 +0000524
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000525 self.list = self.file = None
526 self.done = 0
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000527 if ctype == 'application/x-www-form-urlencoded':
528 self.read_urlencoded()
529 elif ctype[:10] == 'multipart/':
Guido van Rossumf5745001998-10-20 14:43:02 +0000530 self.read_multi(environ, keep_blank_values, strict_parsing)
Barry Warsaw302331a1999-01-08 17:42:03 +0000531 else:
Guido van Rossum60a3bd81999-06-11 18:26:09 +0000532 self.read_single()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000533
534 def __repr__(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000535 """Return a printable representation."""
Walter Dörwald70a6b492004-02-12 17:35:32 +0000536 return "FieldStorage(%r, %r, %r)" % (
537 self.name, self.filename, self.value)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000538
Guido van Rossum4061cbe2002-09-11 18:20:34 +0000539 def __iter__(self):
540 return iter(self.keys())
541
Guido van Rossum7aee3841996-03-07 18:00:44 +0000542 def __getattr__(self, name):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000543 if name != 'value':
544 raise AttributeError, name
545 if self.file:
546 self.file.seek(0)
547 value = self.file.read()
548 self.file.seek(0)
549 elif self.list is not None:
550 value = self.list
551 else:
552 value = None
553 return value
Guido van Rossum7aee3841996-03-07 18:00:44 +0000554
555 def __getitem__(self, key):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000556 """Dictionary style indexing."""
557 if self.list is None:
558 raise TypeError, "not indexable"
559 found = []
560 for item in self.list:
561 if item.name == key: found.append(item)
562 if not found:
563 raise KeyError, key
564 if len(found) == 1:
565 return found[0]
566 else:
567 return found
Guido van Rossum7aee3841996-03-07 18:00:44 +0000568
Moshe Zadkaa1a4b592000-08-25 21:47:56 +0000569 def getvalue(self, key, default=None):
570 """Dictionary style get() method, including 'value' lookup."""
Raymond Hettinger54f02222002-06-01 14:18:47 +0000571 if key in self:
Moshe Zadkaa1a4b592000-08-25 21:47:56 +0000572 value = self[key]
573 if type(value) is type([]):
Raymond Hettingerf871d832004-12-31 21:59:02 +0000574 return map(attrgetter('value'), value)
Moshe Zadkaa1a4b592000-08-25 21:47:56 +0000575 else:
576 return value.value
577 else:
578 return default
579
Guido van Rossum1bfb3882001-09-05 19:45:34 +0000580 def getfirst(self, key, default=None):
581 """ Return the first value received."""
Raymond Hettinger54f02222002-06-01 14:18:47 +0000582 if key in self:
Guido van Rossum1bfb3882001-09-05 19:45:34 +0000583 value = self[key]
584 if type(value) is type([]):
585 return value[0].value
586 else:
587 return value.value
588 else:
589 return default
590
591 def getlist(self, key):
592 """ Return list of received values."""
Raymond Hettinger54f02222002-06-01 14:18:47 +0000593 if key in self:
Guido van Rossum1bfb3882001-09-05 19:45:34 +0000594 value = self[key]
595 if type(value) is type([]):
Raymond Hettingerf871d832004-12-31 21:59:02 +0000596 return map(attrgetter('value'), value)
Guido van Rossum1bfb3882001-09-05 19:45:34 +0000597 else:
598 return [value.value]
599 else:
600 return []
601
Guido van Rossum7aee3841996-03-07 18:00:44 +0000602 def keys(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000603 """Dictionary style keys() method."""
604 if self.list is None:
605 raise TypeError, "not indexable"
606 keys = []
607 for item in self.list:
608 if item.name not in keys: keys.append(item.name)
609 return keys
Guido van Rossum7aee3841996-03-07 18:00:44 +0000610
Guido van Rossum0147db01996-03-09 03:16:04 +0000611 def has_key(self, key):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000612 """Dictionary style has_key() method."""
613 if self.list is None:
614 raise TypeError, "not indexable"
615 for item in self.list:
Tim Petersbc0e9102002-04-04 22:55:58 +0000616 if item.name == key: return True
617 return False
Guido van Rossum0147db01996-03-09 03:16:04 +0000618
Raymond Hettinger54f02222002-06-01 14:18:47 +0000619 def __contains__(self, key):
620 """Dictionary style __contains__ method."""
621 if self.list is None:
622 raise TypeError, "not indexable"
623 for item in self.list:
624 if item.name == key: return True
625 return False
626
Guido van Rossum88b85d41997-01-11 19:21:33 +0000627 def __len__(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000628 """Dictionary style len(x) support."""
629 return len(self.keys())
Guido van Rossum88b85d41997-01-11 19:21:33 +0000630
Guido van Rossum7aee3841996-03-07 18:00:44 +0000631 def read_urlencoded(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000632 """Internal: read data in query string format."""
633 qs = self.fp.read(self.length)
Guido van Rossum1946f0d1999-06-04 17:54:39 +0000634 self.list = list = []
635 for key, value in parse_qsl(qs, self.keep_blank_values,
636 self.strict_parsing):
637 list.append(MiniFieldStorage(key, value))
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000638 self.skip_lines()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000639
Guido van Rossum030d2ec1998-12-09 22:16:46 +0000640 FieldStorageClass = None
641
Guido van Rossumf5745001998-10-20 14:43:02 +0000642 def read_multi(self, environ, keep_blank_values, strict_parsing):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000643 """Internal: read a part that is itself multipart."""
Guido van Rossum2e441f72001-07-25 21:00:19 +0000644 ib = self.innerboundary
645 if not valid_boundary(ib):
Walter Dörwald70a6b492004-02-12 17:35:32 +0000646 raise ValueError, 'Invalid boundary in multipart form: %r' % (ib,)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000647 self.list = []
Guido van Rossum030d2ec1998-12-09 22:16:46 +0000648 klass = self.FieldStorageClass or self.__class__
Guido van Rossum2e441f72001-07-25 21:00:19 +0000649 part = klass(self.fp, {}, ib,
Guido van Rossum030d2ec1998-12-09 22:16:46 +0000650 environ, keep_blank_values, strict_parsing)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000651 # Throw first part away
652 while not part.done:
653 headers = rfc822.Message(self.fp)
Guido van Rossum2e441f72001-07-25 21:00:19 +0000654 part = klass(self.fp, headers, ib,
Guido van Rossum030d2ec1998-12-09 22:16:46 +0000655 environ, keep_blank_values, strict_parsing)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000656 self.list.append(part)
657 self.skip_lines()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000658
659 def read_single(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000660 """Internal: read an atomic part."""
661 if self.length >= 0:
662 self.read_binary()
663 self.skip_lines()
664 else:
665 self.read_lines()
666 self.file.seek(0)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000667
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000668 bufsize = 8*1024 # I/O buffering size for copy to file
Guido van Rossum7aee3841996-03-07 18:00:44 +0000669
670 def read_binary(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000671 """Internal: read binary data."""
672 self.file = self.make_file('b')
673 todo = self.length
674 if todo >= 0:
675 while todo > 0:
676 data = self.fp.read(min(todo, self.bufsize))
677 if not data:
678 self.done = -1
679 break
680 self.file.write(data)
681 todo = todo - len(data)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000682
683 def read_lines(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000684 """Internal: read lines until EOF or outerboundary."""
Guido van Rossum52b8c292001-06-29 13:06:06 +0000685 self.file = self.__file = StringIO()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000686 if self.outerboundary:
687 self.read_lines_to_outerboundary()
688 else:
689 self.read_lines_to_eof()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000690
Guido van Rossum52b8c292001-06-29 13:06:06 +0000691 def __write(self, line):
692 if self.__file is not None:
693 if self.__file.tell() + len(line) > 1000:
694 self.file = self.make_file('')
695 self.file.write(self.__file.getvalue())
696 self.__file = None
697 self.file.write(line)
698
Guido van Rossum7aee3841996-03-07 18:00:44 +0000699 def read_lines_to_eof(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000700 """Internal: read lines until EOF."""
701 while 1:
702 line = self.fp.readline()
703 if not line:
704 self.done = -1
705 break
Guido van Rossum52b8c292001-06-29 13:06:06 +0000706 self.__write(line)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000707
708 def read_lines_to_outerboundary(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000709 """Internal: read lines until outerboundary."""
710 next = "--" + self.outerboundary
711 last = next + "--"
712 delim = ""
713 while 1:
714 line = self.fp.readline()
715 if not line:
716 self.done = -1
717 break
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000718 if line[:2] == "--":
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000719 strippedline = line.strip()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000720 if strippedline == next:
721 break
722 if strippedline == last:
723 self.done = 1
724 break
725 odelim = delim
726 if line[-2:] == "\r\n":
727 delim = "\r\n"
728 line = line[:-2]
729 elif line[-1] == "\n":
730 delim = "\n"
731 line = line[:-1]
732 else:
733 delim = ""
Guido van Rossum52b8c292001-06-29 13:06:06 +0000734 self.__write(odelim + line)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000735
736 def skip_lines(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000737 """Internal: skip lines until outer boundary if defined."""
738 if not self.outerboundary or self.done:
739 return
740 next = "--" + self.outerboundary
741 last = next + "--"
742 while 1:
743 line = self.fp.readline()
744 if not line:
745 self.done = -1
746 break
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000747 if line[:2] == "--":
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000748 strippedline = line.strip()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000749 if strippedline == next:
750 break
751 if strippedline == last:
752 self.done = 1
753 break
Guido van Rossum7aee3841996-03-07 18:00:44 +0000754
Guido van Rossuma5e9fb61997-08-12 18:18:13 +0000755 def make_file(self, binary=None):
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 Rossum45e2fbc1998-03-26 21:13:24 +0000763 The 'binary' argument is unused -- the file is always opened
764 in binary mode.
Guido van Rossum7aee3841996-03-07 18:00:44 +0000765
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000766 This version opens a temporary file for reading and writing,
767 and immediately deletes (unlinks) it. The trick (on Unix!) is
768 that the file can still be used, but it can't be opened by
769 another process, and it will automatically be deleted when it
770 is closed or when the current process terminates.
Guido van Rossum4032c2c1996-03-09 04:04:35 +0000771
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000772 If you want a more permanent file, you derive a class which
773 overrides this method. If you want a visible temporary file
774 that is nevertheless automatically deleted when the script
775 terminates, try defining a __del__ method in a derived class
776 which unlinks the temporary files you have created.
Guido van Rossum7aee3841996-03-07 18:00:44 +0000777
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000778 """
779 import tempfile
780 return tempfile.TemporaryFile("w+b")
Tim Peters88869f92001-01-14 23:36:06 +0000781
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000782
783
Guido van Rossum4032c2c1996-03-09 04:04:35 +0000784# Backwards Compatibility Classes
785# ===============================
Guido van Rossum9a22de11995-01-12 12:29:47 +0000786
Moshe Zadkaa1a4b592000-08-25 21:47:56 +0000787class FormContentDict(UserDict.UserDict):
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000788 """Form content as dictionary with a list of values per field.
Guido van Rossum72755611996-03-06 07:20:06 +0000789
Guido van Rossum7aee3841996-03-07 18:00:44 +0000790 form = FormContentDict()
791
792 form[key] -> [value, value, ...]
Raymond Hettinger54f02222002-06-01 14:18:47 +0000793 key in form -> Boolean
Guido van Rossum7aee3841996-03-07 18:00:44 +0000794 form.keys() -> [key, key, ...]
795 form.values() -> [[val, val, ...], [val, val, ...], ...]
796 form.items() -> [(key, [val, val, ...]), (key, [val, val, ...]), ...]
797 form.dict == {key: [val, val, ...], ...}
798
799 """
Guido van Rossum773ab271996-07-23 03:46:24 +0000800 def __init__(self, environ=os.environ):
Moshe Zadkaa1a4b592000-08-25 21:47:56 +0000801 self.dict = self.data = parse(environ=environ)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000802 self.query_string = environ['QUERY_STRING']
Guido van Rossum9a22de11995-01-12 12:29:47 +0000803
804
Guido van Rossum9a22de11995-01-12 12:29:47 +0000805class SvFormContentDict(FormContentDict):
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000806 """Form content as dictionary expecting a single value per field.
Guido van Rossum7aee3841996-03-07 18:00:44 +0000807
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000808 If you only expect a single value for each field, then form[key]
Guido van Rossum7aee3841996-03-07 18:00:44 +0000809 will return that single value. It will raise an IndexError if
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000810 that expectation is not true. If you expect a field to have
Guido van Rossum7aee3841996-03-07 18:00:44 +0000811 possible multiple values, than you can use form.getlist(key) to
812 get all of the values. values() and items() are a compromise:
813 they return single strings where there is a single value, and
814 lists of strings otherwise.
815
816 """
817 def __getitem__(self, key):
Tim Peters88869f92001-01-14 23:36:06 +0000818 if len(self.dict[key]) > 1:
819 raise IndexError, 'expecting a single value'
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000820 return self.dict[key][0]
Guido van Rossum7aee3841996-03-07 18:00:44 +0000821 def getlist(self, key):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000822 return self.dict[key]
Guido van Rossum7aee3841996-03-07 18:00:44 +0000823 def values(self):
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000824 result = []
825 for value in self.dict.values():
826 if len(value) == 1:
827 result.append(value[0])
828 else: result.append(value)
829 return result
Guido van Rossum7aee3841996-03-07 18:00:44 +0000830 def items(self):
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000831 result = []
832 for key, value in self.dict.items():
833 if len(value) == 1:
834 result.append((key, value[0]))
835 else: result.append((key, value))
836 return result
Guido van Rossum9a22de11995-01-12 12:29:47 +0000837
838
Guido van Rossum9a22de11995-01-12 12:29:47 +0000839class InterpFormContentDict(SvFormContentDict):
Tim Peters88869f92001-01-14 23:36:06 +0000840 """This class is present for backwards compatibility only."""
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000841 def __getitem__(self, key):
842 v = SvFormContentDict.__getitem__(self, key)
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000843 if v[0] in '0123456789+-.':
844 try: return int(v)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000845 except ValueError:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000846 try: return float(v)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000847 except ValueError: pass
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000848 return v.strip()
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000849 def values(self):
850 result = []
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000851 for key in self.keys():
852 try:
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000853 result.append(self[key])
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000854 except IndexError:
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000855 result.append(self.dict[key])
856 return result
857 def items(self):
858 result = []
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000859 for key in self.keys():
860 try:
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000861 result.append((key, self[key]))
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000862 except IndexError:
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000863 result.append((key, self.dict[key]))
864 return result
Guido van Rossum9a22de11995-01-12 12:29:47 +0000865
866
Guido van Rossum9a22de11995-01-12 12:29:47 +0000867class FormContent(FormContentDict):
Tim Peters88869f92001-01-14 23:36:06 +0000868 """This class is present for backwards compatibility only."""
Guido van Rossum0147db01996-03-09 03:16:04 +0000869 def values(self, key):
Raymond Hettinger54f02222002-06-01 14:18:47 +0000870 if key in self.dict :return self.dict[key]
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000871 else: return None
Guido van Rossum0147db01996-03-09 03:16:04 +0000872 def indexed_value(self, key, location):
Raymond Hettinger54f02222002-06-01 14:18:47 +0000873 if key in self.dict:
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000874 if len(self.dict[key]) > location:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000875 return self.dict[key][location]
876 else: return None
877 else: return None
Guido van Rossum0147db01996-03-09 03:16:04 +0000878 def value(self, key):
Raymond Hettinger54f02222002-06-01 14:18:47 +0000879 if key in self.dict: return self.dict[key][0]
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000880 else: return None
Guido van Rossum0147db01996-03-09 03:16:04 +0000881 def length(self, key):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000882 return len(self.dict[key])
Guido van Rossum0147db01996-03-09 03:16:04 +0000883 def stripped(self, key):
Raymond Hettinger54f02222002-06-01 14:18:47 +0000884 if key in self.dict: return self.dict[key][0].strip()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000885 else: return None
Guido van Rossum7aee3841996-03-07 18:00:44 +0000886 def pars(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000887 return self.dict
Guido van Rossum9a22de11995-01-12 12:29:47 +0000888
889
Guido van Rossum72755611996-03-06 07:20:06 +0000890# Test/debug code
891# ===============
Guido van Rossum9a22de11995-01-12 12:29:47 +0000892
Guido van Rossum773ab271996-07-23 03:46:24 +0000893def test(environ=os.environ):
Guido van Rossum7aee3841996-03-07 18:00:44 +0000894 """Robust test CGI script, usable as main program.
Guido van Rossum9a22de11995-01-12 12:29:47 +0000895
Guido van Rossum7aee3841996-03-07 18:00:44 +0000896 Write minimal HTTP headers and dump all information provided to
897 the script in HTML form.
898
899 """
Guido van Rossum7aee3841996-03-07 18:00:44 +0000900 print "Content-type: text/html"
901 print
902 sys.stderr = sys.stdout
903 try:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000904 form = FieldStorage() # Replace with other classes to test those
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000905 print_directory()
906 print_arguments()
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000907 print_form(form)
908 print_environ(environ)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000909 print_environ_usage()
910 def f():
911 exec "testing print_exception() -- <I>italics?</I>"
912 def g(f=f):
913 f()
914 print "<H3>What follows is a test, not an actual exception:</H3>"
915 g()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000916 except:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000917 print_exception()
Guido van Rossumf85de8a1996-08-20 20:22:39 +0000918
Guido van Rossum57d51f22000-09-16 21:16:01 +0000919 print "<H1>Second try with a small maxlen...</H1>"
920
Guido van Rossumad164711997-05-13 19:03:23 +0000921 global maxlen
922 maxlen = 50
923 try:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000924 form = FieldStorage() # Replace with other classes to test those
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000925 print_directory()
926 print_arguments()
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000927 print_form(form)
928 print_environ(environ)
Guido van Rossumad164711997-05-13 19:03:23 +0000929 except:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000930 print_exception()
Guido van Rossumad164711997-05-13 19:03:23 +0000931
Guido van Rossumf85de8a1996-08-20 20:22:39 +0000932def print_exception(type=None, value=None, tb=None, limit=None):
933 if type is None:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000934 type, value, tb = sys.exc_info()
Guido van Rossumf85de8a1996-08-20 20:22:39 +0000935 import traceback
936 print
Guido van Rossum7dd06962000-12-27 19:12:58 +0000937 print "<H3>Traceback (most recent call last):</H3>"
Guido van Rossumf85de8a1996-08-20 20:22:39 +0000938 list = traceback.format_tb(tb, limit) + \
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000939 traceback.format_exception_only(type, value)
Guido van Rossumf85de8a1996-08-20 20:22:39 +0000940 print "<PRE>%s<B>%s</B></PRE>" % (
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000941 escape("".join(list[:-1])),
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000942 escape(list[-1]),
943 )
Guido van Rossumf15d1591997-09-29 23:22:12 +0000944 del tb
Guido van Rossum9a22de11995-01-12 12:29:47 +0000945
Guido van Rossum773ab271996-07-23 03:46:24 +0000946def print_environ(environ=os.environ):
Guido van Rossum7aee3841996-03-07 18:00:44 +0000947 """Dump the shell environment as HTML."""
948 keys = environ.keys()
949 keys.sort()
950 print
Guido van Rossum503e50b1996-05-28 22:57:20 +0000951 print "<H3>Shell Environment:</H3>"
Guido van Rossum7aee3841996-03-07 18:00:44 +0000952 print "<DL>"
953 for key in keys:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000954 print "<DT>", escape(key), "<DD>", escape(environ[key])
Tim Peters88869f92001-01-14 23:36:06 +0000955 print "</DL>"
Guido van Rossum7aee3841996-03-07 18:00:44 +0000956 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."""
960 keys = form.keys()
961 keys.sort()
962 print
Guido van Rossum503e50b1996-05-28 22:57:20 +0000963 print "<H3>Form Contents:</H3>"
Guido van Rossum57d51f22000-09-16 21:16:01 +0000964 if not keys:
965 print "<P>No form fields."
Guido van Rossum7aee3841996-03-07 18:00:44 +0000966 print "<DL>"
967 for key in keys:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000968 print "<DT>" + escape(key) + ":",
969 value = form[key]
Walter Dörwald70a6b492004-02-12 17:35:32 +0000970 print "<i>" + escape(repr(type(value))) + "</i>"
971 print "<DD>" + escape(repr(value))
Guido van Rossum7aee3841996-03-07 18:00:44 +0000972 print "</DL>"
973 print
974
975def print_directory():
976 """Dump the current directory as HTML."""
977 print
978 print "<H3>Current Working Directory:</H3>"
979 try:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000980 pwd = os.getcwd()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000981 except os.error, msg:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000982 print "os.error:", escape(str(msg))
Guido van Rossum7aee3841996-03-07 18:00:44 +0000983 else:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000984 print escape(pwd)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000985 print
Guido van Rossum9a22de11995-01-12 12:29:47 +0000986
Guido van Rossuma8738a51996-03-14 21:30:28 +0000987def print_arguments():
988 print
Guido van Rossum503e50b1996-05-28 22:57:20 +0000989 print "<H3>Command Line Arguments:</H3>"
Guido van Rossuma8738a51996-03-14 21:30:28 +0000990 print
991 print sys.argv
992 print
993
Guido van Rossum9a22de11995-01-12 12:29:47 +0000994def print_environ_usage():
Guido van Rossum7aee3841996-03-07 18:00:44 +0000995 """Dump a list of environment variables used by CGI as HTML."""
996 print """
Guido van Rossum72755611996-03-06 07:20:06 +0000997<H3>These environment variables could have been set:</H3>
998<UL>
Guido van Rossum9a22de11995-01-12 12:29:47 +0000999<LI>AUTH_TYPE
1000<LI>CONTENT_LENGTH
1001<LI>CONTENT_TYPE
1002<LI>DATE_GMT
1003<LI>DATE_LOCAL
1004<LI>DOCUMENT_NAME
1005<LI>DOCUMENT_ROOT
1006<LI>DOCUMENT_URI
1007<LI>GATEWAY_INTERFACE
1008<LI>LAST_MODIFIED
1009<LI>PATH
1010<LI>PATH_INFO
1011<LI>PATH_TRANSLATED
1012<LI>QUERY_STRING
1013<LI>REMOTE_ADDR
1014<LI>REMOTE_HOST
1015<LI>REMOTE_IDENT
1016<LI>REMOTE_USER
1017<LI>REQUEST_METHOD
1018<LI>SCRIPT_NAME
1019<LI>SERVER_NAME
1020<LI>SERVER_PORT
1021<LI>SERVER_PROTOCOL
1022<LI>SERVER_ROOT
1023<LI>SERVER_SOFTWARE
1024</UL>
Guido van Rossum7aee3841996-03-07 18:00:44 +00001025In addition, HTTP headers sent by the server may be passed in the
1026environment as well. Here are some common variable names:
1027<UL>
1028<LI>HTTP_ACCEPT
1029<LI>HTTP_CONNECTION
1030<LI>HTTP_HOST
1031<LI>HTTP_PRAGMA
1032<LI>HTTP_REFERER
1033<LI>HTTP_USER_AGENT
1034</UL>
Guido van Rossum9a22de11995-01-12 12:29:47 +00001035"""
1036
Guido van Rossum9a22de11995-01-12 12:29:47 +00001037
Guido van Rossum72755611996-03-06 07:20:06 +00001038# Utilities
1039# =========
Guido van Rossum9a22de11995-01-12 12:29:47 +00001040
Guido van Rossum64c66201997-07-19 20:11:53 +00001041def escape(s, quote=None):
Guido van Rossum7aee3841996-03-07 18:00:44 +00001042 """Replace special characters '&', '<' and '>' by SGML entities."""
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +00001043 s = s.replace("&", "&amp;") # Must be done first!
1044 s = s.replace("<", "&lt;")
1045 s = s.replace(">", "&gt;")
Guido van Rossum64c66201997-07-19 20:11:53 +00001046 if quote:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +00001047 s = s.replace('"', "&quot;")
Guido van Rossum7aee3841996-03-07 18:00:44 +00001048 return s
Guido van Rossum9a22de11995-01-12 12:29:47 +00001049
Guido van Rossum2e441f72001-07-25 21:00:19 +00001050def valid_boundary(s, _vb_pattern="^[ -~]{0,200}[!-~]$"):
1051 import re
1052 return re.match(_vb_pattern, s)
Guido van Rossum9a22de11995-01-12 12:29:47 +00001053
Guido van Rossum72755611996-03-06 07:20:06 +00001054# Invoke mainline
1055# ===============
1056
1057# Call test() when this file is run as a script (not imported as a module)
Tim Peters88869f92001-01-14 23:36:06 +00001058if __name__ == '__main__':
Guido van Rossum7aee3841996-03-07 18:00:44 +00001059 test()