diff -r 017e7391ab58 Doc/library/cgi.rst --- a/Doc/library/cgi.rst Wed Feb 04 08:37:02 2015 -0800 +++ b/Doc/library/cgi.rst Fri Feb 06 12:56:44 2015 +0000 @@ -29,7 +29,7 @@ .. _cgi-intro: A CGI script is invoked by an HTTP server, usually to process user input -submitted through an HTML ``
`` or ```` element. +submitted through an HTML ```` 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 @@ -41,8 +41,7 @@ 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). +of utilities that help in debugging scripts. 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 @@ -86,22 +85,73 @@ 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, use the :class:`FieldStorage` class. If the form -contains non-ASCII characters, use the *encoding* keyword parameter set to the -value of the encoding defined for the document. It is usually contained in the -META tag in the HEAD section of the HTML document or by the -:mailheader:`Content-Type` header). This reads the form contents from the -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. +To get at submitted form data, use the :class:`FieldStorage` class. -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:`~dict.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. +.. class:: FieldStorage(fp=None, headers=None, environ=os.environ, \ + keep_blank_values=False, strict_parsing=False, \ + encoding='utf-8', errors='replace') + + Creating an instance of this class reads the form contents from the + 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 per request. + + *fp* (defaults to :attr:`sys.stdin.buffer `) can be a + :class:`~io.TextIOWrapper` object or a :term:`file-like object ` whose ``read()`` and ``readline()`` methods return bytes. + + *headers* is a dictionary-like object which, if not specified, is taken from + *environ*. + + *environ* is a :term:`mapping` object specifying the environment to be used. + It defaults to :attr:`os.environ`. + + If *keep_blank_values* is not specified or ``False``, form fields containing + empty strings are ignored and do not appear in the dictionary. If ``True``, + they are included, with ``""`` as the value. + + If the form contains non-ASCII characters, use the *encoding* keyword + parameter set to the value of the encoding defined for the document. It + is usually contained in a ```` element of the HTML document or in + the :mailheader:`Content-Type` header. + + The *errors* argument indicates how to manage encoding errors (see the + :meth:`bytes.decode` documentation). + + The optional argument *strict_parsing* is a flag indicating what to do with + parsing errors. If false (the default), errors are silently ignored. If + ``True``, errors raise a :exc:`ValueError` exception. + +The :class:`FieldStorage` instance is a dictionary-like object, mapping each +form field name to an object that can be: + +* another instance of :class:`FieldStorage` for data sent in the body of a + POST request with a :mimetype:`multipart` encoding type + +* an instance of the :class:`MiniFieldStorage` class for data sent as the + URL query string or as a single data part of type + :mimetype:`application/x-www-form-urlencoded` + +* a list of :class:`FieldStorage` or :class:`MiniFieldStorage` in the case + of multiple fields with the same name (see next section) + +A form submitted via a POST request that also has a query string will contain +both :class:`FieldStorage` and :class:`MiniFieldStorage` items. + +In all cases, the object associated to a field name has an attribute +:attr:`value`. It is set to + +* the field value as a string, or as bytes for file uploads, if there is a + single value for this field name + +* the list of values if there are several values for this field name + +For instances of :class:`FieldStorage` the value can be obtained by the method + +.. method:: FieldStorage.getvalue(name[, default=None]) + + Return the value for the specified field *name* ; the optional argument + *default* is returned if the requested *name* is not present. For instance, the following code (which assumes that the :mailheader:`Content-Type` header and blank line have already been printed) @@ -120,23 +170,61 @@ Here the fields, accessed through ``form[key]``, are themselves instances of :class:`FieldStorage` (or :class:`MiniFieldStorage`, depending on the form encoding). The :attr:`~FieldStorage.value` attribute of the instance yields -the string value of the field. The :meth:`~FieldStorage.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. +the string value of the field. -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 :meth:`~FieldStorage.getlist` method, 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, +Multiple fields with the same name +---------------------------------- + +The submitted form data may contain more than one field with the same name. +This situation is common for example when a form contains a group of multiple +checkboxes with the same name:: + + + + +In this case, the object retrieved by ``form["item"]`` 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 following methods: + +.. 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. + + +.. method:: FieldStorage.getfirst(name[, default=None]) + + 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. + + +For example, this code concatenates any number of fields called ``username``, separated by commas:: value = form.getlist("username") usernames = ",".join(value) +Using these methods you can write code that handles all cases without having to +test if the value is a single instance or a list of instances:: + + import cgi + form = cgi.FieldStorage() + user = form.getfirst("user", "").upper() # This way it's safe. + for item in form.getlist("item"): + do_something(item) + + +File uploads +------------ + If a field represents an uploaded file, accessing the value via the :attr:`~FieldStorage.value` attribute or the :meth:`~FieldStorage.getvalue` method reads the entire file in memory as bytes. This may not be what you @@ -170,98 +258,10 @@ :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 -:attr:`!list`, :attr:`!file`, and :attr:`filename` attributes are always ``None``. - -A form submitted via POST that also has a query string will contain both -:class:`FieldStorage` and :class:`MiniFieldStorage` items. - .. versionchanged:: 3.4 The :attr:`~FieldStorage.file` attribute is automatically closed upon the garbage collection of the creating :class:`FieldStorage` instance. - -Higher Level Interface ----------------------- - -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. - -.. XXX: Is this true ? - -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:: - - - - -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:`~str.upper` 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:`~FieldStorage.getfirst` -and :meth:`~FieldStorage.getlist` provided by this higher level interface. - - -.. method:: FieldStorage.getfirst(name, default=None) - - 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) - - .. _functions-in-cgi-module: Functions