Merged revisions 73286,73294,73296,73459,73462-73463,73544,73576-73577,73595-73596,73693-73694,73704-73705,73707,73713,73937-73940,73945,73951,73979 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk
........
r73286 | georg.brandl | 2009-06-08 09:57:35 +0200 (Mo, 08 Jun 2009) | 1 line
Remove period from end of headings.
........
r73294 | georg.brandl | 2009-06-08 15:34:52 +0200 (Mo, 08 Jun 2009) | 1 line
#6194: O_SHLOCK/O_EXLOCK are not really more platform independent than lockf().
........
r73296 | georg.brandl | 2009-06-08 18:03:41 +0200 (Mo, 08 Jun 2009) | 1 line
#6238: add fillchar to string.just function family.
........
r73459 | raymond.hettinger | 2009-06-17 03:43:47 +0200 (Mi, 17 Jun 2009) | 1 line
Add usage note.
........
r73462 | georg.brandl | 2009-06-17 11:36:21 +0200 (Mi, 17 Jun 2009) | 1 line
#6295: clarify blocking behavior of getch().
........
r73463 | georg.brandl | 2009-06-17 11:43:31 +0200 (Mi, 17 Jun 2009) | 1 line
#6255: document PyInt_FromSize_t.
........
r73544 | georg.brandl | 2009-06-24 08:41:19 +0200 (Mi, 24 Jun 2009) | 1 line
#6332: fix word dupes throughout the source.
........
r73576 | benjamin.peterson | 2009-06-27 01:37:06 +0200 (Sa, 27 Jun 2009) | 1 line
document is_declared_global()
........
r73577 | benjamin.peterson | 2009-06-27 16:16:23 +0200 (Sa, 27 Jun 2009) | 1 line
link to extensive generator docs in the reference manual
........
r73595 | ezio.melotti | 2009-06-28 01:45:39 +0200 (So, 28 Jun 2009) | 1 line
stmt and setup can contain multiple statements, see #5896
........
r73596 | ezio.melotti | 2009-06-28 02:07:45 +0200 (So, 28 Jun 2009) | 1 line
Fixed a wrong apostrophe
........
r73693 | jesse.noller | 2009-06-29 20:20:34 +0200 (Mo, 29 Jun 2009) | 1 line
Bug 5906: add a documentation note for unix daemons vs. multiprocessing daemons
........
r73694 | jesse.noller | 2009-06-29 20:24:26 +0200 (Mo, 29 Jun 2009) | 1 line
Issue 5740: multiprocessing.connection.* authkey fixes
........
r73704 | georg.brandl | 2009-06-30 18:15:43 +0200 (Di, 30 Jun 2009) | 1 line
#6376: fix copy-n-paste oversight.
........
r73705 | georg.brandl | 2009-06-30 18:17:28 +0200 (Di, 30 Jun 2009) | 1 line
#6374: add a bit of explanation about shell=True on Windows.
........
r73707 | georg.brandl | 2009-06-30 18:35:11 +0200 (Di, 30 Jun 2009) | 1 line
#6371: fix link targets.
........
r73713 | ezio.melotti | 2009-07-01 00:56:16 +0200 (Mi, 01 Jul 2009) | 1 line
Fixed a backslash that was not supposed to be there
........
r73937 | georg.brandl | 2009-07-11 12:12:36 +0200 (Sa, 11 Jul 2009) | 1 line
Fix style.
........
r73938 | georg.brandl | 2009-07-11 12:14:54 +0200 (Sa, 11 Jul 2009) | 1 line
#6446: fix import_spam() function to use correct error and reference handling.
........
r73939 | georg.brandl | 2009-07-11 12:18:10 +0200 (Sa, 11 Jul 2009) | 1 line
#6448: clarify docs for find_module().
........
r73940 | georg.brandl | 2009-07-11 12:37:38 +0200 (Sa, 11 Jul 2009) | 1 line
#6430: add note about size of "u" type.
........
r73945 | georg.brandl | 2009-07-11 12:51:31 +0200 (Sa, 11 Jul 2009) | 1 line
#6456: clarify the meaning of constants used as arguments to nl_langinfo().
........
r73951 | georg.brandl | 2009-07-11 16:23:38 +0200 (Sa, 11 Jul 2009) | 2 lines
array.array is actually a class.
........
r73979 | benjamin.peterson | 2009-07-12 18:56:54 +0200 (So, 12 Jul 2009) | 1 line
add versionadded
........
2009-10-27 11:29:22 -03:00
|
|
|
:mod:`cgi` --- Common Gateway Interface support
|
|
|
|
===============================================
|
2007-08-15 11:28:01 -03:00
|
|
|
|
|
|
|
.. module:: cgi
|
|
|
|
:synopsis: Helpers for running Python scripts via the Common Gateway Interface.
|
|
|
|
|
|
|
|
|
|
|
|
.. index::
|
|
|
|
pair: WWW; server
|
|
|
|
pair: CGI; protocol
|
|
|
|
pair: HTTP; protocol
|
|
|
|
pair: MIME; headers
|
|
|
|
single: URL
|
|
|
|
single: Common Gateway Interface
|
|
|
|
|
|
|
|
Support module for Common Gateway Interface (CGI) scripts.
|
|
|
|
|
|
|
|
This module defines a number of utilities for use by CGI scripts written in
|
|
|
|
Python.
|
|
|
|
|
|
|
|
|
|
|
|
Introduction
|
|
|
|
------------
|
|
|
|
|
|
|
|
.. _cgi-intro:
|
|
|
|
|
|
|
|
A CGI script is invoked by an HTTP server, usually to process user input
|
|
|
|
submitted through an HTML ``<FORM>`` or ``<ISINDEX>`` element.
|
|
|
|
|
|
|
|
Most often, CGI scripts live in the server's special :file:`cgi-bin` directory.
|
|
|
|
The HTTP server places all sorts of information about the request (such as the
|
|
|
|
client's hostname, the requested URL, the query string, and lots of other
|
|
|
|
goodies) in the script's shell environment, executes the script, and sends the
|
|
|
|
script's output back to the client.
|
|
|
|
|
|
|
|
The script's input is connected to the client too, and sometimes the form data
|
|
|
|
is read this way; at other times the form data is passed via the "query string"
|
|
|
|
part of the URL. This module is intended to take care of the different cases
|
|
|
|
and provide a simpler interface to the Python script. It also provides a number
|
|
|
|
of utilities that help in debugging scripts, and the latest addition is support
|
|
|
|
for file uploads from a form (if your browser supports it).
|
|
|
|
|
|
|
|
The output of a CGI script should consist of two sections, separated by a blank
|
|
|
|
line. The first section contains a number of headers, telling the client what
|
|
|
|
kind of data is following. Python code to generate a minimal header section
|
|
|
|
looks like this::
|
|
|
|
|
|
|
|
print "Content-Type: text/html" # HTML is following
|
|
|
|
print # blank line, end of headers
|
|
|
|
|
|
|
|
The second section is usually HTML, which allows the client software to display
|
|
|
|
nicely formatted text with header, in-line images, etc. Here's Python code that
|
|
|
|
prints a simple piece of HTML::
|
|
|
|
|
|
|
|
print "<TITLE>CGI script output</TITLE>"
|
|
|
|
print "<H1>This is my first CGI script</H1>"
|
|
|
|
print "Hello, world!"
|
|
|
|
|
|
|
|
|
|
|
|
.. _using-the-cgi-module:
|
|
|
|
|
|
|
|
Using the cgi module
|
|
|
|
--------------------
|
|
|
|
|
|
|
|
Begin by writing ``import cgi``. Do not use ``from cgi import *`` --- the
|
|
|
|
module defines all sorts of names for its own use or for backward compatibility
|
|
|
|
that you don't want in your namespace.
|
|
|
|
|
Merged revisions 68582,68718,68720-68721,68724-68727,68859,68973,69288-69289,69293,69295,69297-69301,69409,69414,69570,69573,69576,69728-69730,69769,69776,69803-69805,69840,69896 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk
........
r68582 | georg.brandl | 2009-01-13 23:14:01 +0100 (Di, 13 Jan 2009) | 2 lines
Use assertRaises.
........
r68718 | georg.brandl | 2009-01-18 11:42:35 +0100 (So, 18 Jan 2009) | 1 line
#4976: union() and intersection() take multiple args, but talk about "the other".
........
r68720 | georg.brandl | 2009-01-18 11:45:22 +0100 (So, 18 Jan 2009) | 1 line
#4974: fix redundant mention of lists and tuples.
........
r68721 | georg.brandl | 2009-01-18 11:48:16 +0100 (So, 18 Jan 2009) | 1 line
#4914: trunc is in math.
........
r68724 | georg.brandl | 2009-01-18 14:24:10 +0100 (So, 18 Jan 2009) | 1 line
#4979: correct result range for some random functions.
........
r68725 | georg.brandl | 2009-01-18 14:47:26 +0100 (So, 18 Jan 2009) | 1 line
#4857: fix augmented assignment target spec.
........
r68726 | georg.brandl | 2009-01-18 15:41:52 +0100 (So, 18 Jan 2009) | 1 line
#4923: clarify what was added.
........
r68727 | georg.brandl | 2009-01-18 19:25:30 +0100 (So, 18 Jan 2009) | 1 line
#4986: augassigns are not expressions.
........
r68859 | georg.brandl | 2009-01-22 19:29:28 +0100 (Do, 22 Jan 2009) | 2 lines
Clarify wording.
........
r68973 | georg.brandl | 2009-01-26 22:29:38 +0100 (Mo, 26 Jan 2009) | 2 lines
Copy over docs on advanced role features from Sphinx docs.
........
r69288 | georg.brandl | 2009-02-05 11:30:57 +0100 (Do, 05 Feb 2009) | 1 line
#5153: fix typo in example.
........
r69289 | georg.brandl | 2009-02-05 11:37:07 +0100 (Do, 05 Feb 2009) | 1 line
#5144: document that PySys_SetArgv prepends the script directory (or the empty string) to sys.path.
........
r69293 | georg.brandl | 2009-02-05 11:59:28 +0100 (Do, 05 Feb 2009) | 1 line
#5059: fix example.
........
r69295 | georg.brandl | 2009-02-05 12:23:47 +0100 (Do, 05 Feb 2009) | 1 line
PyErr_PrintEx is also in 2.x...
........
r69297 | georg.brandl | 2009-02-05 12:32:18 +0100 (Do, 05 Feb 2009) | 1 line
#5015: document PythonHome API functions.
........
r69298 | georg.brandl | 2009-02-05 12:33:21 +0100 (Do, 05 Feb 2009) | 1 line
#4827: fix callback example.
........
r69299 | georg.brandl | 2009-02-05 12:35:28 +0100 (Do, 05 Feb 2009) | 1 line
#4820: use correct module for ctypes.util.
........
r69300 | georg.brandl | 2009-02-05 12:38:23 +0100 (Do, 05 Feb 2009) | 1 line
#4563: disable alpha and roman lists, fixes wrong formatting of contributor list.
........
r69301 | georg.brandl | 2009-02-05 12:40:35 +0100 (Do, 05 Feb 2009) | 1 line
#5031: fix Thread.daemon property docs.
........
r69409 | georg.brandl | 2009-02-07 13:21:17 +0100 (Sa, 07 Feb 2009) | 1 line
#5174: fix wrong file closing in example.
........
r69414 | georg.brandl | 2009-02-07 19:49:54 +0100 (Sa, 07 Feb 2009) | 1 line
make "super only for new-style classes" a note.
........
r69570 | georg.brandl | 2009-02-13 11:40:14 +0100 (Fr, 13 Feb 2009) | 1 line
#4894: document "newurl" parameter to redirect_request().
........
r69573 | georg.brandl | 2009-02-13 11:44:17 +0100 (Fr, 13 Feb 2009) | 1 line
#3734: document complex coercing behavior better.
........
r69576 | georg.brandl | 2009-02-13 11:56:50 +0100 (Fr, 13 Feb 2009) | 1 line
#1661108: note that urlsafe encoded string can contain "=".
........
r69728 | georg.brandl | 2009-02-18 01:22:55 +0100 (Mi, 18 Feb 2009) | 2 lines
#5297: fix example.
........
r69729 | georg.brandl | 2009-02-18 01:25:13 +0100 (Mi, 18 Feb 2009) | 2 lines
#5296: sequence -> iterable.
........
r69730 | georg.brandl | 2009-02-18 01:31:36 +0100 (Mi, 18 Feb 2009) | 2 lines
#5268: mention VMSError.
........
r69769 | georg.brandl | 2009-02-19 09:30:06 +0100 (Do, 19 Feb 2009) | 1 line
#5310, #3558: fix operator precedence table.
........
r69776 | georg.brandl | 2009-02-19 17:34:51 +0100 (Do, 19 Feb 2009) | 2 lines
#5317: update IronPython URL.
........
r69803 | georg.brandl | 2009-02-20 08:48:21 +0100 (Fr, 20 Feb 2009) | 1 line
#5327: fix a broken link by joining it.
........
r69804 | georg.brandl | 2009-02-20 09:22:21 +0100 (Fr, 20 Feb 2009) | 1 line
At least separate imports from other statements.
........
r69805 | georg.brandl | 2009-02-20 09:45:47 +0100 (Fr, 20 Feb 2009) | 2 lines
Fix punctuation.
........
r69840 | georg.brandl | 2009-02-21 20:09:40 +0100 (Sa, 21 Feb 2009) | 1 line
#5338, #5339: two types in the API manual.
........
r69896 | georg.brandl | 2009-02-23 11:24:23 +0100 (Mo, 23 Feb 2009) | 1 line
#5348: format() converts all kinds of values.
........
2009-02-23 06:41:11 -04:00
|
|
|
When you write a new script, consider adding these lines::
|
2007-08-15 11:28:01 -03:00
|
|
|
|
Merged revisions 68582,68718,68720-68721,68724-68727,68859,68973,69288-69289,69293,69295,69297-69301,69409,69414,69570,69573,69576,69728-69730,69769,69776,69803-69805,69840,69896 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk
........
r68582 | georg.brandl | 2009-01-13 23:14:01 +0100 (Di, 13 Jan 2009) | 2 lines
Use assertRaises.
........
r68718 | georg.brandl | 2009-01-18 11:42:35 +0100 (So, 18 Jan 2009) | 1 line
#4976: union() and intersection() take multiple args, but talk about "the other".
........
r68720 | georg.brandl | 2009-01-18 11:45:22 +0100 (So, 18 Jan 2009) | 1 line
#4974: fix redundant mention of lists and tuples.
........
r68721 | georg.brandl | 2009-01-18 11:48:16 +0100 (So, 18 Jan 2009) | 1 line
#4914: trunc is in math.
........
r68724 | georg.brandl | 2009-01-18 14:24:10 +0100 (So, 18 Jan 2009) | 1 line
#4979: correct result range for some random functions.
........
r68725 | georg.brandl | 2009-01-18 14:47:26 +0100 (So, 18 Jan 2009) | 1 line
#4857: fix augmented assignment target spec.
........
r68726 | georg.brandl | 2009-01-18 15:41:52 +0100 (So, 18 Jan 2009) | 1 line
#4923: clarify what was added.
........
r68727 | georg.brandl | 2009-01-18 19:25:30 +0100 (So, 18 Jan 2009) | 1 line
#4986: augassigns are not expressions.
........
r68859 | georg.brandl | 2009-01-22 19:29:28 +0100 (Do, 22 Jan 2009) | 2 lines
Clarify wording.
........
r68973 | georg.brandl | 2009-01-26 22:29:38 +0100 (Mo, 26 Jan 2009) | 2 lines
Copy over docs on advanced role features from Sphinx docs.
........
r69288 | georg.brandl | 2009-02-05 11:30:57 +0100 (Do, 05 Feb 2009) | 1 line
#5153: fix typo in example.
........
r69289 | georg.brandl | 2009-02-05 11:37:07 +0100 (Do, 05 Feb 2009) | 1 line
#5144: document that PySys_SetArgv prepends the script directory (or the empty string) to sys.path.
........
r69293 | georg.brandl | 2009-02-05 11:59:28 +0100 (Do, 05 Feb 2009) | 1 line
#5059: fix example.
........
r69295 | georg.brandl | 2009-02-05 12:23:47 +0100 (Do, 05 Feb 2009) | 1 line
PyErr_PrintEx is also in 2.x...
........
r69297 | georg.brandl | 2009-02-05 12:32:18 +0100 (Do, 05 Feb 2009) | 1 line
#5015: document PythonHome API functions.
........
r69298 | georg.brandl | 2009-02-05 12:33:21 +0100 (Do, 05 Feb 2009) | 1 line
#4827: fix callback example.
........
r69299 | georg.brandl | 2009-02-05 12:35:28 +0100 (Do, 05 Feb 2009) | 1 line
#4820: use correct module for ctypes.util.
........
r69300 | georg.brandl | 2009-02-05 12:38:23 +0100 (Do, 05 Feb 2009) | 1 line
#4563: disable alpha and roman lists, fixes wrong formatting of contributor list.
........
r69301 | georg.brandl | 2009-02-05 12:40:35 +0100 (Do, 05 Feb 2009) | 1 line
#5031: fix Thread.daemon property docs.
........
r69409 | georg.brandl | 2009-02-07 13:21:17 +0100 (Sa, 07 Feb 2009) | 1 line
#5174: fix wrong file closing in example.
........
r69414 | georg.brandl | 2009-02-07 19:49:54 +0100 (Sa, 07 Feb 2009) | 1 line
make "super only for new-style classes" a note.
........
r69570 | georg.brandl | 2009-02-13 11:40:14 +0100 (Fr, 13 Feb 2009) | 1 line
#4894: document "newurl" parameter to redirect_request().
........
r69573 | georg.brandl | 2009-02-13 11:44:17 +0100 (Fr, 13 Feb 2009) | 1 line
#3734: document complex coercing behavior better.
........
r69576 | georg.brandl | 2009-02-13 11:56:50 +0100 (Fr, 13 Feb 2009) | 1 line
#1661108: note that urlsafe encoded string can contain "=".
........
r69728 | georg.brandl | 2009-02-18 01:22:55 +0100 (Mi, 18 Feb 2009) | 2 lines
#5297: fix example.
........
r69729 | georg.brandl | 2009-02-18 01:25:13 +0100 (Mi, 18 Feb 2009) | 2 lines
#5296: sequence -> iterable.
........
r69730 | georg.brandl | 2009-02-18 01:31:36 +0100 (Mi, 18 Feb 2009) | 2 lines
#5268: mention VMSError.
........
r69769 | georg.brandl | 2009-02-19 09:30:06 +0100 (Do, 19 Feb 2009) | 1 line
#5310, #3558: fix operator precedence table.
........
r69776 | georg.brandl | 2009-02-19 17:34:51 +0100 (Do, 19 Feb 2009) | 2 lines
#5317: update IronPython URL.
........
r69803 | georg.brandl | 2009-02-20 08:48:21 +0100 (Fr, 20 Feb 2009) | 1 line
#5327: fix a broken link by joining it.
........
r69804 | georg.brandl | 2009-02-20 09:22:21 +0100 (Fr, 20 Feb 2009) | 1 line
At least separate imports from other statements.
........
r69805 | georg.brandl | 2009-02-20 09:45:47 +0100 (Fr, 20 Feb 2009) | 2 lines
Fix punctuation.
........
r69840 | georg.brandl | 2009-02-21 20:09:40 +0100 (Sa, 21 Feb 2009) | 1 line
#5338, #5339: two types in the API manual.
........
r69896 | georg.brandl | 2009-02-23 11:24:23 +0100 (Mo, 23 Feb 2009) | 1 line
#5348: format() converts all kinds of values.
........
2009-02-23 06:41:11 -04:00
|
|
|
import cgitb
|
|
|
|
cgitb.enable()
|
2007-08-15 11:28:01 -03:00
|
|
|
|
|
|
|
This activates a special exception handler that will display detailed reports in
|
|
|
|
the Web browser if any errors occur. If you'd rather not show the guts of your
|
|
|
|
program to users of your script, you can have the reports saved to files
|
Merged revisions 68582,68718,68720-68721,68724-68727,68859,68973,69288-69289,69293,69295,69297-69301,69409,69414,69570,69573,69576,69728-69730,69769,69776,69803-69805,69840,69896 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk
........
r68582 | georg.brandl | 2009-01-13 23:14:01 +0100 (Di, 13 Jan 2009) | 2 lines
Use assertRaises.
........
r68718 | georg.brandl | 2009-01-18 11:42:35 +0100 (So, 18 Jan 2009) | 1 line
#4976: union() and intersection() take multiple args, but talk about "the other".
........
r68720 | georg.brandl | 2009-01-18 11:45:22 +0100 (So, 18 Jan 2009) | 1 line
#4974: fix redundant mention of lists and tuples.
........
r68721 | georg.brandl | 2009-01-18 11:48:16 +0100 (So, 18 Jan 2009) | 1 line
#4914: trunc is in math.
........
r68724 | georg.brandl | 2009-01-18 14:24:10 +0100 (So, 18 Jan 2009) | 1 line
#4979: correct result range for some random functions.
........
r68725 | georg.brandl | 2009-01-18 14:47:26 +0100 (So, 18 Jan 2009) | 1 line
#4857: fix augmented assignment target spec.
........
r68726 | georg.brandl | 2009-01-18 15:41:52 +0100 (So, 18 Jan 2009) | 1 line
#4923: clarify what was added.
........
r68727 | georg.brandl | 2009-01-18 19:25:30 +0100 (So, 18 Jan 2009) | 1 line
#4986: augassigns are not expressions.
........
r68859 | georg.brandl | 2009-01-22 19:29:28 +0100 (Do, 22 Jan 2009) | 2 lines
Clarify wording.
........
r68973 | georg.brandl | 2009-01-26 22:29:38 +0100 (Mo, 26 Jan 2009) | 2 lines
Copy over docs on advanced role features from Sphinx docs.
........
r69288 | georg.brandl | 2009-02-05 11:30:57 +0100 (Do, 05 Feb 2009) | 1 line
#5153: fix typo in example.
........
r69289 | georg.brandl | 2009-02-05 11:37:07 +0100 (Do, 05 Feb 2009) | 1 line
#5144: document that PySys_SetArgv prepends the script directory (or the empty string) to sys.path.
........
r69293 | georg.brandl | 2009-02-05 11:59:28 +0100 (Do, 05 Feb 2009) | 1 line
#5059: fix example.
........
r69295 | georg.brandl | 2009-02-05 12:23:47 +0100 (Do, 05 Feb 2009) | 1 line
PyErr_PrintEx is also in 2.x...
........
r69297 | georg.brandl | 2009-02-05 12:32:18 +0100 (Do, 05 Feb 2009) | 1 line
#5015: document PythonHome API functions.
........
r69298 | georg.brandl | 2009-02-05 12:33:21 +0100 (Do, 05 Feb 2009) | 1 line
#4827: fix callback example.
........
r69299 | georg.brandl | 2009-02-05 12:35:28 +0100 (Do, 05 Feb 2009) | 1 line
#4820: use correct module for ctypes.util.
........
r69300 | georg.brandl | 2009-02-05 12:38:23 +0100 (Do, 05 Feb 2009) | 1 line
#4563: disable alpha and roman lists, fixes wrong formatting of contributor list.
........
r69301 | georg.brandl | 2009-02-05 12:40:35 +0100 (Do, 05 Feb 2009) | 1 line
#5031: fix Thread.daemon property docs.
........
r69409 | georg.brandl | 2009-02-07 13:21:17 +0100 (Sa, 07 Feb 2009) | 1 line
#5174: fix wrong file closing in example.
........
r69414 | georg.brandl | 2009-02-07 19:49:54 +0100 (Sa, 07 Feb 2009) | 1 line
make "super only for new-style classes" a note.
........
r69570 | georg.brandl | 2009-02-13 11:40:14 +0100 (Fr, 13 Feb 2009) | 1 line
#4894: document "newurl" parameter to redirect_request().
........
r69573 | georg.brandl | 2009-02-13 11:44:17 +0100 (Fr, 13 Feb 2009) | 1 line
#3734: document complex coercing behavior better.
........
r69576 | georg.brandl | 2009-02-13 11:56:50 +0100 (Fr, 13 Feb 2009) | 1 line
#1661108: note that urlsafe encoded string can contain "=".
........
r69728 | georg.brandl | 2009-02-18 01:22:55 +0100 (Mi, 18 Feb 2009) | 2 lines
#5297: fix example.
........
r69729 | georg.brandl | 2009-02-18 01:25:13 +0100 (Mi, 18 Feb 2009) | 2 lines
#5296: sequence -> iterable.
........
r69730 | georg.brandl | 2009-02-18 01:31:36 +0100 (Mi, 18 Feb 2009) | 2 lines
#5268: mention VMSError.
........
r69769 | georg.brandl | 2009-02-19 09:30:06 +0100 (Do, 19 Feb 2009) | 1 line
#5310, #3558: fix operator precedence table.
........
r69776 | georg.brandl | 2009-02-19 17:34:51 +0100 (Do, 19 Feb 2009) | 2 lines
#5317: update IronPython URL.
........
r69803 | georg.brandl | 2009-02-20 08:48:21 +0100 (Fr, 20 Feb 2009) | 1 line
#5327: fix a broken link by joining it.
........
r69804 | georg.brandl | 2009-02-20 09:22:21 +0100 (Fr, 20 Feb 2009) | 1 line
At least separate imports from other statements.
........
r69805 | georg.brandl | 2009-02-20 09:45:47 +0100 (Fr, 20 Feb 2009) | 2 lines
Fix punctuation.
........
r69840 | georg.brandl | 2009-02-21 20:09:40 +0100 (Sa, 21 Feb 2009) | 1 line
#5338, #5339: two types in the API manual.
........
r69896 | georg.brandl | 2009-02-23 11:24:23 +0100 (Mo, 23 Feb 2009) | 1 line
#5348: format() converts all kinds of values.
........
2009-02-23 06:41:11 -04:00
|
|
|
instead, with code like this::
|
2007-08-15 11:28:01 -03:00
|
|
|
|
Merged revisions 68582,68718,68720-68721,68724-68727,68859,68973,69288-69289,69293,69295,69297-69301,69409,69414,69570,69573,69576,69728-69730,69769,69776,69803-69805,69840,69896 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk
........
r68582 | georg.brandl | 2009-01-13 23:14:01 +0100 (Di, 13 Jan 2009) | 2 lines
Use assertRaises.
........
r68718 | georg.brandl | 2009-01-18 11:42:35 +0100 (So, 18 Jan 2009) | 1 line
#4976: union() and intersection() take multiple args, but talk about "the other".
........
r68720 | georg.brandl | 2009-01-18 11:45:22 +0100 (So, 18 Jan 2009) | 1 line
#4974: fix redundant mention of lists and tuples.
........
r68721 | georg.brandl | 2009-01-18 11:48:16 +0100 (So, 18 Jan 2009) | 1 line
#4914: trunc is in math.
........
r68724 | georg.brandl | 2009-01-18 14:24:10 +0100 (So, 18 Jan 2009) | 1 line
#4979: correct result range for some random functions.
........
r68725 | georg.brandl | 2009-01-18 14:47:26 +0100 (So, 18 Jan 2009) | 1 line
#4857: fix augmented assignment target spec.
........
r68726 | georg.brandl | 2009-01-18 15:41:52 +0100 (So, 18 Jan 2009) | 1 line
#4923: clarify what was added.
........
r68727 | georg.brandl | 2009-01-18 19:25:30 +0100 (So, 18 Jan 2009) | 1 line
#4986: augassigns are not expressions.
........
r68859 | georg.brandl | 2009-01-22 19:29:28 +0100 (Do, 22 Jan 2009) | 2 lines
Clarify wording.
........
r68973 | georg.brandl | 2009-01-26 22:29:38 +0100 (Mo, 26 Jan 2009) | 2 lines
Copy over docs on advanced role features from Sphinx docs.
........
r69288 | georg.brandl | 2009-02-05 11:30:57 +0100 (Do, 05 Feb 2009) | 1 line
#5153: fix typo in example.
........
r69289 | georg.brandl | 2009-02-05 11:37:07 +0100 (Do, 05 Feb 2009) | 1 line
#5144: document that PySys_SetArgv prepends the script directory (or the empty string) to sys.path.
........
r69293 | georg.brandl | 2009-02-05 11:59:28 +0100 (Do, 05 Feb 2009) | 1 line
#5059: fix example.
........
r69295 | georg.brandl | 2009-02-05 12:23:47 +0100 (Do, 05 Feb 2009) | 1 line
PyErr_PrintEx is also in 2.x...
........
r69297 | georg.brandl | 2009-02-05 12:32:18 +0100 (Do, 05 Feb 2009) | 1 line
#5015: document PythonHome API functions.
........
r69298 | georg.brandl | 2009-02-05 12:33:21 +0100 (Do, 05 Feb 2009) | 1 line
#4827: fix callback example.
........
r69299 | georg.brandl | 2009-02-05 12:35:28 +0100 (Do, 05 Feb 2009) | 1 line
#4820: use correct module for ctypes.util.
........
r69300 | georg.brandl | 2009-02-05 12:38:23 +0100 (Do, 05 Feb 2009) | 1 line
#4563: disable alpha and roman lists, fixes wrong formatting of contributor list.
........
r69301 | georg.brandl | 2009-02-05 12:40:35 +0100 (Do, 05 Feb 2009) | 1 line
#5031: fix Thread.daemon property docs.
........
r69409 | georg.brandl | 2009-02-07 13:21:17 +0100 (Sa, 07 Feb 2009) | 1 line
#5174: fix wrong file closing in example.
........
r69414 | georg.brandl | 2009-02-07 19:49:54 +0100 (Sa, 07 Feb 2009) | 1 line
make "super only for new-style classes" a note.
........
r69570 | georg.brandl | 2009-02-13 11:40:14 +0100 (Fr, 13 Feb 2009) | 1 line
#4894: document "newurl" parameter to redirect_request().
........
r69573 | georg.brandl | 2009-02-13 11:44:17 +0100 (Fr, 13 Feb 2009) | 1 line
#3734: document complex coercing behavior better.
........
r69576 | georg.brandl | 2009-02-13 11:56:50 +0100 (Fr, 13 Feb 2009) | 1 line
#1661108: note that urlsafe encoded string can contain "=".
........
r69728 | georg.brandl | 2009-02-18 01:22:55 +0100 (Mi, 18 Feb 2009) | 2 lines
#5297: fix example.
........
r69729 | georg.brandl | 2009-02-18 01:25:13 +0100 (Mi, 18 Feb 2009) | 2 lines
#5296: sequence -> iterable.
........
r69730 | georg.brandl | 2009-02-18 01:31:36 +0100 (Mi, 18 Feb 2009) | 2 lines
#5268: mention VMSError.
........
r69769 | georg.brandl | 2009-02-19 09:30:06 +0100 (Do, 19 Feb 2009) | 1 line
#5310, #3558: fix operator precedence table.
........
r69776 | georg.brandl | 2009-02-19 17:34:51 +0100 (Do, 19 Feb 2009) | 2 lines
#5317: update IronPython URL.
........
r69803 | georg.brandl | 2009-02-20 08:48:21 +0100 (Fr, 20 Feb 2009) | 1 line
#5327: fix a broken link by joining it.
........
r69804 | georg.brandl | 2009-02-20 09:22:21 +0100 (Fr, 20 Feb 2009) | 1 line
At least separate imports from other statements.
........
r69805 | georg.brandl | 2009-02-20 09:45:47 +0100 (Fr, 20 Feb 2009) | 2 lines
Fix punctuation.
........
r69840 | georg.brandl | 2009-02-21 20:09:40 +0100 (Sa, 21 Feb 2009) | 1 line
#5338, #5339: two types in the API manual.
........
r69896 | georg.brandl | 2009-02-23 11:24:23 +0100 (Mo, 23 Feb 2009) | 1 line
#5348: format() converts all kinds of values.
........
2009-02-23 06:41:11 -04:00
|
|
|
import cgitb
|
|
|
|
cgitb.enable(display=0, logdir="/tmp")
|
2007-08-15 11:28:01 -03:00
|
|
|
|
|
|
|
It's very helpful to use this feature during script development. The reports
|
|
|
|
produced by :mod:`cgitb` provide information that can save you a lot of time in
|
|
|
|
tracking down bugs. You can always remove the ``cgitb`` line later when you
|
|
|
|
have tested your script and are confident that it works correctly.
|
|
|
|
|
|
|
|
To get at submitted form data, it's best to use the :class:`FieldStorage` class.
|
|
|
|
The other classes defined in this module are provided mostly for backward
|
|
|
|
compatibility. Instantiate it exactly once, without arguments. This reads the
|
|
|
|
form contents from standard input or the environment (depending on the value of
|
|
|
|
various environment variables set according to the CGI standard). Since it may
|
|
|
|
consume standard input, it should be instantiated only once.
|
|
|
|
|
Merged revisions 74008,74021-74022,74074-74075,74077,74148,74179,74188,74192-74194,74200,74205 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk
........
r74008 | benjamin.peterson | 2009-07-15 02:46:42 +0200 (Mi, 15 Jul 2009) | 1 line
update year
........
r74021 | georg.brandl | 2009-07-16 09:33:04 +0200 (Do, 16 Jul 2009) | 1 line
#6486: start with built in functions rather than "built in objects".
........
r74022 | georg.brandl | 2009-07-16 09:38:35 +0200 (Do, 16 Jul 2009) | 1 line
#6481: fix typo in os.system() replacement.
........
r74074 | georg.brandl | 2009-07-18 11:03:10 +0200 (Sa, 18 Jul 2009) | 1 line
#6513: fix example code: warning categories are classes, not instances.
........
r74075 | georg.brandl | 2009-07-18 11:06:31 +0200 (Sa, 18 Jul 2009) | 1 line
#6505: fix typos.
........
r74077 | georg.brandl | 2009-07-18 11:43:40 +0200 (Sa, 18 Jul 2009) | 1 line
#6489: fix an ambiguity in getiterator() documentation.
........
r74148 | ezio.melotti | 2009-07-21 22:18:27 +0200 (Di, 21 Jul 2009) | 1 line
#6536 fixed typo
........
r74179 | ezio.melotti | 2009-07-22 23:08:49 +0200 (Mi, 22 Jul 2009) | 1 line
#6423 has_key -> in
........
r74188 | benjamin.peterson | 2009-07-23 16:25:31 +0200 (Do, 23 Jul 2009) | 1 line
use bools
........
r74192 | georg.brandl | 2009-07-24 18:28:38 +0200 (Fr, 24 Jul 2009) | 1 line
Fix arg types of et#.
........
r74193 | georg.brandl | 2009-07-24 18:46:38 +0200 (Fr, 24 Jul 2009) | 1 line
Dont put "void" in signature for nullary functions.
........
r74194 | georg.brandl | 2009-07-24 22:09:46 +0200 (Fr, 24 Jul 2009) | 1 line
#6564: fix section about the two raise syntaxes.
........
r74200 | georg.brandl | 2009-07-25 15:02:15 +0200 (Sa, 25 Jul 2009) | 1 line
#6571: add index entries for more operators.
........
r74205 | georg.brandl | 2009-07-26 15:36:39 +0200 (So, 26 Jul 2009) | 1 line
#6576: fix cross-refs in re docs.
........
2009-10-27 11:34:21 -03:00
|
|
|
The :class:`FieldStorage` instance can be indexed like a Python dictionary.
|
|
|
|
It allows membership testing with the :keyword:`in` operator, and also supports
|
|
|
|
the standard dictionary method :meth:`keys` and the built-in function
|
|
|
|
:func:`len`. Form fields containing empty strings are ignored and do not appear
|
|
|
|
in the dictionary; to keep such values, provide a true value for the optional
|
|
|
|
*keep_blank_values* keyword parameter when creating the :class:`FieldStorage`
|
|
|
|
instance.
|
2007-08-15 11:28:01 -03:00
|
|
|
|
|
|
|
For instance, the following code (which assumes that the
|
|
|
|
:mailheader:`Content-Type` header and blank line have already been printed)
|
|
|
|
checks that the fields ``name`` and ``addr`` are both set to a non-empty
|
|
|
|
string::
|
|
|
|
|
|
|
|
form = cgi.FieldStorage()
|
Merged revisions 74008,74021-74022,74074-74075,74077,74148,74179,74188,74192-74194,74200,74205 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk
........
r74008 | benjamin.peterson | 2009-07-15 02:46:42 +0200 (Mi, 15 Jul 2009) | 1 line
update year
........
r74021 | georg.brandl | 2009-07-16 09:33:04 +0200 (Do, 16 Jul 2009) | 1 line
#6486: start with built in functions rather than "built in objects".
........
r74022 | georg.brandl | 2009-07-16 09:38:35 +0200 (Do, 16 Jul 2009) | 1 line
#6481: fix typo in os.system() replacement.
........
r74074 | georg.brandl | 2009-07-18 11:03:10 +0200 (Sa, 18 Jul 2009) | 1 line
#6513: fix example code: warning categories are classes, not instances.
........
r74075 | georg.brandl | 2009-07-18 11:06:31 +0200 (Sa, 18 Jul 2009) | 1 line
#6505: fix typos.
........
r74077 | georg.brandl | 2009-07-18 11:43:40 +0200 (Sa, 18 Jul 2009) | 1 line
#6489: fix an ambiguity in getiterator() documentation.
........
r74148 | ezio.melotti | 2009-07-21 22:18:27 +0200 (Di, 21 Jul 2009) | 1 line
#6536 fixed typo
........
r74179 | ezio.melotti | 2009-07-22 23:08:49 +0200 (Mi, 22 Jul 2009) | 1 line
#6423 has_key -> in
........
r74188 | benjamin.peterson | 2009-07-23 16:25:31 +0200 (Do, 23 Jul 2009) | 1 line
use bools
........
r74192 | georg.brandl | 2009-07-24 18:28:38 +0200 (Fr, 24 Jul 2009) | 1 line
Fix arg types of et#.
........
r74193 | georg.brandl | 2009-07-24 18:46:38 +0200 (Fr, 24 Jul 2009) | 1 line
Dont put "void" in signature for nullary functions.
........
r74194 | georg.brandl | 2009-07-24 22:09:46 +0200 (Fr, 24 Jul 2009) | 1 line
#6564: fix section about the two raise syntaxes.
........
r74200 | georg.brandl | 2009-07-25 15:02:15 +0200 (Sa, 25 Jul 2009) | 1 line
#6571: add index entries for more operators.
........
r74205 | georg.brandl | 2009-07-26 15:36:39 +0200 (So, 26 Jul 2009) | 1 line
#6576: fix cross-refs in re docs.
........
2009-10-27 11:34:21 -03:00
|
|
|
if "name" not in form or "addr" not in form:
|
2007-08-15 11:28:01 -03:00
|
|
|
print "<H1>Error</H1>"
|
|
|
|
print "Please fill in the name and addr fields."
|
|
|
|
return
|
|
|
|
print "<p>name:", form["name"].value
|
|
|
|
print "<p>addr:", form["addr"].value
|
|
|
|
...further form processing here...
|
|
|
|
|
|
|
|
Here the fields, accessed through ``form[key]``, are themselves instances of
|
|
|
|
:class:`FieldStorage` (or :class:`MiniFieldStorage`, depending on the form
|
|
|
|
encoding). The :attr:`value` attribute of the instance yields the string value
|
|
|
|
of the field. The :meth:`getvalue` method returns this string value directly;
|
|
|
|
it also accepts an optional second argument as a default to return if the
|
|
|
|
requested key is not present.
|
|
|
|
|
|
|
|
If the submitted form data contains more than one field with the same name, the
|
|
|
|
object retrieved by ``form[key]`` is not a :class:`FieldStorage` or
|
|
|
|
:class:`MiniFieldStorage` instance but a list of such instances. Similarly, in
|
|
|
|
this situation, ``form.getvalue(key)`` would return a list of strings. If you
|
|
|
|
expect this possibility (when your HTML form contains multiple fields with the
|
|
|
|
same name), use the :func:`getlist` function, which always returns a list of
|
|
|
|
values (so that you do not need to special-case the single item case). For
|
|
|
|
example, this code concatenates any number of username fields, separated by
|
|
|
|
commas::
|
|
|
|
|
|
|
|
value = form.getlist("username")
|
|
|
|
usernames = ",".join(value)
|
|
|
|
|
|
|
|
If a field represents an uploaded file, accessing the value via the
|
|
|
|
:attr:`value` attribute or the :func:`getvalue` method reads the entire file in
|
|
|
|
memory as a string. This may not be what you want. You can test for an uploaded
|
2009-10-27 11:36:50 -03:00
|
|
|
file by testing either the :attr:`filename` attribute or the :attr:`!file`
|
|
|
|
attribute. You can then read the data at leisure from the :attr:`!file`
|
2007-08-15 11:28:01 -03:00
|
|
|
attribute::
|
|
|
|
|
|
|
|
fileitem = form["userfile"]
|
|
|
|
if fileitem.file:
|
|
|
|
# It's an uploaded file; count lines
|
|
|
|
linecount = 0
|
|
|
|
while 1:
|
|
|
|
line = fileitem.file.readline()
|
|
|
|
if not line: break
|
|
|
|
linecount = linecount + 1
|
|
|
|
|
2007-09-18 20:34:44 -03:00
|
|
|
If an error is encountered when obtaining the contents of an uploaded file
|
|
|
|
(for example, when the user interrupts the form submission by clicking on
|
|
|
|
a Back or Cancel button) the :attr:`done` attribute of the object for the
|
|
|
|
field will be set to the value -1.
|
|
|
|
|
2007-08-15 11:28:01 -03:00
|
|
|
The file upload draft standard entertains the possibility of uploading multiple
|
|
|
|
files from one field (using a recursive :mimetype:`multipart/\*` encoding).
|
|
|
|
When this occurs, the item will be a dictionary-like :class:`FieldStorage` item.
|
2009-10-27 11:36:50 -03:00
|
|
|
This can be determined by testing its :attr:`!type` attribute, which should be
|
2007-08-15 11:28:01 -03:00
|
|
|
:mimetype:`multipart/form-data` (or perhaps another MIME type matching
|
|
|
|
:mimetype:`multipart/\*`). In this case, it can be iterated over recursively
|
|
|
|
just like the top-level form object.
|
|
|
|
|
|
|
|
When a form is submitted in the "old" format (as the query string or as a single
|
|
|
|
data part of type :mimetype:`application/x-www-form-urlencoded`), the items will
|
|
|
|
actually be instances of the class :class:`MiniFieldStorage`. In this case, the
|
2009-10-27 11:36:50 -03:00
|
|
|
:attr:`!list`, :attr:`!file`, and :attr:`filename` attributes are always ``None``.
|
2007-08-15 11:28:01 -03:00
|
|
|
|
2008-06-21 15:58:04 -03:00
|
|
|
A form submitted via POST that also has a query string will contain both
|
|
|
|
:class:`FieldStorage` and :class:`MiniFieldStorage` items.
|
2007-08-15 11:28:01 -03:00
|
|
|
|
|
|
|
Higher Level Interface
|
|
|
|
----------------------
|
|
|
|
|
|
|
|
.. versionadded:: 2.2
|
|
|
|
|
|
|
|
The previous section explains how to read CGI form data using the
|
|
|
|
:class:`FieldStorage` class. This section describes a higher level interface
|
|
|
|
which was added to this class to allow one to do it in a more readable and
|
|
|
|
intuitive way. The interface doesn't make the techniques described in previous
|
|
|
|
sections obsolete --- they are still useful to process file uploads efficiently,
|
|
|
|
for example.
|
|
|
|
|
2007-12-29 06:57:00 -04:00
|
|
|
.. XXX: Is this true ?
|
2007-08-15 11:28:01 -03:00
|
|
|
|
|
|
|
The interface consists of two simple methods. Using the methods you can process
|
|
|
|
form data in a generic way, without the need to worry whether only one or more
|
|
|
|
values were posted under one name.
|
|
|
|
|
|
|
|
In the previous section, you learned to write following code anytime you
|
|
|
|
expected a user to post more than one value under one name::
|
|
|
|
|
|
|
|
item = form.getvalue("item")
|
|
|
|
if isinstance(item, list):
|
|
|
|
# The user is requesting more than one item.
|
|
|
|
else:
|
|
|
|
# The user is requesting only one item.
|
|
|
|
|
|
|
|
This situation is common for example when a form contains a group of multiple
|
|
|
|
checkboxes with the same name::
|
|
|
|
|
|
|
|
<input type="checkbox" name="item" value="1" />
|
|
|
|
<input type="checkbox" name="item" value="2" />
|
|
|
|
|
|
|
|
In most situations, however, there's only one form control with a particular
|
|
|
|
name in a form and then you expect and need only one value associated with this
|
|
|
|
name. So you write a script containing for example this code::
|
|
|
|
|
|
|
|
user = form.getvalue("user").upper()
|
|
|
|
|
|
|
|
The problem with the code is that you should never expect that a client will
|
|
|
|
provide valid input to your scripts. For example, if a curious user appends
|
|
|
|
another ``user=foo`` pair to the query string, then the script would crash,
|
|
|
|
because in this situation the ``getvalue("user")`` method call returns a list
|
|
|
|
instead of a string. Calling the :meth:`toupper` method on a list is not valid
|
|
|
|
(since lists do not have a method of this name) and results in an
|
|
|
|
:exc:`AttributeError` exception.
|
|
|
|
|
|
|
|
Therefore, the appropriate way to read form data values was to always use the
|
|
|
|
code which checks whether the obtained value is a single value or a list of
|
|
|
|
values. That's annoying and leads to less readable scripts.
|
|
|
|
|
|
|
|
A more convenient approach is to use the methods :meth:`getfirst` and
|
|
|
|
:meth:`getlist` provided by this higher level interface.
|
|
|
|
|
|
|
|
|
|
|
|
.. method:: FieldStorage.getfirst(name[, default])
|
|
|
|
|
|
|
|
This method always returns only one value associated with form field *name*.
|
|
|
|
The method returns only the first value in case that more values were posted
|
|
|
|
under such name. Please note that the order in which the values are received
|
|
|
|
may vary from browser to browser and should not be counted on. [#]_ If no such
|
|
|
|
form field or value exists then the method returns the value specified by the
|
|
|
|
optional parameter *default*. This parameter defaults to ``None`` if not
|
|
|
|
specified.
|
|
|
|
|
|
|
|
|
|
|
|
.. method:: FieldStorage.getlist(name)
|
|
|
|
|
|
|
|
This method always returns a list of values associated with form field *name*.
|
|
|
|
The method returns an empty list if no such form field or value exists for
|
|
|
|
*name*. It returns a list consisting of one item if only one such value exists.
|
|
|
|
|
|
|
|
Using these methods you can write nice compact code::
|
|
|
|
|
|
|
|
import cgi
|
|
|
|
form = cgi.FieldStorage()
|
|
|
|
user = form.getfirst("user", "").upper() # This way it's safe.
|
|
|
|
for item in form.getlist("item"):
|
|
|
|
do_something(item)
|
|
|
|
|
|
|
|
|
|
|
|
Old classes
|
|
|
|
-----------
|
|
|
|
|
2008-05-11 18:37:53 -03:00
|
|
|
.. deprecated:: 2.6
|
|
|
|
|
|
|
|
These classes, present in earlier versions of the :mod:`cgi` module, are
|
|
|
|
still supported for backward compatibility. New applications should use the
|
|
|
|
:class:`FieldStorage` class.
|
2007-08-15 11:28:01 -03:00
|
|
|
|
|
|
|
:class:`SvFormContentDict` stores single value form content as dictionary; it
|
|
|
|
assumes each field name occurs in the form only once.
|
|
|
|
|
|
|
|
:class:`FormContentDict` stores multiple value form content as a dictionary (the
|
|
|
|
form items are lists of values). Useful if your form contains multiple fields
|
|
|
|
with the same name.
|
|
|
|
|
|
|
|
Other classes (:class:`FormContent`, :class:`InterpFormContentDict`) are present
|
2008-06-20 20:13:58 -03:00
|
|
|
for backwards compatibility with really old applications only.
|
2007-08-15 11:28:01 -03:00
|
|
|
|
|
|
|
|
|
|
|
.. _functions-in-cgi-module:
|
|
|
|
|
|
|
|
Functions
|
|
|
|
---------
|
|
|
|
|
|
|
|
These are useful if you want more control, or if you want to employ some of the
|
|
|
|
algorithms implemented in this module in other circumstances.
|
|
|
|
|
|
|
|
|
|
|
|
.. function:: parse(fp[, keep_blank_values[, strict_parsing]])
|
|
|
|
|
|
|
|
Parse a query in the environment or from a file (the file defaults to
|
|
|
|
``sys.stdin``). The *keep_blank_values* and *strict_parsing* parameters are
|
2008-09-03 19:35:50 -03:00
|
|
|
passed to :func:`urlparse.parse_qs` unchanged.
|
2007-08-15 11:28:01 -03:00
|
|
|
|
|
|
|
|
|
|
|
.. function:: parse_qs(qs[, keep_blank_values[, strict_parsing]])
|
|
|
|
|
2008-09-03 19:35:50 -03:00
|
|
|
This function is deprecated in this module. Use :func:`urlparse.parse_qs`
|
|
|
|
instead. It is maintained here only for backward compatiblity.
|
2007-08-15 11:28:01 -03:00
|
|
|
|
|
|
|
.. function:: parse_qsl(qs[, keep_blank_values[, strict_parsing]])
|
|
|
|
|
2008-09-03 19:35:50 -03:00
|
|
|
This function is deprecated in this module. Use :func:`urlparse.parse_qsl`
|
|
|
|
instead. It is maintained here only for backward compatiblity.
|
2007-08-15 11:28:01 -03:00
|
|
|
|
|
|
|
.. function:: parse_multipart(fp, pdict)
|
|
|
|
|
|
|
|
Parse input of type :mimetype:`multipart/form-data` (for file uploads).
|
|
|
|
Arguments are *fp* for the input file and *pdict* for a dictionary containing
|
|
|
|
other parameters in the :mailheader:`Content-Type` header.
|
|
|
|
|
2008-09-03 19:35:50 -03:00
|
|
|
Returns a dictionary just like :func:`urlparse.parse_qs` keys are the field names, each
|
2007-08-15 11:28:01 -03:00
|
|
|
value is a list of values for that field. This is easy to use but not much good
|
|
|
|
if you are expecting megabytes to be uploaded --- in that case, use the
|
|
|
|
:class:`FieldStorage` class instead which is much more flexible.
|
|
|
|
|
|
|
|
Note that this does not parse nested multipart parts --- use
|
|
|
|
:class:`FieldStorage` for that.
|
|
|
|
|
|
|
|
|
|
|
|
.. function:: parse_header(string)
|
|
|
|
|
|
|
|
Parse a MIME header (such as :mailheader:`Content-Type`) into a main value and a
|
|
|
|
dictionary of parameters.
|
|
|
|
|
|
|
|
|
|
|
|
.. function:: test()
|
|
|
|
|
|
|
|
Robust test CGI script, usable as main program. Writes minimal HTTP headers and
|
|
|
|
formats all information provided to the script in HTML form.
|
|
|
|
|
|
|
|
|
|
|
|
.. function:: print_environ()
|
|
|
|
|
|
|
|
Format the shell environment in HTML.
|
|
|
|
|
|
|
|
|
|
|
|
.. function:: print_form(form)
|
|
|
|
|
|
|
|
Format a form in HTML.
|
|
|
|
|
|
|
|
|
|
|
|
.. function:: print_directory()
|
|
|
|
|
|
|
|
Format the current directory in HTML.
|
|
|
|
|
|
|
|
|
|
|
|
.. function:: print_environ_usage()
|
|
|
|
|
|
|
|
Print a list of useful (used by CGI) environment variables in HTML.
|
|
|
|
|
|
|
|
|
|
|
|
.. function:: escape(s[, quote])
|
|
|
|
|
|
|
|
Convert the characters ``'&'``, ``'<'`` and ``'>'`` in string *s* to HTML-safe
|
|
|
|
sequences. Use this if you need to display text that might contain such
|
|
|
|
characters in HTML. If the optional flag *quote* is true, the quotation mark
|
|
|
|
character (``'"'``) is also translated; this helps for inclusion in an HTML
|
|
|
|
attribute value, as in ``<A HREF="...">``. If the value to be quoted might
|
|
|
|
include single- or double-quote characters, or both, consider using the
|
|
|
|
:func:`quoteattr` function in the :mod:`xml.sax.saxutils` module instead.
|
|
|
|
|
|
|
|
|
|
|
|
.. _cgi-security:
|
|
|
|
|
|
|
|
Caring about security
|
|
|
|
---------------------
|
|
|
|
|
|
|
|
.. index:: pair: CGI; security
|
|
|
|
|
|
|
|
There's one important rule: if you invoke an external program (via the
|
|
|
|
:func:`os.system` or :func:`os.popen` functions. or others with similar
|
|
|
|
functionality), make very sure you don't pass arbitrary strings received from
|
|
|
|
the client to the shell. This is a well-known security hole whereby clever
|
|
|
|
hackers anywhere on the Web can exploit a gullible CGI script to invoke
|
|
|
|
arbitrary shell commands. Even parts of the URL or field names cannot be
|
|
|
|
trusted, since the request doesn't have to come from your form!
|
|
|
|
|
|
|
|
To be on the safe side, if you must pass a string gotten from a form to a shell
|
|
|
|
command, you should make sure the string contains only alphanumeric characters,
|
|
|
|
dashes, underscores, and periods.
|
|
|
|
|
|
|
|
|
|
|
|
Installing your CGI script on a Unix system
|
|
|
|
-------------------------------------------
|
|
|
|
|
|
|
|
Read the documentation for your HTTP server and check with your local system
|
|
|
|
administrator to find the directory where CGI scripts should be installed;
|
|
|
|
usually this is in a directory :file:`cgi-bin` in the server tree.
|
|
|
|
|
|
|
|
Make sure that your script is readable and executable by "others"; the Unix file
|
|
|
|
mode should be ``0755`` octal (use ``chmod 0755 filename``). Make sure that the
|
|
|
|
first line of the script contains ``#!`` starting in column 1 followed by the
|
|
|
|
pathname of the Python interpreter, for instance::
|
|
|
|
|
|
|
|
#!/usr/local/bin/python
|
|
|
|
|
|
|
|
Make sure the Python interpreter exists and is executable by "others".
|
|
|
|
|
|
|
|
Make sure that any files your script needs to read or write are readable or
|
|
|
|
writable, respectively, by "others" --- their mode should be ``0644`` for
|
|
|
|
readable and ``0666`` for writable. This is because, for security reasons, the
|
|
|
|
HTTP server executes your script as user "nobody", without any special
|
|
|
|
privileges. It can only read (write, execute) files that everybody can read
|
|
|
|
(write, execute). The current directory at execution time is also different (it
|
|
|
|
is usually the server's cgi-bin directory) and the set of environment variables
|
|
|
|
is also different from what you get when you log in. In particular, don't count
|
|
|
|
on the shell's search path for executables (:envvar:`PATH`) or the Python module
|
|
|
|
search path (:envvar:`PYTHONPATH`) to be set to anything interesting.
|
|
|
|
|
|
|
|
If you need to load modules from a directory which is not on Python's default
|
|
|
|
module search path, you can change the path in your script, before importing
|
|
|
|
other modules. For example::
|
|
|
|
|
|
|
|
import sys
|
|
|
|
sys.path.insert(0, "/usr/home/joe/lib/python")
|
|
|
|
sys.path.insert(0, "/usr/local/lib/python")
|
|
|
|
|
|
|
|
(This way, the directory inserted last will be searched first!)
|
|
|
|
|
|
|
|
Instructions for non-Unix systems will vary; check your HTTP server's
|
|
|
|
documentation (it will usually have a section on CGI scripts).
|
|
|
|
|
|
|
|
|
|
|
|
Testing your CGI script
|
|
|
|
-----------------------
|
|
|
|
|
|
|
|
Unfortunately, a CGI script will generally not run when you try it from the
|
|
|
|
command line, and a script that works perfectly from the command line may fail
|
|
|
|
mysteriously when run from the server. There's one reason why you should still
|
|
|
|
test your script from the command line: if it contains a syntax error, the
|
|
|
|
Python interpreter won't execute it at all, and the HTTP server will most likely
|
|
|
|
send a cryptic error to the client.
|
|
|
|
|
|
|
|
Assuming your script has no syntax errors, yet it does not work, you have no
|
|
|
|
choice but to read the next section.
|
|
|
|
|
|
|
|
|
|
|
|
Debugging CGI scripts
|
|
|
|
---------------------
|
|
|
|
|
|
|
|
.. index:: pair: CGI; debugging
|
|
|
|
|
|
|
|
First of all, check for trivial installation errors --- reading the section
|
|
|
|
above on installing your CGI script carefully can save you a lot of time. If
|
|
|
|
you wonder whether you have understood the installation procedure correctly, try
|
|
|
|
installing a copy of this module file (:file:`cgi.py`) as a CGI script. When
|
|
|
|
invoked as a script, the file will dump its environment and the contents of the
|
|
|
|
form in HTML form. Give it the right mode etc, and send it a request. If it's
|
|
|
|
installed in the standard :file:`cgi-bin` directory, it should be possible to
|
|
|
|
send it a request by entering a URL into your browser of the form::
|
|
|
|
|
|
|
|
http://yourhostname/cgi-bin/cgi.py?name=Joe+Blow&addr=At+Home
|
|
|
|
|
|
|
|
If this gives an error of type 404, the server cannot find the script -- perhaps
|
|
|
|
you need to install it in a different directory. If it gives another error,
|
|
|
|
there's an installation problem that you should fix before trying to go any
|
|
|
|
further. If you get a nicely formatted listing of the environment and form
|
|
|
|
content (in this example, the fields should be listed as "addr" with value "At
|
|
|
|
Home" and "name" with value "Joe Blow"), the :file:`cgi.py` script has been
|
|
|
|
installed correctly. If you follow the same procedure for your own script, you
|
|
|
|
should now be able to debug it.
|
|
|
|
|
|
|
|
The next step could be to call the :mod:`cgi` module's :func:`test` function
|
|
|
|
from your script: replace its main code with the single statement ::
|
|
|
|
|
|
|
|
cgi.test()
|
|
|
|
|
|
|
|
This should produce the same results as those gotten from installing the
|
|
|
|
:file:`cgi.py` file itself.
|
|
|
|
|
|
|
|
When an ordinary Python script raises an unhandled exception (for whatever
|
|
|
|
reason: of a typo in a module name, a file that can't be opened, etc.), the
|
|
|
|
Python interpreter prints a nice traceback and exits. While the Python
|
|
|
|
interpreter will still do this when your CGI script raises an exception, most
|
|
|
|
likely the traceback will end up in one of the HTTP server's log files, or be
|
|
|
|
discarded altogether.
|
|
|
|
|
|
|
|
Fortunately, once you have managed to get your script to execute *some* code,
|
|
|
|
you can easily send tracebacks to the Web browser using the :mod:`cgitb` module.
|
Merged revisions 68582,68718,68720-68721,68724-68727,68859,68973,69288-69289,69293,69295,69297-69301,69409,69414,69570,69573,69576,69728-69730,69769,69776,69803-69805,69840,69896 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk
........
r68582 | georg.brandl | 2009-01-13 23:14:01 +0100 (Di, 13 Jan 2009) | 2 lines
Use assertRaises.
........
r68718 | georg.brandl | 2009-01-18 11:42:35 +0100 (So, 18 Jan 2009) | 1 line
#4976: union() and intersection() take multiple args, but talk about "the other".
........
r68720 | georg.brandl | 2009-01-18 11:45:22 +0100 (So, 18 Jan 2009) | 1 line
#4974: fix redundant mention of lists and tuples.
........
r68721 | georg.brandl | 2009-01-18 11:48:16 +0100 (So, 18 Jan 2009) | 1 line
#4914: trunc is in math.
........
r68724 | georg.brandl | 2009-01-18 14:24:10 +0100 (So, 18 Jan 2009) | 1 line
#4979: correct result range for some random functions.
........
r68725 | georg.brandl | 2009-01-18 14:47:26 +0100 (So, 18 Jan 2009) | 1 line
#4857: fix augmented assignment target spec.
........
r68726 | georg.brandl | 2009-01-18 15:41:52 +0100 (So, 18 Jan 2009) | 1 line
#4923: clarify what was added.
........
r68727 | georg.brandl | 2009-01-18 19:25:30 +0100 (So, 18 Jan 2009) | 1 line
#4986: augassigns are not expressions.
........
r68859 | georg.brandl | 2009-01-22 19:29:28 +0100 (Do, 22 Jan 2009) | 2 lines
Clarify wording.
........
r68973 | georg.brandl | 2009-01-26 22:29:38 +0100 (Mo, 26 Jan 2009) | 2 lines
Copy over docs on advanced role features from Sphinx docs.
........
r69288 | georg.brandl | 2009-02-05 11:30:57 +0100 (Do, 05 Feb 2009) | 1 line
#5153: fix typo in example.
........
r69289 | georg.brandl | 2009-02-05 11:37:07 +0100 (Do, 05 Feb 2009) | 1 line
#5144: document that PySys_SetArgv prepends the script directory (or the empty string) to sys.path.
........
r69293 | georg.brandl | 2009-02-05 11:59:28 +0100 (Do, 05 Feb 2009) | 1 line
#5059: fix example.
........
r69295 | georg.brandl | 2009-02-05 12:23:47 +0100 (Do, 05 Feb 2009) | 1 line
PyErr_PrintEx is also in 2.x...
........
r69297 | georg.brandl | 2009-02-05 12:32:18 +0100 (Do, 05 Feb 2009) | 1 line
#5015: document PythonHome API functions.
........
r69298 | georg.brandl | 2009-02-05 12:33:21 +0100 (Do, 05 Feb 2009) | 1 line
#4827: fix callback example.
........
r69299 | georg.brandl | 2009-02-05 12:35:28 +0100 (Do, 05 Feb 2009) | 1 line
#4820: use correct module for ctypes.util.
........
r69300 | georg.brandl | 2009-02-05 12:38:23 +0100 (Do, 05 Feb 2009) | 1 line
#4563: disable alpha and roman lists, fixes wrong formatting of contributor list.
........
r69301 | georg.brandl | 2009-02-05 12:40:35 +0100 (Do, 05 Feb 2009) | 1 line
#5031: fix Thread.daemon property docs.
........
r69409 | georg.brandl | 2009-02-07 13:21:17 +0100 (Sa, 07 Feb 2009) | 1 line
#5174: fix wrong file closing in example.
........
r69414 | georg.brandl | 2009-02-07 19:49:54 +0100 (Sa, 07 Feb 2009) | 1 line
make "super only for new-style classes" a note.
........
r69570 | georg.brandl | 2009-02-13 11:40:14 +0100 (Fr, 13 Feb 2009) | 1 line
#4894: document "newurl" parameter to redirect_request().
........
r69573 | georg.brandl | 2009-02-13 11:44:17 +0100 (Fr, 13 Feb 2009) | 1 line
#3734: document complex coercing behavior better.
........
r69576 | georg.brandl | 2009-02-13 11:56:50 +0100 (Fr, 13 Feb 2009) | 1 line
#1661108: note that urlsafe encoded string can contain "=".
........
r69728 | georg.brandl | 2009-02-18 01:22:55 +0100 (Mi, 18 Feb 2009) | 2 lines
#5297: fix example.
........
r69729 | georg.brandl | 2009-02-18 01:25:13 +0100 (Mi, 18 Feb 2009) | 2 lines
#5296: sequence -> iterable.
........
r69730 | georg.brandl | 2009-02-18 01:31:36 +0100 (Mi, 18 Feb 2009) | 2 lines
#5268: mention VMSError.
........
r69769 | georg.brandl | 2009-02-19 09:30:06 +0100 (Do, 19 Feb 2009) | 1 line
#5310, #3558: fix operator precedence table.
........
r69776 | georg.brandl | 2009-02-19 17:34:51 +0100 (Do, 19 Feb 2009) | 2 lines
#5317: update IronPython URL.
........
r69803 | georg.brandl | 2009-02-20 08:48:21 +0100 (Fr, 20 Feb 2009) | 1 line
#5327: fix a broken link by joining it.
........
r69804 | georg.brandl | 2009-02-20 09:22:21 +0100 (Fr, 20 Feb 2009) | 1 line
At least separate imports from other statements.
........
r69805 | georg.brandl | 2009-02-20 09:45:47 +0100 (Fr, 20 Feb 2009) | 2 lines
Fix punctuation.
........
r69840 | georg.brandl | 2009-02-21 20:09:40 +0100 (Sa, 21 Feb 2009) | 1 line
#5338, #5339: two types in the API manual.
........
r69896 | georg.brandl | 2009-02-23 11:24:23 +0100 (Mo, 23 Feb 2009) | 1 line
#5348: format() converts all kinds of values.
........
2009-02-23 06:41:11 -04:00
|
|
|
If you haven't done so already, just add the lines::
|
2007-08-15 11:28:01 -03:00
|
|
|
|
Merged revisions 68582,68718,68720-68721,68724-68727,68859,68973,69288-69289,69293,69295,69297-69301,69409,69414,69570,69573,69576,69728-69730,69769,69776,69803-69805,69840,69896 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk
........
r68582 | georg.brandl | 2009-01-13 23:14:01 +0100 (Di, 13 Jan 2009) | 2 lines
Use assertRaises.
........
r68718 | georg.brandl | 2009-01-18 11:42:35 +0100 (So, 18 Jan 2009) | 1 line
#4976: union() and intersection() take multiple args, but talk about "the other".
........
r68720 | georg.brandl | 2009-01-18 11:45:22 +0100 (So, 18 Jan 2009) | 1 line
#4974: fix redundant mention of lists and tuples.
........
r68721 | georg.brandl | 2009-01-18 11:48:16 +0100 (So, 18 Jan 2009) | 1 line
#4914: trunc is in math.
........
r68724 | georg.brandl | 2009-01-18 14:24:10 +0100 (So, 18 Jan 2009) | 1 line
#4979: correct result range for some random functions.
........
r68725 | georg.brandl | 2009-01-18 14:47:26 +0100 (So, 18 Jan 2009) | 1 line
#4857: fix augmented assignment target spec.
........
r68726 | georg.brandl | 2009-01-18 15:41:52 +0100 (So, 18 Jan 2009) | 1 line
#4923: clarify what was added.
........
r68727 | georg.brandl | 2009-01-18 19:25:30 +0100 (So, 18 Jan 2009) | 1 line
#4986: augassigns are not expressions.
........
r68859 | georg.brandl | 2009-01-22 19:29:28 +0100 (Do, 22 Jan 2009) | 2 lines
Clarify wording.
........
r68973 | georg.brandl | 2009-01-26 22:29:38 +0100 (Mo, 26 Jan 2009) | 2 lines
Copy over docs on advanced role features from Sphinx docs.
........
r69288 | georg.brandl | 2009-02-05 11:30:57 +0100 (Do, 05 Feb 2009) | 1 line
#5153: fix typo in example.
........
r69289 | georg.brandl | 2009-02-05 11:37:07 +0100 (Do, 05 Feb 2009) | 1 line
#5144: document that PySys_SetArgv prepends the script directory (or the empty string) to sys.path.
........
r69293 | georg.brandl | 2009-02-05 11:59:28 +0100 (Do, 05 Feb 2009) | 1 line
#5059: fix example.
........
r69295 | georg.brandl | 2009-02-05 12:23:47 +0100 (Do, 05 Feb 2009) | 1 line
PyErr_PrintEx is also in 2.x...
........
r69297 | georg.brandl | 2009-02-05 12:32:18 +0100 (Do, 05 Feb 2009) | 1 line
#5015: document PythonHome API functions.
........
r69298 | georg.brandl | 2009-02-05 12:33:21 +0100 (Do, 05 Feb 2009) | 1 line
#4827: fix callback example.
........
r69299 | georg.brandl | 2009-02-05 12:35:28 +0100 (Do, 05 Feb 2009) | 1 line
#4820: use correct module for ctypes.util.
........
r69300 | georg.brandl | 2009-02-05 12:38:23 +0100 (Do, 05 Feb 2009) | 1 line
#4563: disable alpha and roman lists, fixes wrong formatting of contributor list.
........
r69301 | georg.brandl | 2009-02-05 12:40:35 +0100 (Do, 05 Feb 2009) | 1 line
#5031: fix Thread.daemon property docs.
........
r69409 | georg.brandl | 2009-02-07 13:21:17 +0100 (Sa, 07 Feb 2009) | 1 line
#5174: fix wrong file closing in example.
........
r69414 | georg.brandl | 2009-02-07 19:49:54 +0100 (Sa, 07 Feb 2009) | 1 line
make "super only for new-style classes" a note.
........
r69570 | georg.brandl | 2009-02-13 11:40:14 +0100 (Fr, 13 Feb 2009) | 1 line
#4894: document "newurl" parameter to redirect_request().
........
r69573 | georg.brandl | 2009-02-13 11:44:17 +0100 (Fr, 13 Feb 2009) | 1 line
#3734: document complex coercing behavior better.
........
r69576 | georg.brandl | 2009-02-13 11:56:50 +0100 (Fr, 13 Feb 2009) | 1 line
#1661108: note that urlsafe encoded string can contain "=".
........
r69728 | georg.brandl | 2009-02-18 01:22:55 +0100 (Mi, 18 Feb 2009) | 2 lines
#5297: fix example.
........
r69729 | georg.brandl | 2009-02-18 01:25:13 +0100 (Mi, 18 Feb 2009) | 2 lines
#5296: sequence -> iterable.
........
r69730 | georg.brandl | 2009-02-18 01:31:36 +0100 (Mi, 18 Feb 2009) | 2 lines
#5268: mention VMSError.
........
r69769 | georg.brandl | 2009-02-19 09:30:06 +0100 (Do, 19 Feb 2009) | 1 line
#5310, #3558: fix operator precedence table.
........
r69776 | georg.brandl | 2009-02-19 17:34:51 +0100 (Do, 19 Feb 2009) | 2 lines
#5317: update IronPython URL.
........
r69803 | georg.brandl | 2009-02-20 08:48:21 +0100 (Fr, 20 Feb 2009) | 1 line
#5327: fix a broken link by joining it.
........
r69804 | georg.brandl | 2009-02-20 09:22:21 +0100 (Fr, 20 Feb 2009) | 1 line
At least separate imports from other statements.
........
r69805 | georg.brandl | 2009-02-20 09:45:47 +0100 (Fr, 20 Feb 2009) | 2 lines
Fix punctuation.
........
r69840 | georg.brandl | 2009-02-21 20:09:40 +0100 (Sa, 21 Feb 2009) | 1 line
#5338, #5339: two types in the API manual.
........
r69896 | georg.brandl | 2009-02-23 11:24:23 +0100 (Mo, 23 Feb 2009) | 1 line
#5348: format() converts all kinds of values.
........
2009-02-23 06:41:11 -04:00
|
|
|
import cgitb
|
|
|
|
cgitb.enable()
|
2007-08-15 11:28:01 -03:00
|
|
|
|
|
|
|
to the top of your script. Then try running it again; when a problem occurs,
|
|
|
|
you should see a detailed report that will likely make apparent the cause of the
|
|
|
|
crash.
|
|
|
|
|
|
|
|
If you suspect that there may be a problem in importing the :mod:`cgitb` module,
|
|
|
|
you can use an even more robust approach (which only uses built-in modules)::
|
|
|
|
|
|
|
|
import sys
|
|
|
|
sys.stderr = sys.stdout
|
|
|
|
print "Content-Type: text/plain"
|
|
|
|
print
|
|
|
|
...your code here...
|
|
|
|
|
|
|
|
This relies on the Python interpreter to print the traceback. The content type
|
|
|
|
of the output is set to plain text, which disables all HTML processing. If your
|
|
|
|
script works, the raw HTML will be displayed by your client. If it raises an
|
|
|
|
exception, most likely after the first two lines have been printed, a traceback
|
|
|
|
will be displayed. Because no HTML interpretation is going on, the traceback
|
|
|
|
will be readable.
|
|
|
|
|
|
|
|
|
|
|
|
Common problems and solutions
|
|
|
|
-----------------------------
|
|
|
|
|
|
|
|
* Most HTTP servers buffer the output from CGI scripts until the script is
|
|
|
|
completed. This means that it is not possible to display a progress report on
|
|
|
|
the client's display while the script is running.
|
|
|
|
|
|
|
|
* Check the installation instructions above.
|
|
|
|
|
|
|
|
* Check the HTTP server's log files. (``tail -f logfile`` in a separate window
|
|
|
|
may be useful!)
|
|
|
|
|
|
|
|
* Always check a script for syntax errors first, by doing something like
|
|
|
|
``python script.py``.
|
|
|
|
|
|
|
|
* If your script does not have any syntax errors, try adding ``import cgitb;
|
|
|
|
cgitb.enable()`` to the top of the script.
|
|
|
|
|
|
|
|
* When invoking external programs, make sure they can be found. Usually, this
|
|
|
|
means using absolute path names --- :envvar:`PATH` is usually not set to a very
|
|
|
|
useful value in a CGI script.
|
|
|
|
|
|
|
|
* When reading or writing external files, make sure they can be read or written
|
|
|
|
by the userid under which your CGI script will be running: this is typically the
|
|
|
|
userid under which the web server is running, or some explicitly specified
|
|
|
|
userid for a web server's ``suexec`` feature.
|
|
|
|
|
|
|
|
* Don't try to give a CGI script a set-uid mode. This doesn't work on most
|
|
|
|
systems, and is a security liability as well.
|
|
|
|
|
|
|
|
.. rubric:: Footnotes
|
|
|
|
|
|
|
|
.. [#] Note that some recent versions of the HTML specification do state what order the
|
|
|
|
field values should be supplied in, but knowing whether a request was
|
|
|
|
received from a conforming browser, or even from a browser at all, is tedious
|
|
|
|
and error-prone.
|
|
|
|
|