blob: c22c71b3878516508f63ce5dfcfa99ad1beef554 [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
Pierre Quentel2d7caca2019-09-11 13:05:53 +0200464 if self.limit is None and clen >= 0:
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000465 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
Pierre Quentel2d7caca2019-09-11 13:05:53 +0200645 limit = None if self.limit is None \
646 else self.limit - self.bytes_read
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000647 part = klass(self.fp, headers, ib, environ, keep_blank_values,
Pierre Quentel2d7caca2019-09-11 13:05:53 +0200648 strict_parsing, limit,
matthewbelisle-wfb79b5c02018-10-23 03:14:35 -0500649 self.encoding, self.errors, max_num_fields)
matthewbelisle-wf20914482018-10-19 05:52:59 -0500650
matthewbelisle-wfb79b5c02018-10-23 03:14:35 -0500651 if max_num_fields is not None:
652 max_num_fields -= 1
653 if part.list:
654 max_num_fields -= len(part.list)
655 if max_num_fields < 0:
656 raise ValueError('Max number of fields exceeded')
matthewbelisle-wf20914482018-10-19 05:52:59 -0500657
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000658 self.bytes_read += part.bytes_read
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000659 self.list.append(part)
Florent Xicluna331c3fd2013-07-07 12:44:28 +0200660 if part.done or self.bytes_read >= self.length > 0:
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000661 break
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000662 self.skip_lines()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000663
664 def read_single(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000665 """Internal: read an atomic part."""
666 if self.length >= 0:
667 self.read_binary()
668 self.skip_lines()
669 else:
670 self.read_lines()
671 self.file.seek(0)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000672
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000673 bufsize = 8*1024 # I/O buffering size for copy to file
Guido van Rossum7aee3841996-03-07 18:00:44 +0000674
675 def read_binary(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000676 """Internal: read binary data."""
Guido van Rossuma1a68522007-08-28 03:11:34 +0000677 self.file = self.make_file()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000678 todo = self.length
679 if todo >= 0:
680 while todo > 0:
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000681 data = self.fp.read(min(todo, self.bufsize)) # bytes
682 if not isinstance(data, bytes):
683 raise ValueError("%s should return bytes, got %s"
684 % (self.fp, type(data).__name__))
685 self.bytes_read += len(data)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000686 if not data:
687 self.done = -1
688 break
689 self.file.write(data)
690 todo = todo - len(data)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000691
692 def read_lines(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000693 """Internal: read lines until EOF or outerboundary."""
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000694 if self._binary_file:
695 self.file = self.__file = BytesIO() # store data as bytes for files
696 else:
697 self.file = self.__file = StringIO() # as strings for other fields
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000698 if self.outerboundary:
699 self.read_lines_to_outerboundary()
700 else:
701 self.read_lines_to_eof()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000702
Guido van Rossum52b8c292001-06-29 13:06:06 +0000703 def __write(self, line):
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000704 """line is always bytes, not string"""
Guido van Rossum52b8c292001-06-29 13:06:06 +0000705 if self.__file is not None:
706 if self.__file.tell() + len(line) > 1000:
Guido van Rossuma1a68522007-08-28 03:11:34 +0000707 self.file = self.make_file()
708 data = self.__file.getvalue()
709 self.file.write(data)
Guido van Rossum52b8c292001-06-29 13:06:06 +0000710 self.__file = None
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000711 if self._binary_file:
712 # keep bytes
713 self.file.write(line)
714 else:
715 # decode to string
716 self.file.write(line.decode(self.encoding, self.errors))
Guido van Rossum52b8c292001-06-29 13:06:06 +0000717
Guido van Rossum7aee3841996-03-07 18:00:44 +0000718 def read_lines_to_eof(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000719 """Internal: read lines until EOF."""
720 while 1:
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000721 line = self.fp.readline(1<<16) # bytes
722 self.bytes_read += len(line)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000723 if not line:
724 self.done = -1
725 break
Guido van Rossum52b8c292001-06-29 13:06:06 +0000726 self.__write(line)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000727
728 def read_lines_to_outerboundary(self):
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000729 """Internal: read lines until outerboundary.
730 Data is read as bytes: boundaries and line ends must be converted
731 to bytes for comparisons.
732 """
733 next_boundary = b"--" + self.outerboundary
734 last_boundary = next_boundary + b"--"
735 delim = b""
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000736 last_line_lfend = True
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000737 _read = 0
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000738 while 1:
Pierre Quentel2d7caca2019-09-11 13:05:53 +0200739 if self.limit is not None and _read >= self.limit:
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000740 break
741 line = self.fp.readline(1<<16) # bytes
742 self.bytes_read += len(line)
743 _read += len(line)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000744 if not line:
745 self.done = -1
746 break
Serhiy Storchakac7bfe0e2013-06-17 16:34:41 +0300747 if delim == b"\r":
748 line = delim + line
749 delim = b""
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000750 if line.startswith(b"--") and last_line_lfend:
751 strippedline = line.rstrip()
752 if strippedline == next_boundary:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000753 break
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000754 if strippedline == last_boundary:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000755 self.done = 1
756 break
757 odelim = delim
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000758 if line.endswith(b"\r\n"):
759 delim = b"\r\n"
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000760 line = line[:-2]
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000761 last_line_lfend = True
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000762 elif line.endswith(b"\n"):
763 delim = b"\n"
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000764 line = line[:-1]
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000765 last_line_lfend = True
Serhiy Storchakac7bfe0e2013-06-17 16:34:41 +0300766 elif line.endswith(b"\r"):
767 # We may interrupt \r\n sequences if they span the 2**16
768 # byte boundary
769 delim = b"\r"
770 line = line[:-1]
771 last_line_lfend = False
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000772 else:
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000773 delim = b""
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000774 last_line_lfend = False
Guido van Rossum52b8c292001-06-29 13:06:06 +0000775 self.__write(odelim + line)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000776
777 def skip_lines(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000778 """Internal: skip lines until outer boundary if defined."""
779 if not self.outerboundary or self.done:
780 return
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000781 next_boundary = b"--" + self.outerboundary
782 last_boundary = next_boundary + b"--"
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000783 last_line_lfend = True
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000784 while True:
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000785 line = self.fp.readline(1<<16)
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000786 self.bytes_read += len(line)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000787 if not line:
788 self.done = -1
789 break
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000790 if line.endswith(b"--") and last_line_lfend:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000791 strippedline = line.strip()
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000792 if strippedline == next_boundary:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000793 break
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000794 if strippedline == last_boundary:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000795 self.done = 1
796 break
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000797 last_line_lfend = line.endswith(b'\n')
Guido van Rossum7aee3841996-03-07 18:00:44 +0000798
Guido van Rossuma1a68522007-08-28 03:11:34 +0000799 def make_file(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000800 """Overridable: return a readable & writable file.
Guido van Rossum7aee3841996-03-07 18:00:44 +0000801
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000802 The file will be used as follows:
803 - data is written to it
804 - seek(0)
805 - data is read from it
Guido van Rossum7aee3841996-03-07 18:00:44 +0000806
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000807 The file is opened in binary mode for files, in text mode
808 for other fields
Guido van Rossum7aee3841996-03-07 18:00:44 +0000809
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000810 This version opens a temporary file for reading and writing,
811 and immediately deletes (unlinks) it. The trick (on Unix!) is
812 that the file can still be used, but it can't be opened by
813 another process, and it will automatically be deleted when it
814 is closed or when the current process terminates.
Guido van Rossum4032c2c1996-03-09 04:04:35 +0000815
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000816 If you want a more permanent file, you derive a class which
817 overrides this method. If you want a visible temporary file
818 that is nevertheless automatically deleted when the script
819 terminates, try defining a __del__ method in a derived class
820 which unlinks the temporary files you have created.
Guido van Rossum7aee3841996-03-07 18:00:44 +0000821
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000822 """
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000823 if self._binary_file:
824 return tempfile.TemporaryFile("wb+")
825 else:
826 return tempfile.TemporaryFile("w+",
827 encoding=self.encoding, newline = '\n')
Tim Peters88869f92001-01-14 23:36:06 +0000828
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000829
Guido van Rossum72755611996-03-06 07:20:06 +0000830# Test/debug code
831# ===============
Guido van Rossum9a22de11995-01-12 12:29:47 +0000832
Guido van Rossum773ab271996-07-23 03:46:24 +0000833def test(environ=os.environ):
Guido van Rossum7aee3841996-03-07 18:00:44 +0000834 """Robust test CGI script, usable as main program.
Guido van Rossum9a22de11995-01-12 12:29:47 +0000835
Guido van Rossum7aee3841996-03-07 18:00:44 +0000836 Write minimal HTTP headers and dump all information provided to
837 the script in HTML form.
838
839 """
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000840 print("Content-type: text/html")
841 print()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000842 sys.stderr = sys.stdout
843 try:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000844 form = FieldStorage() # Replace with other classes to test those
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000845 print_directory()
846 print_arguments()
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000847 print_form(form)
848 print_environ(environ)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000849 print_environ_usage()
850 def f():
Georg Brandl7cae87c2006-09-06 06:51:57 +0000851 exec("testing print_exception() -- <I>italics?</I>")
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000852 def g(f=f):
853 f()
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000854 print("<H3>What follows is a test, not an actual exception:</H3>")
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000855 g()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000856 except:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000857 print_exception()
Guido van Rossumf85de8a1996-08-20 20:22:39 +0000858
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000859 print("<H1>Second try with a small maxlen...</H1>")
Guido van Rossum57d51f22000-09-16 21:16:01 +0000860
Guido van Rossumad164711997-05-13 19:03:23 +0000861 global maxlen
862 maxlen = 50
863 try:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000864 form = FieldStorage() # Replace with other classes to test those
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000865 print_directory()
866 print_arguments()
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000867 print_form(form)
868 print_environ(environ)
Guido van Rossumad164711997-05-13 19:03:23 +0000869 except:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000870 print_exception()
Guido van Rossumad164711997-05-13 19:03:23 +0000871
Guido van Rossumf85de8a1996-08-20 20:22:39 +0000872def print_exception(type=None, value=None, tb=None, limit=None):
873 if type is None:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000874 type, value, tb = sys.exc_info()
Guido van Rossumf85de8a1996-08-20 20:22:39 +0000875 import traceback
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000876 print()
877 print("<H3>Traceback (most recent call last):</H3>")
Guido van Rossumf85de8a1996-08-20 20:22:39 +0000878 list = traceback.format_tb(tb, limit) + \
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000879 traceback.format_exception_only(type, value)
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000880 print("<PRE>%s<B>%s</B></PRE>" % (
Georg Brandl1f7fffb2010-10-15 15:57:45 +0000881 html.escape("".join(list[:-1])),
882 html.escape(list[-1]),
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000883 ))
Guido van Rossumf15d1591997-09-29 23:22:12 +0000884 del tb
Guido van Rossum9a22de11995-01-12 12:29:47 +0000885
Guido van Rossum773ab271996-07-23 03:46:24 +0000886def print_environ(environ=os.environ):
Guido van Rossum7aee3841996-03-07 18:00:44 +0000887 """Dump the shell environment as HTML."""
Guido van Rossuma1a68522007-08-28 03:11:34 +0000888 keys = sorted(environ.keys())
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000889 print()
890 print("<H3>Shell Environment:</H3>")
891 print("<DL>")
Guido van Rossum7aee3841996-03-07 18:00:44 +0000892 for key in keys:
Georg Brandl1f7fffb2010-10-15 15:57:45 +0000893 print("<DT>", html.escape(key), "<DD>", html.escape(environ[key]))
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000894 print("</DL>")
895 print()
Guido van Rossum72755611996-03-06 07:20:06 +0000896
897def print_form(form):
Guido van Rossum7aee3841996-03-07 18:00:44 +0000898 """Dump the contents of a form as HTML."""
Guido van Rossuma1a68522007-08-28 03:11:34 +0000899 keys = sorted(form.keys())
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000900 print()
901 print("<H3>Form Contents:</H3>")
Guido van Rossum57d51f22000-09-16 21:16:01 +0000902 if not keys:
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000903 print("<P>No form fields.")
904 print("<DL>")
Guido van Rossum7aee3841996-03-07 18:00:44 +0000905 for key in keys:
Georg Brandl1f7fffb2010-10-15 15:57:45 +0000906 print("<DT>" + html.escape(key) + ":", end=' ')
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000907 value = form[key]
Georg Brandl1f7fffb2010-10-15 15:57:45 +0000908 print("<i>" + html.escape(repr(type(value))) + "</i>")
909 print("<DD>" + html.escape(repr(value)))
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000910 print("</DL>")
911 print()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000912
913def print_directory():
914 """Dump the current directory as HTML."""
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000915 print()
916 print("<H3>Current Working Directory:</H3>")
Guido van Rossum7aee3841996-03-07 18:00:44 +0000917 try:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000918 pwd = os.getcwd()
Andrew Svetlovad28c7f2012-12-18 22:02:39 +0200919 except OSError as msg:
Andrew Svetlov8b33dd82012-12-24 19:58:48 +0200920 print("OSError:", html.escape(str(msg)))
Guido van Rossum7aee3841996-03-07 18:00:44 +0000921 else:
Georg Brandl1f7fffb2010-10-15 15:57:45 +0000922 print(html.escape(pwd))
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000923 print()
Guido van Rossum9a22de11995-01-12 12:29:47 +0000924
Guido van Rossuma8738a51996-03-14 21:30:28 +0000925def print_arguments():
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000926 print()
927 print("<H3>Command Line Arguments:</H3>")
928 print()
929 print(sys.argv)
930 print()
Guido van Rossuma8738a51996-03-14 21:30:28 +0000931
Guido van Rossum9a22de11995-01-12 12:29:47 +0000932def print_environ_usage():
Guido van Rossum7aee3841996-03-07 18:00:44 +0000933 """Dump a list of environment variables used by CGI as HTML."""
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000934 print("""
Guido van Rossum72755611996-03-06 07:20:06 +0000935<H3>These environment variables could have been set:</H3>
936<UL>
Guido van Rossum9a22de11995-01-12 12:29:47 +0000937<LI>AUTH_TYPE
938<LI>CONTENT_LENGTH
939<LI>CONTENT_TYPE
940<LI>DATE_GMT
941<LI>DATE_LOCAL
942<LI>DOCUMENT_NAME
943<LI>DOCUMENT_ROOT
944<LI>DOCUMENT_URI
945<LI>GATEWAY_INTERFACE
946<LI>LAST_MODIFIED
947<LI>PATH
948<LI>PATH_INFO
949<LI>PATH_TRANSLATED
950<LI>QUERY_STRING
951<LI>REMOTE_ADDR
952<LI>REMOTE_HOST
953<LI>REMOTE_IDENT
954<LI>REMOTE_USER
955<LI>REQUEST_METHOD
956<LI>SCRIPT_NAME
957<LI>SERVER_NAME
958<LI>SERVER_PORT
959<LI>SERVER_PROTOCOL
960<LI>SERVER_ROOT
961<LI>SERVER_SOFTWARE
962</UL>
Guido van Rossum7aee3841996-03-07 18:00:44 +0000963In addition, HTTP headers sent by the server may be passed in the
964environment as well. Here are some common variable names:
965<UL>
966<LI>HTTP_ACCEPT
967<LI>HTTP_CONNECTION
968<LI>HTTP_HOST
969<LI>HTTP_PRAGMA
970<LI>HTTP_REFERER
971<LI>HTTP_USER_AGENT
972</UL>
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000973""")
Guido van Rossum9a22de11995-01-12 12:29:47 +0000974
Guido van Rossum9a22de11995-01-12 12:29:47 +0000975
Guido van Rossum72755611996-03-06 07:20:06 +0000976# Utilities
977# =========
Guido van Rossum9a22de11995-01-12 12:29:47 +0000978
Benjamin Peterson4d59a782014-04-03 10:22:10 -0400979def valid_boundary(s):
Guido van Rossum2e441f72001-07-25 21:00:19 +0000980 import re
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000981 if isinstance(s, bytes):
982 _vb_pattern = b"^[ -~]{0,200}[!-~]$"
983 else:
984 _vb_pattern = "^[ -~]{0,200}[!-~]$"
Guido van Rossum2e441f72001-07-25 21:00:19 +0000985 return re.match(_vb_pattern, s)
Guido van Rossum9a22de11995-01-12 12:29:47 +0000986
Guido van Rossum72755611996-03-06 07:20:06 +0000987# Invoke mainline
988# ===============
989
990# Call test() when this file is run as a script (not imported as a module)
Tim Peters88869f92001-01-14 23:36:06 +0000991if __name__ == '__main__':
Guido van Rossum7aee3841996-03-07 18:00:44 +0000992 test()