blob: 6018c3608697af7264011cdc32ea44fa1c60f297 [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 """
Mike Leic143cc32020-12-17 01:34:19 +0000197 # RFC 2046, Section 5.1 : The "multipart" boundary delimiters are always
Pierre Quentelcc3fa202017-05-08 14:08:34 +0200198 # 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)
rogerd8cf3512020-06-15 16:58:54 +0200203 try:
204 headers['Content-Length'] = pdict['CONTENT-LENGTH']
205 except KeyError:
206 pass
Amber Brown545c9552018-05-14 18:11:55 -0400207 fs = FieldStorage(fp, headers=headers, encoding=encoding, errors=errors,
Pierre Quentelcc3fa202017-05-08 14:08:34 +0200208 environ={'REQUEST_METHOD': 'POST'})
209 return {k: fs.getlist(k) for k in fs}
Guido van Rossum9a22de11995-01-12 12:29:47 +0000210
Fred Drake9a0a65b2008-12-04 19:24:50 +0000211def _parseparam(s):
212 while s[:1] == ';':
213 s = s[1:]
214 end = s.find(';')
Senthil Kumaran1ef0c032011-10-20 01:05:44 +0800215 while end > 0 and (s.count('"', 0, end) - s.count('\\"', 0, end)) % 2:
Fred Drake9a0a65b2008-12-04 19:24:50 +0000216 end = s.find(';', end + 1)
217 if end < 0:
218 end = len(s)
219 f = s[:end]
220 yield f.strip()
221 s = s[end:]
222
Guido van Rossum72755611996-03-06 07:20:06 +0000223def parse_header(line):
Guido van Rossum7aee3841996-03-07 18:00:44 +0000224 """Parse a Content-type like header.
225
226 Return the main content-type and a dictionary of options.
227
228 """
Fred Drake9a0a65b2008-12-04 19:24:50 +0000229 parts = _parseparam(';' + line)
230 key = parts.__next__()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000231 pdict = {}
Fred Drake9a0a65b2008-12-04 19:24:50 +0000232 for p in parts:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000233 i = p.find('=')
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000234 if i >= 0:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000235 name = p[:i].strip().lower()
236 value = p[i+1:].strip()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000237 if len(value) >= 2 and value[0] == value[-1] == '"':
238 value = value[1:-1]
Johannes Gijsbers9e15dd62004-08-14 15:39:34 +0000239 value = value.replace('\\\\', '\\').replace('\\"', '"')
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000240 pdict[name] = value
Guido van Rossum7aee3841996-03-07 18:00:44 +0000241 return key, pdict
Guido van Rossum72755611996-03-06 07:20:06 +0000242
243
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000244# Classes for field storage
245# =========================
246
247class MiniFieldStorage:
248
Guido van Rossum0147db01996-03-09 03:16:04 +0000249 """Like FieldStorage, for use when no file uploads are possible."""
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000250
Guido van Rossum7aee3841996-03-07 18:00:44 +0000251 # Dummy attributes
252 filename = None
253 list = None
254 type = None
Guido van Rossum773ab271996-07-23 03:46:24 +0000255 file = None
Guido van Rossum4032c2c1996-03-09 04:04:35 +0000256 type_options = {}
Guido van Rossum7aee3841996-03-07 18:00:44 +0000257 disposition = None
258 disposition_options = {}
259 headers = {}
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000260
Guido van Rossum7aee3841996-03-07 18:00:44 +0000261 def __init__(self, name, value):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000262 """Constructor from field name and value."""
263 self.name = name
264 self.value = value
Guido van Rossum773ab271996-07-23 03:46:24 +0000265 # self.file = StringIO(value)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000266
267 def __repr__(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000268 """Return printable representation."""
Walter Dörwald70a6b492004-02-12 17:35:32 +0000269 return "MiniFieldStorage(%r, %r)" % (self.name, self.value)
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000270
271
272class FieldStorage:
273
Guido van Rossum7aee3841996-03-07 18:00:44 +0000274 """Store a sequence of fields, reading multipart/form-data.
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000275
Guido van Rossum7aee3841996-03-07 18:00:44 +0000276 This class provides naming, typing, files stored on disk, and
277 more. At the top level, it is accessible like a dictionary, whose
278 keys are the field names. (Note: None can occur as a field name.)
279 The items are either a Python list (if there's multiple values) or
280 another FieldStorage or MiniFieldStorage object. If it's a single
281 object, it has the following attributes:
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000282
Guido van Rossum7aee3841996-03-07 18:00:44 +0000283 name: the field name, if specified; otherwise None
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000284
Guido van Rossum7aee3841996-03-07 18:00:44 +0000285 filename: the filename, if specified; otherwise None; this is the
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000286 client side filename, *not* the file name on which it is
287 stored (that's a temporary file you don't deal with)
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000288
Guido van Rossum7aee3841996-03-07 18:00:44 +0000289 value: the value as a *string*; for file uploads, this
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000290 transparently reads the file every time you request the value
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000291 and returns *bytes*
Guido van Rossum7aee3841996-03-07 18:00:44 +0000292
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000293 file: the file(-like) object from which you can read the data *as
294 bytes* ; None if the data is stored a simple string
Guido van Rossum7aee3841996-03-07 18:00:44 +0000295
296 type: the content-type, or None if not specified
297
298 type_options: dictionary of options specified on the content-type
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000299 line
Guido van Rossum7aee3841996-03-07 18:00:44 +0000300
301 disposition: content-disposition, or None if not specified
302
303 disposition_options: dictionary of corresponding options
304
Barry Warsaw596097e2008-06-12 02:38:51 +0000305 headers: a dictionary(-like) object (sometimes email.message.Message or a
Armin Rigo3a703b62005-09-19 09:11:04 +0000306 subclass thereof) containing *all* headers
Guido van Rossum7aee3841996-03-07 18:00:44 +0000307
308 The class is subclassable, mostly for the purpose of overriding
309 the make_file() method, which is called internally to come up with
310 a file open for reading and writing. This makes it possible to
311 override the default choice of storing all files in a temporary
312 directory and unlinking them as soon as they have been opened.
313
314 """
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000315 def __init__(self, fp=None, headers=None, outerboundary=b'',
316 environ=os.environ, keep_blank_values=0, strict_parsing=0,
matthewbelisle-wf20914482018-10-19 05:52:59 -0500317 limit=None, encoding='utf-8', errors='replace',
318 max_num_fields=None):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000319 """Constructor. Read multipart/* until last part.
Guido van Rossum7aee3841996-03-07 18:00:44 +0000320
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000321 Arguments, all optional:
Guido van Rossum7aee3841996-03-07 18:00:44 +0000322
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000323 fp : file pointer; default: sys.stdin.buffer
Guido van Rossumb1b4f941998-05-08 19:55:51 +0000324 (not used when the request method is GET)
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000325 Can be :
326 1. a TextIOWrapper object
327 2. an object whose read() and readline() methods return bytes
Guido van Rossum7aee3841996-03-07 18:00:44 +0000328
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000329 headers : header dictionary-like object; default:
330 taken from environ as per CGI spec
Guido van Rossum7aee3841996-03-07 18:00:44 +0000331
Guido van Rossum773ab271996-07-23 03:46:24 +0000332 outerboundary : terminating multipart boundary
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000333 (for internal use only)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000334
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000335 environ : environment dictionary; default: os.environ
Guido van Rossum773ab271996-07-23 03:46:24 +0000336
337 keep_blank_values: flag indicating whether blank values in
Senthil Kumaran30e86a42010-08-09 20:01:35 +0000338 percent-encoded forms should be treated as blank strings.
Tim Peters88869f92001-01-14 23:36:06 +0000339 A true value indicates that blanks should be retained as
Guido van Rossum773ab271996-07-23 03:46:24 +0000340 blank strings. The default false value indicates that
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000341 blank values are to be ignored and treated as if they were
342 not included.
Guido van Rossum773ab271996-07-23 03:46:24 +0000343
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000344 strict_parsing: flag indicating what to do with parsing errors.
345 If false (the default), errors are silently ignored.
346 If true, errors raise a ValueError exception.
Guido van Rossume08c04c1996-11-11 19:29:11 +0000347
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000348 limit : used internally to read parts of multipart/form-data forms,
349 to exit from the reading loop when reached. It is the difference
350 between the form content-length and the number of bytes already
351 read
352
353 encoding, errors : the encoding and error handler used to decode the
354 binary stream to strings. Must be the same as the charset defined
355 for the page sending the form (content-type : meta http-equiv or
356 header)
357
matthewbelisle-wf20914482018-10-19 05:52:59 -0500358 max_num_fields: int. If set, then __init__ throws a ValueError
359 if there are more than n fields read by parse_qsl().
360
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000361 """
362 method = 'GET'
363 self.keep_blank_values = keep_blank_values
364 self.strict_parsing = strict_parsing
matthewbelisle-wf20914482018-10-19 05:52:59 -0500365 self.max_num_fields = max_num_fields
Raymond Hettinger54f02222002-06-01 14:18:47 +0000366 if 'REQUEST_METHOD' in environ:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000367 method = environ['REQUEST_METHOD'].upper()
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000368 self.qs_on_post = None
Guido van Rossum01852831998-06-25 02:40:17 +0000369 if method == 'GET' or method == 'HEAD':
Raymond Hettinger54f02222002-06-01 14:18:47 +0000370 if 'QUERY_STRING' in environ:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000371 qs = environ['QUERY_STRING']
372 elif sys.argv[1:]:
373 qs = sys.argv[1]
374 else:
375 qs = ""
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000376 qs = qs.encode(locale.getpreferredencoding(), 'surrogateescape')
377 fp = BytesIO(qs)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000378 if headers is None:
379 headers = {'content-type':
380 "application/x-www-form-urlencoded"}
381 if headers is None:
Guido van Rossumcff311a1998-06-11 14:06:59 +0000382 headers = {}
383 if method == 'POST':
384 # Set default content-type for POST to what's traditional
385 headers['content-type'] = "application/x-www-form-urlencoded"
Raymond Hettinger54f02222002-06-01 14:18:47 +0000386 if 'CONTENT_TYPE' in environ:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000387 headers['content-type'] = environ['CONTENT_TYPE']
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000388 if 'QUERY_STRING' in environ:
389 self.qs_on_post = environ['QUERY_STRING']
Raymond Hettinger54f02222002-06-01 14:18:47 +0000390 if 'CONTENT_LENGTH' in environ:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000391 headers['content-length'] = environ['CONTENT_LENGTH']
Senthil Kumaranb4cbb922014-01-11 22:20:16 -0800392 else:
393 if not (isinstance(headers, (Mapping, Message))):
394 raise TypeError("headers must be mapping or an instance of "
395 "email.message.Message")
396 self.headers = headers
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000397 if fp is None:
398 self.fp = sys.stdin.buffer
399 # self.fp.read() must return bytes
400 elif isinstance(fp, TextIOWrapper):
401 self.fp = fp.buffer
402 else:
Senthil Kumaranb4cbb922014-01-11 22:20:16 -0800403 if not (hasattr(fp, 'read') and hasattr(fp, 'readline')):
404 raise TypeError("fp must be file pointer")
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000405 self.fp = fp
406
407 self.encoding = encoding
408 self.errors = errors
409
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000410 if not isinstance(outerboundary, bytes):
411 raise TypeError('outerboundary must be bytes, not %s'
412 % type(outerboundary).__name__)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000413 self.outerboundary = outerboundary
Guido van Rossum7aee3841996-03-07 18:00:44 +0000414
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000415 self.bytes_read = 0
416 self.limit = limit
417
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000418 # Process content-disposition header
419 cdisp, pdict = "", {}
Raymond Hettinger54f02222002-06-01 14:18:47 +0000420 if 'content-disposition' in self.headers:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000421 cdisp, pdict = parse_header(self.headers['content-disposition'])
422 self.disposition = cdisp
423 self.disposition_options = pdict
424 self.name = None
Raymond Hettinger54f02222002-06-01 14:18:47 +0000425 if 'name' in pdict:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000426 self.name = pdict['name']
427 self.filename = None
Raymond Hettinger54f02222002-06-01 14:18:47 +0000428 if 'filename' in pdict:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000429 self.filename = pdict['filename']
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000430 self._binary_file = self.filename is not None
Guido van Rossum7aee3841996-03-07 18:00:44 +0000431
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000432 # Process content-type header
Barry Warsaw302331a1999-01-08 17:42:03 +0000433 #
434 # Honor any existing content-type header. But if there is no
435 # content-type header, use some sensible defaults. Assume
436 # outerboundary is "" at the outer level, but something non-false
437 # inside a multi-part. The default for an inner part is text/plain,
438 # but for an outer part it should be urlencoded. This should catch
439 # bogus clients which erroneously forget to include a content-type
440 # header.
441 #
442 # See below for what we do if there does exist a content-type header,
443 # but it happens to be something we don't understand.
Raymond Hettinger54f02222002-06-01 14:18:47 +0000444 if 'content-type' in self.headers:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000445 ctype, pdict = parse_header(self.headers['content-type'])
Guido van Rossumce900de1999-06-02 18:44:22 +0000446 elif self.outerboundary or method != 'POST':
Barry Warsaw302331a1999-01-08 17:42:03 +0000447 ctype, pdict = "text/plain", {}
448 else:
449 ctype, pdict = 'application/x-www-form-urlencoded', {}
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000450 self.type = ctype
451 self.type_options = pdict
Raymond Hettinger54f02222002-06-01 14:18:47 +0000452 if 'boundary' in pdict:
Amber Brown545c9552018-05-14 18:11:55 -0400453 self.innerboundary = pdict['boundary'].encode(self.encoding,
454 self.errors)
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000455 else:
456 self.innerboundary = b""
457
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000458 clen = -1
Raymond Hettinger54f02222002-06-01 14:18:47 +0000459 if 'content-length' in self.headers:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000460 try:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000461 clen = int(self.headers['content-length'])
Skip Montanarodb5d1442002-03-23 05:50:17 +0000462 except ValueError:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000463 pass
464 if maxlen and clen > maxlen:
Collin Winterce36ad82007-08-30 01:19:48 +0000465 raise ValueError('Maximum content length exceeded')
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000466 self.length = clen
Pierre Quentel2d7caca2019-09-11 13:05:53 +0200467 if self.limit is None and clen >= 0:
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000468 self.limit = clen
Guido van Rossum7aee3841996-03-07 18:00:44 +0000469
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000470 self.list = self.file = None
471 self.done = 0
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000472 if ctype == 'application/x-www-form-urlencoded':
473 self.read_urlencoded()
474 elif ctype[:10] == 'multipart/':
Guido van Rossumf5745001998-10-20 14:43:02 +0000475 self.read_multi(environ, keep_blank_values, strict_parsing)
Barry Warsaw302331a1999-01-08 17:42:03 +0000476 else:
Guido van Rossum60a3bd81999-06-11 18:26:09 +0000477 self.read_single()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000478
Brett Cannonf79126f2013-08-23 15:15:48 -0400479 def __del__(self):
480 try:
481 self.file.close()
482 except AttributeError:
483 pass
484
Berker Peksagbf5e9602015-02-06 10:21:37 +0200485 def __enter__(self):
486 return self
487
488 def __exit__(self, *args):
489 self.file.close()
490
Guido van Rossum7aee3841996-03-07 18:00:44 +0000491 def __repr__(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000492 """Return a printable representation."""
Walter Dörwald70a6b492004-02-12 17:35:32 +0000493 return "FieldStorage(%r, %r, %r)" % (
494 self.name, self.filename, self.value)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000495
Guido van Rossum4061cbe2002-09-11 18:20:34 +0000496 def __iter__(self):
497 return iter(self.keys())
498
Guido van Rossum7aee3841996-03-07 18:00:44 +0000499 def __getattr__(self, name):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000500 if name != 'value':
Collin Winterce36ad82007-08-30 01:19:48 +0000501 raise AttributeError(name)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000502 if self.file:
503 self.file.seek(0)
504 value = self.file.read()
505 self.file.seek(0)
506 elif self.list is not None:
507 value = self.list
508 else:
509 value = None
510 return value
Guido van Rossum7aee3841996-03-07 18:00:44 +0000511
512 def __getitem__(self, key):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000513 """Dictionary style indexing."""
514 if self.list is None:
Collin Winterce36ad82007-08-30 01:19:48 +0000515 raise TypeError("not indexable")
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000516 found = []
517 for item in self.list:
518 if item.name == key: found.append(item)
519 if not found:
Collin Winterce36ad82007-08-30 01:19:48 +0000520 raise KeyError(key)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000521 if len(found) == 1:
522 return found[0]
523 else:
524 return found
Guido van Rossum7aee3841996-03-07 18:00:44 +0000525
Moshe Zadkaa1a4b592000-08-25 21:47:56 +0000526 def getvalue(self, key, default=None):
527 """Dictionary style get() method, including 'value' lookup."""
Raymond Hettinger54f02222002-06-01 14:18:47 +0000528 if key in self:
Moshe Zadkaa1a4b592000-08-25 21:47:56 +0000529 value = self[key]
Victor Stinnerf1c7ca92011-01-14 13:08:27 +0000530 if isinstance(value, list):
Guido van Rossumc1f779c2007-07-03 08:25:58 +0000531 return [x.value for x in value]
Moshe Zadkaa1a4b592000-08-25 21:47:56 +0000532 else:
533 return value.value
534 else:
535 return default
536
Guido van Rossum1bfb3882001-09-05 19:45:34 +0000537 def getfirst(self, key, default=None):
538 """ Return the first value received."""
Raymond Hettinger54f02222002-06-01 14:18:47 +0000539 if key in self:
Guido van Rossum1bfb3882001-09-05 19:45:34 +0000540 value = self[key]
Victor Stinnerf1c7ca92011-01-14 13:08:27 +0000541 if isinstance(value, list):
Guido van Rossum1bfb3882001-09-05 19:45:34 +0000542 return value[0].value
543 else:
544 return value.value
545 else:
546 return default
547
548 def getlist(self, key):
549 """ Return list of received values."""
Raymond Hettinger54f02222002-06-01 14:18:47 +0000550 if key in self:
Guido van Rossum1bfb3882001-09-05 19:45:34 +0000551 value = self[key]
Victor Stinnerf1c7ca92011-01-14 13:08:27 +0000552 if isinstance(value, list):
Guido van Rossumc1f779c2007-07-03 08:25:58 +0000553 return [x.value for x in value]
Guido van Rossum1bfb3882001-09-05 19:45:34 +0000554 else:
555 return [value.value]
556 else:
557 return []
558
Guido van Rossum7aee3841996-03-07 18:00:44 +0000559 def keys(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000560 """Dictionary style keys() method."""
561 if self.list is None:
Collin Winterce36ad82007-08-30 01:19:48 +0000562 raise TypeError("not indexable")
Thomas Wouters8ce81f72007-09-20 18:22:40 +0000563 return list(set(item.name for item in self.list))
Guido van Rossum7aee3841996-03-07 18:00:44 +0000564
Raymond Hettinger54f02222002-06-01 14:18:47 +0000565 def __contains__(self, key):
566 """Dictionary style __contains__ method."""
567 if self.list is None:
Collin Winterce36ad82007-08-30 01:19:48 +0000568 raise TypeError("not indexable")
Thomas Wouters8ce81f72007-09-20 18:22:40 +0000569 return any(item.name == key for item in self.list)
Raymond Hettinger54f02222002-06-01 14:18:47 +0000570
Guido van Rossum88b85d41997-01-11 19:21:33 +0000571 def __len__(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000572 """Dictionary style len(x) support."""
573 return len(self.keys())
Guido van Rossum88b85d41997-01-11 19:21:33 +0000574
Senthil Kumaranb4cbb922014-01-11 22:20:16 -0800575 def __bool__(self):
576 if self.list is None:
577 raise TypeError("Cannot be converted to bool.")
Thomas Wouters8ce81f72007-09-20 18:22:40 +0000578 return bool(self.list)
579
Guido van Rossum7aee3841996-03-07 18:00:44 +0000580 def read_urlencoded(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000581 """Internal: read data in query string format."""
582 qs = self.fp.read(self.length)
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000583 if not isinstance(qs, bytes):
584 raise ValueError("%s should return bytes, got %s" \
585 % (self.fp, type(qs).__name__))
586 qs = qs.decode(self.encoding, self.errors)
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000587 if self.qs_on_post:
588 qs += '&' + self.qs_on_post
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000589 query = urllib.parse.parse_qsl(
590 qs, self.keep_blank_values, self.strict_parsing,
matthewbelisle-wf20914482018-10-19 05:52:59 -0500591 encoding=self.encoding, errors=self.errors,
592 max_num_fields=self.max_num_fields)
593 self.list = [MiniFieldStorage(key, value) for key, value in query]
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000594 self.skip_lines()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000595
Guido van Rossum030d2ec1998-12-09 22:16:46 +0000596 FieldStorageClass = None
597
Guido van Rossumf5745001998-10-20 14:43:02 +0000598 def read_multi(self, environ, keep_blank_values, strict_parsing):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000599 """Internal: read a part that is itself multipart."""
Guido van Rossum2e441f72001-07-25 21:00:19 +0000600 ib = self.innerboundary
601 if not valid_boundary(ib):
Collin Winterce36ad82007-08-30 01:19:48 +0000602 raise ValueError('Invalid boundary in multipart form: %r' % (ib,))
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000603 self.list = []
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000604 if self.qs_on_post:
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000605 query = urllib.parse.parse_qsl(
606 self.qs_on_post, self.keep_blank_values, self.strict_parsing,
matthewbelisle-wf20914482018-10-19 05:52:59 -0500607 encoding=self.encoding, errors=self.errors,
608 max_num_fields=self.max_num_fields)
609 self.list.extend(MiniFieldStorage(key, value) for key, value in query)
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000610
Guido van Rossum030d2ec1998-12-09 22:16:46 +0000611 klass = self.FieldStorageClass or self.__class__
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000612 first_line = self.fp.readline() # bytes
613 if not isinstance(first_line, bytes):
614 raise ValueError("%s should return bytes, got %s" \
615 % (self.fp, type(first_line).__name__))
616 self.bytes_read += len(first_line)
Donald Stufftd90f8d12015-03-29 16:43:23 -0400617
618 # Ensure that we consume the file until we've hit our inner boundary
619 while (first_line.strip() != (b"--" + self.innerboundary) and
620 first_line):
621 first_line = self.fp.readline()
622 self.bytes_read += len(first_line)
623
matthewbelisle-wfb79b5c02018-10-23 03:14:35 -0500624 # Propagate max_num_fields into the sub class appropriately
625 max_num_fields = self.max_num_fields
626 if max_num_fields is not None:
627 max_num_fields -= len(self.list)
628
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000629 while True:
630 parser = FeedParser()
631 hdr_text = b""
632 while True:
633 data = self.fp.readline()
634 hdr_text += data
635 if not data.strip():
636 break
637 if not hdr_text:
638 break
639 # parser takes strings, not bytes
640 self.bytes_read += len(hdr_text)
641 parser.feed(hdr_text.decode(self.encoding, self.errors))
642 headers = parser.close()
Victor Stinner65794592015-08-18 10:21:10 -0700643
644 # Some clients add Content-Length for part headers, ignore them
645 if 'content-length' in headers:
646 del headers['content-length']
647
Pierre Quentel2d7caca2019-09-11 13:05:53 +0200648 limit = None if self.limit is None \
649 else self.limit - self.bytes_read
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000650 part = klass(self.fp, headers, ib, environ, keep_blank_values,
Pierre Quentel2d7caca2019-09-11 13:05:53 +0200651 strict_parsing, limit,
matthewbelisle-wfb79b5c02018-10-23 03:14:35 -0500652 self.encoding, self.errors, max_num_fields)
matthewbelisle-wf20914482018-10-19 05:52:59 -0500653
matthewbelisle-wfb79b5c02018-10-23 03:14:35 -0500654 if max_num_fields is not None:
655 max_num_fields -= 1
656 if part.list:
657 max_num_fields -= len(part.list)
658 if max_num_fields < 0:
659 raise ValueError('Max number of fields exceeded')
matthewbelisle-wf20914482018-10-19 05:52:59 -0500660
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000661 self.bytes_read += part.bytes_read
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000662 self.list.append(part)
Florent Xicluna331c3fd2013-07-07 12:44:28 +0200663 if part.done or self.bytes_read >= self.length > 0:
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000664 break
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000665 self.skip_lines()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000666
667 def read_single(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000668 """Internal: read an atomic part."""
669 if self.length >= 0:
670 self.read_binary()
671 self.skip_lines()
672 else:
673 self.read_lines()
674 self.file.seek(0)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000675
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000676 bufsize = 8*1024 # I/O buffering size for copy to file
Guido van Rossum7aee3841996-03-07 18:00:44 +0000677
678 def read_binary(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000679 """Internal: read binary data."""
Guido van Rossuma1a68522007-08-28 03:11:34 +0000680 self.file = self.make_file()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000681 todo = self.length
682 if todo >= 0:
683 while todo > 0:
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000684 data = self.fp.read(min(todo, self.bufsize)) # bytes
685 if not isinstance(data, bytes):
686 raise ValueError("%s should return bytes, got %s"
687 % (self.fp, type(data).__name__))
688 self.bytes_read += len(data)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000689 if not data:
690 self.done = -1
691 break
692 self.file.write(data)
693 todo = todo - len(data)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000694
695 def read_lines(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000696 """Internal: read lines until EOF or outerboundary."""
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000697 if self._binary_file:
698 self.file = self.__file = BytesIO() # store data as bytes for files
699 else:
700 self.file = self.__file = StringIO() # as strings for other fields
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000701 if self.outerboundary:
702 self.read_lines_to_outerboundary()
703 else:
704 self.read_lines_to_eof()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000705
Guido van Rossum52b8c292001-06-29 13:06:06 +0000706 def __write(self, line):
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000707 """line is always bytes, not string"""
Guido van Rossum52b8c292001-06-29 13:06:06 +0000708 if self.__file is not None:
709 if self.__file.tell() + len(line) > 1000:
Guido van Rossuma1a68522007-08-28 03:11:34 +0000710 self.file = self.make_file()
711 data = self.__file.getvalue()
712 self.file.write(data)
Guido van Rossum52b8c292001-06-29 13:06:06 +0000713 self.__file = None
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000714 if self._binary_file:
715 # keep bytes
716 self.file.write(line)
717 else:
718 # decode to string
719 self.file.write(line.decode(self.encoding, self.errors))
Guido van Rossum52b8c292001-06-29 13:06:06 +0000720
Guido van Rossum7aee3841996-03-07 18:00:44 +0000721 def read_lines_to_eof(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000722 """Internal: read lines until EOF."""
723 while 1:
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000724 line = self.fp.readline(1<<16) # bytes
725 self.bytes_read += len(line)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000726 if not line:
727 self.done = -1
728 break
Guido van Rossum52b8c292001-06-29 13:06:06 +0000729 self.__write(line)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000730
731 def read_lines_to_outerboundary(self):
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000732 """Internal: read lines until outerboundary.
733 Data is read as bytes: boundaries and line ends must be converted
734 to bytes for comparisons.
735 """
736 next_boundary = b"--" + self.outerboundary
737 last_boundary = next_boundary + b"--"
738 delim = b""
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000739 last_line_lfend = True
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000740 _read = 0
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000741 while 1:
rogerd8cf3512020-06-15 16:58:54 +0200742
743 if self.limit is not None and 0 <= self.limit <= _read:
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000744 break
745 line = self.fp.readline(1<<16) # bytes
746 self.bytes_read += len(line)
747 _read += len(line)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000748 if not line:
749 self.done = -1
750 break
Serhiy Storchakac7bfe0e2013-06-17 16:34:41 +0300751 if delim == b"\r":
752 line = delim + line
753 delim = b""
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000754 if line.startswith(b"--") and last_line_lfend:
755 strippedline = line.rstrip()
756 if strippedline == next_boundary:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000757 break
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000758 if strippedline == last_boundary:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000759 self.done = 1
760 break
761 odelim = delim
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000762 if line.endswith(b"\r\n"):
763 delim = b"\r\n"
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000764 line = line[:-2]
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000765 last_line_lfend = True
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000766 elif line.endswith(b"\n"):
767 delim = b"\n"
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000768 line = line[:-1]
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000769 last_line_lfend = True
Serhiy Storchakac7bfe0e2013-06-17 16:34:41 +0300770 elif line.endswith(b"\r"):
771 # We may interrupt \r\n sequences if they span the 2**16
772 # byte boundary
773 delim = b"\r"
774 line = line[:-1]
775 last_line_lfend = False
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000776 else:
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000777 delim = b""
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000778 last_line_lfend = False
Guido van Rossum52b8c292001-06-29 13:06:06 +0000779 self.__write(odelim + line)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000780
781 def skip_lines(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000782 """Internal: skip lines until outer boundary if defined."""
783 if not self.outerboundary or self.done:
784 return
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000785 next_boundary = b"--" + self.outerboundary
786 last_boundary = next_boundary + b"--"
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000787 last_line_lfend = True
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000788 while True:
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000789 line = self.fp.readline(1<<16)
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000790 self.bytes_read += len(line)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000791 if not line:
792 self.done = -1
793 break
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000794 if line.endswith(b"--") and last_line_lfend:
Eric S. Raymond7e9b4f52001-02-09 09:59:10 +0000795 strippedline = line.strip()
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000796 if strippedline == next_boundary:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000797 break
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000798 if strippedline == last_boundary:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000799 self.done = 1
800 break
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000801 last_line_lfend = line.endswith(b'\n')
Guido van Rossum7aee3841996-03-07 18:00:44 +0000802
Guido van Rossuma1a68522007-08-28 03:11:34 +0000803 def make_file(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000804 """Overridable: return a readable & writable file.
Guido van Rossum7aee3841996-03-07 18:00:44 +0000805
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000806 The file will be used as follows:
807 - data is written to it
808 - seek(0)
809 - data is read from it
Guido van Rossum7aee3841996-03-07 18:00:44 +0000810
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000811 The file is opened in binary mode for files, in text mode
812 for other fields
Guido van Rossum7aee3841996-03-07 18:00:44 +0000813
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000814 This version opens a temporary file for reading and writing,
815 and immediately deletes (unlinks) it. The trick (on Unix!) is
816 that the file can still be used, but it can't be opened by
817 another process, and it will automatically be deleted when it
818 is closed or when the current process terminates.
Guido van Rossum4032c2c1996-03-09 04:04:35 +0000819
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000820 If you want a more permanent file, you derive a class which
821 overrides this method. If you want a visible temporary file
822 that is nevertheless automatically deleted when the script
823 terminates, try defining a __del__ method in a derived class
824 which unlinks the temporary files you have created.
Guido van Rossum7aee3841996-03-07 18:00:44 +0000825
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000826 """
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000827 if self._binary_file:
828 return tempfile.TemporaryFile("wb+")
829 else:
830 return tempfile.TemporaryFile("w+",
831 encoding=self.encoding, newline = '\n')
Tim Peters88869f92001-01-14 23:36:06 +0000832
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000833
Guido van Rossum72755611996-03-06 07:20:06 +0000834# Test/debug code
835# ===============
Guido van Rossum9a22de11995-01-12 12:29:47 +0000836
Guido van Rossum773ab271996-07-23 03:46:24 +0000837def test(environ=os.environ):
Guido van Rossum7aee3841996-03-07 18:00:44 +0000838 """Robust test CGI script, usable as main program.
Guido van Rossum9a22de11995-01-12 12:29:47 +0000839
Guido van Rossum7aee3841996-03-07 18:00:44 +0000840 Write minimal HTTP headers and dump all information provided to
841 the script in HTML form.
842
843 """
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000844 print("Content-type: text/html")
845 print()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000846 sys.stderr = sys.stdout
847 try:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000848 form = FieldStorage() # Replace with other classes to test those
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000849 print_directory()
850 print_arguments()
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000851 print_form(form)
852 print_environ(environ)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000853 print_environ_usage()
854 def f():
Georg Brandl7cae87c2006-09-06 06:51:57 +0000855 exec("testing print_exception() -- <I>italics?</I>")
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000856 def g(f=f):
857 f()
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000858 print("<H3>What follows is a test, not an actual exception:</H3>")
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000859 g()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000860 except:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000861 print_exception()
Guido van Rossumf85de8a1996-08-20 20:22:39 +0000862
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000863 print("<H1>Second try with a small maxlen...</H1>")
Guido van Rossum57d51f22000-09-16 21:16:01 +0000864
Guido van Rossumad164711997-05-13 19:03:23 +0000865 global maxlen
866 maxlen = 50
867 try:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000868 form = FieldStorage() # Replace with other classes to test those
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000869 print_directory()
870 print_arguments()
Guido van Rossuma3c6a8a2000-09-19 04:11:46 +0000871 print_form(form)
872 print_environ(environ)
Guido van Rossumad164711997-05-13 19:03:23 +0000873 except:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000874 print_exception()
Guido van Rossumad164711997-05-13 19:03:23 +0000875
Guido van Rossumf85de8a1996-08-20 20:22:39 +0000876def print_exception(type=None, value=None, tb=None, limit=None):
877 if type is None:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000878 type, value, tb = sys.exc_info()
Guido van Rossumf85de8a1996-08-20 20:22:39 +0000879 import traceback
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000880 print()
881 print("<H3>Traceback (most recent call last):</H3>")
Guido van Rossumf85de8a1996-08-20 20:22:39 +0000882 list = traceback.format_tb(tb, limit) + \
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000883 traceback.format_exception_only(type, value)
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000884 print("<PRE>%s<B>%s</B></PRE>" % (
Georg Brandl1f7fffb2010-10-15 15:57:45 +0000885 html.escape("".join(list[:-1])),
886 html.escape(list[-1]),
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000887 ))
Guido van Rossumf15d1591997-09-29 23:22:12 +0000888 del tb
Guido van Rossum9a22de11995-01-12 12:29:47 +0000889
Guido van Rossum773ab271996-07-23 03:46:24 +0000890def print_environ(environ=os.environ):
Guido van Rossum7aee3841996-03-07 18:00:44 +0000891 """Dump the shell environment as HTML."""
Guido van Rossuma1a68522007-08-28 03:11:34 +0000892 keys = sorted(environ.keys())
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000893 print()
894 print("<H3>Shell Environment:</H3>")
895 print("<DL>")
Guido van Rossum7aee3841996-03-07 18:00:44 +0000896 for key in keys:
Georg Brandl1f7fffb2010-10-15 15:57:45 +0000897 print("<DT>", html.escape(key), "<DD>", html.escape(environ[key]))
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000898 print("</DL>")
899 print()
Guido van Rossum72755611996-03-06 07:20:06 +0000900
901def print_form(form):
Guido van Rossum7aee3841996-03-07 18:00:44 +0000902 """Dump the contents of a form as HTML."""
Guido van Rossuma1a68522007-08-28 03:11:34 +0000903 keys = sorted(form.keys())
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000904 print()
905 print("<H3>Form Contents:</H3>")
Guido van Rossum57d51f22000-09-16 21:16:01 +0000906 if not keys:
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000907 print("<P>No form fields.")
908 print("<DL>")
Guido van Rossum7aee3841996-03-07 18:00:44 +0000909 for key in keys:
Georg Brandl1f7fffb2010-10-15 15:57:45 +0000910 print("<DT>" + html.escape(key) + ":", end=' ')
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000911 value = form[key]
Georg Brandl1f7fffb2010-10-15 15:57:45 +0000912 print("<i>" + html.escape(repr(type(value))) + "</i>")
913 print("<DD>" + html.escape(repr(value)))
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000914 print("</DL>")
915 print()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000916
917def print_directory():
918 """Dump the current directory as HTML."""
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000919 print()
920 print("<H3>Current Working Directory:</H3>")
Guido van Rossum7aee3841996-03-07 18:00:44 +0000921 try:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000922 pwd = os.getcwd()
Andrew Svetlovad28c7f2012-12-18 22:02:39 +0200923 except OSError as msg:
Andrew Svetlov8b33dd82012-12-24 19:58:48 +0200924 print("OSError:", html.escape(str(msg)))
Guido van Rossum7aee3841996-03-07 18:00:44 +0000925 else:
Georg Brandl1f7fffb2010-10-15 15:57:45 +0000926 print(html.escape(pwd))
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000927 print()
Guido van Rossum9a22de11995-01-12 12:29:47 +0000928
Guido van Rossuma8738a51996-03-14 21:30:28 +0000929def print_arguments():
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000930 print()
931 print("<H3>Command Line Arguments:</H3>")
932 print()
933 print(sys.argv)
934 print()
Guido van Rossuma8738a51996-03-14 21:30:28 +0000935
Guido van Rossum9a22de11995-01-12 12:29:47 +0000936def print_environ_usage():
Guido van Rossum7aee3841996-03-07 18:00:44 +0000937 """Dump a list of environment variables used by CGI as HTML."""
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000938 print("""
Guido van Rossum72755611996-03-06 07:20:06 +0000939<H3>These environment variables could have been set:</H3>
940<UL>
Guido van Rossum9a22de11995-01-12 12:29:47 +0000941<LI>AUTH_TYPE
942<LI>CONTENT_LENGTH
943<LI>CONTENT_TYPE
944<LI>DATE_GMT
945<LI>DATE_LOCAL
946<LI>DOCUMENT_NAME
947<LI>DOCUMENT_ROOT
948<LI>DOCUMENT_URI
949<LI>GATEWAY_INTERFACE
950<LI>LAST_MODIFIED
951<LI>PATH
952<LI>PATH_INFO
953<LI>PATH_TRANSLATED
954<LI>QUERY_STRING
955<LI>REMOTE_ADDR
956<LI>REMOTE_HOST
957<LI>REMOTE_IDENT
958<LI>REMOTE_USER
959<LI>REQUEST_METHOD
960<LI>SCRIPT_NAME
961<LI>SERVER_NAME
962<LI>SERVER_PORT
963<LI>SERVER_PROTOCOL
964<LI>SERVER_ROOT
965<LI>SERVER_SOFTWARE
966</UL>
Guido van Rossum7aee3841996-03-07 18:00:44 +0000967In addition, HTTP headers sent by the server may be passed in the
968environment as well. Here are some common variable names:
969<UL>
970<LI>HTTP_ACCEPT
971<LI>HTTP_CONNECTION
972<LI>HTTP_HOST
973<LI>HTTP_PRAGMA
974<LI>HTTP_REFERER
975<LI>HTTP_USER_AGENT
976</UL>
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000977""")
Guido van Rossum9a22de11995-01-12 12:29:47 +0000978
Guido van Rossum9a22de11995-01-12 12:29:47 +0000979
Guido van Rossum72755611996-03-06 07:20:06 +0000980# Utilities
981# =========
Guido van Rossum9a22de11995-01-12 12:29:47 +0000982
Benjamin Peterson4d59a782014-04-03 10:22:10 -0400983def valid_boundary(s):
Guido van Rossum2e441f72001-07-25 21:00:19 +0000984 import re
Victor Stinner5c23b8e2011-01-14 13:05:21 +0000985 if isinstance(s, bytes):
986 _vb_pattern = b"^[ -~]{0,200}[!-~]$"
987 else:
988 _vb_pattern = "^[ -~]{0,200}[!-~]$"
Guido van Rossum2e441f72001-07-25 21:00:19 +0000989 return re.match(_vb_pattern, s)
Guido van Rossum9a22de11995-01-12 12:29:47 +0000990
Guido van Rossum72755611996-03-06 07:20:06 +0000991# Invoke mainline
992# ===============
993
994# Call test() when this file is run as a script (not imported as a module)
Tim Peters88869f92001-01-14 23:36:06 +0000995if __name__ == '__main__':
Guido van Rossum7aee3841996-03-07 18:00:44 +0000996 test()