blob: b96bd1f0fe39ac682160bcea3bf985144c50d1fe [file] [log] [blame]
Benjamin Peterson8c703a02010-03-11 22:05:58 +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
Guido van Rossum98d9fd32000-02-28 15:12:25 +000018# History
19# -------
Tim Peters88869f92001-01-14 23:36:06 +000020#
Guido van Rossum98d9fd32000-02-28 15:12:25 +000021# Michael McLay started this module. Steve Majewski changed the
22# interface to SvFormContentDict and FormContentDict. The multipart
23# parsing was inspired by code submitted by Andreas Paepcke. Guido van
24# Rossum rewrote, reformatted and documented the module and is currently
25# responsible for its maintenance.
Tim Peters88869f92001-01-14 23:36:06 +000026#
Guido van Rossum98d9fd32000-02-28 15:12:25 +000027
Guido van Rossum52b8c292001-06-29 13:06:06 +000028__version__ = "2.6"
Guido van Rossum0147db01996-03-09 03:16:04 +000029
Guido van Rossum72755611996-03-06 07:20:06 +000030
31# Imports
32# =======
33
Victor Stinner5c23b8e2011-01-14 13:05:21 +000034from io import StringIO, BytesIO, TextIOWrapper
Serhiy Storchaka2e576f52017-04-24 09:05:00 +030035from collections.abc import Mapping
Guido van Rossum72755611996-03-06 07:20:06 +000036import sys
37import os
Jeremy Hylton1afc1692008-06-18 20:49:58 +000038import urllib.parse
Victor Stinner5c23b8e2011-01-14 13:05:21 +000039from email.parser import FeedParser
Senthil Kumaranb4cbb922014-01-11 22:20:16 -080040from email.message import Message
Georg Brandl1f7fffb2010-10-15 15:57:45 +000041import html
Victor Stinner5c23b8e2011-01-14 13:05:21 +000042import locale
43import tempfile
Guido van Rossum72755611996-03-06 07:20:06 +000044
INADA Naoki698865d2018-06-19 17:28:50 +090045__all__ = ["MiniFieldStorage", "FieldStorage", "parse", "parse_multipart",
Martin Panter1cd27722016-06-06 01:53:28 +000046 "parse_header", "test", "print_exception", "print_environ",
Guido van Rossuma8423a92001-03-19 13:40:44 +000047 "print_form", "print_directory", "print_arguments",
INADA Naoki698865d2018-06-19 17:28:50 +090048 "print_environ_usage"]
Guido van Rossumc204c701996-09-05 19:07:11 +000049
50# Logging support
51# ===============
52
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000053logfile = "" # Filename to log to, if not empty
54logfp = None # File object to log to, if not None
Guido van Rossumc204c701996-09-05 19:07:11 +000055
56def initlog(*allargs):
57 """Write a log message, if there is a log file.
58
59 Even though this function is called initlog(), you should always
60 use log(); log is a variable that is set either to initlog
61 (initially), to dolog (once the log file has been opened), or to
62 nolog (when logging is disabled).
63
64 The first argument is a format string; the remaining arguments (if
65 any) are arguments to the % operator, so e.g.
66 log("%s: %s", "a", "b")
67 will write "a: b" to the log file, followed by a newline.
68
69 If the global logfp is not None, it should be a file object to
70 which log data is written.
71
72 If the global logfp is None, the global logfile may be a string
73 giving a filename to open, in append mode. This file should be
74 world writable!!! If the file can't be opened, logging is
75 silently disabled (since there is no safe place where we could
76 send an error message).
77
78 """
Victor Stinnerd33344a2011-07-14 22:28:36 +020079 global log, logfile, logfp
Guido van Rossumc204c701996-09-05 19:07:11 +000080 if logfile and not logfp:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000081 try:
82 logfp = open(logfile, "a")
Andrew Svetlovf7a17b42012-12-25 16:47:37 +020083 except OSError:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000084 pass
Guido van Rossumc204c701996-09-05 19:07:11 +000085 if not logfp:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000086 log = nolog
Guido van Rossumc204c701996-09-05 19:07:11 +000087 else:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000088 log = dolog
Guido van Rossum68468eb2003-02-27 20:14:51 +000089 log(*allargs)
Guido van Rossumc204c701996-09-05 19:07:11 +000090
91def dolog(fmt, *args):
92 """Write a log message to the log file. See initlog() for docs."""
93 logfp.write(fmt%args + "\n")
94
95def nolog(*allargs):
96 """Dummy function, assigned to log when logging is disabled."""
97 pass
98
Victor Stinnerd33344a2011-07-14 22:28:36 +020099def closelog():
100 """Close the log file."""
101 global log, logfile, logfp
102 logfile = ''
103 if logfp:
104 logfp.close()
105 logfp = None
106 log = initlog
107
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000108log = initlog # The current logging function
Guido van Rossumc204c701996-09-05 19:07:11 +0000109
110
Guido van Rossum72755611996-03-06 07:20:06 +0000111# Parsing functions
112# =================
113
Guido van Rossumad164711997-05-13 19:03:23 +0000114# Maximum input we will accept when REQUEST_METHOD is POST
115# 0 ==> unlimited input
116maxlen = 0
117
Guido van Rossume08c04c1996-11-11 19:29:11 +0000118def parse(fp=None, environ=os.environ, keep_blank_values=0, strict_parsing=0):
Guido van Rossum773ab271996-07-23 03:46:24 +0000119 """Parse a query in the environment or from a file (default stdin)
120
121 Arguments, all optional:
122
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000123 fp : file pointer; default: sys.stdin.buffer
Guido van Rossum773ab271996-07-23 03:46:24 +0000124
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000125 environ : environment dictionary; default: os.environ
Guido van Rossum773ab271996-07-23 03:46:24 +0000126
127 keep_blank_values: flag indicating whether blank values in
Senthil Kumaran30e86a42010-08-09 20:01:35 +0000128 percent-encoded forms should be treated as blank strings.
Tim Peters88869f92001-01-14 23:36:06 +0000129 A true value indicates that blanks should be retained as
Guido van Rossum773ab271996-07-23 03:46:24 +0000130 blank strings. The default false value indicates that
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000131 blank values are to be ignored and treated as if they were
132 not included.
Guido van Rossume08c04c1996-11-11 19:29:11 +0000133
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000134 strict_parsing: flag indicating what to do with parsing errors.
135 If false (the default), errors are silently ignored.
136 If true, errors raise a ValueError exception.
Guido van Rossum773ab271996-07-23 03:46:24 +0000137 """
Raymond Hettingera1449002002-05-31 23:54:44 +0000138 if fp is None:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000139 fp = sys.stdin
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000140
141 # field keys and values (except for files) are returned as strings
142 # an encoding is required to decode the bytes read from self.fp
143 if hasattr(fp,'encoding'):
144 encoding = fp.encoding
145 else:
146 encoding = 'latin-1'
147
148 # fp.read() must return bytes
149 if isinstance(fp, TextIOWrapper):
150 fp = fp.buffer
151
Raymond Hettinger54f02222002-06-01 14:18:47 +0000152 if not 'REQUEST_METHOD' in environ:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000153 environ['REQUEST_METHOD'] = 'GET' # For testing stand-alone
Guido van Rossum7aee3841996-03-07 18:00:44 +0000154 if environ['REQUEST_METHOD'] == 'POST':
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000155 ctype, pdict = parse_header(environ['CONTENT_TYPE'])
156 if ctype == 'multipart/form-data':
157 return parse_multipart(fp, pdict)
158 elif ctype == 'application/x-www-form-urlencoded':
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000159 clength = int(environ['CONTENT_LENGTH'])
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000160 if maxlen and clength > maxlen:
Collin Winterce36ad82007-08-30 01:19:48 +0000161 raise ValueError('Maximum content length exceeded')
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000162 qs = fp.read(clength).decode(encoding)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000163 else:
164 qs = '' # Unknown content-type
Raymond Hettinger54f02222002-06-01 14:18:47 +0000165 if 'QUERY_STRING' in environ:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000166 if qs: qs = qs + '&'
167 qs = qs + environ['QUERY_STRING']
Tim Peters88869f92001-01-14 23:36:06 +0000168 elif sys.argv[1:]:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000169 if qs: qs = qs + '&'
170 qs = qs + sys.argv[1]
171 environ['QUERY_STRING'] = qs # XXX Shouldn't, really
Raymond Hettinger54f02222002-06-01 14:18:47 +0000172 elif 'QUERY_STRING' in environ:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000173 qs = environ['QUERY_STRING']
Guido van Rossum7aee3841996-03-07 18:00:44 +0000174 else:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000175 if sys.argv[1:]:
176 qs = sys.argv[1]
177 else:
178 qs = ""
179 environ['QUERY_STRING'] = qs # XXX Shouldn't, really
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000180 return urllib.parse.parse_qs(qs, keep_blank_values, strict_parsing,
181 encoding=encoding)
Guido van Rossume7808771995-08-07 20:12:09 +0000182
183
Amber Brown545c9552018-05-14 18:11:55 -0400184def parse_multipart(fp, pdict, encoding="utf-8", errors="replace"):
Guido van Rossum7aee3841996-03-07 18:00:44 +0000185 """Parse multipart input.
Guido van Rossum9a22de11995-01-12 12:29:47 +0000186
Guido van Rossum7aee3841996-03-07 18:00:44 +0000187 Arguments:
188 fp : input file
Johannes Gijsbersc7fc10a2005-01-08 13:56:36 +0000189 pdict: dictionary containing other parameters of content-type header
Amber Brown545c9552018-05-14 18:11:55 -0400190 encoding, errors: request encoding and error handler, passed to
191 FieldStorage
Guido van Rossum72755611996-03-06 07:20:06 +0000192
Tim Peters88869f92001-01-14 23:36:06 +0000193 Returns a dictionary just like parse_qs(): keys are the field names, each
Pierre Quentelcc3fa202017-05-08 14:08:34 +0200194 value is a list of values for that field. For non-file fields, the value
195 is a list of strings.
Guido van Rossum7aee3841996-03-07 18:00:44 +0000196 """
Pierre Quentelcc3fa202017-05-08 14:08:34 +0200197 # RFC 2026, Section 5.1 : The "multipart" boundary delimiters are always
198 # represented as 7bit US-ASCII.
199 boundary = pdict['boundary'].decode('ascii')
200 ctype = "multipart/form-data; boundary={}".format(boundary)
201 headers = Message()
202 headers.set_type(ctype)
203 headers['Content-Length'] = pdict['CONTENT-LENGTH']
Amber Brown545c9552018-05-14 18:11:55 -0400204 fs = FieldStorage(fp, headers=headers, encoding=encoding, errors=errors,
Pierre Quentelcc3fa202017-05-08 14:08:34 +0200205 environ={'REQUEST_METHOD': 'POST'})
206 return {k: fs.getlist(k) for k in fs}
Guido van Rossum9a22de11995-01-12 12:29:47 +0000207
Fred Drake9a0a65b2008-12-04 19:24:50 +0000208def _parseparam(s):
209 while s[:1] == ';':
210 s = s[1:]
211 end = s.find(';')
Senthil Kumaran1ef0c032011-10-20 01:05:44 +0800212 while end > 0 and (s.count('"', 0, end) - s.count('\\"', 0, end)) % 2:
Fred Drake9a0a65b2008-12-04 19:24:50 +0000213 end = s.find(';', end + 1)
214 if end < 0:
215 end = len(s)
216 f = s[:end]
217 yield f.strip()
218 s = s[end:]
219
Guido van Rossum72755611996-03-06 07:20:06 +0000220def parse_header(line):
Guido van Rossum7aee3841996-03-07 18:00:44 +0000221 """Parse a Content-type like header.
222
223 Return the main content-type and a dictionary of options.
224
225 """
Fred Drake9a0a65b2008-12-04 19:24:50 +0000226 parts = _parseparam(';' + line)
227 key = parts.__next__()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000228 pdict = {}
Fred Drake9a0a65b2008-12-04 19:24:50 +0000229 for p in parts:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000230 i = p.find('=')
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000231 if i >= 0:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000232 name = p[:i].strip().lower()
233 value = p[i+1:].strip()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000234 if len(value) >= 2 and value[0] == value[-1] == '"':
235 value = value[1:-1]
Johannes Gijsbers9e15dd62004-08-14 15:39:34 +0000236 value = value.replace('\\\\', '\\').replace('\\"', '"')
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000237 pdict[name] = value
Guido van Rossum7aee3841996-03-07 18:00:44 +0000238 return key, pdict
Guido van Rossum72755611996-03-06 07:20:06 +0000239
240
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000241# Classes for field storage
242# =========================
243
244class MiniFieldStorage:
245
Guido van Rossum0147db01996-03-09 03:16:04 +0000246 """Like FieldStorage, for use when no file uploads are possible."""
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000247
Guido van Rossum7aee3841996-03-07 18:00:44 +0000248 # Dummy attributes
249 filename = None
250 list = None
251 type = None
Guido van Rossum773ab271996-07-23 03:46:24 +0000252 file = None
Guido van Rossum4032c2c1996-03-09 04:04:35 +0000253 type_options = {}
Guido van Rossum7aee3841996-03-07 18:00:44 +0000254 disposition = None
255 disposition_options = {}
256 headers = {}
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000257
Guido van Rossum7aee3841996-03-07 18:00:44 +0000258 def __init__(self, name, value):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000259 """Constructor from field name and value."""
260 self.name = name
261 self.value = value
Guido van Rossum773ab271996-07-23 03:46:24 +0000262 # self.file = StringIO(value)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000263
264 def __repr__(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000265 """Return printable representation."""
Walter Dörwald70a6b492004-02-12 17:35:32 +0000266 return "MiniFieldStorage(%r, %r)" % (self.name, self.value)
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000267
268
269class FieldStorage:
270
Guido van Rossum7aee3841996-03-07 18:00:44 +0000271 """Store a sequence of fields, reading multipart/form-data.
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000272
Guido van Rossum7aee3841996-03-07 18:00:44 +0000273 This class provides naming, typing, files stored on disk, and
274 more. At the top level, it is accessible like a dictionary, whose
275 keys are the field names. (Note: None can occur as a field name.)
276 The items are either a Python list (if there's multiple values) or
277 another FieldStorage or MiniFieldStorage object. If it's a single
278 object, it has the following attributes:
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000279
Guido van Rossum7aee3841996-03-07 18:00:44 +0000280 name: the field name, if specified; otherwise None
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000281
Guido van Rossum7aee3841996-03-07 18:00:44 +0000282 filename: the filename, if specified; otherwise None; this is the
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000283 client side filename, *not* the file name on which it is
284 stored (that's a temporary file you don't deal with)
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000285
Guido van Rossum7aee3841996-03-07 18:00:44 +0000286 value: the value as a *string*; for file uploads, this
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000287 transparently reads the file every time you request the value
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000288 and returns *bytes*
Guido van Rossum7aee3841996-03-07 18:00:44 +0000289
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000290 file: the file(-like) object from which you can read the data *as
291 bytes* ; None if the data is stored a simple string
Guido van Rossum7aee3841996-03-07 18:00:44 +0000292
293 type: the content-type, or None if not specified
294
295 type_options: dictionary of options specified on the content-type
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000296 line
Guido van Rossum7aee3841996-03-07 18:00:44 +0000297
298 disposition: content-disposition, or None if not specified
299
300 disposition_options: dictionary of corresponding options
301
Barry Warsaw596097e2008-06-12 02:38:51 +0000302 headers: a dictionary(-like) object (sometimes email.message.Message or a
Armin Rigo3a703b62005-09-19 09:11:04 +0000303 subclass thereof) containing *all* headers
Guido van Rossum7aee3841996-03-07 18:00:44 +0000304
305 The class is subclassable, mostly for the purpose of overriding
306 the make_file() method, which is called internally to come up with
307 a file open for reading and writing. This makes it possible to
308 override the default choice of storing all files in a temporary
309 directory and unlinking them as soon as they have been opened.
310
311 """
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000312 def __init__(self, fp=None, headers=None, outerboundary=b'',
313 environ=os.environ, keep_blank_values=0, strict_parsing=0,
matthewbelisle-wf20914482018-10-19 05:52:59 -0500314 limit=None, encoding='utf-8', errors='replace',
315 max_num_fields=None):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000316 """Constructor. Read multipart/* until last part.
Guido van Rossum7aee3841996-03-07 18:00:44 +0000317
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000318 Arguments, all optional:
Guido van Rossum7aee3841996-03-07 18:00:44 +0000319
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000320 fp : file pointer; default: sys.stdin.buffer
Guido van Rossumb1b4f941998-05-08 19:55:51 +0000321 (not used when the request method is GET)
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000322 Can be :
323 1. a TextIOWrapper object
324 2. an object whose read() and readline() methods return bytes
Guido van Rossum7aee3841996-03-07 18:00:44 +0000325
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000326 headers : header dictionary-like object; default:
327 taken from environ as per CGI spec
Guido van Rossum7aee3841996-03-07 18:00:44 +0000328
Guido van Rossum773ab271996-07-23 03:46:24 +0000329 outerboundary : terminating multipart boundary
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000330 (for internal use only)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000331
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000332 environ : environment dictionary; default: os.environ
Guido van Rossum773ab271996-07-23 03:46:24 +0000333
334 keep_blank_values: flag indicating whether blank values in
Senthil Kumaran30e86a42010-08-09 20:01:35 +0000335 percent-encoded forms should be treated as blank strings.
Tim Peters88869f92001-01-14 23:36:06 +0000336 A true value indicates that blanks should be retained as
Guido van Rossum773ab271996-07-23 03:46:24 +0000337 blank strings. The default false value indicates that
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000338 blank values are to be ignored and treated as if they were
339 not included.
Guido van Rossum773ab271996-07-23 03:46:24 +0000340
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000341 strict_parsing: flag indicating what to do with parsing errors.
342 If false (the default), errors are silently ignored.
343 If true, errors raise a ValueError exception.
Guido van Rossume08c04c1996-11-11 19:29:11 +0000344
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000345 limit : used internally to read parts of multipart/form-data forms,
346 to exit from the reading loop when reached. It is the difference
347 between the form content-length and the number of bytes already
348 read
349
350 encoding, errors : the encoding and error handler used to decode the
351 binary stream to strings. Must be the same as the charset defined
352 for the page sending the form (content-type : meta http-equiv or
353 header)
354
matthewbelisle-wf20914482018-10-19 05:52:59 -0500355 max_num_fields: int. If set, then __init__ throws a ValueError
356 if there are more than n fields read by parse_qsl().
357
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000358 """
359 method = 'GET'
360 self.keep_blank_values = keep_blank_values
361 self.strict_parsing = strict_parsing
matthewbelisle-wf20914482018-10-19 05:52:59 -0500362 self.max_num_fields = max_num_fields
Raymond Hettinger54f02222002-06-01 14:18:47 +0000363 if 'REQUEST_METHOD' in environ:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000364 method = environ['REQUEST_METHOD'].upper()
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000365 self.qs_on_post = None
Guido van Rossum01852831998-06-25 02:40:17 +0000366 if method == 'GET' or method == 'HEAD':
Raymond Hettinger54f02222002-06-01 14:18:47 +0000367 if 'QUERY_STRING' in environ:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000368 qs = environ['QUERY_STRING']
369 elif sys.argv[1:]:
370 qs = sys.argv[1]
371 else:
372 qs = ""
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000373 qs = qs.encode(locale.getpreferredencoding(), 'surrogateescape')
374 fp = BytesIO(qs)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000375 if headers is None:
376 headers = {'content-type':
377 "application/x-www-form-urlencoded"}
378 if headers is None:
Guido van Rossumcff311a1998-06-11 14:06:59 +0000379 headers = {}
380 if method == 'POST':
381 # Set default content-type for POST to what's traditional
382 headers['content-type'] = "application/x-www-form-urlencoded"
Raymond Hettinger54f02222002-06-01 14:18:47 +0000383 if 'CONTENT_TYPE' in environ:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000384 headers['content-type'] = environ['CONTENT_TYPE']
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000385 if 'QUERY_STRING' in environ:
386 self.qs_on_post = environ['QUERY_STRING']
Raymond Hettinger54f02222002-06-01 14:18:47 +0000387 if 'CONTENT_LENGTH' in environ:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000388 headers['content-length'] = environ['CONTENT_LENGTH']
Senthil Kumaranb4cbb922014-01-11 22:20:16 -0800389 else:
390 if not (isinstance(headers, (Mapping, Message))):
391 raise TypeError("headers must be mapping or an instance of "
392 "email.message.Message")
393 self.headers = headers
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000394 if fp is None:
395 self.fp = sys.stdin.buffer
396 # self.fp.read() must return bytes
397 elif isinstance(fp, TextIOWrapper):
398 self.fp = fp.buffer
399 else:
Senthil Kumaranb4cbb922014-01-11 22:20:16 -0800400 if not (hasattr(fp, 'read') and hasattr(fp, 'readline')):
401 raise TypeError("fp must be file pointer")
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000402 self.fp = fp
403
404 self.encoding = encoding
405 self.errors = errors
406
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000407 if not isinstance(outerboundary, bytes):
408 raise TypeError('outerboundary must be bytes, not %s'
409 % type(outerboundary).__name__)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000410 self.outerboundary = outerboundary
Guido van Rossum7aee3841996-03-07 18:00:44 +0000411
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000412 self.bytes_read = 0
413 self.limit = limit
414
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000415 # Process content-disposition header
416 cdisp, pdict = "", {}
Raymond Hettinger54f02222002-06-01 14:18:47 +0000417 if 'content-disposition' in self.headers:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000418 cdisp, pdict = parse_header(self.headers['content-disposition'])
419 self.disposition = cdisp
420 self.disposition_options = pdict
421 self.name = None
Raymond Hettinger54f02222002-06-01 14:18:47 +0000422 if 'name' in pdict:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000423 self.name = pdict['name']
424 self.filename = None
Raymond Hettinger54f02222002-06-01 14:18:47 +0000425 if 'filename' in pdict:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000426 self.filename = pdict['filename']
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000427 self._binary_file = self.filename is not None
Guido van Rossum7aee3841996-03-07 18:00:44 +0000428
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000429 # Process content-type header
Barry Warsaw302331a1999-01-08 17:42:03 +0000430 #
431 # Honor any existing content-type header. But if there is no
432 # content-type header, use some sensible defaults. Assume
433 # outerboundary is "" at the outer level, but something non-false
434 # inside a multi-part. The default for an inner part is text/plain,
435 # but for an outer part it should be urlencoded. This should catch
436 # bogus clients which erroneously forget to include a content-type
437 # header.
438 #
439 # See below for what we do if there does exist a content-type header,
440 # but it happens to be something we don't understand.
Raymond Hettinger54f02222002-06-01 14:18:47 +0000441 if 'content-type' in self.headers:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000442 ctype, pdict = parse_header(self.headers['content-type'])
Guido van Rossumce900de1999-06-02 18:44:22 +0000443 elif self.outerboundary or method != 'POST':
Barry Warsaw302331a1999-01-08 17:42:03 +0000444 ctype, pdict = "text/plain", {}
445 else:
446 ctype, pdict = 'application/x-www-form-urlencoded', {}
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000447 self.type = ctype
448 self.type_options = pdict
Raymond Hettinger54f02222002-06-01 14:18:47 +0000449 if 'boundary' in pdict:
Amber Brown545c9552018-05-14 18:11:55 -0400450 self.innerboundary = pdict['boundary'].encode(self.encoding,
451 self.errors)
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000452 else:
453 self.innerboundary = b""
454
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000455 clen = -1
Raymond Hettinger54f02222002-06-01 14:18:47 +0000456 if 'content-length' in self.headers:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000457 try:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000458 clen = int(self.headers['content-length'])
Skip Montanarodb5d1442002-03-23 05:50:17 +0000459 except ValueError:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000460 pass
461 if maxlen and clen > maxlen:
Collin Winterce36ad82007-08-30 01:19:48 +0000462 raise ValueError('Maximum content length exceeded')
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000463 self.length = clen
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000464 if self.limit is None and clen:
465 self.limit = clen
Guido van Rossum7aee3841996-03-07 18:00:44 +0000466
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000467 self.list = self.file = None
468 self.done = 0
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000469 if ctype == 'application/x-www-form-urlencoded':
470 self.read_urlencoded()
471 elif ctype[:10] == 'multipart/':
Guido van Rossumf5745001998-10-20 14:43:02 +0000472 self.read_multi(environ, keep_blank_values, strict_parsing)
Barry Warsaw302331a1999-01-08 17:42:03 +0000473 else:
Guido van Rossum60a3bd81999-06-11 18:26:09 +0000474 self.read_single()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000475
Brett Cannonf79126f2013-08-23 15:15:48 -0400476 def __del__(self):
477 try:
478 self.file.close()
479 except AttributeError:
480 pass
481
Berker Peksagbf5e9602015-02-06 10:21:37 +0200482 def __enter__(self):
483 return self
484
485 def __exit__(self, *args):
486 self.file.close()
487
Guido van Rossum7aee3841996-03-07 18:00:44 +0000488 def __repr__(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000489 """Return a printable representation."""
Walter Dörwald70a6b492004-02-12 17:35:32 +0000490 return "FieldStorage(%r, %r, %r)" % (
491 self.name, self.filename, self.value)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000492
Guido van Rossum4061cbe2002-09-11 18:20:34 +0000493 def __iter__(self):
494 return iter(self.keys())
495
Guido van Rossum7aee3841996-03-07 18:00:44 +0000496 def __getattr__(self, name):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000497 if name != 'value':
Collin Winterce36ad82007-08-30 01:19:48 +0000498 raise AttributeError(name)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000499 if self.file:
500 self.file.seek(0)
501 value = self.file.read()
502 self.file.seek(0)
503 elif self.list is not None:
504 value = self.list
505 else:
506 value = None
507 return value
Guido van Rossum7aee3841996-03-07 18:00:44 +0000508
509 def __getitem__(self, key):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000510 """Dictionary style indexing."""
511 if self.list is None:
Collin Winterce36ad82007-08-30 01:19:48 +0000512 raise TypeError("not indexable")
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000513 found = []
514 for item in self.list:
515 if item.name == key: found.append(item)
516 if not found:
Collin Winterce36ad82007-08-30 01:19:48 +0000517 raise KeyError(key)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000518 if len(found) == 1:
519 return found[0]
520 else:
521 return found
Guido van Rossum7aee3841996-03-07 18:00:44 +0000522
Moshe Zadkaa1a4b592000-08-25 21:47:56 +0000523 def getvalue(self, key, default=None):
524 """Dictionary style get() method, including 'value' lookup."""
Raymond Hettinger54f02222002-06-01 14:18:47 +0000525 if key in self:
Moshe Zadkaa1a4b592000-08-25 21:47:56 +0000526 value = self[key]
Victor Stinnerf1c7ca92011-01-14 13:08:27 +0000527 if isinstance(value, list):
Guido van Rossumc1f779c2007-07-03 08:25:58 +0000528 return [x.value for x in value]
Moshe Zadkaa1a4b592000-08-25 21:47:56 +0000529 else:
530 return value.value
531 else:
532 return default
533
Guido van Rossum1bfb3882001-09-05 19:45:34 +0000534 def getfirst(self, key, default=None):
535 """ Return the first value received."""
Raymond Hettinger54f02222002-06-01 14:18:47 +0000536 if key in self:
Guido van Rossum1bfb3882001-09-05 19:45:34 +0000537 value = self[key]
Victor Stinnerf1c7ca92011-01-14 13:08:27 +0000538 if isinstance(value, list):
Guido van Rossum1bfb3882001-09-05 19:45:34 +0000539 return value[0].value
540 else:
541 return value.value
542 else:
543 return default
544
545 def getlist(self, key):
546 """ Return list of received values."""
Raymond Hettinger54f02222002-06-01 14:18:47 +0000547 if key in self:
Guido van Rossum1bfb3882001-09-05 19:45:34 +0000548 value = self[key]
Victor Stinnerf1c7ca92011-01-14 13:08:27 +0000549 if isinstance(value, list):
Guido van Rossumc1f779c2007-07-03 08:25:58 +0000550 return [x.value for x in value]
Guido van Rossum1bfb3882001-09-05 19:45:34 +0000551 else:
552 return [value.value]
553 else:
554 return []
555
Guido van Rossum7aee3841996-03-07 18:00:44 +0000556 def keys(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000557 """Dictionary style keys() method."""
558 if self.list is None:
Collin Winterce36ad82007-08-30 01:19:48 +0000559 raise TypeError("not indexable")
Thomas Wouters8ce81f72007-09-20 18:22:40 +0000560 return list(set(item.name for item in self.list))
Guido van Rossum7aee3841996-03-07 18:00:44 +0000561
Raymond Hettinger54f02222002-06-01 14:18:47 +0000562 def __contains__(self, key):
563 """Dictionary style __contains__ method."""
564 if self.list is None:
Collin Winterce36ad82007-08-30 01:19:48 +0000565 raise TypeError("not indexable")
Thomas Wouters8ce81f72007-09-20 18:22:40 +0000566 return any(item.name == key for item in self.list)
Raymond Hettinger54f02222002-06-01 14:18:47 +0000567
Guido van Rossum88b85d41997-01-11 19:21:33 +0000568 def __len__(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000569 """Dictionary style len(x) support."""
570 return len(self.keys())
Guido van Rossum88b85d41997-01-11 19:21:33 +0000571
Senthil Kumaranb4cbb922014-01-11 22:20:16 -0800572 def __bool__(self):
573 if self.list is None:
574 raise TypeError("Cannot be converted to bool.")
Thomas Wouters8ce81f72007-09-20 18:22:40 +0000575 return bool(self.list)
576
Guido van Rossum7aee3841996-03-07 18:00:44 +0000577 def read_urlencoded(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000578 """Internal: read data in query string format."""
579 qs = self.fp.read(self.length)
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000580 if not isinstance(qs, bytes):
581 raise ValueError("%s should return bytes, got %s" \
582 % (self.fp, type(qs).__name__))
583 qs = qs.decode(self.encoding, self.errors)
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000584 if self.qs_on_post:
585 qs += '&' + self.qs_on_post
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000586 query = urllib.parse.parse_qsl(
587 qs, self.keep_blank_values, self.strict_parsing,
matthewbelisle-wf20914482018-10-19 05:52:59 -0500588 encoding=self.encoding, errors=self.errors,
589 max_num_fields=self.max_num_fields)
590 self.list = [MiniFieldStorage(key, value) for key, value in query]
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000591 self.skip_lines()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000592
Guido van Rossum030d2ec1998-12-09 22:16:46 +0000593 FieldStorageClass = None
594
Guido van Rossumf5745001998-10-20 14:43:02 +0000595 def read_multi(self, environ, keep_blank_values, strict_parsing):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000596 """Internal: read a part that is itself multipart."""
Guido van Rossum2e441f72001-07-25 21:00:19 +0000597 ib = self.innerboundary
598 if not valid_boundary(ib):
Collin Winterce36ad82007-08-30 01:19:48 +0000599 raise ValueError('Invalid boundary in multipart form: %r' % (ib,))
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000600 self.list = []
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000601 if self.qs_on_post:
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000602 query = urllib.parse.parse_qsl(
603 self.qs_on_post, self.keep_blank_values, self.strict_parsing,
matthewbelisle-wf20914482018-10-19 05:52:59 -0500604 encoding=self.encoding, errors=self.errors,
605 max_num_fields=self.max_num_fields)
606 self.list.extend(MiniFieldStorage(key, value) for key, value in query)
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000607
Guido van Rossum030d2ec1998-12-09 22:16:46 +0000608 klass = self.FieldStorageClass or self.__class__
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000609 first_line = self.fp.readline() # bytes
610 if not isinstance(first_line, bytes):
611 raise ValueError("%s should return bytes, got %s" \
612 % (self.fp, type(first_line).__name__))
613 self.bytes_read += len(first_line)
Donald Stufftd90f8d12015-03-29 16:43:23 -0400614
615 # Ensure that we consume the file until we've hit our inner boundary
616 while (first_line.strip() != (b"--" + self.innerboundary) and
617 first_line):
618 first_line = self.fp.readline()
619 self.bytes_read += len(first_line)
620
matthewbelisle-wfb79b5c02018-10-23 03:14:35 -0500621 # Propagate max_num_fields into the sub class appropriately
622 max_num_fields = self.max_num_fields
623 if max_num_fields is not None:
624 max_num_fields -= len(self.list)
625
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000626 while True:
627 parser = FeedParser()
628 hdr_text = b""
629 while True:
630 data = self.fp.readline()
631 hdr_text += data
632 if not data.strip():
633 break
634 if not hdr_text:
635 break
636 # parser takes strings, not bytes
637 self.bytes_read += len(hdr_text)
638 parser.feed(hdr_text.decode(self.encoding, self.errors))
639 headers = parser.close()
Victor Stinner65794592015-08-18 10:21:10 -0700640
641 # Some clients add Content-Length for part headers, ignore them
642 if 'content-length' in headers:
643 del headers['content-length']
644
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000645 part = klass(self.fp, headers, ib, environ, keep_blank_values,
646 strict_parsing,self.limit-self.bytes_read,
matthewbelisle-wfb79b5c02018-10-23 03:14:35 -0500647 self.encoding, self.errors, max_num_fields)
matthewbelisle-wf20914482018-10-19 05:52:59 -0500648
matthewbelisle-wfb79b5c02018-10-23 03:14:35 -0500649 if max_num_fields is not None:
650 max_num_fields -= 1
651 if part.list:
652 max_num_fields -= len(part.list)
653 if max_num_fields < 0:
654 raise ValueError('Max number of fields exceeded')
matthewbelisle-wf20914482018-10-19 05:52:59 -0500655
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000656 self.bytes_read += part.bytes_read
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000657 self.list.append(part)
Florent Xicluna331c3fd2013-07-07 12:44:28 +0200658 if part.done or self.bytes_read >= self.length > 0:
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000659 break
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000660 self.skip_lines()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000661
662 def read_single(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000663 """Internal: read an atomic part."""
664 if self.length >= 0:
665 self.read_binary()
666 self.skip_lines()
667 else:
668 self.read_lines()
669 self.file.seek(0)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000670
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000671 bufsize = 8*1024 # I/O buffering size for copy to file
Guido van Rossum7aee3841996-03-07 18:00:44 +0000672
673 def read_binary(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000674 """Internal: read binary data."""
Guido van Rossuma1a68522007-08-28 03:11:34 +0000675 self.file = self.make_file()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000676 todo = self.length
677 if todo >= 0:
678 while todo > 0:
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000679 data = self.fp.read(min(todo, self.bufsize)) # bytes
680 if not isinstance(data, bytes):
681 raise ValueError("%s should return bytes, got %s"
682 % (self.fp, type(data).__name__))
683 self.bytes_read += len(data)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000684 if not data:
685 self.done = -1
686 break
687 self.file.write(data)
688 todo = todo - len(data)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000689
690 def read_lines(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000691 """Internal: read lines until EOF or outerboundary."""
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000692 if self._binary_file:
693 self.file = self.__file = BytesIO() # store data as bytes for files
694 else:
695 self.file = self.__file = StringIO() # as strings for other fields
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000696 if self.outerboundary:
697 self.read_lines_to_outerboundary()
698 else:
699 self.read_lines_to_eof()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000700
Guido van Rossum52b8c292001-06-29 13:06:06 +0000701 def __write(self, line):
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000702 """line is always bytes, not string"""
Guido van Rossum52b8c292001-06-29 13:06:06 +0000703 if self.__file is not None:
704 if self.__file.tell() + len(line) > 1000:
Guido van Rossuma1a68522007-08-28 03:11:34 +0000705 self.file = self.make_file()
706 data = self.__file.getvalue()
707 self.file.write(data)
Guido van Rossum52b8c292001-06-29 13:06:06 +0000708 self.__file = None
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000709 if self._binary_file:
710 # keep bytes
711 self.file.write(line)
712 else:
713 # decode to string
714 self.file.write(line.decode(self.encoding, self.errors))
Guido van Rossum52b8c292001-06-29 13:06:06 +0000715
Guido van Rossum7aee3841996-03-07 18:00:44 +0000716 def read_lines_to_eof(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000717 """Internal: read lines until EOF."""
718 while 1:
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000719 line = self.fp.readline(1<<16) # bytes
720 self.bytes_read += len(line)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000721 if not line:
722 self.done = -1
723 break
Guido van Rossum52b8c292001-06-29 13:06:06 +0000724 self.__write(line)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000725
726 def read_lines_to_outerboundary(self):
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000727 """Internal: read lines until outerboundary.
728 Data is read as bytes: boundaries and line ends must be converted
729 to bytes for comparisons.
730 """
731 next_boundary = b"--" + self.outerboundary
732 last_boundary = next_boundary + b"--"
733 delim = b""
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000734 last_line_lfend = True
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000735 _read = 0
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000736 while 1:
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000737 if _read >= self.limit:
738 break
739 line = self.fp.readline(1<<16) # bytes
740 self.bytes_read += len(line)
741 _read += len(line)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000742 if not line:
743 self.done = -1
744 break
Serhiy Storchakac7bfe0e2013-06-17 16:34:41 +0300745 if delim == b"\r":
746 line = delim + line
747 delim = b""
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000748 if line.startswith(b"--") and last_line_lfend:
749 strippedline = line.rstrip()
750 if strippedline == next_boundary:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000751 break
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000752 if strippedline == last_boundary:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000753 self.done = 1
754 break
755 odelim = delim
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000756 if line.endswith(b"\r\n"):
757 delim = b"\r\n"
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000758 line = line[:-2]
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000759 last_line_lfend = True
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000760 elif line.endswith(b"\n"):
761 delim = b"\n"
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000762 line = line[:-1]
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000763 last_line_lfend = True
Serhiy Storchakac7bfe0e2013-06-17 16:34:41 +0300764 elif line.endswith(b"\r"):
765 # We may interrupt \r\n sequences if they span the 2**16
766 # byte boundary
767 delim = b"\r"
768 line = line[:-1]
769 last_line_lfend = False
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000770 else:
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000771 delim = b""
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000772 last_line_lfend = False
Guido van Rossum52b8c292001-06-29 13:06:06 +0000773 self.__write(odelim + line)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000774
775 def skip_lines(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000776 """Internal: skip lines until outer boundary if defined."""
777 if not self.outerboundary or self.done:
778 return
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000779 next_boundary = b"--" + self.outerboundary
780 last_boundary = next_boundary + b"--"
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000781 last_line_lfend = True
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000782 while True:
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000783 line = self.fp.readline(1<<16)
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000784 self.bytes_read += len(line)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000785 if not line:
786 self.done = -1
787 break
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000788 if line.endswith(b"--") and last_line_lfend:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000789 strippedline = line.strip()
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000790 if strippedline == next_boundary:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000791 break
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000792 if strippedline == last_boundary:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000793 self.done = 1
794 break
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000795 last_line_lfend = line.endswith(b'\n')
Guido van Rossum7aee3841996-03-07 18:00:44 +0000796
Guido van Rossuma1a68522007-08-28 03:11:34 +0000797 def make_file(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000798 """Overridable: return a readable & writable file.
Guido van Rossum7aee3841996-03-07 18:00:44 +0000799
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000800 The file will be used as follows:
801 - data is written to it
802 - seek(0)
803 - data is read from it
Guido van Rossum7aee3841996-03-07 18:00:44 +0000804
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000805 The file is opened in binary mode for files, in text mode
806 for other fields
Guido van Rossum7aee3841996-03-07 18:00:44 +0000807
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000808 This version opens a temporary file for reading and writing,
809 and immediately deletes (unlinks) it. The trick (on Unix!) is
810 that the file can still be used, but it can't be opened by
811 another process, and it will automatically be deleted when it
812 is closed or when the current process terminates.
Guido van Rossum4032c2c1996-03-09 04:04:35 +0000813
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000814 If you want a more permanent file, you derive a class which
815 overrides this method. If you want a visible temporary file
816 that is nevertheless automatically deleted when the script
817 terminates, try defining a __del__ method in a derived class
818 which unlinks the temporary files you have created.
Guido van Rossum7aee3841996-03-07 18:00:44 +0000819
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000820 """
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000821 if self._binary_file:
822 return tempfile.TemporaryFile("wb+")
823 else:
824 return tempfile.TemporaryFile("w+",
825 encoding=self.encoding, newline = '\n')
Tim Peters88869f92001-01-14 23:36:06 +0000826
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000827
Guido van Rossum72755611996-03-06 07:20:06 +0000828# Test/debug code
829# ===============
Guido van Rossum9a22de11995-01-12 12:29:47 +0000830
Guido van Rossum773ab271996-07-23 03:46:24 +0000831def test(environ=os.environ):
Guido van Rossum7aee3841996-03-07 18:00:44 +0000832 """Robust test CGI script, usable as main program.
Guido van Rossum9a22de11995-01-12 12:29:47 +0000833
Guido van Rossum7aee3841996-03-07 18:00:44 +0000834 Write minimal HTTP headers and dump all information provided to
835 the script in HTML form.
836
837 """
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000838 print("Content-type: text/html")
839 print()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000840 sys.stderr = sys.stdout
841 try:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000842 form = FieldStorage() # Replace with other classes to test those
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000843 print_directory()
844 print_arguments()
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000845 print_form(form)
846 print_environ(environ)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000847 print_environ_usage()
848 def f():
Georg Brandl7cae87c2006-09-06 06:51:57 +0000849 exec("testing print_exception() -- <I>italics?</I>")
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000850 def g(f=f):
851 f()
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000852 print("<H3>What follows is a test, not an actual exception:</H3>")
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000853 g()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000854 except:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000855 print_exception()
Guido van Rossumf85de8a1996-08-20 20:22:39 +0000856
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000857 print("<H1>Second try with a small maxlen...</H1>")
Guido van Rossum57d51f22000-09-16 21:16:01 +0000858
Guido van Rossumad164711997-05-13 19:03:23 +0000859 global maxlen
860 maxlen = 50
861 try:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000862 form = FieldStorage() # Replace with other classes to test those
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000863 print_directory()
864 print_arguments()
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000865 print_form(form)
866 print_environ(environ)
Guido van Rossumad164711997-05-13 19:03:23 +0000867 except:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000868 print_exception()
Guido van Rossumad164711997-05-13 19:03:23 +0000869
Guido van Rossumf85de8a1996-08-20 20:22:39 +0000870def print_exception(type=None, value=None, tb=None, limit=None):
871 if type is None:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000872 type, value, tb = sys.exc_info()
Guido van Rossumf85de8a1996-08-20 20:22:39 +0000873 import traceback
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000874 print()
875 print("<H3>Traceback (most recent call last):</H3>")
Guido van Rossumf85de8a1996-08-20 20:22:39 +0000876 list = traceback.format_tb(tb, limit) + \
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000877 traceback.format_exception_only(type, value)
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000878 print("<PRE>%s<B>%s</B></PRE>" % (
Georg Brandl1f7fffb2010-10-15 15:57:45 +0000879 html.escape("".join(list[:-1])),
880 html.escape(list[-1]),
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000881 ))
Guido van Rossumf15d1591997-09-29 23:22:12 +0000882 del tb
Guido van Rossum9a22de11995-01-12 12:29:47 +0000883
Guido van Rossum773ab271996-07-23 03:46:24 +0000884def print_environ(environ=os.environ):
Guido van Rossum7aee3841996-03-07 18:00:44 +0000885 """Dump the shell environment as HTML."""
Guido van Rossuma1a68522007-08-28 03:11:34 +0000886 keys = sorted(environ.keys())
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000887 print()
888 print("<H3>Shell Environment:</H3>")
889 print("<DL>")
Guido van Rossum7aee3841996-03-07 18:00:44 +0000890 for key in keys:
Georg Brandl1f7fffb2010-10-15 15:57:45 +0000891 print("<DT>", html.escape(key), "<DD>", html.escape(environ[key]))
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000892 print("</DL>")
893 print()
Guido van Rossum72755611996-03-06 07:20:06 +0000894
895def print_form(form):
Guido van Rossum7aee3841996-03-07 18:00:44 +0000896 """Dump the contents of a form as HTML."""
Guido van Rossuma1a68522007-08-28 03:11:34 +0000897 keys = sorted(form.keys())
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000898 print()
899 print("<H3>Form Contents:</H3>")
Guido van Rossum57d51f22000-09-16 21:16:01 +0000900 if not keys:
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000901 print("<P>No form fields.")
902 print("<DL>")
Guido van Rossum7aee3841996-03-07 18:00:44 +0000903 for key in keys:
Georg Brandl1f7fffb2010-10-15 15:57:45 +0000904 print("<DT>" + html.escape(key) + ":", end=' ')
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000905 value = form[key]
Georg Brandl1f7fffb2010-10-15 15:57:45 +0000906 print("<i>" + html.escape(repr(type(value))) + "</i>")
907 print("<DD>" + html.escape(repr(value)))
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000908 print("</DL>")
909 print()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000910
911def print_directory():
912 """Dump the current directory as HTML."""
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000913 print()
914 print("<H3>Current Working Directory:</H3>")
Guido van Rossum7aee3841996-03-07 18:00:44 +0000915 try:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000916 pwd = os.getcwd()
Andrew Svetlovad28c7f2012-12-18 22:02:39 +0200917 except OSError as msg:
Andrew Svetlov8b33dd82012-12-24 19:58:48 +0200918 print("OSError:", html.escape(str(msg)))
Guido van Rossum7aee3841996-03-07 18:00:44 +0000919 else:
Georg Brandl1f7fffb2010-10-15 15:57:45 +0000920 print(html.escape(pwd))
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000921 print()
Guido van Rossum9a22de11995-01-12 12:29:47 +0000922
Guido van Rossuma8738a51996-03-14 21:30:28 +0000923def print_arguments():
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000924 print()
925 print("<H3>Command Line Arguments:</H3>")
926 print()
927 print(sys.argv)
928 print()
Guido van Rossuma8738a51996-03-14 21:30:28 +0000929
Guido van Rossum9a22de11995-01-12 12:29:47 +0000930def print_environ_usage():
Guido van Rossum7aee3841996-03-07 18:00:44 +0000931 """Dump a list of environment variables used by CGI as HTML."""
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000932 print("""
Guido van Rossum72755611996-03-06 07:20:06 +0000933<H3>These environment variables could have been set:</H3>
934<UL>
Guido van Rossum9a22de11995-01-12 12:29:47 +0000935<LI>AUTH_TYPE
936<LI>CONTENT_LENGTH
937<LI>CONTENT_TYPE
938<LI>DATE_GMT
939<LI>DATE_LOCAL
940<LI>DOCUMENT_NAME
941<LI>DOCUMENT_ROOT
942<LI>DOCUMENT_URI
943<LI>GATEWAY_INTERFACE
944<LI>LAST_MODIFIED
945<LI>PATH
946<LI>PATH_INFO
947<LI>PATH_TRANSLATED
948<LI>QUERY_STRING
949<LI>REMOTE_ADDR
950<LI>REMOTE_HOST
951<LI>REMOTE_IDENT
952<LI>REMOTE_USER
953<LI>REQUEST_METHOD
954<LI>SCRIPT_NAME
955<LI>SERVER_NAME
956<LI>SERVER_PORT
957<LI>SERVER_PROTOCOL
958<LI>SERVER_ROOT
959<LI>SERVER_SOFTWARE
960</UL>
Guido van Rossum7aee3841996-03-07 18:00:44 +0000961In addition, HTTP headers sent by the server may be passed in the
962environment as well. Here are some common variable names:
963<UL>
964<LI>HTTP_ACCEPT
965<LI>HTTP_CONNECTION
966<LI>HTTP_HOST
967<LI>HTTP_PRAGMA
968<LI>HTTP_REFERER
969<LI>HTTP_USER_AGENT
970</UL>
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000971""")
Guido van Rossum9a22de11995-01-12 12:29:47 +0000972
Guido van Rossum9a22de11995-01-12 12:29:47 +0000973
Guido van Rossum72755611996-03-06 07:20:06 +0000974# Utilities
975# =========
Guido van Rossum9a22de11995-01-12 12:29:47 +0000976
Benjamin Peterson4d59a782014-04-03 10:22:10 -0400977def valid_boundary(s):
Guido van Rossum2e441f72001-07-25 21:00:19 +0000978 import re
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000979 if isinstance(s, bytes):
980 _vb_pattern = b"^[ -~]{0,200}[!-~]$"
981 else:
982 _vb_pattern = "^[ -~]{0,200}[!-~]$"
Guido van Rossum2e441f72001-07-25 21:00:19 +0000983 return re.match(_vb_pattern, s)
Guido van Rossum9a22de11995-01-12 12:29:47 +0000984
Guido van Rossum72755611996-03-06 07:20:06 +0000985# Invoke mainline
986# ===============
987
988# Call test() when this file is run as a script (not imported as a module)
Tim Peters88869f92001-01-14 23:36:06 +0000989if __name__ == '__main__':
Guido van Rossum7aee3841996-03-07 18:00:44 +0000990 test()