blob: b9c4f0d188edd6c301fccaebe94e6c811a73e02c [file] [log] [blame]
Guido van Rossum152f9d91997-02-18 16:55:33 +00001#! /usr/local/bin/python
Guido van Rossum1c9daa81995-09-18 21:52:37 +00002
Guido van Rossum72755611996-03-06 07:20:06 +00003"""Support module for CGI (Common Gateway Interface) scripts.
Guido van Rossum1c9daa81995-09-18 21:52:37 +00004
Guido van Rossum7aee3841996-03-07 18:00:44 +00005This module defines a number of utilities for use by CGI scripts
6written in Python.
Guido van Rossum9a22de11995-01-12 12:29:47 +00007
8
Guido van Rossum72755611996-03-06 07:20:06 +00009Introduction
10------------
11
Guido van Rossum391b4e61996-03-06 19:11:33 +000012A CGI script is invoked by an HTTP server, usually to process user
13input submitted through an HTML <FORM> or <ISINPUT> element.
Guido van Rossum72755611996-03-06 07:20:06 +000014
Guido van Rossum391b4e61996-03-06 19:11:33 +000015Most often, CGI scripts live in the server's special cgi-bin
16directory. The HTTP server places all sorts of information about the
17request (such as the client's hostname, the requested URL, the query
18string, and lots of other goodies) in the script's shell environment,
19executes the script, and sends the script's output back to the client.
Guido van Rossum72755611996-03-06 07:20:06 +000020
Guido van Rossum391b4e61996-03-06 19:11:33 +000021The script's input is connected to the client too, and sometimes the
22form data is read this way; at other times the form data is passed via
23the "query string" part of the URL. This module (cgi.py) is intended
24to take care of the different cases and provide a simpler interface to
25the Python script. It also provides a number of utilities that help
26in debugging scripts, and the latest addition is support for file
27uploads from a form (if your browser supports it -- Grail 0.3 and
28Netscape 2.0 do).
Guido van Rossum72755611996-03-06 07:20:06 +000029
Guido van Rossum391b4e61996-03-06 19:11:33 +000030The output of a CGI script should consist of two sections, separated
31by a blank line. The first section contains a number of headers,
32telling the client what kind of data is following. Python code to
33generate a minimal header section looks like this:
Guido van Rossum72755611996-03-06 07:20:06 +000034
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000035 print "Content-type: text/html" # HTML is following
36 print # blank line, end of headers
Guido van Rossum72755611996-03-06 07:20:06 +000037
Guido van Rossum391b4e61996-03-06 19:11:33 +000038The second section is usually HTML, which allows the client software
39to display nicely formatted text with header, in-line images, etc.
40Here's Python code that prints a simple piece of HTML:
Guido van Rossum72755611996-03-06 07:20:06 +000041
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000042 print "<TITLE>CGI script output</TITLE>"
43 print "<H1>This is my first CGI script</H1>"
44 print "Hello, world!"
Guido van Rossum72755611996-03-06 07:20:06 +000045
Guido van Rossum43055421997-05-28 15:11:01 +000046It may not be fully legal HTML according to the letter of the
47standard, but any browser will understand it.
Guido van Rossum72755611996-03-06 07:20:06 +000048
49
50Using the cgi module
51--------------------
52
Guido van Rossum391b4e61996-03-06 19:11:33 +000053Begin by writing "import cgi". Don't use "from cgi import *" -- the
Guido van Rossum0147db01996-03-09 03:16:04 +000054module defines all sorts of names for its own use or for backward
55compatibility that you don't want in your namespace.
Guido van Rossum72755611996-03-06 07:20:06 +000056
Guido van Rossum0147db01996-03-09 03:16:04 +000057It's best to use the FieldStorage class. The other classes define in this
58module are provided mostly for backward compatibility. Instantiate it
59exactly once, without arguments. This reads the form contents from
60standard input or the environment (depending on the value of various
61environment variables set according to the CGI standard). Since it may
62consume standard input, it should be instantiated only once.
Guido van Rossum72755611996-03-06 07:20:06 +000063
Guido van Rossum0147db01996-03-09 03:16:04 +000064The FieldStorage instance can be accessed as if it were a Python
65dictionary. For instance, the following code (which assumes that the
66Content-type header and blank line have already been printed) checks that
67the fields "name" and "addr" are both set to a non-empty string:
Guido van Rossum72755611996-03-06 07:20:06 +000068
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000069 form = cgi.FieldStorage()
70 form_ok = 0
71 if form.has_key("name") and form.has_key("addr"):
72 if form["name"].value != "" and form["addr"].value != "":
73 form_ok = 1
74 if not form_ok:
75 print "<H1>Error</H1>"
76 print "Please fill in the name and addr fields."
77 return
78 ...further form processing here...
Guido van Rossum72755611996-03-06 07:20:06 +000079
Guido van Rossum4032c2c1996-03-09 04:04:35 +000080Here the fields, accessed through form[key], are themselves instances
81of FieldStorage (or MiniFieldStorage, depending on the form encoding).
Guido van Rossum72755611996-03-06 07:20:06 +000082
Guido van Rossum4032c2c1996-03-09 04:04:35 +000083If the submitted form data contains more than one field with the same
84name, the object retrieved by form[key] is not a (Mini)FieldStorage
Guido van Rossum43055421997-05-28 15:11:01 +000085instance but a list of such instances. If you are expecting this
86possibility (i.e., when your HTML form comtains multiple fields with
87the same name), use the type() function to determine whether you have
88a single instance or a list of instances. For example, here's code
89that concatenates any number of username fields, separated by commas:
Guido van Rossum4032c2c1996-03-09 04:04:35 +000090
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000091 username = form["username"]
92 if type(username) is type([]):
93 # Multiple username fields specified
94 usernames = ""
95 for item in username:
96 if usernames:
97 # Next item -- insert comma
98 usernames = usernames + "," + item.value
99 else:
100 # First item -- don't insert comma
101 usernames = item.value
102 else:
103 # Single username field specified
104 usernames = username.value
Guido van Rossum0147db01996-03-09 03:16:04 +0000105
106If a field represents an uploaded file, the value attribute reads the
107entire file in memory as a string. This may not be what you want. You can
108test for an uploaded file by testing either the filename attribute or the
109file attribute. You can then read the data at leasure from the file
110attribute:
111
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000112 fileitem = form["userfile"]
113 if fileitem.file:
114 # It's an uploaded file; count lines
115 linecount = 0
116 while 1:
117 line = fileitem.file.readline()
118 if not line: break
119 linecount = linecount + 1
Guido van Rossum0147db01996-03-09 03:16:04 +0000120
Guido van Rossum4032c2c1996-03-09 04:04:35 +0000121The file upload draft standard entertains the possibility of uploading
122multiple files from one field (using a recursive multipart/*
123encoding). When this occurs, the item will be a dictionary-like
124FieldStorage item. This can be determined by testing its type
125attribute, which should have the value "multipart/form-data" (or
126perhaps another string beginning with "multipart/"). It this case, it
127can be iterated over recursively just like the top-level form object.
128
Guido van Rossum0147db01996-03-09 03:16:04 +0000129When a form is submitted in the "old" format (as the query string or as a
130single data part of type application/x-www-form-urlencoded), the items
131will actually be instances of the class MiniFieldStorage. In this case,
132the list, file and filename attributes are always None.
Guido van Rossum7aee3841996-03-07 18:00:44 +0000133
Guido van Rossum72755611996-03-06 07:20:06 +0000134
Guido van Rossum0147db01996-03-09 03:16:04 +0000135Old classes
136-----------
Guido van Rossum72755611996-03-06 07:20:06 +0000137
Guido van Rossum0147db01996-03-09 03:16:04 +0000138These classes, present in earlier versions of the cgi module, are still
Guido van Rossum16d5b111996-10-24 14:44:32 +0000139supported for backward compatibility. New applications should use the
140FieldStorage class.
Guido van Rossum7aee3841996-03-07 18:00:44 +0000141
Guido van Rossum0147db01996-03-09 03:16:04 +0000142SvFormContentDict: single value form content as dictionary; assumes each
143field name occurs in the form only once.
Guido van Rossum72755611996-03-06 07:20:06 +0000144
Guido van Rossum391b4e61996-03-06 19:11:33 +0000145FormContentDict: multiple value form content as dictionary (the form
146items are lists of values). Useful if your form contains multiple
147fields with the same name.
Guido van Rossum72755611996-03-06 07:20:06 +0000148
Guido van Rossum391b4e61996-03-06 19:11:33 +0000149Other classes (FormContent, InterpFormContentDict) are present for
Guido van Rossum0147db01996-03-09 03:16:04 +0000150backwards compatibility with really old applications only. If you still
151use these and would be inconvenienced when they disappeared from a next
152version of this module, drop me a note.
Guido van Rossum72755611996-03-06 07:20:06 +0000153
154
Guido van Rossum0147db01996-03-09 03:16:04 +0000155Functions
156---------
Guido van Rossum72755611996-03-06 07:20:06 +0000157
Guido van Rossum391b4e61996-03-06 19:11:33 +0000158These are useful if you want more control, or if you want to employ
159some of the algorithms implemented in this module in other
160circumstances.
Guido van Rossum72755611996-03-06 07:20:06 +0000161
Guido van Rossume08c04c1996-11-11 19:29:11 +0000162parse(fp, [environ, [keep_blank_values, [strict_parsing]]]): parse a
163form into a Python dictionary.
Guido van Rossum72755611996-03-06 07:20:06 +0000164
Guido van Rossume08c04c1996-11-11 19:29:11 +0000165parse_qs(qs, [keep_blank_values, [strict_parsing]]): parse a query
Guido van Rossum1946f0d1999-06-04 17:54:39 +0000166string (data of type application/x-www-form-urlencoded). Data are
167returned as a dictionary. The dictionary keys are the unique query
168variable names and the values are lists of vales for each name.
169
170parse_qsl(qs, [keep_blank_values, [strict_parsing]]): parse a query
171string (data of type application/x-www-form-urlencoded). Data are
172returned as a list of (name, value) pairs.
Guido van Rossum72755611996-03-06 07:20:06 +0000173
Guido van Rossum0147db01996-03-09 03:16:04 +0000174parse_multipart(fp, pdict): parse input of type multipart/form-data (for
Guido van Rossum391b4e61996-03-06 19:11:33 +0000175file uploads).
Guido van Rossum72755611996-03-06 07:20:06 +0000176
Guido van Rossum391b4e61996-03-06 19:11:33 +0000177parse_header(string): parse a header like Content-type into a main
178value and a dictionary of parameters.
Guido van Rossum72755611996-03-06 07:20:06 +0000179
180test(): complete test program.
181
182print_environ(): format the shell environment in HTML.
183
184print_form(form): format a form in HTML.
185
Guido van Rossum391b4e61996-03-06 19:11:33 +0000186print_environ_usage(): print a list of useful environment variables in
187HTML.
Guido van Rossum72755611996-03-06 07:20:06 +0000188
Guido van Rossum391b4e61996-03-06 19:11:33 +0000189escape(): convert the characters "&", "<" and ">" to HTML-safe
190sequences. Use this if you need to display text that might contain
191such characters in HTML. To translate URLs for inclusion in the HREF
192attribute of an <A> tag, use urllib.quote().
Guido van Rossum72755611996-03-06 07:20:06 +0000193
Guido van Rossumc204c701996-09-05 19:07:11 +0000194log(fmt, ...): write a line to a log file; see docs for initlog().
195
Guido van Rossum72755611996-03-06 07:20:06 +0000196
197Caring about security
198---------------------
199
Guido van Rossum391b4e61996-03-06 19:11:33 +0000200There's one important rule: if you invoke an external program (e.g.
201via the os.system() or os.popen() functions), make very sure you don't
202pass arbitrary strings received from the client to the shell. This is
203a well-known security hole whereby clever hackers anywhere on the web
204can exploit a gullible CGI script to invoke arbitrary shell commands.
205Even parts of the URL or field names cannot be trusted, since the
206request doesn't have to come from your form!
Guido van Rossum72755611996-03-06 07:20:06 +0000207
Guido van Rossum391b4e61996-03-06 19:11:33 +0000208To be on the safe side, if you must pass a string gotten from a form
209to a shell command, you should make sure the string contains only
210alphanumeric characters, dashes, underscores, and periods.
Guido van Rossum72755611996-03-06 07:20:06 +0000211
212
213Installing your CGI script on a Unix system
214-------------------------------------------
215
Guido van Rossum391b4e61996-03-06 19:11:33 +0000216Read the documentation for your HTTP server and check with your local
217system administrator to find the directory where CGI scripts should be
Guido van Rossum72755611996-03-06 07:20:06 +0000218installed; usually this is in a directory cgi-bin in the server tree.
219
Guido van Rossum391b4e61996-03-06 19:11:33 +0000220Make sure that your script is readable and executable by "others"; the
221Unix file mode should be 755 (use "chmod 755 filename"). Make sure
Guido van Rossum43055421997-05-28 15:11:01 +0000222that the first line of the script contains #! starting in column 1
Guido van Rossum391b4e61996-03-06 19:11:33 +0000223followed by the pathname of the Python interpreter, for instance:
Guido van Rossum72755611996-03-06 07:20:06 +0000224
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000225 #! /usr/local/bin/python
Guido van Rossum72755611996-03-06 07:20:06 +0000226
Guido van Rossum391b4e61996-03-06 19:11:33 +0000227Make sure the Python interpreter exists and is executable by "others".
Guido van Rossum72755611996-03-06 07:20:06 +0000228
Guido van Rossum43055421997-05-28 15:11:01 +0000229Note that it's probably not a good idea to use #! /usr/bin/env python
Guido van Rossumf06ee5f1996-11-27 19:52:01 +0000230here, since the Python interpreter may not be on the default path
Guido van Rossum43055421997-05-28 15:11:01 +0000231given to CGI scripts!!!
Guido van Rossumf06ee5f1996-11-27 19:52:01 +0000232
Guido van Rossum391b4e61996-03-06 19:11:33 +0000233Make sure that any files your script needs to read or write are
234readable or writable, respectively, by "others" -- their mode should
235be 644 for readable and 666 for writable. This is because, for
236security reasons, the HTTP server executes your script as user
237"nobody", without any special privileges. It can only read (write,
238execute) files that everybody can read (write, execute). The current
239directory at execution time is also different (it is usually the
240server's cgi-bin directory) and the set of environment variables is
241also different from what you get at login. in particular, don't count
242on the shell's search path for executables ($PATH) or the Python
243module search path ($PYTHONPATH) to be set to anything interesting.
Guido van Rossum72755611996-03-06 07:20:06 +0000244
Guido van Rossum391b4e61996-03-06 19:11:33 +0000245If you need to load modules from a directory which is not on Python's
246default module search path, you can change the path in your script,
247before importing other modules, e.g.:
Guido van Rossum72755611996-03-06 07:20:06 +0000248
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000249 import sys
250 sys.path.insert(0, "/usr/home/joe/lib/python")
251 sys.path.insert(0, "/usr/local/lib/python")
Guido van Rossum72755611996-03-06 07:20:06 +0000252
Guido van Rossum43055421997-05-28 15:11:01 +0000253This way, the directory inserted last will be searched first!
Guido van Rossum72755611996-03-06 07:20:06 +0000254
Guido van Rossum391b4e61996-03-06 19:11:33 +0000255Instructions for non-Unix systems will vary; check your HTTP server's
Guido van Rossum72755611996-03-06 07:20:06 +0000256documentation (it will usually have a section on CGI scripts).
257
258
259Testing your CGI script
260-----------------------
261
Guido van Rossum391b4e61996-03-06 19:11:33 +0000262Unfortunately, a CGI script will generally not run when you try it
263from the command line, and a script that works perfectly from the
264command line may fail mysteriously when run from the server. There's
265one reason why you should still test your script from the command
266line: if it contains a syntax error, the python interpreter won't
267execute it at all, and the HTTP server will most likely send a cryptic
268error to the client.
Guido van Rossum72755611996-03-06 07:20:06 +0000269
Guido van Rossum391b4e61996-03-06 19:11:33 +0000270Assuming your script has no syntax errors, yet it does not work, you
271have no choice but to read the next section:
Guido van Rossum72755611996-03-06 07:20:06 +0000272
273
274Debugging CGI scripts
275---------------------
276
Guido van Rossum391b4e61996-03-06 19:11:33 +0000277First of all, check for trivial installation errors -- reading the
278section above on installing your CGI script carefully can save you a
279lot of time. If you wonder whether you have understood the
280installation procedure correctly, try installing a copy of this module
281file (cgi.py) as a CGI script. When invoked as a script, the file
282will dump its environment and the contents of the form in HTML form.
283Give it the right mode etc, and send it a request. If it's installed
284in the standard cgi-bin directory, it should be possible to send it a
285request by entering a URL into your browser of the form:
Guido van Rossum72755611996-03-06 07:20:06 +0000286
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000287 http://yourhostname/cgi-bin/cgi.py?name=Joe+Blow&addr=At+Home
Guido van Rossum72755611996-03-06 07:20:06 +0000288
Guido van Rossum391b4e61996-03-06 19:11:33 +0000289If this gives an error of type 404, the server cannot find the script
290-- perhaps you need to install it in a different directory. If it
291gives another error (e.g. 500), there's an installation problem that
292you should fix before trying to go any further. If you get a nicely
293formatted listing of the environment and form content (in this
294example, the fields should be listed as "addr" with value "At Home"
295and "name" with value "Joe Blow"), the cgi.py script has been
296installed correctly. If you follow the same procedure for your own
297script, you should now be able to debug it.
Guido van Rossum72755611996-03-06 07:20:06 +0000298
Guido van Rossum391b4e61996-03-06 19:11:33 +0000299The next step could be to call the cgi module's test() function from
300your script: replace its main code with the single statement
Guido van Rossum72755611996-03-06 07:20:06 +0000301
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000302 cgi.test()
303
Guido van Rossum391b4e61996-03-06 19:11:33 +0000304This should produce the same results as those gotten from installing
305the cgi.py file itself.
Guido van Rossum72755611996-03-06 07:20:06 +0000306
Guido van Rossum43055421997-05-28 15:11:01 +0000307When an ordinary Python script raises an unhandled exception (e.g.,
308because of a typo in a module name, a file that can't be opened,
Guido van Rossum391b4e61996-03-06 19:11:33 +0000309etc.), the Python interpreter prints a nice traceback and exits.
310While the Python interpreter will still do this when your CGI script
311raises an exception, most likely the traceback will end up in one of
312the HTTP server's log file, or be discarded altogether.
Guido van Rossum72755611996-03-06 07:20:06 +0000313
Guido van Rossum391b4e61996-03-06 19:11:33 +0000314Fortunately, once you have managed to get your script to execute
315*some* code, it is easy to catch exceptions and cause a traceback to
316be printed. The test() function below in this module is an example.
317Here are the rules:
Guido van Rossum72755611996-03-06 07:20:06 +0000318
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000319 1. Import the traceback module (before entering the
320 try-except!)
321
322 2. Make sure you finish printing the headers and the blank
323 line early
324
325 3. Assign sys.stderr to sys.stdout
326
327 3. Wrap all remaining code in a try-except statement
328
329 4. In the except clause, call traceback.print_exc()
Guido van Rossum72755611996-03-06 07:20:06 +0000330
331For example:
332
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000333 import sys
334 import traceback
335 print "Content-type: text/html"
336 print
337 sys.stderr = sys.stdout
338 try:
339 ...your code here...
340 except:
341 print "\n\n<PRE>"
342 traceback.print_exc()
Guido van Rossum72755611996-03-06 07:20:06 +0000343
Guido van Rossum391b4e61996-03-06 19:11:33 +0000344Notes: The assignment to sys.stderr is needed because the traceback
345prints to sys.stderr. The print "\n\n<PRE>" statement is necessary to
346disable the word wrapping in HTML.
Guido van Rossum72755611996-03-06 07:20:06 +0000347
Guido van Rossum391b4e61996-03-06 19:11:33 +0000348If you suspect that there may be a problem in importing the traceback
349module, you can use an even more robust approach (which only uses
350built-in modules):
Guido van Rossum72755611996-03-06 07:20:06 +0000351
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000352 import sys
353 sys.stderr = sys.stdout
354 print "Content-type: text/plain"
355 print
356 ...your code here...
Guido van Rossum72755611996-03-06 07:20:06 +0000357
Guido van Rossum391b4e61996-03-06 19:11:33 +0000358This relies on the Python interpreter to print the traceback. The
359content type of the output is set to plain text, which disables all
360HTML processing. If your script works, the raw HTML will be displayed
361by your client. If it raises an exception, most likely after the
362first two lines have been printed, a traceback will be displayed.
363Because no HTML interpretation is going on, the traceback will
364readable.
Guido van Rossum72755611996-03-06 07:20:06 +0000365
Guido van Rossumc204c701996-09-05 19:07:11 +0000366When all else fails, you may want to insert calls to log() to your
367program or even to a copy of the cgi.py file. Note that this requires
368you to set cgi.logfile to the name of a world-writable file before the
369first call to log() is made!
370
Guido van Rossum72755611996-03-06 07:20:06 +0000371Good luck!
372
373
374Common problems and solutions
375-----------------------------
376
Guido van Rossum391b4e61996-03-06 19:11:33 +0000377- Most HTTP servers buffer the output from CGI scripts until the
378script is completed. This means that it is not possible to display a
379progress report on the client's display while the script is running.
Guido van Rossum72755611996-03-06 07:20:06 +0000380
381- Check the installation instructions above.
382
Guido van Rossum391b4e61996-03-06 19:11:33 +0000383- Check the HTTP server's log files. ("tail -f logfile" in a separate
Guido van Rossum72755611996-03-06 07:20:06 +0000384window may be useful!)
385
Guido van Rossum391b4e61996-03-06 19:11:33 +0000386- Always check a script for syntax errors first, by doing something
387like "python script.py".
Guido van Rossum72755611996-03-06 07:20:06 +0000388
389- When using any of the debugging techniques, don't forget to add
390"import sys" to the top of the script.
391
Guido van Rossum391b4e61996-03-06 19:11:33 +0000392- When invoking external programs, make sure they can be found.
393Usually, this means using absolute path names -- $PATH is usually not
394set to a very useful value in a CGI script.
Guido van Rossum72755611996-03-06 07:20:06 +0000395
Guido van Rossum391b4e61996-03-06 19:11:33 +0000396- When reading or writing external files, make sure they can be read
397or written by every user on the system.
Guido van Rossum72755611996-03-06 07:20:06 +0000398
Guido van Rossum391b4e61996-03-06 19:11:33 +0000399- Don't try to give a CGI script a set-uid mode. This doesn't work on
400most systems, and is a security liability as well.
Guido van Rossum72755611996-03-06 07:20:06 +0000401
402
403History
404-------
405
Guido van Rossum391b4e61996-03-06 19:11:33 +0000406Michael McLay started this module. Steve Majewski changed the
407interface to SvFormContentDict and FormContentDict. The multipart
408parsing was inspired by code submitted by Andreas Paepcke. Guido van
409Rossum rewrote, reformatted and documented the module and is currently
410responsible for its maintenance.
Guido van Rossum72755611996-03-06 07:20:06 +0000411
Guido van Rossum0147db01996-03-09 03:16:04 +0000412
413XXX The module is getting pretty heavy with all those docstrings.
414Perhaps there should be a slimmed version that doesn't contain all those
415backwards compatible and debugging classes and functions?
416
Guido van Rossum72755611996-03-06 07:20:06 +0000417"""
418
Guido van Rossum5f322481997-04-11 18:20:42 +0000419__version__ = "2.2"
Guido van Rossum0147db01996-03-09 03:16:04 +0000420
Guido van Rossum72755611996-03-06 07:20:06 +0000421
422# Imports
423# =======
424
425import string
Guido van Rossum72755611996-03-06 07:20:06 +0000426import sys
427import os
Guido van Rossuma5e9fb61997-08-12 18:18:13 +0000428import urllib
Guido van Rossuma5e9fb61997-08-12 18:18:13 +0000429import mimetools
430import rfc822
431from StringIO import StringIO
Guido van Rossum72755611996-03-06 07:20:06 +0000432
Guido van Rossumc204c701996-09-05 19:07:11 +0000433
434# Logging support
435# ===============
436
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000437logfile = "" # Filename to log to, if not empty
438logfp = None # File object to log to, if not None
Guido van Rossumc204c701996-09-05 19:07:11 +0000439
440def initlog(*allargs):
441 """Write a log message, if there is a log file.
442
443 Even though this function is called initlog(), you should always
444 use log(); log is a variable that is set either to initlog
445 (initially), to dolog (once the log file has been opened), or to
446 nolog (when logging is disabled).
447
448 The first argument is a format string; the remaining arguments (if
449 any) are arguments to the % operator, so e.g.
450 log("%s: %s", "a", "b")
451 will write "a: b" to the log file, followed by a newline.
452
453 If the global logfp is not None, it should be a file object to
454 which log data is written.
455
456 If the global logfp is None, the global logfile may be a string
457 giving a filename to open, in append mode. This file should be
458 world writable!!! If the file can't be opened, logging is
459 silently disabled (since there is no safe place where we could
460 send an error message).
461
462 """
463 global logfp, log
464 if logfile and not logfp:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000465 try:
466 logfp = open(logfile, "a")
467 except IOError:
468 pass
Guido van Rossumc204c701996-09-05 19:07:11 +0000469 if not logfp:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000470 log = nolog
Guido van Rossumc204c701996-09-05 19:07:11 +0000471 else:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000472 log = dolog
Guido van Rossumc204c701996-09-05 19:07:11 +0000473 apply(log, allargs)
474
475def dolog(fmt, *args):
476 """Write a log message to the log file. See initlog() for docs."""
477 logfp.write(fmt%args + "\n")
478
479def nolog(*allargs):
480 """Dummy function, assigned to log when logging is disabled."""
481 pass
482
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000483log = initlog # The current logging function
Guido van Rossumc204c701996-09-05 19:07:11 +0000484
485
Guido van Rossum72755611996-03-06 07:20:06 +0000486# Parsing functions
487# =================
488
Guido van Rossumad164711997-05-13 19:03:23 +0000489# Maximum input we will accept when REQUEST_METHOD is POST
490# 0 ==> unlimited input
491maxlen = 0
492
Guido van Rossume08c04c1996-11-11 19:29:11 +0000493def parse(fp=None, environ=os.environ, keep_blank_values=0, strict_parsing=0):
Guido van Rossum773ab271996-07-23 03:46:24 +0000494 """Parse a query in the environment or from a file (default stdin)
495
496 Arguments, all optional:
497
498 fp : file pointer; default: sys.stdin
499
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000500 environ : environment dictionary; default: os.environ
Guido van Rossum773ab271996-07-23 03:46:24 +0000501
502 keep_blank_values: flag indicating whether blank values in
503 URL encoded forms should be treated as blank strings.
504 A true value inicates that blanks should be retained as
505 blank strings. The default false value indicates that
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000506 blank values are to be ignored and treated as if they were
507 not included.
Guido van Rossume08c04c1996-11-11 19:29:11 +0000508
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000509 strict_parsing: flag indicating what to do with parsing errors.
510 If false (the default), errors are silently ignored.
511 If true, errors raise a ValueError exception.
Guido van Rossum773ab271996-07-23 03:46:24 +0000512 """
Guido van Rossum7aee3841996-03-07 18:00:44 +0000513 if not fp:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000514 fp = sys.stdin
Guido van Rossum7aee3841996-03-07 18:00:44 +0000515 if not environ.has_key('REQUEST_METHOD'):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000516 environ['REQUEST_METHOD'] = 'GET' # For testing stand-alone
Guido van Rossum7aee3841996-03-07 18:00:44 +0000517 if environ['REQUEST_METHOD'] == 'POST':
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000518 ctype, pdict = parse_header(environ['CONTENT_TYPE'])
519 if ctype == 'multipart/form-data':
520 return parse_multipart(fp, pdict)
521 elif ctype == 'application/x-www-form-urlencoded':
522 clength = string.atoi(environ['CONTENT_LENGTH'])
523 if maxlen and clength > maxlen:
524 raise ValueError, 'Maximum content length exceeded'
525 qs = fp.read(clength)
526 else:
527 qs = '' # Unknown content-type
528 if environ.has_key('QUERY_STRING'):
529 if qs: qs = qs + '&'
530 qs = qs + environ['QUERY_STRING']
531 elif sys.argv[1:]:
532 if qs: qs = qs + '&'
533 qs = qs + sys.argv[1]
534 environ['QUERY_STRING'] = qs # XXX Shouldn't, really
Guido van Rossum7aee3841996-03-07 18:00:44 +0000535 elif environ.has_key('QUERY_STRING'):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000536 qs = environ['QUERY_STRING']
Guido van Rossum7aee3841996-03-07 18:00:44 +0000537 else:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000538 if sys.argv[1:]:
539 qs = sys.argv[1]
540 else:
541 qs = ""
542 environ['QUERY_STRING'] = qs # XXX Shouldn't, really
Guido van Rossume08c04c1996-11-11 19:29:11 +0000543 return parse_qs(qs, keep_blank_values, strict_parsing)
Guido van Rossume7808771995-08-07 20:12:09 +0000544
545
Guido van Rossume08c04c1996-11-11 19:29:11 +0000546def parse_qs(qs, keep_blank_values=0, strict_parsing=0):
547 """Parse a query given as a string argument.
Guido van Rossum773ab271996-07-23 03:46:24 +0000548
549 Arguments:
550
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000551 qs: URL-encoded query string to be parsed
Guido van Rossum773ab271996-07-23 03:46:24 +0000552
553 keep_blank_values: flag indicating whether blank values in
554 URL encoded queries should be treated as blank strings.
555 A true value inicates that blanks should be retained as
556 blank strings. The default false value indicates that
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000557 blank values are to be ignored and treated as if they were
558 not included.
Guido van Rossume08c04c1996-11-11 19:29:11 +0000559
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000560 strict_parsing: flag indicating what to do with parsing errors.
561 If false (the default), errors are silently ignored.
562 If true, errors raise a ValueError exception.
Guido van Rossum773ab271996-07-23 03:46:24 +0000563 """
Guido van Rossum7aee3841996-03-07 18:00:44 +0000564 dict = {}
Guido van Rossum1946f0d1999-06-04 17:54:39 +0000565 for name, value in parse_qsl(qs, keep_blank_values, strict_parsing):
566 if len(value) or keep_blank_values:
567 if dict.has_key(name):
568 dict[name].append(value)
569 else:
570 dict[name] = [value]
571 return dict
572
573def parse_qsl(qs, keep_blank_values=0, strict_parsing=0):
574 """Parse a query given as a string argument.
575
576 Arguments:
577
578 qs: URL-encoded query string to be parsed
579
580 keep_blank_values: flag indicating whether blank values in
581 URL encoded queries should be treated as blank strings.
582 A true value inicates that blanks should be retained as
583 blank strings. The default false value indicates that
584 blank values are to be ignored and treated as if they were
585 not included.
586
587 strict_parsing: flag indicating what to do with parsing errors.
588 If false (the default), errors are silently ignored.
589 If true, errors raise a ValueError exception.
590
591 Returns a list, as God intended.
592 """
593 name_value_pairs = string.splitfields(qs, '&')
594 r=[]
Guido van Rossum7aee3841996-03-07 18:00:44 +0000595 for name_value in name_value_pairs:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000596 nv = string.splitfields(name_value, '=')
597 if len(nv) != 2:
598 if strict_parsing:
599 raise ValueError, "bad query field: %s" % `name_value`
600 continue
601 name = urllib.unquote(string.replace(nv[0], '+', ' '))
602 value = urllib.unquote(string.replace(nv[1], '+', ' '))
Guido van Rossum1946f0d1999-06-04 17:54:39 +0000603 r.append(name, value)
604
605 return r
Guido van Rossum9a22de11995-01-12 12:29:47 +0000606
607
Guido van Rossum0147db01996-03-09 03:16:04 +0000608def parse_multipart(fp, pdict):
Guido van Rossum7aee3841996-03-07 18:00:44 +0000609 """Parse multipart input.
Guido van Rossum9a22de11995-01-12 12:29:47 +0000610
Guido van Rossum7aee3841996-03-07 18:00:44 +0000611 Arguments:
612 fp : input file
Guido van Rossum7aee3841996-03-07 18:00:44 +0000613 pdict: dictionary containing other parameters of conten-type header
Guido van Rossum72755611996-03-06 07:20:06 +0000614
Guido van Rossum0147db01996-03-09 03:16:04 +0000615 Returns a dictionary just like parse_qs(): keys are the field names, each
616 value is a list of values for that field. This is easy to use but not
617 much good if you are expecting megabytes to be uploaded -- in that case,
618 use the FieldStorage class instead which is much more flexible. Note
619 that content-type is the raw, unparsed contents of the content-type
620 header.
621
622 XXX This does not parse nested multipart parts -- use FieldStorage for
623 that.
624
625 XXX This should really be subsumed by FieldStorage altogether -- no
626 point in having two implementations of the same parsing algorithm.
Guido van Rossum72755611996-03-06 07:20:06 +0000627
Guido van Rossum7aee3841996-03-07 18:00:44 +0000628 """
Guido van Rossum7aee3841996-03-07 18:00:44 +0000629 if pdict.has_key('boundary'):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000630 boundary = pdict['boundary']
Guido van Rossum7aee3841996-03-07 18:00:44 +0000631 else:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000632 boundary = ""
Guido van Rossum7aee3841996-03-07 18:00:44 +0000633 nextpart = "--" + boundary
634 lastpart = "--" + boundary + "--"
635 partdict = {}
636 terminator = ""
637
638 while terminator != lastpart:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000639 bytes = -1
640 data = None
641 if terminator:
642 # At start of next part. Read headers first.
643 headers = mimetools.Message(fp)
644 clength = headers.getheader('content-length')
645 if clength:
646 try:
647 bytes = string.atoi(clength)
648 except string.atoi_error:
649 pass
650 if bytes > 0:
651 if maxlen and bytes > maxlen:
652 raise ValueError, 'Maximum content length exceeded'
653 data = fp.read(bytes)
654 else:
655 data = ""
656 # Read lines until end of part.
657 lines = []
658 while 1:
659 line = fp.readline()
660 if not line:
661 terminator = lastpart # End outer loop
662 break
663 if line[:2] == "--":
664 terminator = string.strip(line)
665 if terminator in (nextpart, lastpart):
666 break
667 lines.append(line)
668 # Done with part.
669 if data is None:
670 continue
671 if bytes < 0:
672 if lines:
673 # Strip final line terminator
674 line = lines[-1]
675 if line[-2:] == "\r\n":
676 line = line[:-2]
677 elif line[-1:] == "\n":
678 line = line[:-1]
679 lines[-1] = line
680 data = string.joinfields(lines, "")
681 line = headers['content-disposition']
682 if not line:
683 continue
684 key, params = parse_header(line)
685 if key != 'form-data':
686 continue
687 if params.has_key('name'):
688 name = params['name']
689 else:
690 continue
691 if partdict.has_key(name):
692 partdict[name].append(data)
693 else:
694 partdict[name] = [data]
Guido van Rossum72755611996-03-06 07:20:06 +0000695
Guido van Rossum7aee3841996-03-07 18:00:44 +0000696 return partdict
Guido van Rossum9a22de11995-01-12 12:29:47 +0000697
698
Guido van Rossum72755611996-03-06 07:20:06 +0000699def parse_header(line):
Guido van Rossum7aee3841996-03-07 18:00:44 +0000700 """Parse a Content-type like header.
701
702 Return the main content-type and a dictionary of options.
703
704 """
705 plist = map(string.strip, string.splitfields(line, ';'))
706 key = string.lower(plist[0])
707 del plist[0]
708 pdict = {}
709 for p in plist:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000710 i = string.find(p, '=')
711 if i >= 0:
712 name = string.lower(string.strip(p[:i]))
713 value = string.strip(p[i+1:])
714 if len(value) >= 2 and value[0] == value[-1] == '"':
715 value = value[1:-1]
716 pdict[name] = value
Guido van Rossum7aee3841996-03-07 18:00:44 +0000717 return key, pdict
Guido van Rossum72755611996-03-06 07:20:06 +0000718
719
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000720# Classes for field storage
721# =========================
722
723class MiniFieldStorage:
724
Guido van Rossum0147db01996-03-09 03:16:04 +0000725 """Like FieldStorage, for use when no file uploads are possible."""
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000726
Guido van Rossum7aee3841996-03-07 18:00:44 +0000727 # Dummy attributes
728 filename = None
729 list = None
730 type = None
Guido van Rossum773ab271996-07-23 03:46:24 +0000731 file = None
Guido van Rossum4032c2c1996-03-09 04:04:35 +0000732 type_options = {}
Guido van Rossum7aee3841996-03-07 18:00:44 +0000733 disposition = None
734 disposition_options = {}
735 headers = {}
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000736
Guido van Rossum7aee3841996-03-07 18:00:44 +0000737 def __init__(self, name, value):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000738 """Constructor from field name and value."""
739 self.name = name
740 self.value = value
Guido van Rossum773ab271996-07-23 03:46:24 +0000741 # self.file = StringIO(value)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000742
743 def __repr__(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000744 """Return printable representation."""
745 return "MiniFieldStorage(%s, %s)" % (`self.name`, `self.value`)
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000746
747
748class FieldStorage:
749
Guido van Rossum7aee3841996-03-07 18:00:44 +0000750 """Store a sequence of fields, reading multipart/form-data.
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000751
Guido van Rossum7aee3841996-03-07 18:00:44 +0000752 This class provides naming, typing, files stored on disk, and
753 more. At the top level, it is accessible like a dictionary, whose
754 keys are the field names. (Note: None can occur as a field name.)
755 The items are either a Python list (if there's multiple values) or
756 another FieldStorage or MiniFieldStorage object. If it's a single
757 object, it has the following attributes:
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000758
Guido van Rossum7aee3841996-03-07 18:00:44 +0000759 name: the field name, if specified; otherwise None
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000760
Guido van Rossum7aee3841996-03-07 18:00:44 +0000761 filename: the filename, if specified; otherwise None; this is the
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000762 client side filename, *not* the file name on which it is
763 stored (that's a temporary file you don't deal with)
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000764
Guido van Rossum7aee3841996-03-07 18:00:44 +0000765 value: the value as a *string*; for file uploads, this
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000766 transparently reads the file every time you request the value
Guido van Rossum7aee3841996-03-07 18:00:44 +0000767
768 file: the file(-like) object from which you can read the data;
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000769 None if the data is stored a simple string
Guido van Rossum7aee3841996-03-07 18:00:44 +0000770
771 type: the content-type, or None if not specified
772
773 type_options: dictionary of options specified on the content-type
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000774 line
Guido van Rossum7aee3841996-03-07 18:00:44 +0000775
776 disposition: content-disposition, or None if not specified
777
778 disposition_options: dictionary of corresponding options
779
780 headers: a dictionary(-like) object (sometimes rfc822.Message or a
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000781 subclass thereof) containing *all* headers
Guido van Rossum7aee3841996-03-07 18:00:44 +0000782
783 The class is subclassable, mostly for the purpose of overriding
784 the make_file() method, which is called internally to come up with
785 a file open for reading and writing. This makes it possible to
786 override the default choice of storing all files in a temporary
787 directory and unlinking them as soon as they have been opened.
788
789 """
790
Guido van Rossum773ab271996-07-23 03:46:24 +0000791 def __init__(self, fp=None, headers=None, outerboundary="",
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000792 environ=os.environ, keep_blank_values=0, strict_parsing=0):
793 """Constructor. Read multipart/* until last part.
Guido van Rossum7aee3841996-03-07 18:00:44 +0000794
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000795 Arguments, all optional:
Guido van Rossum7aee3841996-03-07 18:00:44 +0000796
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000797 fp : file pointer; default: sys.stdin
Guido van Rossumb1b4f941998-05-08 19:55:51 +0000798 (not used when the request method is GET)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000799
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000800 headers : header dictionary-like object; default:
801 taken from environ as per CGI spec
Guido van Rossum7aee3841996-03-07 18:00:44 +0000802
Guido van Rossum773ab271996-07-23 03:46:24 +0000803 outerboundary : terminating multipart boundary
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000804 (for internal use only)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000805
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000806 environ : environment dictionary; default: os.environ
Guido van Rossum773ab271996-07-23 03:46:24 +0000807
808 keep_blank_values: flag indicating whether blank values in
809 URL encoded forms should be treated as blank strings.
810 A true value inicates that blanks should be retained as
811 blank strings. The default false value indicates that
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000812 blank values are to be ignored and treated as if they were
813 not included.
Guido van Rossum773ab271996-07-23 03:46:24 +0000814
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000815 strict_parsing: flag indicating what to do with parsing errors.
816 If false (the default), errors are silently ignored.
817 If true, errors raise a ValueError exception.
Guido van Rossume08c04c1996-11-11 19:29:11 +0000818
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000819 """
820 method = 'GET'
821 self.keep_blank_values = keep_blank_values
822 self.strict_parsing = strict_parsing
823 if environ.has_key('REQUEST_METHOD'):
824 method = string.upper(environ['REQUEST_METHOD'])
Guido van Rossum01852831998-06-25 02:40:17 +0000825 if method == 'GET' or method == 'HEAD':
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000826 if environ.has_key('QUERY_STRING'):
827 qs = environ['QUERY_STRING']
828 elif sys.argv[1:]:
829 qs = sys.argv[1]
830 else:
831 qs = ""
832 fp = StringIO(qs)
833 if headers is None:
834 headers = {'content-type':
835 "application/x-www-form-urlencoded"}
836 if headers is None:
Guido van Rossumcff311a1998-06-11 14:06:59 +0000837 headers = {}
838 if method == 'POST':
839 # Set default content-type for POST to what's traditional
840 headers['content-type'] = "application/x-www-form-urlencoded"
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000841 if environ.has_key('CONTENT_TYPE'):
842 headers['content-type'] = environ['CONTENT_TYPE']
843 if environ.has_key('CONTENT_LENGTH'):
844 headers['content-length'] = environ['CONTENT_LENGTH']
845 self.fp = fp or sys.stdin
846 self.headers = headers
847 self.outerboundary = outerboundary
Guido van Rossum7aee3841996-03-07 18:00:44 +0000848
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000849 # Process content-disposition header
850 cdisp, pdict = "", {}
851 if self.headers.has_key('content-disposition'):
852 cdisp, pdict = parse_header(self.headers['content-disposition'])
853 self.disposition = cdisp
854 self.disposition_options = pdict
855 self.name = None
856 if pdict.has_key('name'):
857 self.name = pdict['name']
858 self.filename = None
859 if pdict.has_key('filename'):
860 self.filename = pdict['filename']
Guido van Rossum7aee3841996-03-07 18:00:44 +0000861
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000862 # Process content-type header
Barry Warsaw302331a1999-01-08 17:42:03 +0000863 #
864 # Honor any existing content-type header. But if there is no
865 # content-type header, use some sensible defaults. Assume
866 # outerboundary is "" at the outer level, but something non-false
867 # inside a multi-part. The default for an inner part is text/plain,
868 # but for an outer part it should be urlencoded. This should catch
869 # bogus clients which erroneously forget to include a content-type
870 # header.
871 #
872 # See below for what we do if there does exist a content-type header,
873 # but it happens to be something we don't understand.
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000874 if self.headers.has_key('content-type'):
875 ctype, pdict = parse_header(self.headers['content-type'])
Guido van Rossumce900de1999-06-02 18:44:22 +0000876 elif self.outerboundary or method != 'POST':
Barry Warsaw302331a1999-01-08 17:42:03 +0000877 ctype, pdict = "text/plain", {}
878 else:
879 ctype, pdict = 'application/x-www-form-urlencoded', {}
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000880 self.type = ctype
881 self.type_options = pdict
882 self.innerboundary = ""
883 if pdict.has_key('boundary'):
884 self.innerboundary = pdict['boundary']
885 clen = -1
886 if self.headers.has_key('content-length'):
887 try:
888 clen = string.atoi(self.headers['content-length'])
889 except:
890 pass
891 if maxlen and clen > maxlen:
892 raise ValueError, 'Maximum content length exceeded'
893 self.length = clen
Guido van Rossum7aee3841996-03-07 18:00:44 +0000894
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000895 self.list = self.file = None
896 self.done = 0
897 self.lines = []
898 if ctype == 'application/x-www-form-urlencoded':
899 self.read_urlencoded()
900 elif ctype[:10] == 'multipart/':
Guido van Rossumf5745001998-10-20 14:43:02 +0000901 self.read_multi(environ, keep_blank_values, strict_parsing)
Guido van Rossumce900de1999-06-02 18:44:22 +0000902 elif self.outerboundary or method != 'POST':
Barry Warsaw302331a1999-01-08 17:42:03 +0000903 # we're in an inner part, but the content-type wasn't something we
904 # understood. default to read_single() because the resulting
905 # FieldStorage won't be a mapping (and doesn't need to be).
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000906 self.read_single()
Barry Warsaw302331a1999-01-08 17:42:03 +0000907 else:
908 # we're in an outer part, but the content-type wasn't something we
909 # understood. we still want the resulting FieldStorage to be a
910 # mapping, so parse it as if it were urlencoded
911 self.read_urlencoded()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000912
913 def __repr__(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000914 """Return a printable representation."""
915 return "FieldStorage(%s, %s, %s)" % (
916 `self.name`, `self.filename`, `self.value`)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000917
918 def __getattr__(self, name):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000919 if name != 'value':
920 raise AttributeError, name
921 if self.file:
922 self.file.seek(0)
923 value = self.file.read()
924 self.file.seek(0)
925 elif self.list is not None:
926 value = self.list
927 else:
928 value = None
929 return value
Guido van Rossum7aee3841996-03-07 18:00:44 +0000930
931 def __getitem__(self, key):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000932 """Dictionary style indexing."""
933 if self.list is None:
934 raise TypeError, "not indexable"
935 found = []
936 for item in self.list:
937 if item.name == key: found.append(item)
938 if not found:
939 raise KeyError, key
940 if len(found) == 1:
941 return found[0]
942 else:
943 return found
Guido van Rossum7aee3841996-03-07 18:00:44 +0000944
945 def keys(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000946 """Dictionary style keys() method."""
947 if self.list is None:
948 raise TypeError, "not indexable"
949 keys = []
950 for item in self.list:
951 if item.name not in keys: keys.append(item.name)
952 return keys
Guido van Rossum7aee3841996-03-07 18:00:44 +0000953
Guido van Rossum0147db01996-03-09 03:16:04 +0000954 def has_key(self, key):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000955 """Dictionary style has_key() method."""
956 if self.list is None:
957 raise TypeError, "not indexable"
958 for item in self.list:
959 if item.name == key: return 1
960 return 0
Guido van Rossum0147db01996-03-09 03:16:04 +0000961
Guido van Rossum88b85d41997-01-11 19:21:33 +0000962 def __len__(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000963 """Dictionary style len(x) support."""
964 return len(self.keys())
Guido van Rossum88b85d41997-01-11 19:21:33 +0000965
Guido van Rossum7aee3841996-03-07 18:00:44 +0000966 def read_urlencoded(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000967 """Internal: read data in query string format."""
968 qs = self.fp.read(self.length)
Guido van Rossum1946f0d1999-06-04 17:54:39 +0000969 self.list = list = []
970 for key, value in parse_qsl(qs, self.keep_blank_values,
971 self.strict_parsing):
972 list.append(MiniFieldStorage(key, value))
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000973 self.skip_lines()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000974
Guido van Rossum030d2ec1998-12-09 22:16:46 +0000975 FieldStorageClass = None
976
Guido van Rossumf5745001998-10-20 14:43:02 +0000977 def read_multi(self, environ, keep_blank_values, strict_parsing):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000978 """Internal: read a part that is itself multipart."""
979 self.list = []
Guido van Rossum030d2ec1998-12-09 22:16:46 +0000980 klass = self.FieldStorageClass or self.__class__
981 part = klass(self.fp, {}, self.innerboundary,
982 environ, keep_blank_values, strict_parsing)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000983 # Throw first part away
984 while not part.done:
985 headers = rfc822.Message(self.fp)
Guido van Rossum030d2ec1998-12-09 22:16:46 +0000986 part = klass(self.fp, headers, self.innerboundary,
987 environ, keep_blank_values, strict_parsing)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000988 self.list.append(part)
989 self.skip_lines()
Guido van Rossum7aee3841996-03-07 18:00:44 +0000990
991 def read_single(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000992 """Internal: read an atomic part."""
993 if self.length >= 0:
994 self.read_binary()
995 self.skip_lines()
996 else:
997 self.read_lines()
998 self.file.seek(0)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000999
Guido van Rossum45e2fbc1998-03-26 21:13:24 +00001000 bufsize = 8*1024 # I/O buffering size for copy to file
Guido van Rossum7aee3841996-03-07 18:00:44 +00001001
1002 def read_binary(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +00001003 """Internal: read binary data."""
1004 self.file = self.make_file('b')
1005 todo = self.length
1006 if todo >= 0:
1007 while todo > 0:
1008 data = self.fp.read(min(todo, self.bufsize))
1009 if not data:
1010 self.done = -1
1011 break
1012 self.file.write(data)
1013 todo = todo - len(data)
Guido van Rossum7aee3841996-03-07 18:00:44 +00001014
1015 def read_lines(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +00001016 """Internal: read lines until EOF or outerboundary."""
1017 self.file = self.make_file('')
1018 if self.outerboundary:
1019 self.read_lines_to_outerboundary()
1020 else:
1021 self.read_lines_to_eof()
Guido van Rossum7aee3841996-03-07 18:00:44 +00001022
1023 def read_lines_to_eof(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +00001024 """Internal: read lines until EOF."""
1025 while 1:
1026 line = self.fp.readline()
1027 if not line:
1028 self.done = -1
1029 break
1030 self.lines.append(line)
1031 self.file.write(line)
Guido van Rossum7aee3841996-03-07 18:00:44 +00001032
1033 def read_lines_to_outerboundary(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +00001034 """Internal: read lines until outerboundary."""
1035 next = "--" + self.outerboundary
1036 last = next + "--"
1037 delim = ""
1038 while 1:
1039 line = self.fp.readline()
1040 if not line:
1041 self.done = -1
1042 break
1043 self.lines.append(line)
1044 if line[:2] == "--":
1045 strippedline = string.strip(line)
1046 if strippedline == next:
1047 break
1048 if strippedline == last:
1049 self.done = 1
1050 break
1051 odelim = delim
1052 if line[-2:] == "\r\n":
1053 delim = "\r\n"
1054 line = line[:-2]
1055 elif line[-1] == "\n":
1056 delim = "\n"
1057 line = line[:-1]
1058 else:
1059 delim = ""
1060 self.file.write(odelim + line)
Guido van Rossum7aee3841996-03-07 18:00:44 +00001061
1062 def skip_lines(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +00001063 """Internal: skip lines until outer boundary if defined."""
1064 if not self.outerboundary or self.done:
1065 return
1066 next = "--" + self.outerboundary
1067 last = next + "--"
1068 while 1:
1069 line = self.fp.readline()
1070 if not line:
1071 self.done = -1
1072 break
1073 self.lines.append(line)
1074 if line[:2] == "--":
1075 strippedline = string.strip(line)
1076 if strippedline == next:
1077 break
1078 if strippedline == last:
1079 self.done = 1
1080 break
Guido van Rossum7aee3841996-03-07 18:00:44 +00001081
Guido van Rossuma5e9fb61997-08-12 18:18:13 +00001082 def make_file(self, binary=None):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +00001083 """Overridable: return a readable & writable file.
Guido van Rossum7aee3841996-03-07 18:00:44 +00001084
Guido van Rossum45e2fbc1998-03-26 21:13:24 +00001085 The file will be used as follows:
1086 - data is written to it
1087 - seek(0)
1088 - data is read from it
Guido van Rossum7aee3841996-03-07 18:00:44 +00001089
Guido van Rossum45e2fbc1998-03-26 21:13:24 +00001090 The 'binary' argument is unused -- the file is always opened
1091 in binary mode.
Guido van Rossum7aee3841996-03-07 18:00:44 +00001092
Guido van Rossum45e2fbc1998-03-26 21:13:24 +00001093 This version opens a temporary file for reading and writing,
1094 and immediately deletes (unlinks) it. The trick (on Unix!) is
1095 that the file can still be used, but it can't be opened by
1096 another process, and it will automatically be deleted when it
1097 is closed or when the current process terminates.
Guido van Rossum4032c2c1996-03-09 04:04:35 +00001098
Guido van Rossum45e2fbc1998-03-26 21:13:24 +00001099 If you want a more permanent file, you derive a class which
1100 overrides this method. If you want a visible temporary file
1101 that is nevertheless automatically deleted when the script
1102 terminates, try defining a __del__ method in a derived class
1103 which unlinks the temporary files you have created.
Guido van Rossum7aee3841996-03-07 18:00:44 +00001104
Guido van Rossum45e2fbc1998-03-26 21:13:24 +00001105 """
1106 import tempfile
1107 return tempfile.TemporaryFile("w+b")
1108
Guido van Rossum243ddcd1996-03-07 06:33:07 +00001109
1110
Guido van Rossum4032c2c1996-03-09 04:04:35 +00001111# Backwards Compatibility Classes
1112# ===============================
Guido van Rossum9a22de11995-01-12 12:29:47 +00001113
1114class FormContentDict:
Guido van Rossum7aee3841996-03-07 18:00:44 +00001115 """Basic (multiple values per field) form content as dictionary.
Guido van Rossum72755611996-03-06 07:20:06 +00001116
Guido van Rossum7aee3841996-03-07 18:00:44 +00001117 form = FormContentDict()
1118
1119 form[key] -> [value, value, ...]
1120 form.has_key(key) -> Boolean
1121 form.keys() -> [key, key, ...]
1122 form.values() -> [[val, val, ...], [val, val, ...], ...]
1123 form.items() -> [(key, [val, val, ...]), (key, [val, val, ...]), ...]
1124 form.dict == {key: [val, val, ...], ...}
1125
1126 """
Guido van Rossum773ab271996-07-23 03:46:24 +00001127 def __init__(self, environ=os.environ):
Guido van Rossumafb5e931996-08-08 18:42:12 +00001128 self.dict = parse(environ=environ)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +00001129 self.query_string = environ['QUERY_STRING']
Guido van Rossum7aee3841996-03-07 18:00:44 +00001130 def __getitem__(self,key):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +00001131 return self.dict[key]
Guido van Rossum7aee3841996-03-07 18:00:44 +00001132 def keys(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +00001133 return self.dict.keys()
Guido van Rossum7aee3841996-03-07 18:00:44 +00001134 def has_key(self, key):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +00001135 return self.dict.has_key(key)
Guido van Rossum7aee3841996-03-07 18:00:44 +00001136 def values(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +00001137 return self.dict.values()
Guido van Rossum7aee3841996-03-07 18:00:44 +00001138 def items(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +00001139 return self.dict.items()
Guido van Rossum7aee3841996-03-07 18:00:44 +00001140 def __len__( self ):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +00001141 return len(self.dict)
Guido van Rossum9a22de11995-01-12 12:29:47 +00001142
1143
Guido van Rossum9a22de11995-01-12 12:29:47 +00001144class SvFormContentDict(FormContentDict):
Guido van Rossum7aee3841996-03-07 18:00:44 +00001145 """Strict single-value expecting form content as dictionary.
1146
1147 IF you only expect a single value for each field, then form[key]
1148 will return that single value. It will raise an IndexError if
1149 that expectation is not true. IF you expect a field to have
1150 possible multiple values, than you can use form.getlist(key) to
1151 get all of the values. values() and items() are a compromise:
1152 they return single strings where there is a single value, and
1153 lists of strings otherwise.
1154
1155 """
1156 def __getitem__(self, key):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +00001157 if len(self.dict[key]) > 1:
1158 raise IndexError, 'expecting a single value'
1159 return self.dict[key][0]
Guido van Rossum7aee3841996-03-07 18:00:44 +00001160 def getlist(self, key):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +00001161 return self.dict[key]
Guido van Rossum7aee3841996-03-07 18:00:44 +00001162 def values(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +00001163 lis = []
1164 for each in self.dict.values():
1165 if len( each ) == 1 :
1166 lis.append(each[0])
1167 else: lis.append(each)
1168 return lis
Guido van Rossum7aee3841996-03-07 18:00:44 +00001169 def items(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +00001170 lis = []
1171 for key,value in self.dict.items():
1172 if len(value) == 1 :
1173 lis.append((key, value[0]))
1174 else: lis.append((key, value))
1175 return lis
Guido van Rossum9a22de11995-01-12 12:29:47 +00001176
1177
Guido van Rossum9a22de11995-01-12 12:29:47 +00001178class InterpFormContentDict(SvFormContentDict):
Guido van Rossum7aee3841996-03-07 18:00:44 +00001179 """This class is present for backwards compatibility only."""
1180 def __getitem__( self, key ):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +00001181 v = SvFormContentDict.__getitem__( self, key )
1182 if v[0] in string.digits+'+-.' :
1183 try: return string.atoi( v )
1184 except ValueError:
1185 try: return string.atof( v )
1186 except ValueError: pass
1187 return string.strip(v)
Guido van Rossum7aee3841996-03-07 18:00:44 +00001188 def values( self ):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +00001189 lis = []
1190 for key in self.keys():
1191 try:
1192 lis.append( self[key] )
1193 except IndexError:
1194 lis.append( self.dict[key] )
1195 return lis
Guido van Rossum7aee3841996-03-07 18:00:44 +00001196 def items( self ):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +00001197 lis = []
1198 for key in self.keys():
1199 try:
1200 lis.append( (key, self[key]) )
1201 except IndexError:
1202 lis.append( (key, self.dict[key]) )
1203 return lis
Guido van Rossum9a22de11995-01-12 12:29:47 +00001204
1205
Guido van Rossum9a22de11995-01-12 12:29:47 +00001206class FormContent(FormContentDict):
Guido van Rossum7aee3841996-03-07 18:00:44 +00001207 """This class is present for backwards compatibility only."""
Guido van Rossum0147db01996-03-09 03:16:04 +00001208 def values(self, key):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +00001209 if self.dict.has_key(key) :return self.dict[key]
1210 else: return None
Guido van Rossum0147db01996-03-09 03:16:04 +00001211 def indexed_value(self, key, location):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +00001212 if self.dict.has_key(key):
1213 if len (self.dict[key]) > location:
1214 return self.dict[key][location]
1215 else: return None
1216 else: return None
Guido van Rossum0147db01996-03-09 03:16:04 +00001217 def value(self, key):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +00001218 if self.dict.has_key(key): return self.dict[key][0]
1219 else: return None
Guido van Rossum0147db01996-03-09 03:16:04 +00001220 def length(self, key):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +00001221 return len(self.dict[key])
Guido van Rossum0147db01996-03-09 03:16:04 +00001222 def stripped(self, key):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +00001223 if self.dict.has_key(key): return string.strip(self.dict[key][0])
1224 else: return None
Guido van Rossum7aee3841996-03-07 18:00:44 +00001225 def pars(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +00001226 return self.dict
Guido van Rossum9a22de11995-01-12 12:29:47 +00001227
1228
Guido van Rossum72755611996-03-06 07:20:06 +00001229# Test/debug code
1230# ===============
Guido van Rossum9a22de11995-01-12 12:29:47 +00001231
Guido van Rossum773ab271996-07-23 03:46:24 +00001232def test(environ=os.environ):
Guido van Rossum7aee3841996-03-07 18:00:44 +00001233 """Robust test CGI script, usable as main program.
Guido van Rossum9a22de11995-01-12 12:29:47 +00001234
Guido van Rossum7aee3841996-03-07 18:00:44 +00001235 Write minimal HTTP headers and dump all information provided to
1236 the script in HTML form.
1237
1238 """
1239 import traceback
1240 print "Content-type: text/html"
1241 print
1242 sys.stderr = sys.stdout
1243 try:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +00001244 form = FieldStorage() # Replace with other classes to test those
1245 print_form(form)
Guido van Rossum773ab271996-07-23 03:46:24 +00001246 print_environ(environ)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +00001247 print_directory()
1248 print_arguments()
1249 print_environ_usage()
1250 def f():
1251 exec "testing print_exception() -- <I>italics?</I>"
1252 def g(f=f):
1253 f()
1254 print "<H3>What follows is a test, not an actual exception:</H3>"
1255 g()
Guido van Rossum7aee3841996-03-07 18:00:44 +00001256 except:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +00001257 print_exception()
Guido van Rossumf85de8a1996-08-20 20:22:39 +00001258
Guido van Rossumad164711997-05-13 19:03:23 +00001259 # Second try with a small maxlen...
1260 global maxlen
1261 maxlen = 50
1262 try:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +00001263 form = FieldStorage() # Replace with other classes to test those
1264 print_form(form)
1265 print_environ(environ)
1266 print_directory()
1267 print_arguments()
1268 print_environ_usage()
Guido van Rossumad164711997-05-13 19:03:23 +00001269 except:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +00001270 print_exception()
Guido van Rossumad164711997-05-13 19:03:23 +00001271
Guido van Rossumf85de8a1996-08-20 20:22:39 +00001272def print_exception(type=None, value=None, tb=None, limit=None):
1273 if type is None:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +00001274 type, value, tb = sys.exc_info()
Guido van Rossumf85de8a1996-08-20 20:22:39 +00001275 import traceback
1276 print
1277 print "<H3>Traceback (innermost last):</H3>"
1278 list = traceback.format_tb(tb, limit) + \
Guido van Rossum45e2fbc1998-03-26 21:13:24 +00001279 traceback.format_exception_only(type, value)
Guido van Rossumf85de8a1996-08-20 20:22:39 +00001280 print "<PRE>%s<B>%s</B></PRE>" % (
Guido van Rossum45e2fbc1998-03-26 21:13:24 +00001281 escape(string.join(list[:-1], "")),
1282 escape(list[-1]),
1283 )
Guido van Rossumf15d1591997-09-29 23:22:12 +00001284 del tb
Guido van Rossum9a22de11995-01-12 12:29:47 +00001285
Guido van Rossum773ab271996-07-23 03:46:24 +00001286def print_environ(environ=os.environ):
Guido van Rossum7aee3841996-03-07 18:00:44 +00001287 """Dump the shell environment as HTML."""
1288 keys = environ.keys()
1289 keys.sort()
1290 print
Guido van Rossum503e50b1996-05-28 22:57:20 +00001291 print "<H3>Shell Environment:</H3>"
Guido van Rossum7aee3841996-03-07 18:00:44 +00001292 print "<DL>"
1293 for key in keys:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +00001294 print "<DT>", escape(key), "<DD>", escape(environ[key])
Guido van Rossum7aee3841996-03-07 18:00:44 +00001295 print "</DL>"
1296 print
Guido van Rossum72755611996-03-06 07:20:06 +00001297
1298def print_form(form):
Guido van Rossum7aee3841996-03-07 18:00:44 +00001299 """Dump the contents of a form as HTML."""
1300 keys = form.keys()
1301 keys.sort()
1302 print
Guido van Rossum503e50b1996-05-28 22:57:20 +00001303 print "<H3>Form Contents:</H3>"
Guido van Rossum7aee3841996-03-07 18:00:44 +00001304 print "<DL>"
1305 for key in keys:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +00001306 print "<DT>" + escape(key) + ":",
1307 value = form[key]
1308 print "<i>" + escape(`type(value)`) + "</i>"
1309 print "<DD>" + escape(`value`)
Guido van Rossum7aee3841996-03-07 18:00:44 +00001310 print "</DL>"
1311 print
1312
1313def print_directory():
1314 """Dump the current directory as HTML."""
1315 print
1316 print "<H3>Current Working Directory:</H3>"
1317 try:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +00001318 pwd = os.getcwd()
Guido van Rossum7aee3841996-03-07 18:00:44 +00001319 except os.error, msg:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +00001320 print "os.error:", escape(str(msg))
Guido van Rossum7aee3841996-03-07 18:00:44 +00001321 else:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +00001322 print escape(pwd)
Guido van Rossum7aee3841996-03-07 18:00:44 +00001323 print
Guido van Rossum9a22de11995-01-12 12:29:47 +00001324
Guido van Rossuma8738a51996-03-14 21:30:28 +00001325def print_arguments():
1326 print
Guido van Rossum503e50b1996-05-28 22:57:20 +00001327 print "<H3>Command Line Arguments:</H3>"
Guido van Rossuma8738a51996-03-14 21:30:28 +00001328 print
1329 print sys.argv
1330 print
1331
Guido van Rossum9a22de11995-01-12 12:29:47 +00001332def print_environ_usage():
Guido van Rossum7aee3841996-03-07 18:00:44 +00001333 """Dump a list of environment variables used by CGI as HTML."""
1334 print """
Guido van Rossum72755611996-03-06 07:20:06 +00001335<H3>These environment variables could have been set:</H3>
1336<UL>
Guido van Rossum9a22de11995-01-12 12:29:47 +00001337<LI>AUTH_TYPE
1338<LI>CONTENT_LENGTH
1339<LI>CONTENT_TYPE
1340<LI>DATE_GMT
1341<LI>DATE_LOCAL
1342<LI>DOCUMENT_NAME
1343<LI>DOCUMENT_ROOT
1344<LI>DOCUMENT_URI
1345<LI>GATEWAY_INTERFACE
1346<LI>LAST_MODIFIED
1347<LI>PATH
1348<LI>PATH_INFO
1349<LI>PATH_TRANSLATED
1350<LI>QUERY_STRING
1351<LI>REMOTE_ADDR
1352<LI>REMOTE_HOST
1353<LI>REMOTE_IDENT
1354<LI>REMOTE_USER
1355<LI>REQUEST_METHOD
1356<LI>SCRIPT_NAME
1357<LI>SERVER_NAME
1358<LI>SERVER_PORT
1359<LI>SERVER_PROTOCOL
1360<LI>SERVER_ROOT
1361<LI>SERVER_SOFTWARE
1362</UL>
Guido van Rossum7aee3841996-03-07 18:00:44 +00001363In addition, HTTP headers sent by the server may be passed in the
1364environment as well. Here are some common variable names:
1365<UL>
1366<LI>HTTP_ACCEPT
1367<LI>HTTP_CONNECTION
1368<LI>HTTP_HOST
1369<LI>HTTP_PRAGMA
1370<LI>HTTP_REFERER
1371<LI>HTTP_USER_AGENT
1372</UL>
Guido van Rossum9a22de11995-01-12 12:29:47 +00001373"""
1374
Guido van Rossum9a22de11995-01-12 12:29:47 +00001375
Guido van Rossum72755611996-03-06 07:20:06 +00001376# Utilities
1377# =========
Guido van Rossum9a22de11995-01-12 12:29:47 +00001378
Guido van Rossum64c66201997-07-19 20:11:53 +00001379def escape(s, quote=None):
Guido van Rossum7aee3841996-03-07 18:00:44 +00001380 """Replace special characters '&', '<' and '>' by SGML entities."""
Guido van Rossum45e2fbc1998-03-26 21:13:24 +00001381 s = string.replace(s, "&", "&amp;") # Must be done first!
Guido van Rossum00f9fea1997-12-24 21:18:41 +00001382 s = string.replace(s, "<", "&lt;")
1383 s = string.replace(s, ">", "&gt;",)
Guido van Rossum64c66201997-07-19 20:11:53 +00001384 if quote:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +00001385 s = string.replace(s, '"', "&quot;")
Guido van Rossum7aee3841996-03-07 18:00:44 +00001386 return s
Guido van Rossum9a22de11995-01-12 12:29:47 +00001387
Guido van Rossum9a22de11995-01-12 12:29:47 +00001388
Guido van Rossum72755611996-03-06 07:20:06 +00001389# Invoke mainline
1390# ===============
1391
1392# Call test() when this file is run as a script (not imported as a module)
1393if __name__ == '__main__':
Guido van Rossum7aee3841996-03-07 18:00:44 +00001394 test()