cinap_lenrekadd hg and python4bb9e2215 years agoHistory
602 lines · 23.8 KB · TeX
RawDownload
\section{\module{cgi} ---         Common Gateway Interface support.}\declaremodule{standard}{cgi} \modulesynopsis{Common Gateway Interface support, used to interpretforms in server-side scripts.} \indexii{WWW}{server}\indexii{CGI}{protocol}\indexii{HTTP}{protocol}\indexii{MIME}{headers}\index{URL}  Support module for Common Gateway Interface (CGI) scripts.%\index{Common Gateway Interface} This module defines a number of utilities for use by CGI scriptswritten in Python. \subsection{Introduction}\nodename{cgi-intro} A CGI script is invoked by an HTTP server, usually to process userinput submitted through an HTML \code{<FORM>} or \code{<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 therequest (such as the client's hostname, the requested URL, the querystring, 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 theform data is read this way; at other times the form data is passed viathe ``query string'' part of the URL.  This module is intendedto take care of the different cases and provide a simpler interface tothe Python script.  It also provides a number of utilities that helpin debugging scripts, and the latest addition is support for fileuploads from a form (if your browser supports it). The output of a CGI script should consist of two sections, separatedby a blank line.  The first section contains a number of headers,telling the client what kind of data is following.  Python code togenerate a minimal header section looks like this: \begin{verbatim}print "Content-Type: text/html"     # HTML is followingprint                               # blank line, end of headers\end{verbatim} The second section is usually HTML, which allows the client softwareto display nicely formatted text with header, in-line images, etc.Here's Python code that prints a simple piece of HTML: \begin{verbatim}print "<TITLE>CGI script output</TITLE>"print "<H1>This is my first CGI script</H1>"print "Hello, world!"\end{verbatim} \subsection{Using the cgi module}\nodename{Using the cgi module} Begin by writing \samp{import cgi}.  Do not use \samp{from cgi import*} --- the module defines all sorts of names for its own use or forbackward compatibility that you don't want in your namespace. When you write a new script, consider adding the line: \begin{verbatim}import cgitb; cgitb.enable()\end{verbatim} This activates a special exception handler that will display detailedreports in the Web browser if any errors occur.  If you'd rather notshow the guts of your program to users of your script, you can havethe reports saved to files instead, with a line like this: \begin{verbatim}import cgitb; cgitb.enable(display=0, logdir="/tmp")\end{verbatim} It's very helpful to use this feature during script development.The reports produced by \refmodule{cgitb} provide information thatcan save you a lot of time in tracking down bugs.  You can alwaysremove the \code{cgitb} line later when you have tested your scriptand are confident that it works correctly. To get at submitted form data,it's best to use the \class{FieldStorage} class.  The other classesdefined in this module are provided mostly for backward compatibility.Instantiate it exactly once, without arguments.  This reads the formcontents from standard input or the environment (depending on thevalue of various environment variables set according to the CGIstandard).  Since it may consume standard input, it should beinstantiated only once. The \class{FieldStorage} instance can be indexed like a Pythondictionary, and also supports the standard dictionary methods\method{has_key()} and \method{keys()}.  The built-in \function{len()}is also supported.  Form fields containing empty strings are ignoredand do not appear in the dictionary; to keep such values, providea true value for the optional \var{keep_blank_values} keywordparameter when creating the \class{FieldStorage} instance. For instance, the following code (which assumes that the \mailheader{Content-Type} header and blank line have already beenprinted) checks that the fields \code{name} and \code{addr} are bothset to a non-empty string: \begin{verbatim}form = cgi.FieldStorage()if not (form.has_key("name") and form.has_key("addr")):    print "<H1>Error</H1>"    print "Please fill in the name and addr fields."    returnprint "<p>name:", form["name"].valueprint "<p>addr:", form["addr"].value...further form processing here...\end{verbatim} Here the fields, accessed through \samp{form[\var{key}]}, arethemselves instances of \class{FieldStorage} (or\class{MiniFieldStorage}, depending on the form encoding).The \member{value} attribute of the instance yields the string valueof the field.  The \method{getvalue()} method returns this string valuedirectly; it also accepts an optional second argument as a default toreturn if the requested key is not present. If the submitted form data contains more than one field with the samename, the object retrieved by \samp{form[\var{key}]} is not a\class{FieldStorage} or \class{MiniFieldStorage}instance but a list of such instances.  Similarly, in this situation,\samp{form.getvalue(\var{key})} would return a list of strings.If you expect this possibility(when your HTML form contains multiple fields with the same name), usethe \function{getlist()} function, which always returns a list of values (so that youdo not need to special-case the single item case).  For example, thiscode concatenates any number of username fields, separated bycommas: \begin{verbatim}value = form.getlist("username")usernames = ",".join(value)\end{verbatim} If a field represents an uploaded file, accessing the value via the\member{value} attribute or the \function{getvalue()} method reads theentire file in memory as a string.  This may not be what you want.You can test for an uploaded file by testing either the \member{filename}attribute or the \member{file} attribute.  You can then read the data atleisure from the \member{file} attribute: \begin{verbatim}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\end{verbatim} The file upload draft standard entertains the possibility of uploadingmultiple files from one field (using a recursive\mimetype{multipart/*} encoding).  When this occurs, the item will bea dictionary-like \class{FieldStorage} item.  This can be determinedby testing its \member{type} attribute, which should be\mimetype{multipart/form-data} (or perhaps another MIME type matching\mimetype{multipart/*}).  In this case, it can be iterated overrecursively just like the top-level form object. When a form is submitted in the ``old'' format (as the query string oras a single data part of type\mimetype{application/x-www-form-urlencoded}), the items will actuallybe instances of the class \class{MiniFieldStorage}.  In this case, the\member{list}, \member{file}, and \member{filename} attributes arealways \code{None}.  \subsection{Higher Level Interface} \versionadded{2.2}  % XXX: Is this true ?  The previous section explains how to read CGI form data using the\class{FieldStorage} class.  This section describes a higher levelinterface which was added to this class to allow one to do it in amore readable and intuitive way.  The interface doesn't make thetechniques described in previous sections obsolete --- they are stilluseful to process file uploads efficiently, for example. The interface consists of two simple methods. Using the methodsyou can process form data in a generic way, without the need to worrywhether only one or more values were posted under one name. In the previous section, you learned to write following code anytimeyou expected a user to post more than one value under one name: \begin{verbatim}item = form.getvalue("item")if isinstance(item, list):    # The user is requesting more than one item.else:    # The user is requesting only one item.\end{verbatim} This situation is common for example when a form contains a group ofmultiple checkboxes with the same name: \begin{verbatim}<input type="checkbox" name="item" value="1" /><input type="checkbox" name="item" value="2" />\end{verbatim} In most situations, however, there's only one form control with aparticular name in a form and then you expect and need only one valueassociated with this name.  So you write a script containing forexample this code: \begin{verbatim}user = form.getvalue("user").upper()\end{verbatim} The problem with the code is that you should never expect that aclient will provide valid input to your scripts.  For example, if acurious user appends another \samp{user=foo} pair to the query string,then the script would crash, because in this situation the\code{getvalue("user")} method call returns a list instead of astring.  Calling the \method{toupper()} method on a list is not valid(since lists do not have a method of this name) and results in an\exception{AttributeError} exception. Therefore, the appropriate way to read form data values was to alwaysuse the code which checks whether the obtained value is a single valueor a list of values.  That's annoying and leads to less readablescripts. A more convenient approach is to use the methods \method{getfirst()}and \method{getlist()} provided by this higher level interface. \begin{methoddesc}[FieldStorage]{getfirst}{name\optional{, default}}  This method always returns only one value associated with form field  \var{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.\footnote{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.}  If no such form  field or value exists then the method returns the value specified by  the optional parameter \var{default}.  This parameter defaults to  \code{None} if not specified.\end{methoddesc} \begin{methoddesc}[FieldStorage]{getlist}{name}  This method always returns a list of values associated with form  field \var{name}.  The method returns an empty list if no such form  field or value exists for \var{name}.  It returns a list consisting  of one item if only one such value exists.\end{methoddesc} Using these methods you can write nice compact code: \begin{verbatim}import cgiform = cgi.FieldStorage()user = form.getfirst("user", "").upper()    # This way it's safe.for item in form.getlist("item"):    do_something(item)\end{verbatim}  \subsection{Old classes} These classes, present in earlier versions of the \module{cgi} module,are still supported for backward compatibility.  New applicationsshould use the \class{FieldStorage} class. \class{SvFormContentDict} stores single value form content asdictionary; it assumes each field name occurs in the form only once. \class{FormContentDict} stores multiple value form content as adictionary (the form items are lists of values).  Useful if your formcontains multiple fields with the same name. Other classes (\class{FormContent}, \class{InterpFormContentDict}) arepresent for backwards compatibility with really old applications only.If you still use these and would be inconvenienced when theydisappeared from a next version of this module, drop me a note.  \subsection{Functions}\nodename{Functions in cgi module} These are useful if you want more control, or if you want to employsome of the algorithms implemented in this module in othercircumstances. \begin{funcdesc}{parse}{fp\optional{, keep_blank_values\optional{,                        strict_parsing}}}  Parse a query in the environment or from a file (the file defaults  to \code{sys.stdin}).  The \var{keep_blank_values} and  \var{strict_parsing} parameters are passed to \function{parse_qs()}  unchanged.\end{funcdesc} \begin{funcdesc}{parse_qs}{qs\optional{, keep_blank_values\optional{,                           strict_parsing}}}Parse a query string given as a string argument (data of type \mimetype{application/x-www-form-urlencoded}).  Data arereturned as a dictionary.  The dictionary keys are the unique queryvariable names and the values are lists of values for each name. The optional argument \var{keep_blank_values} isa flag indicating whether blank values inURL encoded queries should be treated as blank strings.  A true value indicates that blanks should be retained as blank strings.  The default false value indicates thatblank values are to be ignored and treated as if they werenot included. The optional argument \var{strict_parsing} is a flag indicating whatto do with parsing errors.  If false (the default), errorsare silently ignored.  If true, errors raise a \exception{ValueError}exception. Use the \function{\refmodule{urllib}.urlencode()} function to convertsuch dictionaries into query strings. \end{funcdesc} \begin{funcdesc}{parse_qsl}{qs\optional{, keep_blank_values\optional{,                            strict_parsing}}}Parse a query string given as a string argument (data of type \mimetype{application/x-www-form-urlencoded}).  Data arereturned as a list of name, value pairs. The optional argument \var{keep_blank_values} isa flag indicating whether blank values inURL encoded queries should be treated as blank strings.  A true value indicates that blanks should be retained as blank strings.  The default false value indicates thatblank values are to be ignored and treated as if they werenot included. The optional argument \var{strict_parsing} is a flag indicating whatto do with parsing errors.  If false (the default), errorsare silently ignored.  If true, errors raise a \exception{ValueError}exception. Use the \function{\refmodule{urllib}.urlencode()} function to convertsuch lists of pairs into query strings.\end{funcdesc} \begin{funcdesc}{parse_multipart}{fp, pdict}Parse input of type \mimetype{multipart/form-data} (for file uploads).  Arguments are \var{fp} for the input file and\var{pdict} for a dictionary containing other parameters inthe \mailheader{Content-Type} header. Returns a dictionary just like \function{parse_qs()} keys are thefield names, each value is a list of values for that field.  This iseasy to use but not much good if you are expecting megabytes to beuploaded --- in that case, use the \class{FieldStorage} class insteadwhich is much more flexible. Note that this does not parse nested multipart parts --- use\class{FieldStorage} for that.\end{funcdesc} \begin{funcdesc}{parse_header}{string}Parse a MIME header (such as \mailheader{Content-Type}) into a mainvalue and a dictionary of parameters.\end{funcdesc} \begin{funcdesc}{test}{}Robust test CGI script, usable as main program.Writes minimal HTTP headers and formats all information provided tothe script in HTML form.\end{funcdesc} \begin{funcdesc}{print_environ}{}Format the shell environment in HTML.\end{funcdesc} \begin{funcdesc}{print_form}{form}Format a form in HTML.\end{funcdesc} \begin{funcdesc}{print_directory}{}Format the current directory in HTML.\end{funcdesc} \begin{funcdesc}{print_environ_usage}{}Print a list of useful (used by CGI) environment variables inHTML.\end{funcdesc} \begin{funcdesc}{escape}{s\optional{, quote}}Convert the characters\character{\&}, \character{<} and \character{>} in string \var{s} toHTML-safe sequences.  Use this if you need to display text that mightcontain such characters in HTML.  If the optional flag \var{quote} istrue, the quotation mark character (\character{"}) is also translated;this helps for inclusion in an HTML attribute value, as in \code{<AHREF="...">}.  If the value to be quoted might include single- ordouble-quote characters, or both, consider using the\function{quoteattr()} function in the \refmodule{xml.sax.saxutils}module instead.\end{funcdesc}  \subsection{Caring about security \label{cgi-security}} \indexii{CGI}{security} There's one important rule: if you invoke an external program (via the\function{os.system()} or \function{os.popen()} functions. or otherswith similar functionality), make very sure you don't pass arbitrarystrings received from the client to the shell.  This is a well-knownsecurity hole whereby clever hackers anywhere on the Web can exploit agullible CGI script to invoke arbitrary shell commands.  Even parts ofthe URL or field names cannot be trusted, since the request doesn'thave to come from your form! To be on the safe side, if you must pass a string gotten from a formto a shell command, you should make sure the string contains onlyalphanumeric characters, dashes, underscores, and periods.  \subsection{Installing your CGI script on a \UNIX\ system} Read the documentation for your HTTP server and check with your localsystem administrator to find the directory where CGI scripts should beinstalled; 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 \code{0755} octal (use \samp{chmod 0755\var{filename}}).  Make sure that the first line of the script contains\code{\#!} starting in column 1 followed by the pathname of the Pythoninterpreter, for instance: \begin{verbatim}#!/usr/local/bin/python\end{verbatim} Make sure the Python interpreter exists and is executable by ``others''. Make sure that any files your script needs to read or write arereadable or writable, respectively, by ``others'' --- their modeshould be \code{0644} for readable and \code{0666} for writable.  Thisis because, for security reasons, the HTTP server executes your scriptas user ``nobody'', without any special privileges.  It can only read(write, execute) files that everybody can read (write, execute).  Thecurrent directory at execution time is also different (it is usuallythe server's cgi-bin directory) and the set of environment variablesis also different from what you get when you log in.  In particular, don'tcount on the shell's search path for executables (\envvar{PATH}) orthe Python module search path (\envvar{PYTHONPATH}) to be set toanything interesting. If you need to load modules from a directory which is not on Python'sdefault module search path, you can change the path in your script,before importing other modules.  For example: \begin{verbatim}import syssys.path.insert(0, "/usr/home/joe/lib/python")sys.path.insert(0, "/usr/local/lib/python")\end{verbatim} (This way, the directory inserted last will be searched first!) Instructions for non-\UNIX{} systems will vary; check your HTTP server'sdocumentation (it will usually have a section on CGI scripts).  \subsection{Testing your CGI script} Unfortunately, a CGI script will generally not run when you try itfrom the command line, and a script that works perfectly from thecommand line may fail mysteriously when run from the server.  There'sone reason why you should still test your script from the commandline: if it contains a syntax error, the Python interpreter won'texecute it at all, and the HTTP server will most likely send a crypticerror to the client. Assuming your script has no syntax errors, yet it does not work, youhave no choice but to read the next section.  \subsection{Debugging CGI scripts} \indexii{CGI}{debugging} First of all, check for trivial installation errors --- reading thesection above on installing your CGI script carefully can save you alot of time.  If you wonder whether you have understood theinstallation procedure correctly, try installing a copy of this modulefile (\file{cgi.py}) as a CGI script.  When invoked as a script, the file

Lines 1–500 of 602.