blob: 561f5adc566e5b05f962616962eb28ca7d5be26a [file] [log] [blame]
Guido van Rossum51914632000-10-03 13:51:09 +00001#! /usr/local/bin/python
Guido van Rossum1c9daa81995-09-18 21:52:37 +00002
Guido van Rossum467d7232001-02-13 13:13:33 +00003# NOTE: the above "/usr/local/bin/python" is NOT a mistake. It is
4# intentionally NOT "/usr/bin/env python". On many systems
5# (e.g. Solaris), /usr/local/bin is not in $PATH as passed to CGI
6# scripts, and /usr/local/bin is the default directory where Python is
7# installed, so /usr/bin/env would be unable to find python. Granted,
8# binary installations by Linux vendors often install Python in
9# /usr/bin. So let those vendors patch cgi.py to match their choice
10# of installation.
11
Guido van Rossum72755611996-03-06 07:20:06 +000012"""Support module for CGI (Common Gateway Interface) scripts.
Guido van Rossum1c9daa81995-09-18 21:52:37 +000013
Guido van Rossum7aee3841996-03-07 18:00:44 +000014This module defines a number of utilities for use by CGI scripts
15written in Python.
Guido van Rossum72755611996-03-06 07:20:06 +000016"""
17
Jeremy Hyltonc253d9a2000-08-03 20:57:44 +000018# XXX Perhaps there should be a slimmed version that doesn't contain
19# all those backwards compatible and debugging classes and functions?
Guido van Rossum98d9fd32000-02-28 15:12:25 +000020
21# History
22# -------
Tim Peters88869f92001-01-14 23:36:06 +000023#
Guido van Rossum98d9fd32000-02-28 15:12:25 +000024# Michael McLay started this module. Steve Majewski changed the
25# interface to SvFormContentDict and FormContentDict. The multipart
26# parsing was inspired by code submitted by Andreas Paepcke. Guido van
27# Rossum rewrote, reformatted and documented the module and is currently
28# responsible for its maintenance.
Tim Peters88869f92001-01-14 23:36:06 +000029#
Guido van Rossum98d9fd32000-02-28 15:12:25 +000030
Guido van Rossum52b8c292001-06-29 13:06:06 +000031__version__ = "2.6"
Guido van Rossum0147db01996-03-09 03:16:04 +000032
Guido van Rossum72755611996-03-06 07:20:06 +000033
34# Imports
35# =======
36
Raymond Hettingerf871d832004-12-31 21:59:02 +000037from operator import attrgetter
Guido van Rossum72755611996-03-06 07:20:06 +000038import sys
39import os
Guido van Rossuma5e9fb61997-08-12 18:18:13 +000040import urllib
Armin Rigo3a703b62005-09-19 09:11:04 +000041import mimetools
42import rfc822
Moshe Zadkaa1a4b592000-08-25 21:47:56 +000043import UserDict
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
Johannes Gijsbersc7fc10a2005-01-08 13:56:36 +0000240 pdict: dictionary containing other parameters of content-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 Rossum9568b732006-08-10 17:41:07 +0000254 Also, FieldStorage protects itself better against certain DoS attacks
255 by limiting the size of the data read in one chunk. The API here
256 does not support that kind of protection. This also affects parse()
257 since it can call parse_multipart().
Guido van Rossum72755611996-03-06 07:20:06 +0000258
Guido van Rossum7aee3841996-03-07 18:00:44 +0000259 """
Guido van Rossum2e441f72001-07-25 21:00:19 +0000260 boundary = ""
Raymond Hettinger54f02222002-06-01 14:18:47 +0000261 if 'boundary' in pdict:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000262 boundary = pdict['boundary']
Guido van Rossum2e441f72001-07-25 21:00:19 +0000263 if not valid_boundary(boundary):
Walter Dörwald70a6b492004-02-12 17:35:32 +0000264 raise ValueError, ('Invalid boundary in multipart form: %r'
265 % (boundary,))
Tim Petersab9ba272001-08-09 21:40:30 +0000266
Guido van Rossum7aee3841996-03-07 18:00:44 +0000267 nextpart = "--" + boundary
268 lastpart = "--" + boundary + "--"
269 partdict = {}
270 terminator = ""
271
272 while terminator != lastpart:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000273 bytes = -1
274 data = None
275 if terminator:
276 # At start of next part. Read headers first.
Armin Rigo3a703b62005-09-19 09:11:04 +0000277 headers = mimetools.Message(fp)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000278 clength = headers.getheader('content-length')
279 if clength:
280 try:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000281 bytes = int(clength)
282 except ValueError:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000283 pass
284 if bytes > 0:
285 if maxlen and bytes > maxlen:
286 raise ValueError, 'Maximum content length exceeded'
287 data = fp.read(bytes)
288 else:
289 data = ""
290 # Read lines until end of part.
291 lines = []
292 while 1:
293 line = fp.readline()
294 if not line:
295 terminator = lastpart # End outer loop
296 break
297 if line[:2] == "--":
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000298 terminator = line.strip()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000299 if terminator in (nextpart, lastpart):
300 break
301 lines.append(line)
302 # Done with part.
303 if data is None:
304 continue
305 if bytes < 0:
306 if lines:
307 # Strip final line terminator
308 line = lines[-1]
309 if line[-2:] == "\r\n":
310 line = line[:-2]
311 elif line[-1:] == "\n":
312 line = line[:-1]
313 lines[-1] = line
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000314 data = "".join(lines)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000315 line = headers['content-disposition']
316 if not line:
317 continue
318 key, params = parse_header(line)
319 if key != 'form-data':
320 continue
Raymond Hettinger54f02222002-06-01 14:18:47 +0000321 if 'name' in params:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000322 name = params['name']
323 else:
324 continue
Raymond Hettinger54f02222002-06-01 14:18:47 +0000325 if name in partdict:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000326 partdict[name].append(data)
327 else:
328 partdict[name] = [data]
Guido van Rossum72755611996-03-06 07:20:06 +0000329
Guido van Rossum7aee3841996-03-07 18:00:44 +0000330 return partdict
Guido van Rossum9a22de11995-01-12 12:29:47 +0000331
332
Guido van Rossum72755611996-03-06 07:20:06 +0000333def parse_header(line):
Guido van Rossum7aee3841996-03-07 18:00:44 +0000334 """Parse a Content-type like header.
335
336 Return the main content-type and a dictionary of options.
337
338 """
Raymond Hettingerf871d832004-12-31 21:59:02 +0000339 plist = [x.strip() for x in line.split(';')]
Raymond Hettinger46ac8eb2002-06-30 03:39:14 +0000340 key = plist.pop(0).lower()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000341 pdict = {}
342 for p in plist:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000343 i = p.find('=')
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000344 if i >= 0:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000345 name = p[:i].strip().lower()
346 value = p[i+1:].strip()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000347 if len(value) >= 2 and value[0] == value[-1] == '"':
348 value = value[1:-1]
Johannes Gijsbers9e15dd62004-08-14 15:39:34 +0000349 value = value.replace('\\\\', '\\').replace('\\"', '"')
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000350 pdict[name] = value
Guido van Rossum7aee3841996-03-07 18:00:44 +0000351 return key, pdict
Guido van Rossum72755611996-03-06 07:20:06 +0000352
353
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000354# Classes for field storage
355# =========================
356
357class MiniFieldStorage:
358
Guido van Rossum0147db01996-03-09 03:16:04 +0000359 """Like FieldStorage, for use when no file uploads are possible."""
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000360
Guido van Rossum7aee3841996-03-07 18:00:44 +0000361 # Dummy attributes
362 filename = None
363 list = None
364 type = None
Guido van Rossum773ab271996-07-23 03:46:24 +0000365 file = None
Guido van Rossum4032c2c1996-03-09 04:04:35 +0000366 type_options = {}
Guido van Rossum7aee3841996-03-07 18:00:44 +0000367 disposition = None
368 disposition_options = {}
369 headers = {}
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000370
Guido van Rossum7aee3841996-03-07 18:00:44 +0000371 def __init__(self, name, value):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000372 """Constructor from field name and value."""
373 self.name = name
374 self.value = value
Guido van Rossum773ab271996-07-23 03:46:24 +0000375 # self.file = StringIO(value)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000376
377 def __repr__(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000378 """Return printable representation."""
Walter Dörwald70a6b492004-02-12 17:35:32 +0000379 return "MiniFieldStorage(%r, %r)" % (self.name, self.value)
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000380
381
382class FieldStorage:
383
Guido van Rossum7aee3841996-03-07 18:00:44 +0000384 """Store a sequence of fields, reading multipart/form-data.
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000385
Guido van Rossum7aee3841996-03-07 18:00:44 +0000386 This class provides naming, typing, files stored on disk, and
387 more. At the top level, it is accessible like a dictionary, whose
388 keys are the field names. (Note: None can occur as a field name.)
389 The items are either a Python list (if there's multiple values) or
390 another FieldStorage or MiniFieldStorage object. If it's a single
391 object, it has the following attributes:
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000392
Guido van Rossum7aee3841996-03-07 18:00:44 +0000393 name: the field name, if specified; otherwise None
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000394
Guido van Rossum7aee3841996-03-07 18:00:44 +0000395 filename: the filename, if specified; otherwise None; this is the
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000396 client side filename, *not* the file name on which it is
397 stored (that's a temporary file you don't deal with)
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000398
Guido van Rossum7aee3841996-03-07 18:00:44 +0000399 value: the value as a *string*; for file uploads, this
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000400 transparently reads the file every time you request the value
Guido van Rossum7aee3841996-03-07 18:00:44 +0000401
402 file: the file(-like) object from which you can read the data;
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000403 None if the data is stored a simple string
Guido van Rossum7aee3841996-03-07 18:00:44 +0000404
405 type: the content-type, or None if not specified
406
407 type_options: dictionary of options specified on the content-type
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000408 line
Guido van Rossum7aee3841996-03-07 18:00:44 +0000409
410 disposition: content-disposition, or None if not specified
411
412 disposition_options: dictionary of corresponding options
413
Armin Rigo3a703b62005-09-19 09:11:04 +0000414 headers: a dictionary(-like) object (sometimes rfc822.Message or a
415 subclass thereof) containing *all* headers
Guido van Rossum7aee3841996-03-07 18:00:44 +0000416
417 The class is subclassable, mostly for the purpose of overriding
418 the make_file() method, which is called internally to come up with
419 a file open for reading and writing. This makes it possible to
420 override the default choice of storing all files in a temporary
421 directory and unlinking them as soon as they have been opened.
422
423 """
424
Guido van Rossum773ab271996-07-23 03:46:24 +0000425 def __init__(self, fp=None, headers=None, outerboundary="",
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000426 environ=os.environ, keep_blank_values=0, strict_parsing=0):
427 """Constructor. Read multipart/* until last part.
Guido van Rossum7aee3841996-03-07 18:00:44 +0000428
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000429 Arguments, all optional:
Guido van Rossum7aee3841996-03-07 18:00:44 +0000430
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000431 fp : file pointer; default: sys.stdin
Guido van Rossumb1b4f941998-05-08 19:55:51 +0000432 (not used when the request method is GET)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000433
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000434 headers : header dictionary-like object; default:
435 taken from environ as per CGI spec
Guido van Rossum7aee3841996-03-07 18:00:44 +0000436
Guido van Rossum773ab271996-07-23 03:46:24 +0000437 outerboundary : terminating multipart boundary
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000438 (for internal use only)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000439
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000440 environ : environment dictionary; default: os.environ
Guido van Rossum773ab271996-07-23 03:46:24 +0000441
442 keep_blank_values: flag indicating whether blank values in
Tim Peters88869f92001-01-14 23:36:06 +0000443 URL encoded forms should be treated as blank strings.
444 A true value indicates that blanks should be retained as
Guido van Rossum773ab271996-07-23 03:46:24 +0000445 blank strings. The default false value indicates that
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000446 blank values are to be ignored and treated as if they were
447 not included.
Guido van Rossum773ab271996-07-23 03:46:24 +0000448
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000449 strict_parsing: flag indicating what to do with parsing errors.
450 If false (the default), errors are silently ignored.
451 If true, errors raise a ValueError exception.
Guido van Rossume08c04c1996-11-11 19:29:11 +0000452
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000453 """
454 method = 'GET'
455 self.keep_blank_values = keep_blank_values
456 self.strict_parsing = strict_parsing
Raymond Hettinger54f02222002-06-01 14:18:47 +0000457 if 'REQUEST_METHOD' in environ:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000458 method = environ['REQUEST_METHOD'].upper()
Facundo Batistaa6a4d502008-06-21 18:58:04 +0000459 self.qs_on_post = None
Guido van Rossum01852831998-06-25 02:40:17 +0000460 if method == 'GET' or method == 'HEAD':
Raymond Hettinger54f02222002-06-01 14:18:47 +0000461 if 'QUERY_STRING' in environ:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000462 qs = environ['QUERY_STRING']
463 elif sys.argv[1:]:
464 qs = sys.argv[1]
465 else:
466 qs = ""
467 fp = StringIO(qs)
468 if headers is None:
469 headers = {'content-type':
470 "application/x-www-form-urlencoded"}
471 if headers is None:
Guido van Rossumcff311a1998-06-11 14:06:59 +0000472 headers = {}
473 if method == 'POST':
474 # Set default content-type for POST to what's traditional
475 headers['content-type'] = "application/x-www-form-urlencoded"
Raymond Hettinger54f02222002-06-01 14:18:47 +0000476 if 'CONTENT_TYPE' in environ:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000477 headers['content-type'] = environ['CONTENT_TYPE']
Facundo Batistaa6a4d502008-06-21 18:58:04 +0000478 if 'QUERY_STRING' in environ:
479 self.qs_on_post = environ['QUERY_STRING']
Raymond Hettinger54f02222002-06-01 14:18:47 +0000480 if 'CONTENT_LENGTH' in environ:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000481 headers['content-length'] = environ['CONTENT_LENGTH']
482 self.fp = fp or sys.stdin
483 self.headers = headers
484 self.outerboundary = outerboundary
Guido van Rossum7aee3841996-03-07 18:00:44 +0000485
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000486 # Process content-disposition header
487 cdisp, pdict = "", {}
Raymond Hettinger54f02222002-06-01 14:18:47 +0000488 if 'content-disposition' in self.headers:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000489 cdisp, pdict = parse_header(self.headers['content-disposition'])
490 self.disposition = cdisp
491 self.disposition_options = pdict
492 self.name = None
Raymond Hettinger54f02222002-06-01 14:18:47 +0000493 if 'name' in pdict:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000494 self.name = pdict['name']
495 self.filename = None
Raymond Hettinger54f02222002-06-01 14:18:47 +0000496 if 'filename' in pdict:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000497 self.filename = pdict['filename']
Guido van Rossum7aee3841996-03-07 18:00:44 +0000498
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000499 # Process content-type header
Barry Warsaw302331a1999-01-08 17:42:03 +0000500 #
501 # Honor any existing content-type header. But if there is no
502 # content-type header, use some sensible defaults. Assume
503 # outerboundary is "" at the outer level, but something non-false
504 # inside a multi-part. The default for an inner part is text/plain,
505 # but for an outer part it should be urlencoded. This should catch
506 # bogus clients which erroneously forget to include a content-type
507 # header.
508 #
509 # See below for what we do if there does exist a content-type header,
510 # but it happens to be something we don't understand.
Raymond Hettinger54f02222002-06-01 14:18:47 +0000511 if 'content-type' in self.headers:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000512 ctype, pdict = parse_header(self.headers['content-type'])
Guido van Rossumce900de1999-06-02 18:44:22 +0000513 elif self.outerboundary or method != 'POST':
Barry Warsaw302331a1999-01-08 17:42:03 +0000514 ctype, pdict = "text/plain", {}
515 else:
516 ctype, pdict = 'application/x-www-form-urlencoded', {}
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000517 self.type = ctype
518 self.type_options = pdict
519 self.innerboundary = ""
Raymond Hettinger54f02222002-06-01 14:18:47 +0000520 if 'boundary' in pdict:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000521 self.innerboundary = pdict['boundary']
522 clen = -1
Raymond Hettinger54f02222002-06-01 14:18:47 +0000523 if 'content-length' in self.headers:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000524 try:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000525 clen = int(self.headers['content-length'])
Skip Montanarodb5d1442002-03-23 05:50:17 +0000526 except ValueError:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000527 pass
528 if maxlen and clen > maxlen:
529 raise ValueError, 'Maximum content length exceeded'
530 self.length = clen
Guido van Rossum7aee3841996-03-07 18:00:44 +0000531
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000532 self.list = self.file = None
533 self.done = 0
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000534 if ctype == 'application/x-www-form-urlencoded':
535 self.read_urlencoded()
536 elif ctype[:10] == 'multipart/':
Guido van Rossumf5745001998-10-20 14:43:02 +0000537 self.read_multi(environ, keep_blank_values, strict_parsing)
Barry Warsaw302331a1999-01-08 17:42:03 +0000538 else:
Guido van Rossum60a3bd81999-06-11 18:26:09 +0000539 self.read_single()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000540
541 def __repr__(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000542 """Return a printable representation."""
Walter Dörwald70a6b492004-02-12 17:35:32 +0000543 return "FieldStorage(%r, %r, %r)" % (
544 self.name, self.filename, self.value)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000545
Guido van Rossum4061cbe2002-09-11 18:20:34 +0000546 def __iter__(self):
547 return iter(self.keys())
548
Guido van Rossum7aee3841996-03-07 18:00:44 +0000549 def __getattr__(self, name):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000550 if name != 'value':
551 raise AttributeError, name
552 if self.file:
553 self.file.seek(0)
554 value = self.file.read()
555 self.file.seek(0)
556 elif self.list is not None:
557 value = self.list
558 else:
559 value = None
560 return value
Guido van Rossum7aee3841996-03-07 18:00:44 +0000561
562 def __getitem__(self, key):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000563 """Dictionary style indexing."""
564 if self.list is None:
565 raise TypeError, "not indexable"
566 found = []
567 for item in self.list:
568 if item.name == key: found.append(item)
569 if not found:
570 raise KeyError, key
571 if len(found) == 1:
572 return found[0]
573 else:
574 return found
Guido van Rossum7aee3841996-03-07 18:00:44 +0000575
Moshe Zadkaa1a4b592000-08-25 21:47:56 +0000576 def getvalue(self, key, default=None):
577 """Dictionary style get() method, including 'value' lookup."""
Raymond Hettinger54f02222002-06-01 14:18:47 +0000578 if key in self:
Moshe Zadkaa1a4b592000-08-25 21:47:56 +0000579 value = self[key]
580 if type(value) is type([]):
Raymond Hettingerf871d832004-12-31 21:59:02 +0000581 return map(attrgetter('value'), value)
Moshe Zadkaa1a4b592000-08-25 21:47:56 +0000582 else:
583 return value.value
584 else:
585 return default
586
Guido van Rossum1bfb3882001-09-05 19:45:34 +0000587 def getfirst(self, key, default=None):
588 """ Return the first value received."""
Raymond Hettinger54f02222002-06-01 14:18:47 +0000589 if key in self:
Guido van Rossum1bfb3882001-09-05 19:45:34 +0000590 value = self[key]
591 if type(value) is type([]):
592 return value[0].value
593 else:
594 return value.value
595 else:
596 return default
597
598 def getlist(self, key):
599 """ Return list of received values."""
Raymond Hettinger54f02222002-06-01 14:18:47 +0000600 if key in self:
Guido van Rossum1bfb3882001-09-05 19:45:34 +0000601 value = self[key]
602 if type(value) is type([]):
Raymond Hettingerf871d832004-12-31 21:59:02 +0000603 return map(attrgetter('value'), value)
Guido van Rossum1bfb3882001-09-05 19:45:34 +0000604 else:
605 return [value.value]
606 else:
607 return []
608
Guido van Rossum7aee3841996-03-07 18:00:44 +0000609 def keys(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000610 """Dictionary style keys() method."""
611 if self.list is None:
612 raise TypeError, "not indexable"
Georg Brandlaff85e22007-09-20 16:06:07 +0000613 return list(set(item.name for item in self.list))
Guido van Rossum7aee3841996-03-07 18:00:44 +0000614
Guido van Rossum0147db01996-03-09 03:16:04 +0000615 def has_key(self, key):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000616 """Dictionary style has_key() method."""
617 if self.list is None:
618 raise TypeError, "not indexable"
Georg Brandlaff85e22007-09-20 16:06:07 +0000619 return any(item.name == key for item in self.list)
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"
Georg Brandlaff85e22007-09-20 16:06:07 +0000625 return any(item.name == key for item in self.list)
Raymond Hettinger54f02222002-06-01 14:18:47 +0000626
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
Georg Brandlaff85e22007-09-20 16:06:07 +0000631 def __nonzero__(self):
632 return bool(self.list)
633
Guido van Rossum7aee3841996-03-07 18:00:44 +0000634 def read_urlencoded(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000635 """Internal: read data in query string format."""
636 qs = self.fp.read(self.length)
Facundo Batistaa6a4d502008-06-21 18:58:04 +0000637 if self.qs_on_post:
638 qs += '&' + self.qs_on_post
Guido van Rossum1946f0d1999-06-04 17:54:39 +0000639 self.list = list = []
640 for key, value in parse_qsl(qs, self.keep_blank_values,
641 self.strict_parsing):
642 list.append(MiniFieldStorage(key, value))
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000643 self.skip_lines()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000644
Guido van Rossum030d2ec1998-12-09 22:16:46 +0000645 FieldStorageClass = None
646
Guido van Rossumf5745001998-10-20 14:43:02 +0000647 def read_multi(self, environ, keep_blank_values, strict_parsing):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000648 """Internal: read a part that is itself multipart."""
Guido van Rossum2e441f72001-07-25 21:00:19 +0000649 ib = self.innerboundary
650 if not valid_boundary(ib):
Walter Dörwald70a6b492004-02-12 17:35:32 +0000651 raise ValueError, 'Invalid boundary in multipart form: %r' % (ib,)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000652 self.list = []
Facundo Batistaa6a4d502008-06-21 18:58:04 +0000653 if self.qs_on_post:
654 for key, value in parse_qsl(self.qs_on_post, self.keep_blank_values,
655 self.strict_parsing):
656 self.list.append(MiniFieldStorage(key, value))
657 FieldStorageClass = None
658
Guido van Rossum030d2ec1998-12-09 22:16:46 +0000659 klass = self.FieldStorageClass or self.__class__
Guido van Rossum2e441f72001-07-25 21:00:19 +0000660 part = klass(self.fp, {}, ib,
Guido van Rossum030d2ec1998-12-09 22:16:46 +0000661 environ, keep_blank_values, strict_parsing)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000662 # Throw first part away
663 while not part.done:
Armin Rigo3a703b62005-09-19 09:11:04 +0000664 headers = rfc822.Message(self.fp)
Guido van Rossum2e441f72001-07-25 21:00:19 +0000665 part = klass(self.fp, headers, ib,
Guido van Rossum030d2ec1998-12-09 22:16:46 +0000666 environ, keep_blank_values, strict_parsing)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000667 self.list.append(part)
668 self.skip_lines()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000669
670 def read_single(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000671 """Internal: read an atomic part."""
672 if self.length >= 0:
673 self.read_binary()
674 self.skip_lines()
675 else:
676 self.read_lines()
677 self.file.seek(0)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000678
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000679 bufsize = 8*1024 # I/O buffering size for copy to file
Guido van Rossum7aee3841996-03-07 18:00:44 +0000680
681 def read_binary(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000682 """Internal: read binary data."""
683 self.file = self.make_file('b')
684 todo = self.length
685 if todo >= 0:
686 while todo > 0:
687 data = self.fp.read(min(todo, self.bufsize))
688 if not data:
689 self.done = -1
690 break
691 self.file.write(data)
692 todo = todo - len(data)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000693
694 def read_lines(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000695 """Internal: read lines until EOF or outerboundary."""
Guido van Rossum52b8c292001-06-29 13:06:06 +0000696 self.file = self.__file = StringIO()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000697 if self.outerboundary:
698 self.read_lines_to_outerboundary()
699 else:
700 self.read_lines_to_eof()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000701
Guido van Rossum52b8c292001-06-29 13:06:06 +0000702 def __write(self, line):
703 if self.__file is not None:
704 if self.__file.tell() + len(line) > 1000:
705 self.file = self.make_file('')
706 self.file.write(self.__file.getvalue())
707 self.__file = None
708 self.file.write(line)
709
Guido van Rossum7aee3841996-03-07 18:00:44 +0000710 def read_lines_to_eof(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000711 """Internal: read lines until EOF."""
712 while 1:
Guido van Rossum9568b732006-08-10 17:41:07 +0000713 line = self.fp.readline(1<<16)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000714 if not line:
715 self.done = -1
716 break
Guido van Rossum52b8c292001-06-29 13:06:06 +0000717 self.__write(line)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000718
719 def read_lines_to_outerboundary(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000720 """Internal: read lines until outerboundary."""
721 next = "--" + self.outerboundary
722 last = next + "--"
723 delim = ""
Guido van Rossum9568b732006-08-10 17:41:07 +0000724 last_line_lfend = True
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000725 while 1:
Guido van Rossum9568b732006-08-10 17:41:07 +0000726 line = self.fp.readline(1<<16)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000727 if not line:
728 self.done = -1
729 break
Guido van Rossum9568b732006-08-10 17:41:07 +0000730 if line[:2] == "--" and last_line_lfend:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000731 strippedline = line.strip()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000732 if strippedline == next:
733 break
734 if strippedline == last:
735 self.done = 1
736 break
737 odelim = delim
738 if line[-2:] == "\r\n":
739 delim = "\r\n"
740 line = line[:-2]
Guido van Rossum9568b732006-08-10 17:41:07 +0000741 last_line_lfend = True
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000742 elif line[-1] == "\n":
743 delim = "\n"
744 line = line[:-1]
Guido van Rossum9568b732006-08-10 17:41:07 +0000745 last_line_lfend = True
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000746 else:
747 delim = ""
Guido van Rossum9568b732006-08-10 17:41:07 +0000748 last_line_lfend = False
Guido van Rossum52b8c292001-06-29 13:06:06 +0000749 self.__write(odelim + line)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000750
751 def skip_lines(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000752 """Internal: skip lines until outer boundary if defined."""
753 if not self.outerboundary or self.done:
754 return
755 next = "--" + self.outerboundary
756 last = next + "--"
Guido van Rossum9568b732006-08-10 17:41:07 +0000757 last_line_lfend = True
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000758 while 1:
Guido van Rossum9568b732006-08-10 17:41:07 +0000759 line = self.fp.readline(1<<16)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000760 if not line:
761 self.done = -1
762 break
Guido van Rossum9568b732006-08-10 17:41:07 +0000763 if line[:2] == "--" and last_line_lfend:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000764 strippedline = line.strip()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000765 if strippedline == next:
766 break
767 if strippedline == last:
768 self.done = 1
769 break
Guido van Rossum9568b732006-08-10 17:41:07 +0000770 last_line_lfend = line.endswith('\n')
Guido van Rossum7aee3841996-03-07 18:00:44 +0000771
Guido van Rossuma5e9fb61997-08-12 18:18:13 +0000772 def make_file(self, binary=None):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000773 """Overridable: return a readable & writable file.
Guido van Rossum7aee3841996-03-07 18:00:44 +0000774
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000775 The file will be used as follows:
776 - data is written to it
777 - seek(0)
778 - data is read from it
Guido van Rossum7aee3841996-03-07 18:00:44 +0000779
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000780 The 'binary' argument is unused -- the file is always opened
781 in binary mode.
Guido van Rossum7aee3841996-03-07 18:00:44 +0000782
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000783 This version opens a temporary file for reading and writing,
784 and immediately deletes (unlinks) it. The trick (on Unix!) is
785 that the file can still be used, but it can't be opened by
786 another process, and it will automatically be deleted when it
787 is closed or when the current process terminates.
Guido van Rossum4032c2c1996-03-09 04:04:35 +0000788
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000789 If you want a more permanent file, you derive a class which
790 overrides this method. If you want a visible temporary file
791 that is nevertheless automatically deleted when the script
792 terminates, try defining a __del__ method in a derived class
793 which unlinks the temporary files you have created.
Guido van Rossum7aee3841996-03-07 18:00:44 +0000794
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000795 """
796 import tempfile
797 return tempfile.TemporaryFile("w+b")
Tim Peters88869f92001-01-14 23:36:06 +0000798
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000799
800
Guido van Rossum4032c2c1996-03-09 04:04:35 +0000801# Backwards Compatibility Classes
802# ===============================
Guido van Rossum9a22de11995-01-12 12:29:47 +0000803
Moshe Zadkaa1a4b592000-08-25 21:47:56 +0000804class FormContentDict(UserDict.UserDict):
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000805 """Form content as dictionary with a list of values per field.
Guido van Rossum72755611996-03-06 07:20:06 +0000806
Guido van Rossum7aee3841996-03-07 18:00:44 +0000807 form = FormContentDict()
808
809 form[key] -> [value, value, ...]
Raymond Hettinger54f02222002-06-01 14:18:47 +0000810 key in form -> Boolean
Guido van Rossum7aee3841996-03-07 18:00:44 +0000811 form.keys() -> [key, key, ...]
812 form.values() -> [[val, val, ...], [val, val, ...], ...]
813 form.items() -> [(key, [val, val, ...]), (key, [val, val, ...]), ...]
814 form.dict == {key: [val, val, ...], ...}
815
816 """
Georg Brandl05b3c452006-09-30 10:58:01 +0000817 def __init__(self, environ=os.environ, keep_blank_values=0, strict_parsing=0):
818 self.dict = self.data = parse(environ=environ,
819 keep_blank_values=keep_blank_values,
820 strict_parsing=strict_parsing)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000821 self.query_string = environ['QUERY_STRING']
Guido van Rossum9a22de11995-01-12 12:29:47 +0000822
823
Guido van Rossum9a22de11995-01-12 12:29:47 +0000824class SvFormContentDict(FormContentDict):
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000825 """Form content as dictionary expecting a single value per field.
Guido van Rossum7aee3841996-03-07 18:00:44 +0000826
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000827 If you only expect a single value for each field, then form[key]
Guido van Rossum7aee3841996-03-07 18:00:44 +0000828 will return that single value. It will raise an IndexError if
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000829 that expectation is not true. If you expect a field to have
Guido van Rossum7aee3841996-03-07 18:00:44 +0000830 possible multiple values, than you can use form.getlist(key) to
831 get all of the values. values() and items() are a compromise:
832 they return single strings where there is a single value, and
833 lists of strings otherwise.
834
835 """
836 def __getitem__(self, key):
Tim Peters88869f92001-01-14 23:36:06 +0000837 if len(self.dict[key]) > 1:
838 raise IndexError, 'expecting a single value'
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000839 return self.dict[key][0]
Guido van Rossum7aee3841996-03-07 18:00:44 +0000840 def getlist(self, key):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000841 return self.dict[key]
Guido van Rossum7aee3841996-03-07 18:00:44 +0000842 def values(self):
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000843 result = []
844 for value in self.dict.values():
845 if len(value) == 1:
846 result.append(value[0])
847 else: result.append(value)
848 return result
Guido van Rossum7aee3841996-03-07 18:00:44 +0000849 def items(self):
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000850 result = []
851 for key, value in self.dict.items():
852 if len(value) == 1:
853 result.append((key, value[0]))
854 else: result.append((key, value))
855 return result
Guido van Rossum9a22de11995-01-12 12:29:47 +0000856
857
Guido van Rossum9a22de11995-01-12 12:29:47 +0000858class InterpFormContentDict(SvFormContentDict):
Tim Peters88869f92001-01-14 23:36:06 +0000859 """This class is present for backwards compatibility only."""
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000860 def __getitem__(self, key):
861 v = SvFormContentDict.__getitem__(self, key)
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000862 if v[0] in '0123456789+-.':
863 try: return int(v)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000864 except ValueError:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000865 try: return float(v)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000866 except ValueError: pass
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000867 return v.strip()
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000868 def values(self):
869 result = []
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000870 for key in self.keys():
871 try:
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000872 result.append(self[key])
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000873 except IndexError:
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000874 result.append(self.dict[key])
875 return result
876 def items(self):
877 result = []
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000878 for key in self.keys():
879 try:
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000880 result.append((key, self[key]))
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000881 except IndexError:
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000882 result.append((key, self.dict[key]))
883 return result
Guido van Rossum9a22de11995-01-12 12:29:47 +0000884
885
Guido van Rossum9a22de11995-01-12 12:29:47 +0000886class FormContent(FormContentDict):
Tim Peters88869f92001-01-14 23:36:06 +0000887 """This class is present for backwards compatibility only."""
Guido van Rossum0147db01996-03-09 03:16:04 +0000888 def values(self, key):
Raymond Hettinger54f02222002-06-01 14:18:47 +0000889 if key in self.dict :return self.dict[key]
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000890 else: return None
Guido van Rossum0147db01996-03-09 03:16:04 +0000891 def indexed_value(self, key, location):
Raymond Hettinger54f02222002-06-01 14:18:47 +0000892 if key in self.dict:
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000893 if len(self.dict[key]) > location:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000894 return self.dict[key][location]
895 else: return None
896 else: return None
Guido van Rossum0147db01996-03-09 03:16:04 +0000897 def value(self, key):
Raymond Hettinger54f02222002-06-01 14:18:47 +0000898 if key in self.dict: return self.dict[key][0]
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000899 else: return None
Guido van Rossum0147db01996-03-09 03:16:04 +0000900 def length(self, key):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000901 return len(self.dict[key])
Guido van Rossum0147db01996-03-09 03:16:04 +0000902 def stripped(self, key):
Raymond Hettinger54f02222002-06-01 14:18:47 +0000903 if key in self.dict: return self.dict[key][0].strip()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000904 else: return None
Guido van Rossum7aee3841996-03-07 18:00:44 +0000905 def pars(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000906 return self.dict
Guido van Rossum9a22de11995-01-12 12:29:47 +0000907
908
Guido van Rossum72755611996-03-06 07:20:06 +0000909# Test/debug code
910# ===============
Guido van Rossum9a22de11995-01-12 12:29:47 +0000911
Guido van Rossum773ab271996-07-23 03:46:24 +0000912def test(environ=os.environ):
Guido van Rossum7aee3841996-03-07 18:00:44 +0000913 """Robust test CGI script, usable as main program.
Guido van Rossum9a22de11995-01-12 12:29:47 +0000914
Guido van Rossum7aee3841996-03-07 18:00:44 +0000915 Write minimal HTTP headers and dump all information provided to
916 the script in HTML form.
917
918 """
Guido van Rossum7aee3841996-03-07 18:00:44 +0000919 print "Content-type: text/html"
920 print
921 sys.stderr = sys.stdout
922 try:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000923 form = FieldStorage() # Replace with other classes to test those
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000924 print_directory()
925 print_arguments()
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000926 print_form(form)
927 print_environ(environ)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000928 print_environ_usage()
929 def f():
930 exec "testing print_exception() -- <I>italics?</I>"
931 def g(f=f):
932 f()
933 print "<H3>What follows is a test, not an actual exception:</H3>"
934 g()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000935 except:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000936 print_exception()
Guido van Rossumf85de8a1996-08-20 20:22:39 +0000937
Guido van Rossum57d51f22000-09-16 21:16:01 +0000938 print "<H1>Second try with a small maxlen...</H1>"
939
Guido van Rossumad164711997-05-13 19:03:23 +0000940 global maxlen
941 maxlen = 50
942 try:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000943 form = FieldStorage() # Replace with other classes to test those
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000944 print_directory()
945 print_arguments()
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000946 print_form(form)
947 print_environ(environ)
Guido van Rossumad164711997-05-13 19:03:23 +0000948 except:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000949 print_exception()
Guido van Rossumad164711997-05-13 19:03:23 +0000950
Guido van Rossumf85de8a1996-08-20 20:22:39 +0000951def print_exception(type=None, value=None, tb=None, limit=None):
952 if type is None:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000953 type, value, tb = sys.exc_info()
Guido van Rossumf85de8a1996-08-20 20:22:39 +0000954 import traceback
955 print
Guido van Rossum7dd06962000-12-27 19:12:58 +0000956 print "<H3>Traceback (most recent call last):</H3>"
Guido van Rossumf85de8a1996-08-20 20:22:39 +0000957 list = traceback.format_tb(tb, limit) + \
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000958 traceback.format_exception_only(type, value)
Guido van Rossumf85de8a1996-08-20 20:22:39 +0000959 print "<PRE>%s<B>%s</B></PRE>" % (
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000960 escape("".join(list[:-1])),
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000961 escape(list[-1]),
962 )
Guido van Rossumf15d1591997-09-29 23:22:12 +0000963 del tb
Guido van Rossum9a22de11995-01-12 12:29:47 +0000964
Guido van Rossum773ab271996-07-23 03:46:24 +0000965def print_environ(environ=os.environ):
Guido van Rossum7aee3841996-03-07 18:00:44 +0000966 """Dump the shell environment as HTML."""
967 keys = environ.keys()
968 keys.sort()
969 print
Guido van Rossum503e50b1996-05-28 22:57:20 +0000970 print "<H3>Shell Environment:</H3>"
Guido van Rossum7aee3841996-03-07 18:00:44 +0000971 print "<DL>"
972 for key in keys:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000973 print "<DT>", escape(key), "<DD>", escape(environ[key])
Tim Peters88869f92001-01-14 23:36:06 +0000974 print "</DL>"
Guido van Rossum7aee3841996-03-07 18:00:44 +0000975 print
Guido van Rossum72755611996-03-06 07:20:06 +0000976
977def print_form(form):
Guido van Rossum7aee3841996-03-07 18:00:44 +0000978 """Dump the contents of a form as HTML."""
979 keys = form.keys()
980 keys.sort()
981 print
Guido van Rossum503e50b1996-05-28 22:57:20 +0000982 print "<H3>Form Contents:</H3>"
Guido van Rossum57d51f22000-09-16 21:16:01 +0000983 if not keys:
984 print "<P>No form fields."
Guido van Rossum7aee3841996-03-07 18:00:44 +0000985 print "<DL>"
986 for key in keys:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000987 print "<DT>" + escape(key) + ":",
988 value = form[key]
Walter Dörwald70a6b492004-02-12 17:35:32 +0000989 print "<i>" + escape(repr(type(value))) + "</i>"
990 print "<DD>" + escape(repr(value))
Guido van Rossum7aee3841996-03-07 18:00:44 +0000991 print "</DL>"
992 print
993
994def print_directory():
995 """Dump the current directory as HTML."""
996 print
997 print "<H3>Current Working Directory:</H3>"
998 try:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000999 pwd = os.getcwd()
Guido van Rossum7aee3841996-03-07 18:00:44 +00001000 except os.error, msg:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +00001001 print "os.error:", escape(str(msg))
Guido van Rossum7aee3841996-03-07 18:00:44 +00001002 else:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +00001003 print escape(pwd)
Guido van Rossum7aee3841996-03-07 18:00:44 +00001004 print
Guido van Rossum9a22de11995-01-12 12:29:47 +00001005
Guido van Rossuma8738a51996-03-14 21:30:28 +00001006def print_arguments():
1007 print
Guido van Rossum503e50b1996-05-28 22:57:20 +00001008 print "<H3>Command Line Arguments:</H3>"
Guido van Rossuma8738a51996-03-14 21:30:28 +00001009 print
1010 print sys.argv
1011 print
1012
Guido van Rossum9a22de11995-01-12 12:29:47 +00001013def print_environ_usage():
Guido van Rossum7aee3841996-03-07 18:00:44 +00001014 """Dump a list of environment variables used by CGI as HTML."""
1015 print """
Guido van Rossum72755611996-03-06 07:20:06 +00001016<H3>These environment variables could have been set:</H3>
1017<UL>
Guido van Rossum9a22de11995-01-12 12:29:47 +00001018<LI>AUTH_TYPE
1019<LI>CONTENT_LENGTH
1020<LI>CONTENT_TYPE
1021<LI>DATE_GMT
1022<LI>DATE_LOCAL
1023<LI>DOCUMENT_NAME
1024<LI>DOCUMENT_ROOT
1025<LI>DOCUMENT_URI
1026<LI>GATEWAY_INTERFACE
1027<LI>LAST_MODIFIED
1028<LI>PATH
1029<LI>PATH_INFO
1030<LI>PATH_TRANSLATED
1031<LI>QUERY_STRING
1032<LI>REMOTE_ADDR
1033<LI>REMOTE_HOST
1034<LI>REMOTE_IDENT
1035<LI>REMOTE_USER
1036<LI>REQUEST_METHOD
1037<LI>SCRIPT_NAME
1038<LI>SERVER_NAME
1039<LI>SERVER_PORT
1040<LI>SERVER_PROTOCOL
1041<LI>SERVER_ROOT
1042<LI>SERVER_SOFTWARE
1043</UL>
Guido van Rossum7aee3841996-03-07 18:00:44 +00001044In addition, HTTP headers sent by the server may be passed in the
1045environment as well. Here are some common variable names:
1046<UL>
1047<LI>HTTP_ACCEPT
1048<LI>HTTP_CONNECTION
1049<LI>HTTP_HOST
1050<LI>HTTP_PRAGMA
1051<LI>HTTP_REFERER
1052<LI>HTTP_USER_AGENT
1053</UL>
Guido van Rossum9a22de11995-01-12 12:29:47 +00001054"""
1055
Guido van Rossum9a22de11995-01-12 12:29:47 +00001056
Guido van Rossum72755611996-03-06 07:20:06 +00001057# Utilities
1058# =========
Guido van Rossum9a22de11995-01-12 12:29:47 +00001059
Guido van Rossum64c66201997-07-19 20:11:53 +00001060def escape(s, quote=None):
Skip Montanaro97b2fa22005-08-02 02:50:25 +00001061 '''Replace special characters "&", "<" and ">" to HTML-safe sequences.
1062 If the optional flag quote is true, the quotation mark character (")
1063 is also translated.'''
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +00001064 s = s.replace("&", "&amp;") # Must be done first!
1065 s = s.replace("<", "&lt;")
1066 s = s.replace(">", "&gt;")
Guido van Rossum64c66201997-07-19 20:11:53 +00001067 if quote:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +00001068 s = s.replace('"', "&quot;")
Guido van Rossum7aee3841996-03-07 18:00:44 +00001069 return s
Guido van Rossum9a22de11995-01-12 12:29:47 +00001070
Guido van Rossum2e441f72001-07-25 21:00:19 +00001071def valid_boundary(s, _vb_pattern="^[ -~]{0,200}[!-~]$"):
1072 import re
1073 return re.match(_vb_pattern, s)
Guido van Rossum9a22de11995-01-12 12:29:47 +00001074
Guido van Rossum72755611996-03-06 07:20:06 +00001075# Invoke mainline
1076# ===============
1077
1078# Call test() when this file is run as a script (not imported as a module)
Tim Peters88869f92001-01-14 23:36:06 +00001079if __name__ == '__main__':
Guido van Rossum7aee3841996-03-07 18:00:44 +00001080 test()