blob: 1a998685a1448e6e16df92fa76c1c3c52b8f8e11 [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
Johannes Gijsbersc7fc10a2005-01-08 13:56:36 +000041import email.Parser
Moshe Zadkaa1a4b592000-08-25 21:47:56 +000042import UserDict
Raymond Hettingera6172712004-12-31 19:15:26 +000043try:
44 from cStringIO import StringIO
45except ImportError:
46 from StringIO import StringIO
Guido van Rossum72755611996-03-06 07:20:06 +000047
Guido van Rossuma8423a92001-03-19 13:40:44 +000048__all__ = ["MiniFieldStorage", "FieldStorage", "FormContentDict",
49 "SvFormContentDict", "InterpFormContentDict", "FormContent",
50 "parse", "parse_qs", "parse_qsl", "parse_multipart",
51 "parse_header", "print_exception", "print_environ",
52 "print_form", "print_directory", "print_arguments",
53 "print_environ_usage", "escape"]
Guido van Rossumc204c701996-09-05 19:07:11 +000054
55# Logging support
56# ===============
57
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000058logfile = "" # Filename to log to, if not empty
59logfp = None # File object to log to, if not None
Guido van Rossumc204c701996-09-05 19:07:11 +000060
61def initlog(*allargs):
62 """Write a log message, if there is a log file.
63
64 Even though this function is called initlog(), you should always
65 use log(); log is a variable that is set either to initlog
66 (initially), to dolog (once the log file has been opened), or to
67 nolog (when logging is disabled).
68
69 The first argument is a format string; the remaining arguments (if
70 any) are arguments to the % operator, so e.g.
71 log("%s: %s", "a", "b")
72 will write "a: b" to the log file, followed by a newline.
73
74 If the global logfp is not None, it should be a file object to
75 which log data is written.
76
77 If the global logfp is None, the global logfile may be a string
78 giving a filename to open, in append mode. This file should be
79 world writable!!! If the file can't be opened, logging is
80 silently disabled (since there is no safe place where we could
81 send an error message).
82
83 """
84 global logfp, log
85 if logfile and not logfp:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000086 try:
87 logfp = open(logfile, "a")
88 except IOError:
89 pass
Guido van Rossumc204c701996-09-05 19:07:11 +000090 if not logfp:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000091 log = nolog
Guido van Rossumc204c701996-09-05 19:07:11 +000092 else:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000093 log = dolog
Guido van Rossum68468eb2003-02-27 20:14:51 +000094 log(*allargs)
Guido van Rossumc204c701996-09-05 19:07:11 +000095
96def dolog(fmt, *args):
97 """Write a log message to the log file. See initlog() for docs."""
98 logfp.write(fmt%args + "\n")
99
100def nolog(*allargs):
101 """Dummy function, assigned to log when logging is disabled."""
102 pass
103
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000104log = initlog # The current logging function
Guido van Rossumc204c701996-09-05 19:07:11 +0000105
106
Guido van Rossum72755611996-03-06 07:20:06 +0000107# Parsing functions
108# =================
109
Johannes Gijsbersc7fc10a2005-01-08 13:56:36 +0000110_header_parser = email.Parser.HeaderParser()
111
Guido van Rossumad164711997-05-13 19:03:23 +0000112# Maximum input we will accept when REQUEST_METHOD is POST
113# 0 ==> unlimited input
114maxlen = 0
115
Guido van Rossume08c04c1996-11-11 19:29:11 +0000116def parse(fp=None, environ=os.environ, keep_blank_values=0, strict_parsing=0):
Guido van Rossum773ab271996-07-23 03:46:24 +0000117 """Parse a query in the environment or from a file (default stdin)
118
119 Arguments, all optional:
120
121 fp : file pointer; default: sys.stdin
122
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000123 environ : environment dictionary; default: os.environ
Guido van Rossum773ab271996-07-23 03:46:24 +0000124
125 keep_blank_values: flag indicating whether blank values in
Tim Peters88869f92001-01-14 23:36:06 +0000126 URL encoded forms should be treated as blank strings.
127 A true value indicates that blanks should be retained as
Guido van Rossum773ab271996-07-23 03:46:24 +0000128 blank strings. The default false value indicates that
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000129 blank values are to be ignored and treated as if they were
130 not included.
Guido van Rossume08c04c1996-11-11 19:29:11 +0000131
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000132 strict_parsing: flag indicating what to do with parsing errors.
133 If false (the default), errors are silently ignored.
134 If true, errors raise a ValueError exception.
Guido van Rossum773ab271996-07-23 03:46:24 +0000135 """
Raymond Hettingera1449002002-05-31 23:54:44 +0000136 if fp is None:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000137 fp = sys.stdin
Raymond Hettinger54f02222002-06-01 14:18:47 +0000138 if not 'REQUEST_METHOD' in environ:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000139 environ['REQUEST_METHOD'] = 'GET' # For testing stand-alone
Guido van Rossum7aee3841996-03-07 18:00:44 +0000140 if environ['REQUEST_METHOD'] == 'POST':
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000141 ctype, pdict = parse_header(environ['CONTENT_TYPE'])
142 if ctype == 'multipart/form-data':
143 return parse_multipart(fp, pdict)
144 elif ctype == 'application/x-www-form-urlencoded':
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000145 clength = int(environ['CONTENT_LENGTH'])
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000146 if maxlen and clength > maxlen:
147 raise ValueError, 'Maximum content length exceeded'
148 qs = fp.read(clength)
149 else:
150 qs = '' # Unknown content-type
Raymond Hettinger54f02222002-06-01 14:18:47 +0000151 if 'QUERY_STRING' in environ:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000152 if qs: qs = qs + '&'
153 qs = qs + environ['QUERY_STRING']
Tim Peters88869f92001-01-14 23:36:06 +0000154 elif sys.argv[1:]:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000155 if qs: qs = qs + '&'
156 qs = qs + sys.argv[1]
157 environ['QUERY_STRING'] = qs # XXX Shouldn't, really
Raymond Hettinger54f02222002-06-01 14:18:47 +0000158 elif 'QUERY_STRING' in environ:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000159 qs = environ['QUERY_STRING']
Guido van Rossum7aee3841996-03-07 18:00:44 +0000160 else:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000161 if sys.argv[1:]:
162 qs = sys.argv[1]
163 else:
164 qs = ""
165 environ['QUERY_STRING'] = qs # XXX Shouldn't, really
Guido van Rossume08c04c1996-11-11 19:29:11 +0000166 return parse_qs(qs, keep_blank_values, strict_parsing)
Guido van Rossume7808771995-08-07 20:12:09 +0000167
168
Guido van Rossume08c04c1996-11-11 19:29:11 +0000169def parse_qs(qs, keep_blank_values=0, strict_parsing=0):
170 """Parse a query given as a string argument.
Guido van Rossum773ab271996-07-23 03:46:24 +0000171
172 Arguments:
173
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000174 qs: URL-encoded query string to be parsed
Guido van Rossum773ab271996-07-23 03:46:24 +0000175
176 keep_blank_values: flag indicating whether blank values in
Tim Peters88869f92001-01-14 23:36:06 +0000177 URL encoded queries should be treated as blank strings.
178 A true value indicates that blanks should be retained as
Guido van Rossum773ab271996-07-23 03:46:24 +0000179 blank strings. The default false value indicates that
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000180 blank values are to be ignored and treated as if they were
181 not included.
Guido van Rossume08c04c1996-11-11 19:29:11 +0000182
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000183 strict_parsing: flag indicating what to do with parsing errors.
184 If false (the default), errors are silently ignored.
185 If true, errors raise a ValueError exception.
Guido van Rossum773ab271996-07-23 03:46:24 +0000186 """
Guido van Rossum7aee3841996-03-07 18:00:44 +0000187 dict = {}
Guido van Rossum1946f0d1999-06-04 17:54:39 +0000188 for name, value in parse_qsl(qs, keep_blank_values, strict_parsing):
Raymond Hettinger54f02222002-06-01 14:18:47 +0000189 if name in dict:
Moshe Zadkaa1a4b592000-08-25 21:47:56 +0000190 dict[name].append(value)
191 else:
192 dict[name] = [value]
Guido van Rossum1946f0d1999-06-04 17:54:39 +0000193 return dict
194
195def parse_qsl(qs, keep_blank_values=0, strict_parsing=0):
196 """Parse a query given as a string argument.
197
Jeremy Hyltonafde7e22000-09-15 20:06:57 +0000198 Arguments:
Guido van Rossum1946f0d1999-06-04 17:54:39 +0000199
Jeremy Hyltonafde7e22000-09-15 20:06:57 +0000200 qs: URL-encoded query string to be parsed
Guido van Rossum1946f0d1999-06-04 17:54:39 +0000201
Jeremy Hyltonafde7e22000-09-15 20:06:57 +0000202 keep_blank_values: flag indicating whether blank values in
203 URL encoded queries should be treated as blank strings. A
204 true value indicates that blanks should be retained as blank
205 strings. The default false value indicates that blank values
206 are to be ignored and treated as if they were not included.
Guido van Rossum1946f0d1999-06-04 17:54:39 +0000207
Jeremy Hyltonafde7e22000-09-15 20:06:57 +0000208 strict_parsing: flag indicating what to do with parsing errors. If
209 false (the default), errors are silently ignored. If true,
Tim Peters88869f92001-01-14 23:36:06 +0000210 errors raise a ValueError exception.
Guido van Rossum1946f0d1999-06-04 17:54:39 +0000211
Jeremy Hyltonafde7e22000-09-15 20:06:57 +0000212 Returns a list, as G-d intended.
Guido van Rossum1946f0d1999-06-04 17:54:39 +0000213 """
Jeremy Hyltonafde7e22000-09-15 20:06:57 +0000214 pairs = [s2 for s1 in qs.split('&') for s2 in s1.split(';')]
215 r = []
216 for name_value in pairs:
Neil Schemenauer66edb622004-07-19 15:38:11 +0000217 if not name_value and not strict_parsing:
218 continue
Jeremy Hyltonafde7e22000-09-15 20:06:57 +0000219 nv = name_value.split('=', 1)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000220 if len(nv) != 2:
221 if strict_parsing:
Walter Dörwald70a6b492004-02-12 17:35:32 +0000222 raise ValueError, "bad query field: %r" % (name_value,)
Brett Cannon8d9b60f2004-03-21 22:16:15 +0000223 # Handle case of a control-name with no equal sign
224 if keep_blank_values:
225 nv.append('')
226 else:
227 continue
Moshe Zadkaa1a4b592000-08-25 21:47:56 +0000228 if len(nv[1]) or keep_blank_values:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000229 name = urllib.unquote(nv[0].replace('+', ' '))
230 value = urllib.unquote(nv[1].replace('+', ' '))
Moshe Zadkaa1a4b592000-08-25 21:47:56 +0000231 r.append((name, value))
Guido van Rossum1946f0d1999-06-04 17:54:39 +0000232
233 return r
Guido van Rossum9a22de11995-01-12 12:29:47 +0000234
235
Guido van Rossum0147db01996-03-09 03:16:04 +0000236def parse_multipart(fp, pdict):
Guido van Rossum7aee3841996-03-07 18:00:44 +0000237 """Parse multipart input.
Guido van Rossum9a22de11995-01-12 12:29:47 +0000238
Guido van Rossum7aee3841996-03-07 18:00:44 +0000239 Arguments:
240 fp : input file
Johannes Gijsbersc7fc10a2005-01-08 13:56:36 +0000241 pdict: dictionary containing other parameters of content-type header
Guido van Rossum72755611996-03-06 07:20:06 +0000242
Tim Peters88869f92001-01-14 23:36:06 +0000243 Returns a dictionary just like parse_qs(): keys are the field names, each
244 value is a list of values for that field. This is easy to use but not
245 much good if you are expecting megabytes to be uploaded -- in that case,
246 use the FieldStorage class instead which is much more flexible. Note
247 that content-type is the raw, unparsed contents of the content-type
Guido van Rossum0147db01996-03-09 03:16:04 +0000248 header.
Tim Peters88869f92001-01-14 23:36:06 +0000249
250 XXX This does not parse nested multipart parts -- use FieldStorage for
Guido van Rossum0147db01996-03-09 03:16:04 +0000251 that.
Tim Peters88869f92001-01-14 23:36:06 +0000252
253 XXX This should really be subsumed by FieldStorage altogether -- no
Guido van Rossum0147db01996-03-09 03:16:04 +0000254 point in having two implementations of the same parsing algorithm.
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.
Johannes Gijsbersc7fc10a2005-01-08 13:56:36 +0000274 headers = _header_parser.parse(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
Johannes Gijsbersc7fc10a2005-01-08 13:56:36 +0000411 headers: a dictionary(-like) object (sometimes
412 email.Message.Message or a subclass thereof) containing *all*
413 headers
Guido van Rossum7aee3841996-03-07 18:00:44 +0000414
415 The class is subclassable, mostly for the purpose of overriding
416 the make_file() method, which is called internally to come up with
417 a file open for reading and writing. This makes it possible to
418 override the default choice of storing all files in a temporary
419 directory and unlinking them as soon as they have been opened.
420
421 """
422
Guido van Rossum773ab271996-07-23 03:46:24 +0000423 def __init__(self, fp=None, headers=None, outerboundary="",
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000424 environ=os.environ, keep_blank_values=0, strict_parsing=0):
425 """Constructor. Read multipart/* until last part.
Guido van Rossum7aee3841996-03-07 18:00:44 +0000426
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000427 Arguments, all optional:
Guido van Rossum7aee3841996-03-07 18:00:44 +0000428
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000429 fp : file pointer; default: sys.stdin
Guido van Rossumb1b4f941998-05-08 19:55:51 +0000430 (not used when the request method is GET)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000431
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000432 headers : header dictionary-like object; default:
433 taken from environ as per CGI spec
Guido van Rossum7aee3841996-03-07 18:00:44 +0000434
Guido van Rossum773ab271996-07-23 03:46:24 +0000435 outerboundary : terminating multipart boundary
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000436 (for internal use only)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000437
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000438 environ : environment dictionary; default: os.environ
Guido van Rossum773ab271996-07-23 03:46:24 +0000439
440 keep_blank_values: flag indicating whether blank values in
Tim Peters88869f92001-01-14 23:36:06 +0000441 URL encoded forms should be treated as blank strings.
442 A true value indicates that blanks should be retained as
Guido van Rossum773ab271996-07-23 03:46:24 +0000443 blank strings. The default false value indicates that
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000444 blank values are to be ignored and treated as if they were
445 not included.
Guido van Rossum773ab271996-07-23 03:46:24 +0000446
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000447 strict_parsing: flag indicating what to do with parsing errors.
448 If false (the default), errors are silently ignored.
449 If true, errors raise a ValueError exception.
Guido van Rossume08c04c1996-11-11 19:29:11 +0000450
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000451 """
452 method = 'GET'
453 self.keep_blank_values = keep_blank_values
454 self.strict_parsing = strict_parsing
Raymond Hettinger54f02222002-06-01 14:18:47 +0000455 if 'REQUEST_METHOD' in environ:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000456 method = environ['REQUEST_METHOD'].upper()
Guido van Rossum01852831998-06-25 02:40:17 +0000457 if method == 'GET' or method == 'HEAD':
Raymond Hettinger54f02222002-06-01 14:18:47 +0000458 if 'QUERY_STRING' in environ:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000459 qs = environ['QUERY_STRING']
460 elif sys.argv[1:]:
461 qs = sys.argv[1]
462 else:
463 qs = ""
464 fp = StringIO(qs)
465 if headers is None:
466 headers = {'content-type':
467 "application/x-www-form-urlencoded"}
468 if headers is None:
Guido van Rossumcff311a1998-06-11 14:06:59 +0000469 headers = {}
470 if method == 'POST':
471 # Set default content-type for POST to what's traditional
472 headers['content-type'] = "application/x-www-form-urlencoded"
Raymond Hettinger54f02222002-06-01 14:18:47 +0000473 if 'CONTENT_TYPE' in environ:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000474 headers['content-type'] = environ['CONTENT_TYPE']
Raymond Hettinger54f02222002-06-01 14:18:47 +0000475 if 'CONTENT_LENGTH' in environ:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000476 headers['content-length'] = environ['CONTENT_LENGTH']
477 self.fp = fp or sys.stdin
478 self.headers = headers
479 self.outerboundary = outerboundary
Guido van Rossum7aee3841996-03-07 18:00:44 +0000480
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000481 # Process content-disposition header
482 cdisp, pdict = "", {}
Raymond Hettinger54f02222002-06-01 14:18:47 +0000483 if 'content-disposition' in self.headers:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000484 cdisp, pdict = parse_header(self.headers['content-disposition'])
485 self.disposition = cdisp
486 self.disposition_options = pdict
487 self.name = None
Raymond Hettinger54f02222002-06-01 14:18:47 +0000488 if 'name' in pdict:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000489 self.name = pdict['name']
490 self.filename = None
Raymond Hettinger54f02222002-06-01 14:18:47 +0000491 if 'filename' in pdict:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000492 self.filename = pdict['filename']
Guido van Rossum7aee3841996-03-07 18:00:44 +0000493
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000494 # Process content-type header
Barry Warsaw302331a1999-01-08 17:42:03 +0000495 #
496 # Honor any existing content-type header. But if there is no
497 # content-type header, use some sensible defaults. Assume
498 # outerboundary is "" at the outer level, but something non-false
499 # inside a multi-part. The default for an inner part is text/plain,
500 # but for an outer part it should be urlencoded. This should catch
501 # bogus clients which erroneously forget to include a content-type
502 # header.
503 #
504 # See below for what we do if there does exist a content-type header,
505 # but it happens to be something we don't understand.
Raymond Hettinger54f02222002-06-01 14:18:47 +0000506 if 'content-type' in self.headers:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000507 ctype, pdict = parse_header(self.headers['content-type'])
Guido van Rossumce900de1999-06-02 18:44:22 +0000508 elif self.outerboundary or method != 'POST':
Barry Warsaw302331a1999-01-08 17:42:03 +0000509 ctype, pdict = "text/plain", {}
510 else:
511 ctype, pdict = 'application/x-www-form-urlencoded', {}
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000512 self.type = ctype
513 self.type_options = pdict
514 self.innerboundary = ""
Raymond Hettinger54f02222002-06-01 14:18:47 +0000515 if 'boundary' in pdict:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000516 self.innerboundary = pdict['boundary']
517 clen = -1
Raymond Hettinger54f02222002-06-01 14:18:47 +0000518 if 'content-length' in self.headers:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000519 try:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000520 clen = int(self.headers['content-length'])
Skip Montanarodb5d1442002-03-23 05:50:17 +0000521 except ValueError:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000522 pass
523 if maxlen and clen > maxlen:
524 raise ValueError, 'Maximum content length exceeded'
525 self.length = clen
Guido van Rossum7aee3841996-03-07 18:00:44 +0000526
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000527 self.list = self.file = None
528 self.done = 0
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000529 if ctype == 'application/x-www-form-urlencoded':
530 self.read_urlencoded()
531 elif ctype[:10] == 'multipart/':
Guido van Rossumf5745001998-10-20 14:43:02 +0000532 self.read_multi(environ, keep_blank_values, strict_parsing)
Barry Warsaw302331a1999-01-08 17:42:03 +0000533 else:
Guido van Rossum60a3bd81999-06-11 18:26:09 +0000534 self.read_single()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000535
536 def __repr__(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000537 """Return a printable representation."""
Walter Dörwald70a6b492004-02-12 17:35:32 +0000538 return "FieldStorage(%r, %r, %r)" % (
539 self.name, self.filename, self.value)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000540
Guido van Rossum4061cbe2002-09-11 18:20:34 +0000541 def __iter__(self):
542 return iter(self.keys())
543
Guido van Rossum7aee3841996-03-07 18:00:44 +0000544 def __getattr__(self, name):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000545 if name != 'value':
546 raise AttributeError, name
547 if self.file:
548 self.file.seek(0)
549 value = self.file.read()
550 self.file.seek(0)
551 elif self.list is not None:
552 value = self.list
553 else:
554 value = None
555 return value
Guido van Rossum7aee3841996-03-07 18:00:44 +0000556
557 def __getitem__(self, key):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000558 """Dictionary style indexing."""
559 if self.list is None:
560 raise TypeError, "not indexable"
561 found = []
562 for item in self.list:
563 if item.name == key: found.append(item)
564 if not found:
565 raise KeyError, key
566 if len(found) == 1:
567 return found[0]
568 else:
569 return found
Guido van Rossum7aee3841996-03-07 18:00:44 +0000570
Moshe Zadkaa1a4b592000-08-25 21:47:56 +0000571 def getvalue(self, key, default=None):
572 """Dictionary style get() method, including 'value' lookup."""
Raymond Hettinger54f02222002-06-01 14:18:47 +0000573 if key in self:
Moshe Zadkaa1a4b592000-08-25 21:47:56 +0000574 value = self[key]
575 if type(value) is type([]):
Raymond Hettingerf871d832004-12-31 21:59:02 +0000576 return map(attrgetter('value'), value)
Moshe Zadkaa1a4b592000-08-25 21:47:56 +0000577 else:
578 return value.value
579 else:
580 return default
581
Guido van Rossum1bfb3882001-09-05 19:45:34 +0000582 def getfirst(self, key, default=None):
583 """ Return the first value received."""
Raymond Hettinger54f02222002-06-01 14:18:47 +0000584 if key in self:
Guido van Rossum1bfb3882001-09-05 19:45:34 +0000585 value = self[key]
586 if type(value) is type([]):
587 return value[0].value
588 else:
589 return value.value
590 else:
591 return default
592
593 def getlist(self, key):
594 """ Return list of received values."""
Raymond Hettinger54f02222002-06-01 14:18:47 +0000595 if key in self:
Guido van Rossum1bfb3882001-09-05 19:45:34 +0000596 value = self[key]
597 if type(value) is type([]):
Raymond Hettingerf871d832004-12-31 21:59:02 +0000598 return map(attrgetter('value'), value)
Guido van Rossum1bfb3882001-09-05 19:45:34 +0000599 else:
600 return [value.value]
601 else:
602 return []
603
Guido van Rossum7aee3841996-03-07 18:00:44 +0000604 def keys(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000605 """Dictionary style keys() method."""
606 if self.list is None:
607 raise TypeError, "not indexable"
608 keys = []
609 for item in self.list:
610 if item.name not in keys: keys.append(item.name)
611 return keys
Guido van Rossum7aee3841996-03-07 18:00:44 +0000612
Guido van Rossum0147db01996-03-09 03:16:04 +0000613 def has_key(self, key):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000614 """Dictionary style has_key() method."""
615 if self.list is None:
616 raise TypeError, "not indexable"
617 for item in self.list:
Tim Petersbc0e9102002-04-04 22:55:58 +0000618 if item.name == key: return True
619 return False
Guido van Rossum0147db01996-03-09 03:16:04 +0000620
Raymond Hettinger54f02222002-06-01 14:18:47 +0000621 def __contains__(self, key):
622 """Dictionary style __contains__ method."""
623 if self.list is None:
624 raise TypeError, "not indexable"
625 for item in self.list:
626 if item.name == key: return True
627 return False
628
Guido van Rossum88b85d41997-01-11 19:21:33 +0000629 def __len__(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000630 """Dictionary style len(x) support."""
631 return len(self.keys())
Guido van Rossum88b85d41997-01-11 19:21:33 +0000632
Guido van Rossum7aee3841996-03-07 18:00:44 +0000633 def read_urlencoded(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000634 """Internal: read data in query string format."""
635 qs = self.fp.read(self.length)
Guido van Rossum1946f0d1999-06-04 17:54:39 +0000636 self.list = list = []
637 for key, value in parse_qsl(qs, self.keep_blank_values,
638 self.strict_parsing):
639 list.append(MiniFieldStorage(key, value))
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000640 self.skip_lines()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000641
Guido van Rossum030d2ec1998-12-09 22:16:46 +0000642 FieldStorageClass = None
643
Guido van Rossumf5745001998-10-20 14:43:02 +0000644 def read_multi(self, environ, keep_blank_values, strict_parsing):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000645 """Internal: read a part that is itself multipart."""
Guido van Rossum2e441f72001-07-25 21:00:19 +0000646 ib = self.innerboundary
647 if not valid_boundary(ib):
Walter Dörwald70a6b492004-02-12 17:35:32 +0000648 raise ValueError, 'Invalid boundary in multipart form: %r' % (ib,)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000649 self.list = []
Guido van Rossum030d2ec1998-12-09 22:16:46 +0000650 klass = self.FieldStorageClass or self.__class__
Guido van Rossum2e441f72001-07-25 21:00:19 +0000651 part = klass(self.fp, {}, ib,
Guido van Rossum030d2ec1998-12-09 22:16:46 +0000652 environ, keep_blank_values, strict_parsing)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000653 # Throw first part away
654 while not part.done:
Johannes Gijsbersc7fc10a2005-01-08 13:56:36 +0000655 headers = _header_parser.parse(self.fp)
Guido van Rossum2e441f72001-07-25 21:00:19 +0000656 part = klass(self.fp, headers, ib,
Guido van Rossum030d2ec1998-12-09 22:16:46 +0000657 environ, keep_blank_values, strict_parsing)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000658 self.list.append(part)
659 self.skip_lines()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000660
661 def read_single(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000662 """Internal: read an atomic part."""
663 if self.length >= 0:
664 self.read_binary()
665 self.skip_lines()
666 else:
667 self.read_lines()
668 self.file.seek(0)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000669
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000670 bufsize = 8*1024 # I/O buffering size for copy to file
Guido van Rossum7aee3841996-03-07 18:00:44 +0000671
672 def read_binary(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000673 """Internal: read binary data."""
674 self.file = self.make_file('b')
675 todo = self.length
676 if todo >= 0:
677 while todo > 0:
678 data = self.fp.read(min(todo, self.bufsize))
679 if not data:
680 self.done = -1
681 break
682 self.file.write(data)
683 todo = todo - len(data)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000684
685 def read_lines(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000686 """Internal: read lines until EOF or outerboundary."""
Guido van Rossum52b8c292001-06-29 13:06:06 +0000687 self.file = self.__file = StringIO()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000688 if self.outerboundary:
689 self.read_lines_to_outerboundary()
690 else:
691 self.read_lines_to_eof()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000692
Guido van Rossum52b8c292001-06-29 13:06:06 +0000693 def __write(self, line):
694 if self.__file is not None:
695 if self.__file.tell() + len(line) > 1000:
696 self.file = self.make_file('')
697 self.file.write(self.__file.getvalue())
698 self.__file = None
699 self.file.write(line)
700
Guido van Rossum7aee3841996-03-07 18:00:44 +0000701 def read_lines_to_eof(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000702 """Internal: read lines until EOF."""
703 while 1:
704 line = self.fp.readline()
705 if not line:
706 self.done = -1
707 break
Guido van Rossum52b8c292001-06-29 13:06:06 +0000708 self.__write(line)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000709
710 def read_lines_to_outerboundary(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000711 """Internal: read lines until outerboundary."""
712 next = "--" + self.outerboundary
713 last = next + "--"
714 delim = ""
715 while 1:
716 line = self.fp.readline()
717 if not line:
718 self.done = -1
719 break
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000720 if line[:2] == "--":
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000721 strippedline = line.strip()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000722 if strippedline == next:
723 break
724 if strippedline == last:
725 self.done = 1
726 break
727 odelim = delim
728 if line[-2:] == "\r\n":
729 delim = "\r\n"
730 line = line[:-2]
731 elif line[-1] == "\n":
732 delim = "\n"
733 line = line[:-1]
734 else:
735 delim = ""
Guido van Rossum52b8c292001-06-29 13:06:06 +0000736 self.__write(odelim + line)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000737
738 def skip_lines(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000739 """Internal: skip lines until outer boundary if defined."""
740 if not self.outerboundary or self.done:
741 return
742 next = "--" + self.outerboundary
743 last = next + "--"
744 while 1:
745 line = self.fp.readline()
746 if not line:
747 self.done = -1
748 break
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000749 if line[:2] == "--":
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000750 strippedline = line.strip()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000751 if strippedline == next:
752 break
753 if strippedline == last:
754 self.done = 1
755 break
Guido van Rossum7aee3841996-03-07 18:00:44 +0000756
Guido van Rossuma5e9fb61997-08-12 18:18:13 +0000757 def make_file(self, binary=None):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000758 """Overridable: return a readable & writable file.
Guido van Rossum7aee3841996-03-07 18:00:44 +0000759
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000760 The file will be used as follows:
761 - data is written to it
762 - seek(0)
763 - data is read from it
Guido van Rossum7aee3841996-03-07 18:00:44 +0000764
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000765 The 'binary' argument is unused -- the file is always opened
766 in binary mode.
Guido van Rossum7aee3841996-03-07 18:00:44 +0000767
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000768 This version opens a temporary file for reading and writing,
769 and immediately deletes (unlinks) it. The trick (on Unix!) is
770 that the file can still be used, but it can't be opened by
771 another process, and it will automatically be deleted when it
772 is closed or when the current process terminates.
Guido van Rossum4032c2c1996-03-09 04:04:35 +0000773
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000774 If you want a more permanent file, you derive a class which
775 overrides this method. If you want a visible temporary file
776 that is nevertheless automatically deleted when the script
777 terminates, try defining a __del__ method in a derived class
778 which unlinks the temporary files you have created.
Guido van Rossum7aee3841996-03-07 18:00:44 +0000779
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000780 """
781 import tempfile
782 return tempfile.TemporaryFile("w+b")
Tim Peters88869f92001-01-14 23:36:06 +0000783
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000784
785
Guido van Rossum4032c2c1996-03-09 04:04:35 +0000786# Backwards Compatibility Classes
787# ===============================
Guido van Rossum9a22de11995-01-12 12:29:47 +0000788
Moshe Zadkaa1a4b592000-08-25 21:47:56 +0000789class FormContentDict(UserDict.UserDict):
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000790 """Form content as dictionary with a list of values per field.
Guido van Rossum72755611996-03-06 07:20:06 +0000791
Guido van Rossum7aee3841996-03-07 18:00:44 +0000792 form = FormContentDict()
793
794 form[key] -> [value, value, ...]
Raymond Hettinger54f02222002-06-01 14:18:47 +0000795 key in form -> Boolean
Guido van Rossum7aee3841996-03-07 18:00:44 +0000796 form.keys() -> [key, key, ...]
797 form.values() -> [[val, val, ...], [val, val, ...], ...]
798 form.items() -> [(key, [val, val, ...]), (key, [val, val, ...]), ...]
799 form.dict == {key: [val, val, ...], ...}
800
801 """
Guido van Rossum773ab271996-07-23 03:46:24 +0000802 def __init__(self, environ=os.environ):
Moshe Zadkaa1a4b592000-08-25 21:47:56 +0000803 self.dict = self.data = parse(environ=environ)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000804 self.query_string = environ['QUERY_STRING']
Guido van Rossum9a22de11995-01-12 12:29:47 +0000805
806
Guido van Rossum9a22de11995-01-12 12:29:47 +0000807class SvFormContentDict(FormContentDict):
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000808 """Form content as dictionary expecting a single value per field.
Guido van Rossum7aee3841996-03-07 18:00:44 +0000809
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000810 If you only expect a single value for each field, then form[key]
Guido van Rossum7aee3841996-03-07 18:00:44 +0000811 will return that single value. It will raise an IndexError if
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000812 that expectation is not true. If you expect a field to have
Guido van Rossum7aee3841996-03-07 18:00:44 +0000813 possible multiple values, than you can use form.getlist(key) to
814 get all of the values. values() and items() are a compromise:
815 they return single strings where there is a single value, and
816 lists of strings otherwise.
817
818 """
819 def __getitem__(self, key):
Tim Peters88869f92001-01-14 23:36:06 +0000820 if len(self.dict[key]) > 1:
821 raise IndexError, 'expecting a single value'
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000822 return self.dict[key][0]
Guido van Rossum7aee3841996-03-07 18:00:44 +0000823 def getlist(self, key):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000824 return self.dict[key]
Guido van Rossum7aee3841996-03-07 18:00:44 +0000825 def values(self):
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000826 result = []
827 for value in self.dict.values():
828 if len(value) == 1:
829 result.append(value[0])
830 else: result.append(value)
831 return result
Guido van Rossum7aee3841996-03-07 18:00:44 +0000832 def items(self):
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000833 result = []
834 for key, value in self.dict.items():
835 if len(value) == 1:
836 result.append((key, value[0]))
837 else: result.append((key, value))
838 return result
Guido van Rossum9a22de11995-01-12 12:29:47 +0000839
840
Guido van Rossum9a22de11995-01-12 12:29:47 +0000841class InterpFormContentDict(SvFormContentDict):
Tim Peters88869f92001-01-14 23:36:06 +0000842 """This class is present for backwards compatibility only."""
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000843 def __getitem__(self, key):
844 v = SvFormContentDict.__getitem__(self, key)
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000845 if v[0] in '0123456789+-.':
846 try: return int(v)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000847 except ValueError:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000848 try: return float(v)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000849 except ValueError: pass
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000850 return v.strip()
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000851 def values(self):
852 result = []
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000853 for key in self.keys():
854 try:
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000855 result.append(self[key])
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000856 except IndexError:
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000857 result.append(self.dict[key])
858 return result
859 def items(self):
860 result = []
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000861 for key in self.keys():
862 try:
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000863 result.append((key, self[key]))
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000864 except IndexError:
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000865 result.append((key, self.dict[key]))
866 return result
Guido van Rossum9a22de11995-01-12 12:29:47 +0000867
868
Guido van Rossum9a22de11995-01-12 12:29:47 +0000869class FormContent(FormContentDict):
Tim Peters88869f92001-01-14 23:36:06 +0000870 """This class is present for backwards compatibility only."""
Guido van Rossum0147db01996-03-09 03:16:04 +0000871 def values(self, key):
Raymond Hettinger54f02222002-06-01 14:18:47 +0000872 if key in self.dict :return self.dict[key]
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000873 else: return None
Guido van Rossum0147db01996-03-09 03:16:04 +0000874 def indexed_value(self, key, location):
Raymond Hettinger54f02222002-06-01 14:18:47 +0000875 if key in self.dict:
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000876 if len(self.dict[key]) > location:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000877 return self.dict[key][location]
878 else: return None
879 else: return None
Guido van Rossum0147db01996-03-09 03:16:04 +0000880 def value(self, key):
Raymond Hettinger54f02222002-06-01 14:18:47 +0000881 if key in self.dict: return self.dict[key][0]
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000882 else: return None
Guido van Rossum0147db01996-03-09 03:16:04 +0000883 def length(self, key):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000884 return len(self.dict[key])
Guido van Rossum0147db01996-03-09 03:16:04 +0000885 def stripped(self, key):
Raymond Hettinger54f02222002-06-01 14:18:47 +0000886 if key in self.dict: return self.dict[key][0].strip()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000887 else: return None
Guido van Rossum7aee3841996-03-07 18:00:44 +0000888 def pars(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000889 return self.dict
Guido van Rossum9a22de11995-01-12 12:29:47 +0000890
891
Guido van Rossum72755611996-03-06 07:20:06 +0000892# Test/debug code
893# ===============
Guido van Rossum9a22de11995-01-12 12:29:47 +0000894
Guido van Rossum773ab271996-07-23 03:46:24 +0000895def test(environ=os.environ):
Guido van Rossum7aee3841996-03-07 18:00:44 +0000896 """Robust test CGI script, usable as main program.
Guido van Rossum9a22de11995-01-12 12:29:47 +0000897
Guido van Rossum7aee3841996-03-07 18:00:44 +0000898 Write minimal HTTP headers and dump all information provided to
899 the script in HTML form.
900
901 """
Guido van Rossum7aee3841996-03-07 18:00:44 +0000902 print "Content-type: text/html"
903 print
904 sys.stderr = sys.stdout
905 try:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000906 form = FieldStorage() # Replace with other classes to test those
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000907 print_directory()
908 print_arguments()
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000909 print_form(form)
910 print_environ(environ)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000911 print_environ_usage()
912 def f():
913 exec "testing print_exception() -- <I>italics?</I>"
914 def g(f=f):
915 f()
916 print "<H3>What follows is a test, not an actual exception:</H3>"
917 g()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000918 except:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000919 print_exception()
Guido van Rossumf85de8a1996-08-20 20:22:39 +0000920
Guido van Rossum57d51f22000-09-16 21:16:01 +0000921 print "<H1>Second try with a small maxlen...</H1>"
922
Guido van Rossumad164711997-05-13 19:03:23 +0000923 global maxlen
924 maxlen = 50
925 try:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000926 form = FieldStorage() # Replace with other classes to test those
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000927 print_directory()
928 print_arguments()
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000929 print_form(form)
930 print_environ(environ)
Guido van Rossumad164711997-05-13 19:03:23 +0000931 except:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000932 print_exception()
Guido van Rossumad164711997-05-13 19:03:23 +0000933
Guido van Rossumf85de8a1996-08-20 20:22:39 +0000934def print_exception(type=None, value=None, tb=None, limit=None):
935 if type is None:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000936 type, value, tb = sys.exc_info()
Guido van Rossumf85de8a1996-08-20 20:22:39 +0000937 import traceback
938 print
Guido van Rossum7dd06962000-12-27 19:12:58 +0000939 print "<H3>Traceback (most recent call last):</H3>"
Guido van Rossumf85de8a1996-08-20 20:22:39 +0000940 list = traceback.format_tb(tb, limit) + \
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000941 traceback.format_exception_only(type, value)
Guido van Rossumf85de8a1996-08-20 20:22:39 +0000942 print "<PRE>%s<B>%s</B></PRE>" % (
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000943 escape("".join(list[:-1])),
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000944 escape(list[-1]),
945 )
Guido van Rossumf15d1591997-09-29 23:22:12 +0000946 del tb
Guido van Rossum9a22de11995-01-12 12:29:47 +0000947
Guido van Rossum773ab271996-07-23 03:46:24 +0000948def print_environ(environ=os.environ):
Guido van Rossum7aee3841996-03-07 18:00:44 +0000949 """Dump the shell environment as HTML."""
950 keys = environ.keys()
951 keys.sort()
952 print
Guido van Rossum503e50b1996-05-28 22:57:20 +0000953 print "<H3>Shell Environment:</H3>"
Guido van Rossum7aee3841996-03-07 18:00:44 +0000954 print "<DL>"
955 for key in keys:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000956 print "<DT>", escape(key), "<DD>", escape(environ[key])
Tim Peters88869f92001-01-14 23:36:06 +0000957 print "</DL>"
Guido van Rossum7aee3841996-03-07 18:00:44 +0000958 print
Guido van Rossum72755611996-03-06 07:20:06 +0000959
960def print_form(form):
Guido van Rossum7aee3841996-03-07 18:00:44 +0000961 """Dump the contents of a form as HTML."""
962 keys = form.keys()
963 keys.sort()
964 print
Guido van Rossum503e50b1996-05-28 22:57:20 +0000965 print "<H3>Form Contents:</H3>"
Guido van Rossum57d51f22000-09-16 21:16:01 +0000966 if not keys:
967 print "<P>No form fields."
Guido van Rossum7aee3841996-03-07 18:00:44 +0000968 print "<DL>"
969 for key in keys:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000970 print "<DT>" + escape(key) + ":",
971 value = form[key]
Walter Dörwald70a6b492004-02-12 17:35:32 +0000972 print "<i>" + escape(repr(type(value))) + "</i>"
973 print "<DD>" + escape(repr(value))
Guido van Rossum7aee3841996-03-07 18:00:44 +0000974 print "</DL>"
975 print
976
977def print_directory():
978 """Dump the current directory as HTML."""
979 print
980 print "<H3>Current Working Directory:</H3>"
981 try:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000982 pwd = os.getcwd()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000983 except os.error, msg:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000984 print "os.error:", escape(str(msg))
Guido van Rossum7aee3841996-03-07 18:00:44 +0000985 else:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000986 print escape(pwd)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000987 print
Guido van Rossum9a22de11995-01-12 12:29:47 +0000988
Guido van Rossuma8738a51996-03-14 21:30:28 +0000989def print_arguments():
990 print
Guido van Rossum503e50b1996-05-28 22:57:20 +0000991 print "<H3>Command Line Arguments:</H3>"
Guido van Rossuma8738a51996-03-14 21:30:28 +0000992 print
993 print sys.argv
994 print
995
Guido van Rossum9a22de11995-01-12 12:29:47 +0000996def print_environ_usage():
Guido van Rossum7aee3841996-03-07 18:00:44 +0000997 """Dump a list of environment variables used by CGI as HTML."""
998 print """
Guido van Rossum72755611996-03-06 07:20:06 +0000999<H3>These environment variables could have been set:</H3>
1000<UL>
Guido van Rossum9a22de11995-01-12 12:29:47 +00001001<LI>AUTH_TYPE
1002<LI>CONTENT_LENGTH
1003<LI>CONTENT_TYPE
1004<LI>DATE_GMT
1005<LI>DATE_LOCAL
1006<LI>DOCUMENT_NAME
1007<LI>DOCUMENT_ROOT
1008<LI>DOCUMENT_URI
1009<LI>GATEWAY_INTERFACE
1010<LI>LAST_MODIFIED
1011<LI>PATH
1012<LI>PATH_INFO
1013<LI>PATH_TRANSLATED
1014<LI>QUERY_STRING
1015<LI>REMOTE_ADDR
1016<LI>REMOTE_HOST
1017<LI>REMOTE_IDENT
1018<LI>REMOTE_USER
1019<LI>REQUEST_METHOD
1020<LI>SCRIPT_NAME
1021<LI>SERVER_NAME
1022<LI>SERVER_PORT
1023<LI>SERVER_PROTOCOL
1024<LI>SERVER_ROOT
1025<LI>SERVER_SOFTWARE
1026</UL>
Guido van Rossum7aee3841996-03-07 18:00:44 +00001027In addition, HTTP headers sent by the server may be passed in the
1028environment as well. Here are some common variable names:
1029<UL>
1030<LI>HTTP_ACCEPT
1031<LI>HTTP_CONNECTION
1032<LI>HTTP_HOST
1033<LI>HTTP_PRAGMA
1034<LI>HTTP_REFERER
1035<LI>HTTP_USER_AGENT
1036</UL>
Guido van Rossum9a22de11995-01-12 12:29:47 +00001037"""
1038
Guido van Rossum9a22de11995-01-12 12:29:47 +00001039
Guido van Rossum72755611996-03-06 07:20:06 +00001040# Utilities
1041# =========
Guido van Rossum9a22de11995-01-12 12:29:47 +00001042
Guido van Rossum64c66201997-07-19 20:11:53 +00001043def escape(s, quote=None):
Guido van Rossum7aee3841996-03-07 18:00:44 +00001044 """Replace special characters '&', '<' and '>' by SGML entities."""
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +00001045 s = s.replace("&", "&amp;") # Must be done first!
1046 s = s.replace("<", "&lt;")
1047 s = s.replace(">", "&gt;")
Guido van Rossum64c66201997-07-19 20:11:53 +00001048 if quote:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +00001049 s = s.replace('"', "&quot;")
Guido van Rossum7aee3841996-03-07 18:00:44 +00001050 return s
Guido van Rossum9a22de11995-01-12 12:29:47 +00001051
Guido van Rossum2e441f72001-07-25 21:00:19 +00001052def valid_boundary(s, _vb_pattern="^[ -~]{0,200}[!-~]$"):
1053 import re
1054 return re.match(_vb_pattern, s)
Guido van Rossum9a22de11995-01-12 12:29:47 +00001055
Guido van Rossum72755611996-03-06 07:20:06 +00001056# Invoke mainline
1057# ===============
1058
1059# Call test() when this file is run as a script (not imported as a module)
Tim Peters88869f92001-01-14 23:36:06 +00001060if __name__ == '__main__':
Guido van Rossum7aee3841996-03-07 18:00:44 +00001061 test()