blob: 388e4402d0994299258a11dc4f183f1778a0a103 [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 Rossum243ddcd1996-03-07 06:33:07 +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
42 print "<TITLE>CGI script output</TITLE>"
43 print "<H1>This is my first CGI script</H1>"
44 print "Hello, world!"
45
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 Rossum503e50b1996-05-28 22:57:20 +000069 form = cgi.FieldStorage()
Guido van Rossum72755611996-03-06 07:20:06 +000070 form_ok = 0
71 if form.has_key("name") and form.has_key("addr"):
Guido van Rossum0147db01996-03-09 03:16:04 +000072 if form["name"].value != "" and form["addr"].value != "":
Guido van Rossum72755611996-03-06 07:20:06 +000073 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
Guido van Rossum0147db01996-03-09 03:16:04 +000078 ...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
91 username = form["username"]
Guido van Rossum0147db01996-03-09 03:16:04 +000092 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
Guido van Rossum4032c2c1996-03-09 04:04:35 +0000104 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
112 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
120
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
166string (data of type application/x-www-form-urlencoded).
Guido van Rossum72755611996-03-06 07:20:06 +0000167
Guido van Rossum0147db01996-03-09 03:16:04 +0000168parse_multipart(fp, pdict): parse input of type multipart/form-data (for
Guido van Rossum391b4e61996-03-06 19:11:33 +0000169file uploads).
Guido van Rossum72755611996-03-06 07:20:06 +0000170
Guido van Rossum391b4e61996-03-06 19:11:33 +0000171parse_header(string): parse a header like Content-type into a main
172value and a dictionary of parameters.
Guido van Rossum72755611996-03-06 07:20:06 +0000173
174test(): complete test program.
175
176print_environ(): format the shell environment in HTML.
177
178print_form(form): format a form in HTML.
179
Guido van Rossum391b4e61996-03-06 19:11:33 +0000180print_environ_usage(): print a list of useful environment variables in
181HTML.
Guido van Rossum72755611996-03-06 07:20:06 +0000182
Guido van Rossum391b4e61996-03-06 19:11:33 +0000183escape(): convert the characters "&", "<" and ">" to HTML-safe
184sequences. Use this if you need to display text that might contain
185such characters in HTML. To translate URLs for inclusion in the HREF
186attribute of an <A> tag, use urllib.quote().
Guido van Rossum72755611996-03-06 07:20:06 +0000187
Guido van Rossumc204c701996-09-05 19:07:11 +0000188log(fmt, ...): write a line to a log file; see docs for initlog().
189
Guido van Rossum72755611996-03-06 07:20:06 +0000190
191Caring about security
192---------------------
193
Guido van Rossum391b4e61996-03-06 19:11:33 +0000194There's one important rule: if you invoke an external program (e.g.
195via the os.system() or os.popen() functions), make very sure you don't
196pass arbitrary strings received from the client to the shell. This is
197a well-known security hole whereby clever hackers anywhere on the web
198can exploit a gullible CGI script to invoke arbitrary shell commands.
199Even parts of the URL or field names cannot be trusted, since the
200request doesn't have to come from your form!
Guido van Rossum72755611996-03-06 07:20:06 +0000201
Guido van Rossum391b4e61996-03-06 19:11:33 +0000202To be on the safe side, if you must pass a string gotten from a form
203to a shell command, you should make sure the string contains only
204alphanumeric characters, dashes, underscores, and periods.
Guido van Rossum72755611996-03-06 07:20:06 +0000205
206
207Installing your CGI script on a Unix system
208-------------------------------------------
209
Guido van Rossum391b4e61996-03-06 19:11:33 +0000210Read the documentation for your HTTP server and check with your local
211system administrator to find the directory where CGI scripts should be
Guido van Rossum72755611996-03-06 07:20:06 +0000212installed; usually this is in a directory cgi-bin in the server tree.
213
Guido van Rossum391b4e61996-03-06 19:11:33 +0000214Make sure that your script is readable and executable by "others"; the
215Unix file mode should be 755 (use "chmod 755 filename"). Make sure
Guido van Rossum43055421997-05-28 15:11:01 +0000216that the first line of the script contains #! starting in column 1
Guido van Rossum391b4e61996-03-06 19:11:33 +0000217followed by the pathname of the Python interpreter, for instance:
Guido van Rossum72755611996-03-06 07:20:06 +0000218
Guido van Rossumf06ee5f1996-11-27 19:52:01 +0000219 #! /usr/local/bin/python
Guido van Rossum72755611996-03-06 07:20:06 +0000220
Guido van Rossum391b4e61996-03-06 19:11:33 +0000221Make sure the Python interpreter exists and is executable by "others".
Guido van Rossum72755611996-03-06 07:20:06 +0000222
Guido van Rossum43055421997-05-28 15:11:01 +0000223Note that it's probably not a good idea to use #! /usr/bin/env python
Guido van Rossumf06ee5f1996-11-27 19:52:01 +0000224here, since the Python interpreter may not be on the default path
Guido van Rossum43055421997-05-28 15:11:01 +0000225given to CGI scripts!!!
Guido van Rossumf06ee5f1996-11-27 19:52:01 +0000226
Guido van Rossum391b4e61996-03-06 19:11:33 +0000227Make sure that any files your script needs to read or write are
228readable or writable, respectively, by "others" -- their mode should
229be 644 for readable and 666 for writable. This is because, for
230security reasons, the HTTP server executes your script as user
231"nobody", without any special privileges. It can only read (write,
232execute) files that everybody can read (write, execute). The current
233directory at execution time is also different (it is usually the
234server's cgi-bin directory) and the set of environment variables is
235also different from what you get at login. in particular, don't count
236on the shell's search path for executables ($PATH) or the Python
237module search path ($PYTHONPATH) to be set to anything interesting.
Guido van Rossum72755611996-03-06 07:20:06 +0000238
Guido van Rossum391b4e61996-03-06 19:11:33 +0000239If you need to load modules from a directory which is not on Python's
240default module search path, you can change the path in your script,
241before importing other modules, e.g.:
Guido van Rossum72755611996-03-06 07:20:06 +0000242
243 import sys
244 sys.path.insert(0, "/usr/home/joe/lib/python")
245 sys.path.insert(0, "/usr/local/lib/python")
246
Guido van Rossum43055421997-05-28 15:11:01 +0000247This way, the directory inserted last will be searched first!
Guido van Rossum72755611996-03-06 07:20:06 +0000248
Guido van Rossum391b4e61996-03-06 19:11:33 +0000249Instructions for non-Unix systems will vary; check your HTTP server's
Guido van Rossum72755611996-03-06 07:20:06 +0000250documentation (it will usually have a section on CGI scripts).
251
252
253Testing your CGI script
254-----------------------
255
Guido van Rossum391b4e61996-03-06 19:11:33 +0000256Unfortunately, a CGI script will generally not run when you try it
257from the command line, and a script that works perfectly from the
258command line may fail mysteriously when run from the server. There's
259one reason why you should still test your script from the command
260line: if it contains a syntax error, the python interpreter won't
261execute it at all, and the HTTP server will most likely send a cryptic
262error to the client.
Guido van Rossum72755611996-03-06 07:20:06 +0000263
Guido van Rossum391b4e61996-03-06 19:11:33 +0000264Assuming your script has no syntax errors, yet it does not work, you
265have no choice but to read the next section:
Guido van Rossum72755611996-03-06 07:20:06 +0000266
267
268Debugging CGI scripts
269---------------------
270
Guido van Rossum391b4e61996-03-06 19:11:33 +0000271First of all, check for trivial installation errors -- reading the
272section above on installing your CGI script carefully can save you a
273lot of time. If you wonder whether you have understood the
274installation procedure correctly, try installing a copy of this module
275file (cgi.py) as a CGI script. When invoked as a script, the file
276will dump its environment and the contents of the form in HTML form.
277Give it the right mode etc, and send it a request. If it's installed
278in the standard cgi-bin directory, it should be possible to send it a
279request by entering a URL into your browser of the form:
Guido van Rossum72755611996-03-06 07:20:06 +0000280
281 http://yourhostname/cgi-bin/cgi.py?name=Joe+Blow&addr=At+Home
282
Guido van Rossum391b4e61996-03-06 19:11:33 +0000283If this gives an error of type 404, the server cannot find the script
284-- perhaps you need to install it in a different directory. If it
285gives another error (e.g. 500), there's an installation problem that
286you should fix before trying to go any further. If you get a nicely
287formatted listing of the environment and form content (in this
288example, the fields should be listed as "addr" with value "At Home"
289and "name" with value "Joe Blow"), the cgi.py script has been
290installed correctly. If you follow the same procedure for your own
291script, you should now be able to debug it.
Guido van Rossum72755611996-03-06 07:20:06 +0000292
Guido van Rossum391b4e61996-03-06 19:11:33 +0000293The next step could be to call the cgi module's test() function from
294your script: replace its main code with the single statement
Guido van Rossum72755611996-03-06 07:20:06 +0000295
296 cgi.test()
297
Guido van Rossum391b4e61996-03-06 19:11:33 +0000298This should produce the same results as those gotten from installing
299the cgi.py file itself.
Guido van Rossum72755611996-03-06 07:20:06 +0000300
Guido van Rossum43055421997-05-28 15:11:01 +0000301When an ordinary Python script raises an unhandled exception (e.g.,
302because of a typo in a module name, a file that can't be opened,
Guido van Rossum391b4e61996-03-06 19:11:33 +0000303etc.), the Python interpreter prints a nice traceback and exits.
304While the Python interpreter will still do this when your CGI script
305raises an exception, most likely the traceback will end up in one of
306the HTTP server's log file, or be discarded altogether.
Guido van Rossum72755611996-03-06 07:20:06 +0000307
Guido van Rossum391b4e61996-03-06 19:11:33 +0000308Fortunately, once you have managed to get your script to execute
309*some* code, it is easy to catch exceptions and cause a traceback to
310be printed. The test() function below in this module is an example.
311Here are the rules:
Guido van Rossum72755611996-03-06 07:20:06 +0000312
Guido van Rossum391b4e61996-03-06 19:11:33 +0000313 1. Import the traceback module (before entering the
314 try-except!)
Guido van Rossum72755611996-03-06 07:20:06 +0000315
Guido van Rossum391b4e61996-03-06 19:11:33 +0000316 2. Make sure you finish printing the headers and the blank
317 line early
Guido van Rossum72755611996-03-06 07:20:06 +0000318
319 3. Assign sys.stderr to sys.stdout
320
321 3. Wrap all remaining code in a try-except statement
322
323 4. In the except clause, call traceback.print_exc()
324
325For example:
326
327 import sys
328 import traceback
329 print "Content-type: text/html"
330 print
331 sys.stderr = sys.stdout
332 try:
333 ...your code here...
334 except:
335 print "\n\n<PRE>"
336 traceback.print_exc()
337
Guido van Rossum391b4e61996-03-06 19:11:33 +0000338Notes: The assignment to sys.stderr is needed because the traceback
339prints to sys.stderr. The print "\n\n<PRE>" statement is necessary to
340disable the word wrapping in HTML.
Guido van Rossum72755611996-03-06 07:20:06 +0000341
Guido van Rossum391b4e61996-03-06 19:11:33 +0000342If you suspect that there may be a problem in importing the traceback
343module, you can use an even more robust approach (which only uses
344built-in modules):
Guido van Rossum72755611996-03-06 07:20:06 +0000345
346 import sys
347 sys.stderr = sys.stdout
348 print "Content-type: text/plain"
349 print
350 ...your code here...
351
Guido van Rossum391b4e61996-03-06 19:11:33 +0000352This relies on the Python interpreter to print the traceback. The
353content type of the output is set to plain text, which disables all
354HTML processing. If your script works, the raw HTML will be displayed
355by your client. If it raises an exception, most likely after the
356first two lines have been printed, a traceback will be displayed.
357Because no HTML interpretation is going on, the traceback will
358readable.
Guido van Rossum72755611996-03-06 07:20:06 +0000359
Guido van Rossumc204c701996-09-05 19:07:11 +0000360When all else fails, you may want to insert calls to log() to your
361program or even to a copy of the cgi.py file. Note that this requires
362you to set cgi.logfile to the name of a world-writable file before the
363first call to log() is made!
364
Guido van Rossum72755611996-03-06 07:20:06 +0000365Good luck!
366
367
368Common problems and solutions
369-----------------------------
370
Guido van Rossum391b4e61996-03-06 19:11:33 +0000371- Most HTTP servers buffer the output from CGI scripts until the
372script is completed. This means that it is not possible to display a
373progress report on the client's display while the script is running.
Guido van Rossum72755611996-03-06 07:20:06 +0000374
375- Check the installation instructions above.
376
Guido van Rossum391b4e61996-03-06 19:11:33 +0000377- Check the HTTP server's log files. ("tail -f logfile" in a separate
Guido van Rossum72755611996-03-06 07:20:06 +0000378window may be useful!)
379
Guido van Rossum391b4e61996-03-06 19:11:33 +0000380- Always check a script for syntax errors first, by doing something
381like "python script.py".
Guido van Rossum72755611996-03-06 07:20:06 +0000382
383- When using any of the debugging techniques, don't forget to add
384"import sys" to the top of the script.
385
Guido van Rossum391b4e61996-03-06 19:11:33 +0000386- When invoking external programs, make sure they can be found.
387Usually, this means using absolute path names -- $PATH is usually not
388set to a very useful value in a CGI script.
Guido van Rossum72755611996-03-06 07:20:06 +0000389
Guido van Rossum391b4e61996-03-06 19:11:33 +0000390- When reading or writing external files, make sure they can be read
391or written by every user on the system.
Guido van Rossum72755611996-03-06 07:20:06 +0000392
Guido van Rossum391b4e61996-03-06 19:11:33 +0000393- Don't try to give a CGI script a set-uid mode. This doesn't work on
394most systems, and is a security liability as well.
Guido van Rossum72755611996-03-06 07:20:06 +0000395
396
397History
398-------
399
Guido van Rossum391b4e61996-03-06 19:11:33 +0000400Michael McLay started this module. Steve Majewski changed the
401interface to SvFormContentDict and FormContentDict. The multipart
402parsing was inspired by code submitted by Andreas Paepcke. Guido van
403Rossum rewrote, reformatted and documented the module and is currently
404responsible for its maintenance.
Guido van Rossum72755611996-03-06 07:20:06 +0000405
Guido van Rossum0147db01996-03-09 03:16:04 +0000406
407XXX The module is getting pretty heavy with all those docstrings.
408Perhaps there should be a slimmed version that doesn't contain all those
409backwards compatible and debugging classes and functions?
410
Guido van Rossum72755611996-03-06 07:20:06 +0000411"""
412
Guido van Rossum5f322481997-04-11 18:20:42 +0000413__version__ = "2.2"
Guido van Rossum0147db01996-03-09 03:16:04 +0000414
Guido van Rossum72755611996-03-06 07:20:06 +0000415
416# Imports
417# =======
418
419import string
Guido van Rossum72755611996-03-06 07:20:06 +0000420import sys
421import os
Guido van Rossuma5e9fb61997-08-12 18:18:13 +0000422import urllib
423import regsub
424import mimetools
425import rfc822
426from StringIO import StringIO
Guido van Rossum72755611996-03-06 07:20:06 +0000427
Guido van Rossumc204c701996-09-05 19:07:11 +0000428
429# Logging support
430# ===============
431
432logfile = "" # Filename to log to, if not empty
433logfp = None # File object to log to, if not None
434
435def initlog(*allargs):
436 """Write a log message, if there is a log file.
437
438 Even though this function is called initlog(), you should always
439 use log(); log is a variable that is set either to initlog
440 (initially), to dolog (once the log file has been opened), or to
441 nolog (when logging is disabled).
442
443 The first argument is a format string; the remaining arguments (if
444 any) are arguments to the % operator, so e.g.
445 log("%s: %s", "a", "b")
446 will write "a: b" to the log file, followed by a newline.
447
448 If the global logfp is not None, it should be a file object to
449 which log data is written.
450
451 If the global logfp is None, the global logfile may be a string
452 giving a filename to open, in append mode. This file should be
453 world writable!!! If the file can't be opened, logging is
454 silently disabled (since there is no safe place where we could
455 send an error message).
456
457 """
458 global logfp, log
459 if logfile and not logfp:
460 try:
461 logfp = open(logfile, "a")
462 except IOError:
463 pass
464 if not logfp:
465 log = nolog
466 else:
467 log = dolog
468 apply(log, allargs)
469
470def dolog(fmt, *args):
471 """Write a log message to the log file. See initlog() for docs."""
472 logfp.write(fmt%args + "\n")
473
474def nolog(*allargs):
475 """Dummy function, assigned to log when logging is disabled."""
476 pass
477
478log = initlog # The current logging function
479
480
Guido van Rossum72755611996-03-06 07:20:06 +0000481# Parsing functions
482# =================
483
Guido van Rossumad164711997-05-13 19:03:23 +0000484# Maximum input we will accept when REQUEST_METHOD is POST
485# 0 ==> unlimited input
486maxlen = 0
487
Guido van Rossume08c04c1996-11-11 19:29:11 +0000488def parse(fp=None, environ=os.environ, keep_blank_values=0, strict_parsing=0):
Guido van Rossum773ab271996-07-23 03:46:24 +0000489 """Parse a query in the environment or from a file (default stdin)
490
491 Arguments, all optional:
492
493 fp : file pointer; default: sys.stdin
494
495 environ : environment dictionary; default: os.environ
496
497 keep_blank_values: flag indicating whether blank values in
498 URL encoded forms should be treated as blank strings.
499 A true value inicates that blanks should be retained as
500 blank strings. The default false value indicates that
501 blank values are to be ignored and treated as if they were
502 not included.
Guido van Rossume08c04c1996-11-11 19:29:11 +0000503
504 strict_parsing: flag indicating what to do with parsing errors.
505 If false (the default), errors are silently ignored.
506 If true, errors raise a ValueError exception.
Guido van Rossum773ab271996-07-23 03:46:24 +0000507 """
Guido van Rossum7aee3841996-03-07 18:00:44 +0000508 if not fp:
509 fp = sys.stdin
510 if not environ.has_key('REQUEST_METHOD'):
511 environ['REQUEST_METHOD'] = 'GET' # For testing stand-alone
512 if environ['REQUEST_METHOD'] == 'POST':
513 ctype, pdict = parse_header(environ['CONTENT_TYPE'])
514 if ctype == 'multipart/form-data':
Guido van Rossum0147db01996-03-09 03:16:04 +0000515 return parse_multipart(fp, pdict)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000516 elif ctype == 'application/x-www-form-urlencoded':
517 clength = string.atoi(environ['CONTENT_LENGTH'])
Guido van Rossumad164711997-05-13 19:03:23 +0000518 if maxlen and clength > maxlen:
519 raise ValueError, 'Maximum content length exceeded'
Guido van Rossum7aee3841996-03-07 18:00:44 +0000520 qs = fp.read(clength)
Guido van Rossum1c9daa81995-09-18 21:52:37 +0000521 else:
Guido van Rossum0147db01996-03-09 03:16:04 +0000522 qs = '' # Unknown content-type
Guido van Rossumafb5e931996-08-08 18:42:12 +0000523 if environ.has_key('QUERY_STRING'):
524 if qs: qs = qs + '&'
525 qs = qs + environ['QUERY_STRING']
526 elif sys.argv[1:]:
527 if qs: qs = qs + '&'
528 qs = qs + sys.argv[1]
Guido van Rossum7aee3841996-03-07 18:00:44 +0000529 environ['QUERY_STRING'] = qs # XXX Shouldn't, really
530 elif environ.has_key('QUERY_STRING'):
531 qs = environ['QUERY_STRING']
532 else:
533 if sys.argv[1:]:
534 qs = sys.argv[1]
535 else:
536 qs = ""
537 environ['QUERY_STRING'] = qs # XXX Shouldn't, really
Guido van Rossume08c04c1996-11-11 19:29:11 +0000538 return parse_qs(qs, keep_blank_values, strict_parsing)
Guido van Rossume7808771995-08-07 20:12:09 +0000539
540
Guido van Rossume08c04c1996-11-11 19:29:11 +0000541def parse_qs(qs, keep_blank_values=0, strict_parsing=0):
542 """Parse a query given as a string argument.
Guido van Rossum773ab271996-07-23 03:46:24 +0000543
544 Arguments:
545
Guido van Rossume08c04c1996-11-11 19:29:11 +0000546 qs: URL-encoded query string to be parsed
Guido van Rossum773ab271996-07-23 03:46:24 +0000547
548 keep_blank_values: flag indicating whether blank values in
549 URL encoded queries should be treated as blank strings.
550 A true value inicates that blanks should be retained as
551 blank strings. The default false value indicates that
552 blank values are to be ignored and treated as if they were
553 not included.
Guido van Rossume08c04c1996-11-11 19:29:11 +0000554
555 strict_parsing: flag indicating what to do with parsing errors.
556 If false (the default), errors are silently ignored.
557 If true, errors raise a ValueError exception.
Guido van Rossum773ab271996-07-23 03:46:24 +0000558 """
Guido van Rossum7aee3841996-03-07 18:00:44 +0000559 name_value_pairs = string.splitfields(qs, '&')
560 dict = {}
561 for name_value in name_value_pairs:
562 nv = string.splitfields(name_value, '=')
563 if len(nv) != 2:
Guido van Rossume08c04c1996-11-11 19:29:11 +0000564 if strict_parsing:
565 raise ValueError, "bad query field: %s" % `name_value`
Guido van Rossum7aee3841996-03-07 18:00:44 +0000566 continue
Guido van Rossum5f322481997-04-11 18:20:42 +0000567 name = urllib.unquote(regsub.gsub('+', ' ', nv[0]))
Guido van Rossum7aee3841996-03-07 18:00:44 +0000568 value = urllib.unquote(regsub.gsub('+', ' ', nv[1]))
Guido van Rossum773ab271996-07-23 03:46:24 +0000569 if len(value) or keep_blank_values:
Guido van Rossum7aee3841996-03-07 18:00:44 +0000570 if dict.has_key (name):
571 dict[name].append(value)
572 else:
573 dict[name] = [value]
574 return dict
Guido van Rossum9a22de11995-01-12 12:29:47 +0000575
576
Guido van Rossum0147db01996-03-09 03:16:04 +0000577def parse_multipart(fp, pdict):
Guido van Rossum7aee3841996-03-07 18:00:44 +0000578 """Parse multipart input.
Guido van Rossum9a22de11995-01-12 12:29:47 +0000579
Guido van Rossum7aee3841996-03-07 18:00:44 +0000580 Arguments:
581 fp : input file
Guido van Rossum7aee3841996-03-07 18:00:44 +0000582 pdict: dictionary containing other parameters of conten-type header
Guido van Rossum72755611996-03-06 07:20:06 +0000583
Guido van Rossum0147db01996-03-09 03:16:04 +0000584 Returns a dictionary just like parse_qs(): keys are the field names, each
585 value is a list of values for that field. This is easy to use but not
586 much good if you are expecting megabytes to be uploaded -- in that case,
587 use the FieldStorage class instead which is much more flexible. Note
588 that content-type is the raw, unparsed contents of the content-type
589 header.
590
591 XXX This does not parse nested multipart parts -- use FieldStorage for
592 that.
593
594 XXX This should really be subsumed by FieldStorage altogether -- no
595 point in having two implementations of the same parsing algorithm.
Guido van Rossum72755611996-03-06 07:20:06 +0000596
Guido van Rossum7aee3841996-03-07 18:00:44 +0000597 """
Guido van Rossum7aee3841996-03-07 18:00:44 +0000598 if pdict.has_key('boundary'):
599 boundary = pdict['boundary']
600 else:
601 boundary = ""
602 nextpart = "--" + boundary
603 lastpart = "--" + boundary + "--"
604 partdict = {}
605 terminator = ""
606
607 while terminator != lastpart:
608 bytes = -1
609 data = None
610 if terminator:
611 # At start of next part. Read headers first.
612 headers = mimetools.Message(fp)
613 clength = headers.getheader('content-length')
614 if clength:
615 try:
616 bytes = string.atoi(clength)
617 except string.atoi_error:
618 pass
619 if bytes > 0:
Guido van Rossumad164711997-05-13 19:03:23 +0000620 if maxlen and bytes > maxlen:
621 raise ValueError, 'Maximum content length exceeded'
Guido van Rossum7aee3841996-03-07 18:00:44 +0000622 data = fp.read(bytes)
623 else:
624 data = ""
625 # Read lines until end of part.
626 lines = []
627 while 1:
628 line = fp.readline()
629 if not line:
630 terminator = lastpart # End outer loop
631 break
632 if line[:2] == "--":
633 terminator = string.strip(line)
634 if terminator in (nextpart, lastpart):
635 break
Guido van Rossum7aee3841996-03-07 18:00:44 +0000636 lines.append(line)
637 # Done with part.
638 if data is None:
639 continue
640 if bytes < 0:
Guido van Rossum99aa2a41996-07-23 17:27:05 +0000641 if lines:
642 # Strip final line terminator
643 line = lines[-1]
644 if line[-2:] == "\r\n":
645 line = line[:-2]
646 elif line[-1:] == "\n":
647 line = line[:-1]
648 lines[-1] = line
649 data = string.joinfields(lines, "")
Guido van Rossum7aee3841996-03-07 18:00:44 +0000650 line = headers['content-disposition']
651 if not line:
652 continue
653 key, params = parse_header(line)
654 if key != 'form-data':
655 continue
656 if params.has_key('name'):
657 name = params['name']
Guido van Rossum72755611996-03-06 07:20:06 +0000658 else:
Guido van Rossum7aee3841996-03-07 18:00:44 +0000659 continue
Guido van Rossum7aee3841996-03-07 18:00:44 +0000660 if partdict.has_key(name):
661 partdict[name].append(data)
662 else:
663 partdict[name] = [data]
Guido van Rossum72755611996-03-06 07:20:06 +0000664
Guido van Rossum7aee3841996-03-07 18:00:44 +0000665 return partdict
Guido van Rossum9a22de11995-01-12 12:29:47 +0000666
667
Guido van Rossum72755611996-03-06 07:20:06 +0000668def parse_header(line):
Guido van Rossum7aee3841996-03-07 18:00:44 +0000669 """Parse a Content-type like header.
670
671 Return the main content-type and a dictionary of options.
672
673 """
674 plist = map(string.strip, string.splitfields(line, ';'))
675 key = string.lower(plist[0])
676 del plist[0]
677 pdict = {}
678 for p in plist:
679 i = string.find(p, '=')
680 if i >= 0:
681 name = string.lower(string.strip(p[:i]))
682 value = string.strip(p[i+1:])
683 if len(value) >= 2 and value[0] == value[-1] == '"':
684 value = value[1:-1]
685 pdict[name] = value
686 return key, pdict
Guido van Rossum72755611996-03-06 07:20:06 +0000687
688
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000689# Classes for field storage
690# =========================
691
692class MiniFieldStorage:
693
Guido van Rossum0147db01996-03-09 03:16:04 +0000694 """Like FieldStorage, for use when no file uploads are possible."""
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000695
Guido van Rossum7aee3841996-03-07 18:00:44 +0000696 # Dummy attributes
697 filename = None
698 list = None
699 type = None
Guido van Rossum773ab271996-07-23 03:46:24 +0000700 file = None
Guido van Rossum4032c2c1996-03-09 04:04:35 +0000701 type_options = {}
Guido van Rossum7aee3841996-03-07 18:00:44 +0000702 disposition = None
703 disposition_options = {}
704 headers = {}
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000705
Guido van Rossum7aee3841996-03-07 18:00:44 +0000706 def __init__(self, name, value):
707 """Constructor from field name and value."""
Guido van Rossum7aee3841996-03-07 18:00:44 +0000708 self.name = name
709 self.value = value
Guido van Rossum773ab271996-07-23 03:46:24 +0000710 # self.file = StringIO(value)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000711
712 def __repr__(self):
713 """Return printable representation."""
714 return "MiniFieldStorage(%s, %s)" % (`self.name`, `self.value`)
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000715
716
717class FieldStorage:
718
Guido van Rossum7aee3841996-03-07 18:00:44 +0000719 """Store a sequence of fields, reading multipart/form-data.
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000720
Guido van Rossum7aee3841996-03-07 18:00:44 +0000721 This class provides naming, typing, files stored on disk, and
722 more. At the top level, it is accessible like a dictionary, whose
723 keys are the field names. (Note: None can occur as a field name.)
724 The items are either a Python list (if there's multiple values) or
725 another FieldStorage or MiniFieldStorage object. If it's a single
726 object, it has the following attributes:
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000727
Guido van Rossum7aee3841996-03-07 18:00:44 +0000728 name: the field name, if specified; otherwise None
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000729
Guido van Rossum7aee3841996-03-07 18:00:44 +0000730 filename: the filename, if specified; otherwise None; this is the
731 client side filename, *not* the file name on which it is
Guido van Rossum0147db01996-03-09 03:16:04 +0000732 stored (that's a temporary file you don't deal with)
Guido van Rossum243ddcd1996-03-07 06:33:07 +0000733
Guido van Rossum7aee3841996-03-07 18:00:44 +0000734 value: the value as a *string*; for file uploads, this
735 transparently reads the file every time you request the value
736
737 file: the file(-like) object from which you can read the data;
738 None if the data is stored a simple string
739
740 type: the content-type, or None if not specified
741
742 type_options: dictionary of options specified on the content-type
743 line
744
745 disposition: content-disposition, or None if not specified
746
747 disposition_options: dictionary of corresponding options
748
749 headers: a dictionary(-like) object (sometimes rfc822.Message or a
750 subclass thereof) containing *all* headers
751
752 The class is subclassable, mostly for the purpose of overriding
753 the make_file() method, which is called internally to come up with
754 a file open for reading and writing. This makes it possible to
755 override the default choice of storing all files in a temporary
756 directory and unlinking them as soon as they have been opened.
757
758 """
759
Guido van Rossum773ab271996-07-23 03:46:24 +0000760 def __init__(self, fp=None, headers=None, outerboundary="",
Guido van Rossume08c04c1996-11-11 19:29:11 +0000761 environ=os.environ, keep_blank_values=0, strict_parsing=0):
Guido van Rossum7aee3841996-03-07 18:00:44 +0000762 """Constructor. Read multipart/* until last part.
763
764 Arguments, all optional:
765
766 fp : file pointer; default: sys.stdin
767
768 headers : header dictionary-like object; default:
769 taken from environ as per CGI spec
770
Guido van Rossum773ab271996-07-23 03:46:24 +0000771 outerboundary : terminating multipart boundary
Guido van Rossum7aee3841996-03-07 18:00:44 +0000772 (for internal use only)
773
Guido van Rossum773ab271996-07-23 03:46:24 +0000774 environ : environment dictionary; default: os.environ
775
776 keep_blank_values: flag indicating whether blank values in
777 URL encoded forms should be treated as blank strings.
778 A true value inicates that blanks should be retained as
779 blank strings. The default false value indicates that
780 blank values are to be ignored and treated as if they were
781 not included.
782
Guido van Rossume08c04c1996-11-11 19:29:11 +0000783 strict_parsing: flag indicating what to do with parsing errors.
784 If false (the default), errors are silently ignored.
785 If true, errors raise a ValueError exception.
786
Guido van Rossum7aee3841996-03-07 18:00:44 +0000787 """
Guido van Rossumd7c9d961997-05-28 15:39:15 +0000788 method = 'GET'
Guido van Rossum773ab271996-07-23 03:46:24 +0000789 self.keep_blank_values = keep_blank_values
Guido van Rossume08c04c1996-11-11 19:29:11 +0000790 self.strict_parsing = strict_parsing
Guido van Rossum7aee3841996-03-07 18:00:44 +0000791 if environ.has_key('REQUEST_METHOD'):
792 method = string.upper(environ['REQUEST_METHOD'])
793 if not fp and method == 'GET':
Guido van Rossum7aee3841996-03-07 18:00:44 +0000794 if environ.has_key('QUERY_STRING'):
795 qs = environ['QUERY_STRING']
Guido van Rossumd7c9d961997-05-28 15:39:15 +0000796 elif sys.argv[1:]:
797 qs = sys.argv[1]
798 else:
799 qs = ""
Guido van Rossumd7c9d961997-05-28 15:39:15 +0000800 fp = StringIO(qs)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000801 if headers is None:
802 headers = {'content-type':
803 "application/x-www-form-urlencoded"}
804 if headers is None:
805 headers = {}
806 if environ.has_key('CONTENT_TYPE'):
807 headers['content-type'] = environ['CONTENT_TYPE']
808 if environ.has_key('CONTENT_LENGTH'):
809 headers['content-length'] = environ['CONTENT_LENGTH']
810 self.fp = fp or sys.stdin
811 self.headers = headers
812 self.outerboundary = outerboundary
813
814 # Process content-disposition header
815 cdisp, pdict = "", {}
816 if self.headers.has_key('content-disposition'):
817 cdisp, pdict = parse_header(self.headers['content-disposition'])
818 self.disposition = cdisp
819 self.disposition_options = pdict
820 self.name = None
821 if pdict.has_key('name'):
822 self.name = pdict['name']
823 self.filename = None
824 if pdict.has_key('filename'):
825 self.filename = pdict['filename']
826
827 # Process content-type header
828 ctype, pdict = "text/plain", {}
829 if self.headers.has_key('content-type'):
830 ctype, pdict = parse_header(self.headers['content-type'])
831 self.type = ctype
832 self.type_options = pdict
833 self.innerboundary = ""
834 if pdict.has_key('boundary'):
835 self.innerboundary = pdict['boundary']
836 clen = -1
837 if self.headers.has_key('content-length'):
838 try:
839 clen = string.atoi(self.headers['content-length'])
840 except:
841 pass
Guido van Rossumad164711997-05-13 19:03:23 +0000842 if maxlen and clen > maxlen:
843 raise ValueError, 'Maximum content length exceeded'
Guido van Rossum7aee3841996-03-07 18:00:44 +0000844 self.length = clen
845
846 self.list = self.file = None
847 self.done = 0
848 self.lines = []
849 if ctype == 'application/x-www-form-urlencoded':
850 self.read_urlencoded()
851 elif ctype[:10] == 'multipart/':
852 self.read_multi()
853 else:
854 self.read_single()
855
856 def __repr__(self):
857 """Return a printable representation."""
858 return "FieldStorage(%s, %s, %s)" % (
859 `self.name`, `self.filename`, `self.value`)
860
861 def __getattr__(self, name):
862 if name != 'value':
863 raise AttributeError, name
864 if self.file:
865 self.file.seek(0)
866 value = self.file.read()
867 self.file.seek(0)
868 elif self.list is not None:
869 value = self.list
870 else:
871 value = None
872 return value
873
874 def __getitem__(self, key):
875 """Dictionary style indexing."""
876 if self.list is None:
877 raise TypeError, "not indexable"
878 found = []
879 for item in self.list:
880 if item.name == key: found.append(item)
881 if not found:
882 raise KeyError, key
Guido van Rossum0147db01996-03-09 03:16:04 +0000883 if len(found) == 1:
884 return found[0]
885 else:
886 return found
Guido van Rossum7aee3841996-03-07 18:00:44 +0000887
888 def keys(self):
889 """Dictionary style keys() method."""
890 if self.list is None:
891 raise TypeError, "not indexable"
892 keys = []
893 for item in self.list:
894 if item.name not in keys: keys.append(item.name)
895 return keys
896
Guido van Rossum0147db01996-03-09 03:16:04 +0000897 def has_key(self, key):
898 """Dictionary style has_key() method."""
899 if self.list is None:
900 raise TypeError, "not indexable"
901 for item in self.list:
902 if item.name == key: return 1
903 return 0
904
Guido van Rossum88b85d41997-01-11 19:21:33 +0000905 def __len__(self):
906 """Dictionary style len(x) support."""
907 return len(self.keys())
908
Guido van Rossum7aee3841996-03-07 18:00:44 +0000909 def read_urlencoded(self):
910 """Internal: read data in query string format."""
911 qs = self.fp.read(self.length)
Guido van Rossume08c04c1996-11-11 19:29:11 +0000912 dict = parse_qs(qs, self.keep_blank_values, self.strict_parsing)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000913 self.list = []
914 for key, valuelist in dict.items():
915 for value in valuelist:
916 self.list.append(MiniFieldStorage(key, value))
917 self.skip_lines()
918
919 def read_multi(self):
920 """Internal: read a part that is itself multipart."""
Guido van Rossum7aee3841996-03-07 18:00:44 +0000921 self.list = []
922 part = self.__class__(self.fp, {}, self.innerboundary)
923 # Throw first part away
924 while not part.done:
925 headers = rfc822.Message(self.fp)
926 part = self.__class__(self.fp, headers, self.innerboundary)
927 self.list.append(part)
928 self.skip_lines()
929
930 def read_single(self):
931 """Internal: read an atomic part."""
932 if self.length >= 0:
933 self.read_binary()
934 self.skip_lines()
935 else:
936 self.read_lines()
937 self.file.seek(0)
938
939 bufsize = 8*1024 # I/O buffering size for copy to file
940
941 def read_binary(self):
942 """Internal: read binary data."""
943 self.file = self.make_file('b')
944 todo = self.length
945 if todo >= 0:
946 while todo > 0:
947 data = self.fp.read(min(todo, self.bufsize))
948 if not data:
949 self.done = -1
950 break
951 self.file.write(data)
952 todo = todo - len(data)
953
954 def read_lines(self):
955 """Internal: read lines until EOF or outerboundary."""
956 self.file = self.make_file('')
957 if self.outerboundary:
958 self.read_lines_to_outerboundary()
959 else:
960 self.read_lines_to_eof()
961
962 def read_lines_to_eof(self):
963 """Internal: read lines until EOF."""
964 while 1:
965 line = self.fp.readline()
966 if not line:
967 self.done = -1
968 break
969 self.lines.append(line)
Guido van Rossum7aee3841996-03-07 18:00:44 +0000970 self.file.write(line)
971
972 def read_lines_to_outerboundary(self):
973 """Internal: read lines until outerboundary."""
974 next = "--" + self.outerboundary
975 last = next + "--"
976 delim = ""
977 while 1:
978 line = self.fp.readline()
979 if not line:
980 self.done = -1
981 break
982 self.lines.append(line)
983 if line[:2] == "--":
984 strippedline = string.strip(line)
985 if strippedline == next:
986 break
987 if strippedline == last:
988 self.done = 1
989 break
Guido van Rossume5e46e01996-09-05 19:03:36 +0000990 odelim = delim
Guido van Rossum7aee3841996-03-07 18:00:44 +0000991 if line[-2:] == "\r\n":
Guido van Rossum99aa2a41996-07-23 17:27:05 +0000992 delim = "\r\n"
Guido van Rossum7aee3841996-03-07 18:00:44 +0000993 line = line[:-2]
994 elif line[-1] == "\n":
Guido van Rossum99aa2a41996-07-23 17:27:05 +0000995 delim = "\n"
Guido van Rossum7aee3841996-03-07 18:00:44 +0000996 line = line[:-1]
Guido van Rossum99aa2a41996-07-23 17:27:05 +0000997 else:
998 delim = ""
Guido van Rossume5e46e01996-09-05 19:03:36 +0000999 self.file.write(odelim + line)
Guido van Rossum7aee3841996-03-07 18:00:44 +00001000
1001 def skip_lines(self):
1002 """Internal: skip lines until outer boundary if defined."""
1003 if not self.outerboundary or self.done:
1004 return
1005 next = "--" + self.outerboundary
1006 last = next + "--"
1007 while 1:
1008 line = self.fp.readline()
1009 if not line:
1010 self.done = -1
1011 break
1012 self.lines.append(line)
1013 if line[:2] == "--":
1014 strippedline = string.strip(line)
1015 if strippedline == next:
1016 break
1017 if strippedline == last:
1018 self.done = 1
1019 break
1020
Guido van Rossuma5e9fb61997-08-12 18:18:13 +00001021 def make_file(self, binary=None):
Guido van Rossum7aee3841996-03-07 18:00:44 +00001022 """Overridable: return a readable & writable file.
1023
1024 The file will be used as follows:
1025 - data is written to it
1026 - seek(0)
1027 - data is read from it
1028
Guido van Rossuma5e9fb61997-08-12 18:18:13 +00001029 The 'binary' argument is unused -- the file is always opened
1030 in binary mode.
Guido van Rossum7aee3841996-03-07 18:00:44 +00001031
Guido van Rossum4032c2c1996-03-09 04:04:35 +00001032 This version opens a temporary file for reading and writing,
1033 and immediately deletes (unlinks) it. The trick (on Unix!) is
1034 that the file can still be used, but it can't be opened by
1035 another process, and it will automatically be deleted when it
1036 is closed or when the current process terminates.
1037
1038 If you want a more permanent file, you derive a class which
1039 overrides this method. If you want a visible temporary file
1040 that is nevertheless automatically deleted when the script
1041 terminates, try defining a __del__ method in a derived class
1042 which unlinks the temporary files you have created.
Guido van Rossum7aee3841996-03-07 18:00:44 +00001043
1044 """
Guido van Rossum4032c2c1996-03-09 04:04:35 +00001045 import tempfile
Guido van Rossuma5e9fb61997-08-12 18:18:13 +00001046 return tempfile.TemporaryFile("w+b")
1047
Guido van Rossum243ddcd1996-03-07 06:33:07 +00001048
1049
Guido van Rossum4032c2c1996-03-09 04:04:35 +00001050# Backwards Compatibility Classes
1051# ===============================
Guido van Rossum9a22de11995-01-12 12:29:47 +00001052
1053class FormContentDict:
Guido van Rossum7aee3841996-03-07 18:00:44 +00001054 """Basic (multiple values per field) form content as dictionary.
Guido van Rossum72755611996-03-06 07:20:06 +00001055
Guido van Rossum7aee3841996-03-07 18:00:44 +00001056 form = FormContentDict()
1057
1058 form[key] -> [value, value, ...]
1059 form.has_key(key) -> Boolean
1060 form.keys() -> [key, key, ...]
1061 form.values() -> [[val, val, ...], [val, val, ...], ...]
1062 form.items() -> [(key, [val, val, ...]), (key, [val, val, ...]), ...]
1063 form.dict == {key: [val, val, ...], ...}
1064
1065 """
Guido van Rossum773ab271996-07-23 03:46:24 +00001066 def __init__(self, environ=os.environ):
Guido van Rossumafb5e931996-08-08 18:42:12 +00001067 self.dict = parse(environ=environ)
Guido van Rossum7aee3841996-03-07 18:00:44 +00001068 self.query_string = environ['QUERY_STRING']
1069 def __getitem__(self,key):
1070 return self.dict[key]
1071 def keys(self):
1072 return self.dict.keys()
1073 def has_key(self, key):
1074 return self.dict.has_key(key)
1075 def values(self):
1076 return self.dict.values()
1077 def items(self):
1078 return self.dict.items()
1079 def __len__( self ):
1080 return len(self.dict)
Guido van Rossum9a22de11995-01-12 12:29:47 +00001081
1082
Guido van Rossum9a22de11995-01-12 12:29:47 +00001083class SvFormContentDict(FormContentDict):
Guido van Rossum7aee3841996-03-07 18:00:44 +00001084 """Strict single-value expecting form content as dictionary.
1085
1086 IF you only expect a single value for each field, then form[key]
1087 will return that single value. It will raise an IndexError if
1088 that expectation is not true. IF you expect a field to have
1089 possible multiple values, than you can use form.getlist(key) to
1090 get all of the values. values() and items() are a compromise:
1091 they return single strings where there is a single value, and
1092 lists of strings otherwise.
1093
1094 """
1095 def __getitem__(self, key):
1096 if len(self.dict[key]) > 1:
1097 raise IndexError, 'expecting a single value'
1098 return self.dict[key][0]
1099 def getlist(self, key):
1100 return self.dict[key]
1101 def values(self):
1102 lis = []
1103 for each in self.dict.values():
1104 if len( each ) == 1 :
1105 lis.append(each[0])
1106 else: lis.append(each)
1107 return lis
1108 def items(self):
1109 lis = []
1110 for key,value in self.dict.items():
1111 if len(value) == 1 :
1112 lis.append((key, value[0]))
1113 else: lis.append((key, value))
1114 return lis
Guido van Rossum9a22de11995-01-12 12:29:47 +00001115
1116
Guido van Rossum9a22de11995-01-12 12:29:47 +00001117class InterpFormContentDict(SvFormContentDict):
Guido van Rossum7aee3841996-03-07 18:00:44 +00001118 """This class is present for backwards compatibility only."""
1119 def __getitem__( self, key ):
1120 v = SvFormContentDict.__getitem__( self, key )
1121 if v[0] in string.digits+'+-.' :
1122 try: return string.atoi( v )
1123 except ValueError:
1124 try: return string.atof( v )
1125 except ValueError: pass
1126 return string.strip(v)
1127 def values( self ):
1128 lis = []
1129 for key in self.keys():
1130 try:
1131 lis.append( self[key] )
1132 except IndexError:
1133 lis.append( self.dict[key] )
1134 return lis
1135 def items( self ):
1136 lis = []
1137 for key in self.keys():
1138 try:
1139 lis.append( (key, self[key]) )
1140 except IndexError:
1141 lis.append( (key, self.dict[key]) )
1142 return lis
Guido van Rossum9a22de11995-01-12 12:29:47 +00001143
1144
Guido van Rossum9a22de11995-01-12 12:29:47 +00001145class FormContent(FormContentDict):
Guido van Rossum7aee3841996-03-07 18:00:44 +00001146 """This class is present for backwards compatibility only."""
Guido van Rossum0147db01996-03-09 03:16:04 +00001147 def values(self, key):
1148 if self.dict.has_key(key) :return self.dict[key]
Guido van Rossum7aee3841996-03-07 18:00:44 +00001149 else: return None
Guido van Rossum0147db01996-03-09 03:16:04 +00001150 def indexed_value(self, key, location):
Guido van Rossum7aee3841996-03-07 18:00:44 +00001151 if self.dict.has_key(key):
1152 if len (self.dict[key]) > location:
1153 return self.dict[key][location]
1154 else: return None
1155 else: return None
Guido van Rossum0147db01996-03-09 03:16:04 +00001156 def value(self, key):
1157 if self.dict.has_key(key): return self.dict[key][0]
Guido van Rossum7aee3841996-03-07 18:00:44 +00001158 else: return None
Guido van Rossum0147db01996-03-09 03:16:04 +00001159 def length(self, key):
1160 return len(self.dict[key])
1161 def stripped(self, key):
1162 if self.dict.has_key(key): return string.strip(self.dict[key][0])
Guido van Rossum7aee3841996-03-07 18:00:44 +00001163 else: return None
1164 def pars(self):
1165 return self.dict
Guido van Rossum9a22de11995-01-12 12:29:47 +00001166
1167
Guido van Rossum72755611996-03-06 07:20:06 +00001168# Test/debug code
1169# ===============
Guido van Rossum9a22de11995-01-12 12:29:47 +00001170
Guido van Rossum773ab271996-07-23 03:46:24 +00001171def test(environ=os.environ):
Guido van Rossum7aee3841996-03-07 18:00:44 +00001172 """Robust test CGI script, usable as main program.
Guido van Rossum9a22de11995-01-12 12:29:47 +00001173
Guido van Rossum7aee3841996-03-07 18:00:44 +00001174 Write minimal HTTP headers and dump all information provided to
1175 the script in HTML form.
1176
1177 """
1178 import traceback
1179 print "Content-type: text/html"
1180 print
1181 sys.stderr = sys.stdout
1182 try:
Guido van Rossum0147db01996-03-09 03:16:04 +00001183 form = FieldStorage() # Replace with other classes to test those
1184 print_form(form)
Guido van Rossum773ab271996-07-23 03:46:24 +00001185 print_environ(environ)
Guido van Rossum7aee3841996-03-07 18:00:44 +00001186 print_directory()
Guido van Rossuma8738a51996-03-14 21:30:28 +00001187 print_arguments()
Guido van Rossum7aee3841996-03-07 18:00:44 +00001188 print_environ_usage()
Guido van Rossumf85de8a1996-08-20 20:22:39 +00001189 def f():
1190 exec "testing print_exception() -- <I>italics?</I>"
1191 def g(f=f):
1192 f()
1193 print "<H3>What follows is a test, not an actual exception:</H3>"
1194 g()
Guido van Rossum7aee3841996-03-07 18:00:44 +00001195 except:
Guido van Rossumf85de8a1996-08-20 20:22:39 +00001196 print_exception()
1197
Guido van Rossumad164711997-05-13 19:03:23 +00001198 # Second try with a small maxlen...
1199 global maxlen
1200 maxlen = 50
1201 try:
1202 form = FieldStorage() # Replace with other classes to test those
1203 print_form(form)
1204 print_environ(environ)
1205 print_directory()
1206 print_arguments()
1207 print_environ_usage()
1208 except:
1209 print_exception()
1210
Guido van Rossumf85de8a1996-08-20 20:22:39 +00001211def print_exception(type=None, value=None, tb=None, limit=None):
1212 if type is None:
1213 type, value, tb = sys.exc_type, sys.exc_value, sys.exc_traceback
1214 import traceback
1215 print
1216 print "<H3>Traceback (innermost last):</H3>"
1217 list = traceback.format_tb(tb, limit) + \
1218 traceback.format_exception_only(type, value)
1219 print "<PRE>%s<B>%s</B></PRE>" % (
1220 escape(string.join(list[:-1], "")),
1221 escape(list[-1]),
1222 )
Guido van Rossum9a22de11995-01-12 12:29:47 +00001223
Guido van Rossum773ab271996-07-23 03:46:24 +00001224def print_environ(environ=os.environ):
Guido van Rossum7aee3841996-03-07 18:00:44 +00001225 """Dump the shell environment as HTML."""
1226 keys = environ.keys()
1227 keys.sort()
1228 print
Guido van Rossum503e50b1996-05-28 22:57:20 +00001229 print "<H3>Shell Environment:</H3>"
Guido van Rossum7aee3841996-03-07 18:00:44 +00001230 print "<DL>"
1231 for key in keys:
1232 print "<DT>", escape(key), "<DD>", escape(environ[key])
1233 print "</DL>"
1234 print
Guido van Rossum72755611996-03-06 07:20:06 +00001235
1236def print_form(form):
Guido van Rossum7aee3841996-03-07 18:00:44 +00001237 """Dump the contents of a form as HTML."""
1238 keys = form.keys()
1239 keys.sort()
1240 print
Guido van Rossum503e50b1996-05-28 22:57:20 +00001241 print "<H3>Form Contents:</H3>"
Guido van Rossum7aee3841996-03-07 18:00:44 +00001242 print "<DL>"
1243 for key in keys:
1244 print "<DT>" + escape(key) + ":",
1245 value = form[key]
1246 print "<i>" + escape(`type(value)`) + "</i>"
1247 print "<DD>" + escape(`value`)
1248 print "</DL>"
1249 print
1250
1251def print_directory():
1252 """Dump the current directory as HTML."""
1253 print
1254 print "<H3>Current Working Directory:</H3>"
1255 try:
1256 pwd = os.getcwd()
1257 except os.error, msg:
1258 print "os.error:", escape(str(msg))
1259 else:
1260 print escape(pwd)
1261 print
Guido van Rossum9a22de11995-01-12 12:29:47 +00001262
Guido van Rossuma8738a51996-03-14 21:30:28 +00001263def print_arguments():
1264 print
Guido van Rossum503e50b1996-05-28 22:57:20 +00001265 print "<H3>Command Line Arguments:</H3>"
Guido van Rossuma8738a51996-03-14 21:30:28 +00001266 print
1267 print sys.argv
1268 print
1269
Guido van Rossum9a22de11995-01-12 12:29:47 +00001270def print_environ_usage():
Guido van Rossum7aee3841996-03-07 18:00:44 +00001271 """Dump a list of environment variables used by CGI as HTML."""
1272 print """
Guido van Rossum72755611996-03-06 07:20:06 +00001273<H3>These environment variables could have been set:</H3>
1274<UL>
Guido van Rossum9a22de11995-01-12 12:29:47 +00001275<LI>AUTH_TYPE
1276<LI>CONTENT_LENGTH
1277<LI>CONTENT_TYPE
1278<LI>DATE_GMT
1279<LI>DATE_LOCAL
1280<LI>DOCUMENT_NAME
1281<LI>DOCUMENT_ROOT
1282<LI>DOCUMENT_URI
1283<LI>GATEWAY_INTERFACE
1284<LI>LAST_MODIFIED
1285<LI>PATH
1286<LI>PATH_INFO
1287<LI>PATH_TRANSLATED
1288<LI>QUERY_STRING
1289<LI>REMOTE_ADDR
1290<LI>REMOTE_HOST
1291<LI>REMOTE_IDENT
1292<LI>REMOTE_USER
1293<LI>REQUEST_METHOD
1294<LI>SCRIPT_NAME
1295<LI>SERVER_NAME
1296<LI>SERVER_PORT
1297<LI>SERVER_PROTOCOL
1298<LI>SERVER_ROOT
1299<LI>SERVER_SOFTWARE
1300</UL>
Guido van Rossum7aee3841996-03-07 18:00:44 +00001301In addition, HTTP headers sent by the server may be passed in the
1302environment as well. Here are some common variable names:
1303<UL>
1304<LI>HTTP_ACCEPT
1305<LI>HTTP_CONNECTION
1306<LI>HTTP_HOST
1307<LI>HTTP_PRAGMA
1308<LI>HTTP_REFERER
1309<LI>HTTP_USER_AGENT
1310</UL>
Guido van Rossum9a22de11995-01-12 12:29:47 +00001311"""
1312
Guido van Rossum9a22de11995-01-12 12:29:47 +00001313
Guido van Rossum72755611996-03-06 07:20:06 +00001314# Utilities
1315# =========
Guido van Rossum9a22de11995-01-12 12:29:47 +00001316
Guido van Rossum64c66201997-07-19 20:11:53 +00001317def escape(s, quote=None):
Guido van Rossum7aee3841996-03-07 18:00:44 +00001318 """Replace special characters '&', '<' and '>' by SGML entities."""
1319 s = regsub.gsub("&", "&amp;", s) # Must be done first!
1320 s = regsub.gsub("<", "&lt;", s)
1321 s = regsub.gsub(">", "&gt;", s)
Guido van Rossum64c66201997-07-19 20:11:53 +00001322 if quote:
1323 s = regsub.gsub('"', "&quot;", s)
Guido van Rossum7aee3841996-03-07 18:00:44 +00001324 return s
Guido van Rossum9a22de11995-01-12 12:29:47 +00001325
Guido van Rossum9a22de11995-01-12 12:29:47 +00001326
Guido van Rossum72755611996-03-06 07:20:06 +00001327# Invoke mainline
1328# ===============
1329
1330# Call test() when this file is run as a script (not imported as a module)
1331if __name__ == '__main__':
Guido van Rossum7aee3841996-03-07 18:00:44 +00001332 test()