blob: 64ba6d16cafba9602dc9268d45fcd270a7d9e446 [file] [log] [blame]
Benjamin Petersonafa595b2010-03-11 22:03:45 +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
Moshe Zadkaa1a4b592000-08-25 21:47:56 +000040import UserDict
Facundo Batistac585df92008-09-03 22:35:50 +000041import urlparse
42
43from warnings import filterwarnings, catch_warnings, warn
Brett Cannon1eaf0742008-09-02 01:25:16 +000044with catch_warnings():
45 if sys.py3kwarning:
46 filterwarnings("ignore", ".*mimetools has been removed",
Florent Xicluna78c18712010-03-17 20:05:11 +000047 DeprecationWarning)
48 filterwarnings("ignore", ".*rfc822 has been removed",
49 DeprecationWarning)
Brett Cannon721b1452008-08-16 22:00:27 +000050 import mimetools
Brett Cannon721b1452008-08-16 22:00:27 +000051 import rfc822
52
Raymond Hettingera6172712004-12-31 19:15:26 +000053try:
54 from cStringIO import StringIO
55except ImportError:
56 from StringIO import StringIO
Guido van Rossum72755611996-03-06 07:20:06 +000057
Guido van Rossuma8423a92001-03-19 13:40:44 +000058__all__ = ["MiniFieldStorage", "FieldStorage", "FormContentDict",
59 "SvFormContentDict", "InterpFormContentDict", "FormContent",
60 "parse", "parse_qs", "parse_qsl", "parse_multipart",
61 "parse_header", "print_exception", "print_environ",
62 "print_form", "print_directory", "print_arguments",
63 "print_environ_usage", "escape"]
Guido van Rossumc204c701996-09-05 19:07:11 +000064
65# Logging support
66# ===============
67
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000068logfile = "" # Filename to log to, if not empty
69logfp = None # File object to log to, if not None
Guido van Rossumc204c701996-09-05 19:07:11 +000070
71def initlog(*allargs):
72 """Write a log message, if there is a log file.
73
74 Even though this function is called initlog(), you should always
75 use log(); log is a variable that is set either to initlog
76 (initially), to dolog (once the log file has been opened), or to
77 nolog (when logging is disabled).
78
79 The first argument is a format string; the remaining arguments (if
80 any) are arguments to the % operator, so e.g.
81 log("%s: %s", "a", "b")
82 will write "a: b" to the log file, followed by a newline.
83
84 If the global logfp is not None, it should be a file object to
85 which log data is written.
86
87 If the global logfp is None, the global logfile may be a string
88 giving a filename to open, in append mode. This file should be
89 world writable!!! If the file can't be opened, logging is
90 silently disabled (since there is no safe place where we could
91 send an error message).
92
93 """
94 global logfp, log
95 if logfile and not logfp:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000096 try:
97 logfp = open(logfile, "a")
98 except IOError:
99 pass
Guido van Rossumc204c701996-09-05 19:07:11 +0000100 if not logfp:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000101 log = nolog
Guido van Rossumc204c701996-09-05 19:07:11 +0000102 else:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000103 log = dolog
Guido van Rossum68468eb2003-02-27 20:14:51 +0000104 log(*allargs)
Guido van Rossumc204c701996-09-05 19:07:11 +0000105
106def dolog(fmt, *args):
107 """Write a log message to the log file. See initlog() for docs."""
108 logfp.write(fmt%args + "\n")
109
110def nolog(*allargs):
111 """Dummy function, assigned to log when logging is disabled."""
112 pass
113
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000114log = initlog # The current logging function
Guido van Rossumc204c701996-09-05 19:07:11 +0000115
116
Guido van Rossum72755611996-03-06 07:20:06 +0000117# Parsing functions
118# =================
119
Guido van Rossumad164711997-05-13 19:03:23 +0000120# Maximum input we will accept when REQUEST_METHOD is POST
121# 0 ==> unlimited input
122maxlen = 0
123
Guido van Rossume08c04c1996-11-11 19:29:11 +0000124def parse(fp=None, environ=os.environ, keep_blank_values=0, strict_parsing=0):
Guido van Rossum773ab271996-07-23 03:46:24 +0000125 """Parse a query in the environment or from a file (default stdin)
126
127 Arguments, all optional:
128
129 fp : file pointer; default: sys.stdin
130
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000131 environ : environment dictionary; default: os.environ
Guido van Rossum773ab271996-07-23 03:46:24 +0000132
133 keep_blank_values: flag indicating whether blank values in
Senthil Kumarana5ba05c2010-08-09 20:18:04 +0000134 percent-encoded forms should be treated as blank strings.
Tim Peters88869f92001-01-14 23:36:06 +0000135 A true value indicates that blanks should be retained as
Guido van Rossum773ab271996-07-23 03:46:24 +0000136 blank strings. The default false value indicates that
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000137 blank values are to be ignored and treated as if they were
138 not included.
Guido van Rossume08c04c1996-11-11 19:29:11 +0000139
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000140 strict_parsing: flag indicating what to do with parsing errors.
141 If false (the default), errors are silently ignored.
142 If true, errors raise a ValueError exception.
Guido van Rossum773ab271996-07-23 03:46:24 +0000143 """
Raymond Hettingera1449002002-05-31 23:54:44 +0000144 if fp is None:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000145 fp = sys.stdin
Raymond Hettinger54f02222002-06-01 14:18:47 +0000146 if not 'REQUEST_METHOD' in environ:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000147 environ['REQUEST_METHOD'] = 'GET' # For testing stand-alone
Guido van Rossum7aee3841996-03-07 18:00:44 +0000148 if environ['REQUEST_METHOD'] == 'POST':
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000149 ctype, pdict = parse_header(environ['CONTENT_TYPE'])
150 if ctype == 'multipart/form-data':
151 return parse_multipart(fp, pdict)
152 elif ctype == 'application/x-www-form-urlencoded':
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000153 clength = int(environ['CONTENT_LENGTH'])
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000154 if maxlen and clength > maxlen:
155 raise ValueError, 'Maximum content length exceeded'
156 qs = fp.read(clength)
157 else:
158 qs = '' # Unknown content-type
Raymond Hettinger54f02222002-06-01 14:18:47 +0000159 if 'QUERY_STRING' in environ:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000160 if qs: qs = qs + '&'
161 qs = qs + environ['QUERY_STRING']
Tim Peters88869f92001-01-14 23:36:06 +0000162 elif sys.argv[1:]:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000163 if qs: qs = qs + '&'
164 qs = qs + sys.argv[1]
165 environ['QUERY_STRING'] = qs # XXX Shouldn't, really
Raymond Hettinger54f02222002-06-01 14:18:47 +0000166 elif 'QUERY_STRING' in environ:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000167 qs = environ['QUERY_STRING']
Guido van Rossum7aee3841996-03-07 18:00:44 +0000168 else:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000169 if sys.argv[1:]:
170 qs = sys.argv[1]
171 else:
172 qs = ""
173 environ['QUERY_STRING'] = qs # XXX Shouldn't, really
Ezio Melottief490962010-01-31 11:46:54 +0000174 return urlparse.parse_qs(qs, keep_blank_values, strict_parsing)
Guido van Rossume7808771995-08-07 20:12:09 +0000175
176
Facundo Batistac585df92008-09-03 22:35:50 +0000177# parse query string function called from urlparse,
178# this is done in order to maintain backward compatiblity.
179
Guido van Rossume08c04c1996-11-11 19:29:11 +0000180def parse_qs(qs, keep_blank_values=0, strict_parsing=0):
Facundo Batistac585df92008-09-03 22:35:50 +0000181 """Parse a query given as a string argument."""
Florent Xicluna78c18712010-03-17 20:05:11 +0000182 warn("cgi.parse_qs is deprecated, use urlparse.parse_qs instead",
183 PendingDeprecationWarning, 2)
Facundo Batistac585df92008-09-03 22:35:50 +0000184 return urlparse.parse_qs(qs, keep_blank_values, strict_parsing)
Guido van Rossum773ab271996-07-23 03:46:24 +0000185
Guido van Rossum1946f0d1999-06-04 17:54:39 +0000186
187def parse_qsl(qs, keep_blank_values=0, strict_parsing=0):
Facundo Batistac585df92008-09-03 22:35:50 +0000188 """Parse a query given as a string argument."""
189 warn("cgi.parse_qsl is deprecated, use urlparse.parse_qsl instead",
Philip Jenveyd846f1d2009-05-08 02:28:39 +0000190 PendingDeprecationWarning, 2)
Facundo Batistaace0bcf2008-09-08 00:20:28 +0000191 return urlparse.parse_qsl(qs, keep_blank_values, strict_parsing)
Guido van Rossum9a22de11995-01-12 12:29:47 +0000192
Guido van Rossum0147db01996-03-09 03:16:04 +0000193def parse_multipart(fp, pdict):
Guido van Rossum7aee3841996-03-07 18:00:44 +0000194 """Parse multipart input.
Guido van Rossum9a22de11995-01-12 12:29:47 +0000195
Guido van Rossum7aee3841996-03-07 18:00:44 +0000196 Arguments:
197 fp : input file
Johannes Gijsbersc7fc10a2005-01-08 13:56:36 +0000198 pdict: dictionary containing other parameters of content-type header
Guido van Rossum72755611996-03-06 07:20:06 +0000199
Tim Peters88869f92001-01-14 23:36:06 +0000200 Returns a dictionary just like parse_qs(): keys are the field names, each
201 value is a list of values for that field. This is easy to use but not
202 much good if you are expecting megabytes to be uploaded -- in that case,
203 use the FieldStorage class instead which is much more flexible. Note
204 that content-type is the raw, unparsed contents of the content-type
Guido van Rossum0147db01996-03-09 03:16:04 +0000205 header.
Tim Peters88869f92001-01-14 23:36:06 +0000206
207 XXX This does not parse nested multipart parts -- use FieldStorage for
Guido van Rossum0147db01996-03-09 03:16:04 +0000208 that.
Tim Peters88869f92001-01-14 23:36:06 +0000209
210 XXX This should really be subsumed by FieldStorage altogether -- no
Guido van Rossum0147db01996-03-09 03:16:04 +0000211 point in having two implementations of the same parsing algorithm.
Guido van Rossum9568b732006-08-10 17:41:07 +0000212 Also, FieldStorage protects itself better against certain DoS attacks
213 by limiting the size of the data read in one chunk. The API here
214 does not support that kind of protection. This also affects parse()
215 since it can call parse_multipart().
Guido van Rossum72755611996-03-06 07:20:06 +0000216
Guido van Rossum7aee3841996-03-07 18:00:44 +0000217 """
Guido van Rossum2e441f72001-07-25 21:00:19 +0000218 boundary = ""
Raymond Hettinger54f02222002-06-01 14:18:47 +0000219 if 'boundary' in pdict:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000220 boundary = pdict['boundary']
Guido van Rossum2e441f72001-07-25 21:00:19 +0000221 if not valid_boundary(boundary):
Walter Dörwald70a6b492004-02-12 17:35:32 +0000222 raise ValueError, ('Invalid boundary in multipart form: %r'
223 % (boundary,))
Tim Petersab9ba272001-08-09 21:40:30 +0000224
Guido van Rossum7aee3841996-03-07 18:00:44 +0000225 nextpart = "--" + boundary
226 lastpart = "--" + boundary + "--"
227 partdict = {}
228 terminator = ""
229
230 while terminator != lastpart:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000231 bytes = -1
232 data = None
233 if terminator:
234 # At start of next part. Read headers first.
Armin Rigo3a703b62005-09-19 09:11:04 +0000235 headers = mimetools.Message(fp)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000236 clength = headers.getheader('content-length')
237 if clength:
238 try:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000239 bytes = int(clength)
240 except ValueError:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000241 pass
242 if bytes > 0:
243 if maxlen and bytes > maxlen:
244 raise ValueError, 'Maximum content length exceeded'
245 data = fp.read(bytes)
246 else:
247 data = ""
248 # Read lines until end of part.
249 lines = []
250 while 1:
251 line = fp.readline()
252 if not line:
253 terminator = lastpart # End outer loop
254 break
255 if line[:2] == "--":
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000256 terminator = line.strip()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000257 if terminator in (nextpart, lastpart):
258 break
259 lines.append(line)
260 # Done with part.
261 if data is None:
262 continue
263 if bytes < 0:
264 if lines:
265 # Strip final line terminator
266 line = lines[-1]
267 if line[-2:] == "\r\n":
268 line = line[:-2]
269 elif line[-1:] == "\n":
270 line = line[:-1]
271 lines[-1] = line
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000272 data = "".join(lines)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000273 line = headers['content-disposition']
274 if not line:
275 continue
276 key, params = parse_header(line)
277 if key != 'form-data':
278 continue
Raymond Hettinger54f02222002-06-01 14:18:47 +0000279 if 'name' in params:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000280 name = params['name']
281 else:
282 continue
Raymond Hettinger54f02222002-06-01 14:18:47 +0000283 if name in partdict:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000284 partdict[name].append(data)
285 else:
286 partdict[name] = [data]
Guido van Rossum72755611996-03-06 07:20:06 +0000287
Guido van Rossum7aee3841996-03-07 18:00:44 +0000288 return partdict
Guido van Rossum9a22de11995-01-12 12:29:47 +0000289
290
Fred Drake52481032008-12-04 18:25:17 +0000291def _parseparam(s):
292 while s[:1] == ';':
293 s = s[1:]
294 end = s.find(';')
Senthil Kumaran59a06d42011-10-20 00:52:24 +0800295 while end > 0 and (s.count('"', 0, end) - s.count('\\"', 0, end)) % 2:
Fred Drake52481032008-12-04 18:25:17 +0000296 end = s.find(';', end + 1)
297 if end < 0:
298 end = len(s)
299 f = s[:end]
300 yield f.strip()
301 s = s[end:]
302
Guido van Rossum72755611996-03-06 07:20:06 +0000303def parse_header(line):
Guido van Rossum7aee3841996-03-07 18:00:44 +0000304 """Parse a Content-type like header.
305
306 Return the main content-type and a dictionary of options.
307
308 """
Fred Drake52481032008-12-04 18:25:17 +0000309 parts = _parseparam(';' + line)
310 key = parts.next()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000311 pdict = {}
Fred Drake52481032008-12-04 18:25:17 +0000312 for p in parts:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000313 i = p.find('=')
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000314 if i >= 0:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000315 name = p[:i].strip().lower()
316 value = p[i+1:].strip()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000317 if len(value) >= 2 and value[0] == value[-1] == '"':
318 value = value[1:-1]
Johannes Gijsbers9e15dd62004-08-14 15:39:34 +0000319 value = value.replace('\\\\', '\\').replace('\\"', '"')
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000320 pdict[name] = value
Guido van Rossum7aee3841996-03-07 18:00:44 +0000321 return key, pdict
Guido van Rossum72755611996-03-06 07:20:06 +0000322
323
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000324# Classes for field storage
325# =========================
326
327class MiniFieldStorage:
328
Guido van Rossum0147db01996-03-09 03:16:04 +0000329 """Like FieldStorage, for use when no file uploads are possible."""
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000330
Guido van Rossum7aee3841996-03-07 18:00:44 +0000331 # Dummy attributes
332 filename = None
333 list = None
334 type = None
Guido van Rossum773ab271996-07-23 03:46:24 +0000335 file = None
Guido van Rossum4032c2c1996-03-09 04:04:35 +0000336 type_options = {}
Guido van Rossum7aee3841996-03-07 18:00:44 +0000337 disposition = None
338 disposition_options = {}
339 headers = {}
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000340
Guido van Rossum7aee3841996-03-07 18:00:44 +0000341 def __init__(self, name, value):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000342 """Constructor from field name and value."""
343 self.name = name
344 self.value = value
Guido van Rossum773ab271996-07-23 03:46:24 +0000345 # self.file = StringIO(value)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000346
347 def __repr__(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000348 """Return printable representation."""
Walter Dörwald70a6b492004-02-12 17:35:32 +0000349 return "MiniFieldStorage(%r, %r)" % (self.name, self.value)
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000350
351
352class FieldStorage:
353
Guido van Rossum7aee3841996-03-07 18:00:44 +0000354 """Store a sequence of fields, reading multipart/form-data.
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000355
Guido van Rossum7aee3841996-03-07 18:00:44 +0000356 This class provides naming, typing, files stored on disk, and
357 more. At the top level, it is accessible like a dictionary, whose
358 keys are the field names. (Note: None can occur as a field name.)
359 The items are either a Python list (if there's multiple values) or
360 another FieldStorage or MiniFieldStorage object. If it's a single
361 object, it has the following attributes:
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000362
Guido van Rossum7aee3841996-03-07 18:00:44 +0000363 name: the field name, if specified; otherwise None
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000364
Guido van Rossum7aee3841996-03-07 18:00:44 +0000365 filename: the filename, if specified; otherwise None; this is the
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000366 client side filename, *not* the file name on which it is
367 stored (that's a temporary file you don't deal with)
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000368
Guido van Rossum7aee3841996-03-07 18:00:44 +0000369 value: the value as a *string*; for file uploads, this
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000370 transparently reads the file every time you request the value
Guido van Rossum7aee3841996-03-07 18:00:44 +0000371
372 file: the file(-like) object from which you can read the data;
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000373 None if the data is stored a simple string
Guido van Rossum7aee3841996-03-07 18:00:44 +0000374
375 type: the content-type, or None if not specified
376
377 type_options: dictionary of options specified on the content-type
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000378 line
Guido van Rossum7aee3841996-03-07 18:00:44 +0000379
380 disposition: content-disposition, or None if not specified
381
382 disposition_options: dictionary of corresponding options
383
Armin Rigo3a703b62005-09-19 09:11:04 +0000384 headers: a dictionary(-like) object (sometimes rfc822.Message or a
385 subclass thereof) containing *all* headers
Guido van Rossum7aee3841996-03-07 18:00:44 +0000386
387 The class is subclassable, mostly for the purpose of overriding
388 the make_file() method, which is called internally to come up with
389 a file open for reading and writing. This makes it possible to
390 override the default choice of storing all files in a temporary
391 directory and unlinking them as soon as they have been opened.
392
393 """
394
Guido van Rossum773ab271996-07-23 03:46:24 +0000395 def __init__(self, fp=None, headers=None, outerboundary="",
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000396 environ=os.environ, keep_blank_values=0, strict_parsing=0):
397 """Constructor. Read multipart/* until last part.
Guido van Rossum7aee3841996-03-07 18:00:44 +0000398
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000399 Arguments, all optional:
Guido van Rossum7aee3841996-03-07 18:00:44 +0000400
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000401 fp : file pointer; default: sys.stdin
Guido van Rossumb1b4f941998-05-08 19:55:51 +0000402 (not used when the request method is GET)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000403
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000404 headers : header dictionary-like object; default:
405 taken from environ as per CGI spec
Guido van Rossum7aee3841996-03-07 18:00:44 +0000406
Guido van Rossum773ab271996-07-23 03:46:24 +0000407 outerboundary : terminating multipart boundary
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000408 (for internal use only)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000409
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000410 environ : environment dictionary; default: os.environ
Guido van Rossum773ab271996-07-23 03:46:24 +0000411
412 keep_blank_values: flag indicating whether blank values in
Senthil Kumarana5ba05c2010-08-09 20:18:04 +0000413 percent-encoded forms should be treated as blank strings.
Tim Peters88869f92001-01-14 23:36:06 +0000414 A true value indicates that blanks should be retained as
Guido van Rossum773ab271996-07-23 03:46:24 +0000415 blank strings. The default false value indicates that
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000416 blank values are to be ignored and treated as if they were
417 not included.
Guido van Rossum773ab271996-07-23 03:46:24 +0000418
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000419 strict_parsing: flag indicating what to do with parsing errors.
420 If false (the default), errors are silently ignored.
421 If true, errors raise a ValueError exception.
Guido van Rossume08c04c1996-11-11 19:29:11 +0000422
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000423 """
424 method = 'GET'
425 self.keep_blank_values = keep_blank_values
426 self.strict_parsing = strict_parsing
Raymond Hettinger54f02222002-06-01 14:18:47 +0000427 if 'REQUEST_METHOD' in environ:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000428 method = environ['REQUEST_METHOD'].upper()
Facundo Batistaa6a4d502008-06-21 18:58:04 +0000429 self.qs_on_post = None
Guido van Rossum01852831998-06-25 02:40:17 +0000430 if method == 'GET' or method == 'HEAD':
Raymond Hettinger54f02222002-06-01 14:18:47 +0000431 if 'QUERY_STRING' in environ:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000432 qs = environ['QUERY_STRING']
433 elif sys.argv[1:]:
434 qs = sys.argv[1]
435 else:
436 qs = ""
437 fp = StringIO(qs)
438 if headers is None:
439 headers = {'content-type':
440 "application/x-www-form-urlencoded"}
441 if headers is None:
Guido van Rossumcff311a1998-06-11 14:06:59 +0000442 headers = {}
443 if method == 'POST':
444 # Set default content-type for POST to what's traditional
445 headers['content-type'] = "application/x-www-form-urlencoded"
Raymond Hettinger54f02222002-06-01 14:18:47 +0000446 if 'CONTENT_TYPE' in environ:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000447 headers['content-type'] = environ['CONTENT_TYPE']
Facundo Batistaa6a4d502008-06-21 18:58:04 +0000448 if 'QUERY_STRING' in environ:
449 self.qs_on_post = environ['QUERY_STRING']
Raymond Hettinger54f02222002-06-01 14:18:47 +0000450 if 'CONTENT_LENGTH' in environ:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000451 headers['content-length'] = environ['CONTENT_LENGTH']
452 self.fp = fp or sys.stdin
453 self.headers = headers
454 self.outerboundary = outerboundary
Guido van Rossum7aee3841996-03-07 18:00:44 +0000455
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000456 # Process content-disposition header
457 cdisp, pdict = "", {}
Raymond Hettinger54f02222002-06-01 14:18:47 +0000458 if 'content-disposition' in self.headers:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000459 cdisp, pdict = parse_header(self.headers['content-disposition'])
460 self.disposition = cdisp
461 self.disposition_options = pdict
462 self.name = None
Raymond Hettinger54f02222002-06-01 14:18:47 +0000463 if 'name' in pdict:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000464 self.name = pdict['name']
465 self.filename = None
Raymond Hettinger54f02222002-06-01 14:18:47 +0000466 if 'filename' in pdict:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000467 self.filename = pdict['filename']
Guido van Rossum7aee3841996-03-07 18:00:44 +0000468
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000469 # Process content-type header
Barry Warsaw302331a1999-01-08 17:42:03 +0000470 #
471 # Honor any existing content-type header. But if there is no
472 # content-type header, use some sensible defaults. Assume
473 # outerboundary is "" at the outer level, but something non-false
474 # inside a multi-part. The default for an inner part is text/plain,
475 # but for an outer part it should be urlencoded. This should catch
476 # bogus clients which erroneously forget to include a content-type
477 # header.
478 #
479 # See below for what we do if there does exist a content-type header,
480 # but it happens to be something we don't understand.
Raymond Hettinger54f02222002-06-01 14:18:47 +0000481 if 'content-type' in self.headers:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000482 ctype, pdict = parse_header(self.headers['content-type'])
Guido van Rossumce900de1999-06-02 18:44:22 +0000483 elif self.outerboundary or method != 'POST':
Barry Warsaw302331a1999-01-08 17:42:03 +0000484 ctype, pdict = "text/plain", {}
485 else:
486 ctype, pdict = 'application/x-www-form-urlencoded', {}
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000487 self.type = ctype
488 self.type_options = pdict
489 self.innerboundary = ""
Raymond Hettinger54f02222002-06-01 14:18:47 +0000490 if 'boundary' in pdict:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000491 self.innerboundary = pdict['boundary']
492 clen = -1
Raymond Hettinger54f02222002-06-01 14:18:47 +0000493 if 'content-length' in self.headers:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000494 try:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000495 clen = int(self.headers['content-length'])
Skip Montanarodb5d1442002-03-23 05:50:17 +0000496 except ValueError:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000497 pass
498 if maxlen and clen > maxlen:
499 raise ValueError, 'Maximum content length exceeded'
500 self.length = clen
Guido van Rossum7aee3841996-03-07 18:00:44 +0000501
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000502 self.list = self.file = None
503 self.done = 0
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000504 if ctype == 'application/x-www-form-urlencoded':
505 self.read_urlencoded()
506 elif ctype[:10] == 'multipart/':
Guido van Rossumf5745001998-10-20 14:43:02 +0000507 self.read_multi(environ, keep_blank_values, strict_parsing)
Barry Warsaw302331a1999-01-08 17:42:03 +0000508 else:
Guido van Rossum60a3bd81999-06-11 18:26:09 +0000509 self.read_single()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000510
511 def __repr__(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000512 """Return a printable representation."""
Walter Dörwald70a6b492004-02-12 17:35:32 +0000513 return "FieldStorage(%r, %r, %r)" % (
514 self.name, self.filename, self.value)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000515
Guido van Rossum4061cbe2002-09-11 18:20:34 +0000516 def __iter__(self):
517 return iter(self.keys())
518
Guido van Rossum7aee3841996-03-07 18:00:44 +0000519 def __getattr__(self, name):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000520 if name != 'value':
521 raise AttributeError, name
522 if self.file:
523 self.file.seek(0)
524 value = self.file.read()
525 self.file.seek(0)
526 elif self.list is not None:
527 value = self.list
528 else:
529 value = None
530 return value
Guido van Rossum7aee3841996-03-07 18:00:44 +0000531
532 def __getitem__(self, key):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000533 """Dictionary style indexing."""
534 if self.list is None:
535 raise TypeError, "not indexable"
536 found = []
537 for item in self.list:
538 if item.name == key: found.append(item)
539 if not found:
540 raise KeyError, key
541 if len(found) == 1:
542 return found[0]
543 else:
544 return found
Guido van Rossum7aee3841996-03-07 18:00:44 +0000545
Moshe Zadkaa1a4b592000-08-25 21:47:56 +0000546 def getvalue(self, key, default=None):
547 """Dictionary style get() method, including 'value' lookup."""
Raymond Hettinger54f02222002-06-01 14:18:47 +0000548 if key in self:
Moshe Zadkaa1a4b592000-08-25 21:47:56 +0000549 value = self[key]
550 if type(value) is type([]):
Raymond Hettingerf871d832004-12-31 21:59:02 +0000551 return map(attrgetter('value'), value)
Moshe Zadkaa1a4b592000-08-25 21:47:56 +0000552 else:
553 return value.value
554 else:
555 return default
556
Guido van Rossum1bfb3882001-09-05 19:45:34 +0000557 def getfirst(self, key, default=None):
558 """ Return the first value received."""
Raymond Hettinger54f02222002-06-01 14:18:47 +0000559 if key in self:
Guido van Rossum1bfb3882001-09-05 19:45:34 +0000560 value = self[key]
561 if type(value) is type([]):
562 return value[0].value
563 else:
564 return value.value
565 else:
566 return default
567
568 def getlist(self, key):
569 """ Return list of received values."""
Raymond Hettinger54f02222002-06-01 14:18:47 +0000570 if key in self:
Guido van Rossum1bfb3882001-09-05 19:45:34 +0000571 value = self[key]
572 if type(value) is type([]):
Raymond Hettingerf871d832004-12-31 21:59:02 +0000573 return map(attrgetter('value'), value)
Guido van Rossum1bfb3882001-09-05 19:45:34 +0000574 else:
575 return [value.value]
576 else:
577 return []
578
Guido van Rossum7aee3841996-03-07 18:00:44 +0000579 def keys(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000580 """Dictionary style keys() method."""
581 if self.list is None:
582 raise TypeError, "not indexable"
Georg Brandlaff85e22007-09-20 16:06:07 +0000583 return list(set(item.name for item in self.list))
Guido van Rossum7aee3841996-03-07 18:00:44 +0000584
Guido van Rossum0147db01996-03-09 03:16:04 +0000585 def has_key(self, key):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000586 """Dictionary style has_key() method."""
587 if self.list is None:
588 raise TypeError, "not indexable"
Georg Brandlaff85e22007-09-20 16:06:07 +0000589 return any(item.name == key for item in self.list)
Guido van Rossum0147db01996-03-09 03:16:04 +0000590
Raymond Hettinger54f02222002-06-01 14:18:47 +0000591 def __contains__(self, key):
592 """Dictionary style __contains__ method."""
593 if self.list is None:
594 raise TypeError, "not indexable"
Georg Brandlaff85e22007-09-20 16:06:07 +0000595 return any(item.name == key for item in self.list)
Raymond Hettinger54f02222002-06-01 14:18:47 +0000596
Guido van Rossum88b85d41997-01-11 19:21:33 +0000597 def __len__(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000598 """Dictionary style len(x) support."""
599 return len(self.keys())
Guido van Rossum88b85d41997-01-11 19:21:33 +0000600
Georg Brandlaff85e22007-09-20 16:06:07 +0000601 def __nonzero__(self):
602 return bool(self.list)
603
Guido van Rossum7aee3841996-03-07 18:00:44 +0000604 def read_urlencoded(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000605 """Internal: read data in query string format."""
606 qs = self.fp.read(self.length)
Facundo Batistaa6a4d502008-06-21 18:58:04 +0000607 if self.qs_on_post:
608 qs += '&' + self.qs_on_post
Guido van Rossum1946f0d1999-06-04 17:54:39 +0000609 self.list = list = []
Facundo Batistac585df92008-09-03 22:35:50 +0000610 for key, value in urlparse.parse_qsl(qs, self.keep_blank_values,
611 self.strict_parsing):
Guido van Rossum1946f0d1999-06-04 17:54:39 +0000612 list.append(MiniFieldStorage(key, value))
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000613 self.skip_lines()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000614
Guido van Rossum030d2ec1998-12-09 22:16:46 +0000615 FieldStorageClass = None
616
Guido van Rossumf5745001998-10-20 14:43:02 +0000617 def read_multi(self, environ, keep_blank_values, strict_parsing):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000618 """Internal: read a part that is itself multipart."""
Guido van Rossum2e441f72001-07-25 21:00:19 +0000619 ib = self.innerboundary
620 if not valid_boundary(ib):
Walter Dörwald70a6b492004-02-12 17:35:32 +0000621 raise ValueError, 'Invalid boundary in multipart form: %r' % (ib,)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000622 self.list = []
Facundo Batistaa6a4d502008-06-21 18:58:04 +0000623 if self.qs_on_post:
Facundo Batistac585df92008-09-03 22:35:50 +0000624 for key, value in urlparse.parse_qsl(self.qs_on_post,
625 self.keep_blank_values, self.strict_parsing):
Facundo Batistaa6a4d502008-06-21 18:58:04 +0000626 self.list.append(MiniFieldStorage(key, value))
627 FieldStorageClass = None
628
Guido van Rossum030d2ec1998-12-09 22:16:46 +0000629 klass = self.FieldStorageClass or self.__class__
Guido van Rossum2e441f72001-07-25 21:00:19 +0000630 part = klass(self.fp, {}, ib,
Guido van Rossum030d2ec1998-12-09 22:16:46 +0000631 environ, keep_blank_values, strict_parsing)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000632 # Throw first part away
633 while not part.done:
Armin Rigo3a703b62005-09-19 09:11:04 +0000634 headers = rfc822.Message(self.fp)
Guido van Rossum2e441f72001-07-25 21:00:19 +0000635 part = klass(self.fp, headers, ib,
Guido van Rossum030d2ec1998-12-09 22:16:46 +0000636 environ, keep_blank_values, strict_parsing)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000637 self.list.append(part)
638 self.skip_lines()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000639
640 def read_single(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000641 """Internal: read an atomic part."""
642 if self.length >= 0:
643 self.read_binary()
644 self.skip_lines()
645 else:
646 self.read_lines()
647 self.file.seek(0)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000648
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000649 bufsize = 8*1024 # I/O buffering size for copy to file
Guido van Rossum7aee3841996-03-07 18:00:44 +0000650
651 def read_binary(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000652 """Internal: read binary data."""
653 self.file = self.make_file('b')
654 todo = self.length
655 if todo >= 0:
656 while todo > 0:
657 data = self.fp.read(min(todo, self.bufsize))
658 if not data:
659 self.done = -1
660 break
661 self.file.write(data)
662 todo = todo - len(data)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000663
664 def read_lines(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000665 """Internal: read lines until EOF or outerboundary."""
Guido van Rossum52b8c292001-06-29 13:06:06 +0000666 self.file = self.__file = StringIO()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000667 if self.outerboundary:
668 self.read_lines_to_outerboundary()
669 else:
670 self.read_lines_to_eof()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000671
Guido van Rossum52b8c292001-06-29 13:06:06 +0000672 def __write(self, line):
673 if self.__file is not None:
674 if self.__file.tell() + len(line) > 1000:
675 self.file = self.make_file('')
676 self.file.write(self.__file.getvalue())
677 self.__file = None
678 self.file.write(line)
679
Guido van Rossum7aee3841996-03-07 18:00:44 +0000680 def read_lines_to_eof(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000681 """Internal: read lines until EOF."""
682 while 1:
Guido van Rossum9568b732006-08-10 17:41:07 +0000683 line = self.fp.readline(1<<16)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000684 if not line:
685 self.done = -1
686 break
Guido van Rossum52b8c292001-06-29 13:06:06 +0000687 self.__write(line)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000688
689 def read_lines_to_outerboundary(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000690 """Internal: read lines until outerboundary."""
691 next = "--" + self.outerboundary
692 last = next + "--"
693 delim = ""
Guido van Rossum9568b732006-08-10 17:41:07 +0000694 last_line_lfend = True
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000695 while 1:
Guido van Rossum9568b732006-08-10 17:41:07 +0000696 line = self.fp.readline(1<<16)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000697 if not line:
698 self.done = -1
699 break
Serhiy Storchakae2cc3412013-06-17 16:33:48 +0300700 if delim == "\r":
701 line = delim + line
702 delim = ""
Guido van Rossum9568b732006-08-10 17:41:07 +0000703 if line[:2] == "--" and last_line_lfend:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000704 strippedline = line.strip()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000705 if strippedline == next:
706 break
707 if strippedline == last:
708 self.done = 1
709 break
710 odelim = delim
711 if line[-2:] == "\r\n":
712 delim = "\r\n"
713 line = line[:-2]
Guido van Rossum9568b732006-08-10 17:41:07 +0000714 last_line_lfend = True
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000715 elif line[-1] == "\n":
716 delim = "\n"
717 line = line[:-1]
Guido van Rossum9568b732006-08-10 17:41:07 +0000718 last_line_lfend = True
Serhiy Storchakae2cc3412013-06-17 16:33:48 +0300719 elif line[-1] == "\r":
720 # We may interrupt \r\n sequences if they span the 2**16
721 # byte boundary
722 delim = "\r"
723 line = line[:-1]
724 last_line_lfend = False
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000725 else:
726 delim = ""
Guido van Rossum9568b732006-08-10 17:41:07 +0000727 last_line_lfend = False
Guido van Rossum52b8c292001-06-29 13:06:06 +0000728 self.__write(odelim + line)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000729
730 def skip_lines(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000731 """Internal: skip lines until outer boundary if defined."""
732 if not self.outerboundary or self.done:
733 return
734 next = "--" + self.outerboundary
735 last = next + "--"
Guido van Rossum9568b732006-08-10 17:41:07 +0000736 last_line_lfend = True
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000737 while 1:
Guido van Rossum9568b732006-08-10 17:41:07 +0000738 line = self.fp.readline(1<<16)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000739 if not line:
740 self.done = -1
741 break
Guido van Rossum9568b732006-08-10 17:41:07 +0000742 if line[:2] == "--" and last_line_lfend:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000743 strippedline = line.strip()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000744 if strippedline == next:
745 break
746 if strippedline == last:
747 self.done = 1
748 break
Guido van Rossum9568b732006-08-10 17:41:07 +0000749 last_line_lfend = line.endswith('\n')
Guido van Rossum7aee3841996-03-07 18:00:44 +0000750
Guido van Rossuma5e9fb61997-08-12 18:18:13 +0000751 def make_file(self, binary=None):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000752 """Overridable: return a readable & writable file.
Guido van Rossum7aee3841996-03-07 18:00:44 +0000753
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000754 The file will be used as follows:
755 - data is written to it
756 - seek(0)
757 - data is read from it
Guido van Rossum7aee3841996-03-07 18:00:44 +0000758
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000759 The 'binary' argument is unused -- the file is always opened
760 in binary mode.
Guido van Rossum7aee3841996-03-07 18:00:44 +0000761
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000762 This version opens a temporary file for reading and writing,
763 and immediately deletes (unlinks) it. The trick (on Unix!) is
764 that the file can still be used, but it can't be opened by
765 another process, and it will automatically be deleted when it
766 is closed or when the current process terminates.
Guido van Rossum4032c2c1996-03-09 04:04:35 +0000767
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000768 If you want a more permanent file, you derive a class which
769 overrides this method. If you want a visible temporary file
770 that is nevertheless automatically deleted when the script
771 terminates, try defining a __del__ method in a derived class
772 which unlinks the temporary files you have created.
Guido van Rossum7aee3841996-03-07 18:00:44 +0000773
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000774 """
775 import tempfile
776 return tempfile.TemporaryFile("w+b")
Tim Peters88869f92001-01-14 23:36:06 +0000777
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000778
779
Guido van Rossum4032c2c1996-03-09 04:04:35 +0000780# Backwards Compatibility Classes
781# ===============================
Guido van Rossum9a22de11995-01-12 12:29:47 +0000782
Moshe Zadkaa1a4b592000-08-25 21:47:56 +0000783class FormContentDict(UserDict.UserDict):
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000784 """Form content as dictionary with a list of values per field.
Guido van Rossum72755611996-03-06 07:20:06 +0000785
Guido van Rossum7aee3841996-03-07 18:00:44 +0000786 form = FormContentDict()
787
788 form[key] -> [value, value, ...]
Raymond Hettinger54f02222002-06-01 14:18:47 +0000789 key in form -> Boolean
Guido van Rossum7aee3841996-03-07 18:00:44 +0000790 form.keys() -> [key, key, ...]
791 form.values() -> [[val, val, ...], [val, val, ...], ...]
792 form.items() -> [(key, [val, val, ...]), (key, [val, val, ...]), ...]
793 form.dict == {key: [val, val, ...], ...}
794
795 """
Georg Brandl05b3c452006-09-30 10:58:01 +0000796 def __init__(self, environ=os.environ, keep_blank_values=0, strict_parsing=0):
797 self.dict = self.data = parse(environ=environ,
798 keep_blank_values=keep_blank_values,
799 strict_parsing=strict_parsing)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000800 self.query_string = environ['QUERY_STRING']
Guido van Rossum9a22de11995-01-12 12:29:47 +0000801
802
Guido van Rossum9a22de11995-01-12 12:29:47 +0000803class SvFormContentDict(FormContentDict):
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000804 """Form content as dictionary expecting a single value per field.
Guido van Rossum7aee3841996-03-07 18:00:44 +0000805
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000806 If you only expect a single value for each field, then form[key]
Guido van Rossum7aee3841996-03-07 18:00:44 +0000807 will return that single value. It will raise an IndexError if
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000808 that expectation is not true. If you expect a field to have
Guido van Rossum7aee3841996-03-07 18:00:44 +0000809 possible multiple values, than you can use form.getlist(key) to
810 get all of the values. values() and items() are a compromise:
811 they return single strings where there is a single value, and
812 lists of strings otherwise.
813
814 """
815 def __getitem__(self, key):
Tim Peters88869f92001-01-14 23:36:06 +0000816 if len(self.dict[key]) > 1:
817 raise IndexError, 'expecting a single value'
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000818 return self.dict[key][0]
Guido van Rossum7aee3841996-03-07 18:00:44 +0000819 def getlist(self, key):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000820 return self.dict[key]
Guido van Rossum7aee3841996-03-07 18:00:44 +0000821 def values(self):
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000822 result = []
823 for value in self.dict.values():
824 if len(value) == 1:
825 result.append(value[0])
826 else: result.append(value)
827 return result
Guido van Rossum7aee3841996-03-07 18:00:44 +0000828 def items(self):
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000829 result = []
830 for key, value in self.dict.items():
831 if len(value) == 1:
832 result.append((key, value[0]))
833 else: result.append((key, value))
834 return result
Guido van Rossum9a22de11995-01-12 12:29:47 +0000835
836
Guido van Rossum9a22de11995-01-12 12:29:47 +0000837class InterpFormContentDict(SvFormContentDict):
Tim Peters88869f92001-01-14 23:36:06 +0000838 """This class is present for backwards compatibility only."""
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000839 def __getitem__(self, key):
840 v = SvFormContentDict.__getitem__(self, key)
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000841 if v[0] in '0123456789+-.':
842 try: return int(v)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000843 except ValueError:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000844 try: return float(v)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000845 except ValueError: pass
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000846 return v.strip()
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000847 def values(self):
848 result = []
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000849 for key in self.keys():
850 try:
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000851 result.append(self[key])
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000852 except IndexError:
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000853 result.append(self.dict[key])
854 return result
855 def items(self):
856 result = []
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000857 for key in self.keys():
858 try:
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000859 result.append((key, self[key]))
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000860 except IndexError:
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000861 result.append((key, self.dict[key]))
862 return result
Guido van Rossum9a22de11995-01-12 12:29:47 +0000863
864
Guido van Rossum9a22de11995-01-12 12:29:47 +0000865class FormContent(FormContentDict):
Tim Peters88869f92001-01-14 23:36:06 +0000866 """This class is present for backwards compatibility only."""
Guido van Rossum0147db01996-03-09 03:16:04 +0000867 def values(self, key):
Raymond Hettinger54f02222002-06-01 14:18:47 +0000868 if key in self.dict :return self.dict[key]
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000869 else: return None
Guido van Rossum0147db01996-03-09 03:16:04 +0000870 def indexed_value(self, key, location):
Raymond Hettinger54f02222002-06-01 14:18:47 +0000871 if key in self.dict:
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000872 if len(self.dict[key]) > location:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000873 return self.dict[key][location]
874 else: return None
875 else: return None
Guido van Rossum0147db01996-03-09 03:16:04 +0000876 def value(self, key):
Raymond Hettinger54f02222002-06-01 14:18:47 +0000877 if key in self.dict: return self.dict[key][0]
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000878 else: return None
Guido van Rossum0147db01996-03-09 03:16:04 +0000879 def length(self, key):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000880 return len(self.dict[key])
Guido van Rossum0147db01996-03-09 03:16:04 +0000881 def stripped(self, key):
Raymond Hettinger54f02222002-06-01 14:18:47 +0000882 if key in self.dict: return self.dict[key][0].strip()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000883 else: return None
Guido van Rossum7aee3841996-03-07 18:00:44 +0000884 def pars(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000885 return self.dict
Guido van Rossum9a22de11995-01-12 12:29:47 +0000886
887
Guido van Rossum72755611996-03-06 07:20:06 +0000888# Test/debug code
889# ===============
Guido van Rossum9a22de11995-01-12 12:29:47 +0000890
Guido van Rossum773ab271996-07-23 03:46:24 +0000891def test(environ=os.environ):
Guido van Rossum7aee3841996-03-07 18:00:44 +0000892 """Robust test CGI script, usable as main program.
Guido van Rossum9a22de11995-01-12 12:29:47 +0000893
Guido van Rossum7aee3841996-03-07 18:00:44 +0000894 Write minimal HTTP headers and dump all information provided to
895 the script in HTML form.
896
897 """
Guido van Rossum7aee3841996-03-07 18:00:44 +0000898 print "Content-type: text/html"
899 print
900 sys.stderr = sys.stdout
901 try:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000902 form = FieldStorage() # Replace with other classes to test those
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000903 print_directory()
904 print_arguments()
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000905 print_form(form)
906 print_environ(environ)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000907 print_environ_usage()
908 def f():
909 exec "testing print_exception() -- <I>italics?</I>"
910 def g(f=f):
911 f()
912 print "<H3>What follows is a test, not an actual exception:</H3>"
913 g()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000914 except:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000915 print_exception()
Guido van Rossumf85de8a1996-08-20 20:22:39 +0000916
Guido van Rossum57d51f22000-09-16 21:16:01 +0000917 print "<H1>Second try with a small maxlen...</H1>"
918
Guido van Rossumad164711997-05-13 19:03:23 +0000919 global maxlen
920 maxlen = 50
921 try:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000922 form = FieldStorage() # Replace with other classes to test those
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000923 print_directory()
924 print_arguments()
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000925 print_form(form)
926 print_environ(environ)
Guido van Rossumad164711997-05-13 19:03:23 +0000927 except:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000928 print_exception()
Guido van Rossumad164711997-05-13 19:03:23 +0000929
Guido van Rossumf85de8a1996-08-20 20:22:39 +0000930def print_exception(type=None, value=None, tb=None, limit=None):
931 if type is None:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000932 type, value, tb = sys.exc_info()
Guido van Rossumf85de8a1996-08-20 20:22:39 +0000933 import traceback
934 print
Guido van Rossum7dd06962000-12-27 19:12:58 +0000935 print "<H3>Traceback (most recent call last):</H3>"
Guido van Rossumf85de8a1996-08-20 20:22:39 +0000936 list = traceback.format_tb(tb, limit) + \
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000937 traceback.format_exception_only(type, value)
Guido van Rossumf85de8a1996-08-20 20:22:39 +0000938 print "<PRE>%s<B>%s</B></PRE>" % (
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000939 escape("".join(list[:-1])),
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000940 escape(list[-1]),
941 )
Guido van Rossumf15d1591997-09-29 23:22:12 +0000942 del tb
Guido van Rossum9a22de11995-01-12 12:29:47 +0000943
Guido van Rossum773ab271996-07-23 03:46:24 +0000944def print_environ(environ=os.environ):
Guido van Rossum7aee3841996-03-07 18:00:44 +0000945 """Dump the shell environment as HTML."""
946 keys = environ.keys()
947 keys.sort()
948 print
Guido van Rossum503e50b1996-05-28 22:57:20 +0000949 print "<H3>Shell Environment:</H3>"
Guido van Rossum7aee3841996-03-07 18:00:44 +0000950 print "<DL>"
951 for key in keys:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000952 print "<DT>", escape(key), "<DD>", escape(environ[key])
Tim Peters88869f92001-01-14 23:36:06 +0000953 print "</DL>"
Guido van Rossum7aee3841996-03-07 18:00:44 +0000954 print
Guido van Rossum72755611996-03-06 07:20:06 +0000955
956def print_form(form):
Guido van Rossum7aee3841996-03-07 18:00:44 +0000957 """Dump the contents of a form as HTML."""
958 keys = form.keys()
959 keys.sort()
960 print
Guido van Rossum503e50b1996-05-28 22:57:20 +0000961 print "<H3>Form Contents:</H3>"
Guido van Rossum57d51f22000-09-16 21:16:01 +0000962 if not keys:
963 print "<P>No form fields."
Guido van Rossum7aee3841996-03-07 18:00:44 +0000964 print "<DL>"
965 for key in keys:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000966 print "<DT>" + escape(key) + ":",
967 value = form[key]
Walter Dörwald70a6b492004-02-12 17:35:32 +0000968 print "<i>" + escape(repr(type(value))) + "</i>"
969 print "<DD>" + escape(repr(value))
Guido van Rossum7aee3841996-03-07 18:00:44 +0000970 print "</DL>"
971 print
972
973def print_directory():
974 """Dump the current directory as HTML."""
975 print
976 print "<H3>Current Working Directory:</H3>"
977 try:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000978 pwd = os.getcwd()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000979 except os.error, msg:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000980 print "os.error:", escape(str(msg))
Guido van Rossum7aee3841996-03-07 18:00:44 +0000981 else:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000982 print escape(pwd)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000983 print
Guido van Rossum9a22de11995-01-12 12:29:47 +0000984
Guido van Rossuma8738a51996-03-14 21:30:28 +0000985def print_arguments():
986 print
Guido van Rossum503e50b1996-05-28 22:57:20 +0000987 print "<H3>Command Line Arguments:</H3>"
Guido van Rossuma8738a51996-03-14 21:30:28 +0000988 print
989 print sys.argv
990 print
991
Guido van Rossum9a22de11995-01-12 12:29:47 +0000992def print_environ_usage():
Guido van Rossum7aee3841996-03-07 18:00:44 +0000993 """Dump a list of environment variables used by CGI as HTML."""
994 print """
Guido van Rossum72755611996-03-06 07:20:06 +0000995<H3>These environment variables could have been set:</H3>
996<UL>
Guido van Rossum9a22de11995-01-12 12:29:47 +0000997<LI>AUTH_TYPE
998<LI>CONTENT_LENGTH
999<LI>CONTENT_TYPE
1000<LI>DATE_GMT
1001<LI>DATE_LOCAL
1002<LI>DOCUMENT_NAME
1003<LI>DOCUMENT_ROOT
1004<LI>DOCUMENT_URI
1005<LI>GATEWAY_INTERFACE
1006<LI>LAST_MODIFIED
1007<LI>PATH
1008<LI>PATH_INFO
1009<LI>PATH_TRANSLATED
1010<LI>QUERY_STRING
1011<LI>REMOTE_ADDR
1012<LI>REMOTE_HOST
1013<LI>REMOTE_IDENT
1014<LI>REMOTE_USER
1015<LI>REQUEST_METHOD
1016<LI>SCRIPT_NAME
1017<LI>SERVER_NAME
1018<LI>SERVER_PORT
1019<LI>SERVER_PROTOCOL
1020<LI>SERVER_ROOT
1021<LI>SERVER_SOFTWARE
1022</UL>
Guido van Rossum7aee3841996-03-07 18:00:44 +00001023In addition, HTTP headers sent by the server may be passed in the
1024environment as well. Here are some common variable names:
1025<UL>
1026<LI>HTTP_ACCEPT
1027<LI>HTTP_CONNECTION
1028<LI>HTTP_HOST
1029<LI>HTTP_PRAGMA
1030<LI>HTTP_REFERER
1031<LI>HTTP_USER_AGENT
1032</UL>
Guido van Rossum9a22de11995-01-12 12:29:47 +00001033"""
1034
Guido van Rossum9a22de11995-01-12 12:29:47 +00001035
Guido van Rossum72755611996-03-06 07:20:06 +00001036# Utilities
1037# =========
Guido van Rossum9a22de11995-01-12 12:29:47 +00001038
Guido van Rossum64c66201997-07-19 20:11:53 +00001039def escape(s, quote=None):
Skip Montanaro97b2fa22005-08-02 02:50:25 +00001040 '''Replace special characters "&", "<" and ">" to HTML-safe sequences.
1041 If the optional flag quote is true, the quotation mark character (")
1042 is also translated.'''
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +00001043 s = s.replace("&", "&amp;") # Must be done first!
1044 s = s.replace("<", "&lt;")
1045 s = s.replace(">", "&gt;")
Guido van Rossum64c66201997-07-19 20:11:53 +00001046 if quote:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +00001047 s = s.replace('"', "&quot;")
Guido van Rossum7aee3841996-03-07 18:00:44 +00001048 return s
Guido van Rossum9a22de11995-01-12 12:29:47 +00001049
Guido van Rossum2e441f72001-07-25 21:00:19 +00001050def valid_boundary(s, _vb_pattern="^[ -~]{0,200}[!-~]$"):
1051 import re
1052 return re.match(_vb_pattern, s)
Guido van Rossum9a22de11995-01-12 12:29:47 +00001053
Guido van Rossum72755611996-03-06 07:20:06 +00001054# Invoke mainline
1055# ===============
1056
1057# Call test() when this file is run as a script (not imported as a module)
Tim Peters88869f92001-01-14 23:36:06 +00001058if __name__ == '__main__':
Guido van Rossum7aee3841996-03-07 18:00:44 +00001059 test()