Skip to content
Snippets Groups Projects
Commit 4c592936 authored by SVN-Git Migration's avatar SVN-Git Migration
Browse files

Imported Upstream version 3.3.1

parent 6522f9c3
No related branches found
No related tags found
No related merge requests found
...@@ -81,4 +81,6 @@ Enrique Vaamonde <evaamo@loquesea.com> ...@@ -81,4 +81,6 @@ Enrique Vaamonde <evaamo@loquesea.com>
Dave Wallace <dwallace@delanet.com> Dave Wallace <dwallace@delanet.com>
Aaron Watters <arw1961@yahoo.com>
...@@ -45,6 +45,7 @@ MPFILES= modpython.tex \ ...@@ -45,6 +45,7 @@ MPFILES= modpython.tex \
modpython3.tex \ modpython3.tex \
modpython5.tex \ modpython5.tex \
modpython6.tex \ modpython6.tex \
modpython7.tex \
appendixa.tex \ appendixa.tex \
appendixb.tex appendixb.tex
......
...@@ -23,3 +23,34 @@ make ps ...@@ -23,3 +23,34 @@ make ps
Good Luck! Good Luck!
LaTeX Notes
-----------
Using the tilde character in LaTex is a bit of a headache as ~ is used for
markup.
The obvious solution of escaping it as \~ doesn't work, as this is also used
for markup and actually adds a diactrical to the immediately following
character.
If you want a ~ enclosed in double quotes you can use \character{\~}.
So \character{\~} becomes "~" in the generated documentation.
If you want a ~ without the quotes you can use \textasciitilde.
For example ~/foo/bar should be written as \textasciitilde/foo/bar in the
LaTeX source.
Using \textasciitilde does not work if there is an alpha-numeric character
immediately following. For a url you can hex encode the ~ as %7e. For example:
http://people.apache.org/~jgallacher
should be written as:
http://people.apache.org/\%7ejgallacher
Note that the ~ character is handled properly within a {verbatim} section,
so the following works without modification:
\begin{verbatim}
path = "~/foo/bar"
\end{verbatim}
This diff is collapsed.
...@@ -57,6 +57,7 @@ and a tutorial all-in-one. ...@@ -57,6 +57,7 @@ and a tutorial all-in-one.
\input{modpython4} % Python API \input{modpython4} % Python API
\input{modpython5} % Apache directives \input{modpython5} % Apache directives
\input{modpython6} % Handlers \input{modpython6} % Handlers
\input{modpython7} % Security
\appendix \appendix
%\input{appendixa} % Windows Install %\input{appendixa} % Windows Install
%\input{appendixb} % VMS Install %\input{appendixb} % VMS Install
......
...@@ -47,12 +47,29 @@ ...@@ -47,12 +47,29 @@
\section{History\label{intr-history}} \section{History\label{intr-history}}
Mod_python originates from a project called Mod_python originates from a project called
\citetitle[http://www.ispol.com/home/grisha/httpdapy/]{Httpdapy} \citetitle[http://www.modpython.org/httpdapy/]{Httpdapy}
(1997). For a long time Httpdapy was not called mod_python because (1997). For a long time Httpdapy was not called mod_python because
Httpdapy was not meant to be Apache-specific. Httpdapy was designed Httpdapy was not meant to be Apache-specific. Httpdapy was designed
to be cross-platform and in fact was initially written for the to be cross-platform and in fact was initially written for the
Netscape server (back then it was called Nsapy (1997). Netscape server (back then it was called Nsapy (1997).
Nsapy itself was based on an original concept and first code by
Aaron Watters from "Internet Programming with Python" by Aaron Watters,
Guido Van Rossum and James C. Ahlstrom, ISBN 1-55851-484-8.
Without Aaron's inspiration, there would be no mod_python. Quoting from
the Httpdapy README file:
\begin{verbatim}
Although Nsapy only worked with Netscape servers, it was very generic in its
design and was based on some brilliant ideas that weren't necessarily Netscape
specific. Its design is a combination of extensibility, simplicity and
efficiency that takes advantage of many of the key benefits of Python and is
totally in the spirit of Python.
\end{verbatim}
This excerpt from the Httpdapy README file describes well the This excerpt from the Httpdapy README file describes well the
challenges and the solution provided by embedding Python within the challenges and the solution provided by embedding Python within the
HTTP server: HTTP server:
......
...@@ -8,15 +8,23 @@ ...@@ -8,15 +8,23 @@
mod_python mailing list by sending an e-mail with the word mod_python mailing list by sending an e-mail with the word
\samp{subscribe} in the subject to \samp{subscribe} in the subject to
\email{mod_python-request@modpython.org}. \email{mod_python-request@modpython.org}.
Also check out Graham Dumpleton's assorted articles on mod_python
at \citetitle[http://www.dscpl.com.au/wiki/ModPython/Articles]{http://www.dscpl.com.au/wiki/ModPython/Articles}.
These include alternate instructions for getting a first mod_python
handler working, as well as articles covering problems, short comings and
constraints in various versions of mod_python.
\end{notice} \end{notice}
\section{Prerequisites\label{inst-prerequisites}} \section{Prerequisites\label{inst-prerequisites}}
\begin{itemize} \begin{itemize}
\item \item
Python 2.2.1 or later. Earlier versions of Python will not work. Python 2.3.4 or later. Python versions less than 2.3 will not work.
\item \item
Apache 2.0.47 or later (For Apache 1.3.x, use mod_python version 2.7.x). Apache 2.0.54 or later. Apache versions 2.0.47 to 2.0.53 may work
but have not been tested with this release.
(For Apache 1.3.x, use mod_python version 2.7.x).
\end{itemize} \end{itemize}
In order to compile mod_python you will need to have the include files In order to compile mod_python you will need to have the include files
...@@ -117,7 +125,7 @@ autoconf stuff, \program{./configure} does the following: ...@@ -117,7 +125,7 @@ autoconf stuff, \program{./configure} does the following:
\citetitle[dir-other-po.html]{PythonOption} directive. \citetitle[dir-other-po.html]{PythonOption} directive.
See \citetitle[inst-apacheconfig.html]{Configuring Apache}. See \citetitle[inst-apacheconfig.html]{Configuring Apache}.
\emph{Back ported from version 3.3.0} New in version 3.3.0
\item \item
\index{./configure!\longprogramopt{with-max-locks}} \index{./configure!\longprogramopt{with-max-locks}}
...@@ -283,7 +291,7 @@ autoconf stuff, \program{./configure} does the following: ...@@ -283,7 +291,7 @@ autoconf stuff, \program{./configure} does the following:
directive in your apache configuration file is immediately directive in your apache configuration file is immediately
following the \strong{LoadModule} directive. following the \strong{LoadModule} directive.
\emph{Back ported from version 3.3.0} \emph{New in version 3.3.0}
\item \strong{Mutex Locks} \indexii{apache configuration}{mutex locks} \item \strong{Mutex Locks} \indexii{apache configuration}{mutex locks}
...@@ -317,7 +325,7 @@ autoconf stuff, \program{./configure} does the following: ...@@ -317,7 +325,7 @@ autoconf stuff, \program{./configure} does the following:
directive in your apache configuration file is immediately directive in your apache configuration file is immediately
following the \strong{LoadModule} directive. following the \strong{LoadModule} directive.
\emph{Back ported from version 3.3.0} \emph{New in version 3.3.0}
\end{description} \end{description}
...@@ -407,7 +415,7 @@ if you are using Apache 1.3.x), please refer to the proper documentation. ...@@ -407,7 +415,7 @@ if you are using Apache 1.3.x), please refer to the proper documentation.
\end{enumerate} \end{enumerate}
\begin{seealso} \begin{seealso}
\seeurl{http://home.comcast.net/~d.popowich/mpservlets}{mpservlets} \seeurl{http://www.astro.umass.edu/\%7edpopowich/python/mpservlets/}{mpservlets}
\seeurl{http://www.dscpl.com.au/projects/vampire}{Vampire} \seeurl{http://www.dscpl.com.au/projects/vampire}{Vampire}
\end{seealso} \end{seealso}
......
...@@ -362,6 +362,11 @@ looks like this now: ...@@ -362,6 +362,11 @@ looks like this now:
</Directory> </Directory>
\end{verbatim} \end{verbatim}
Note that depending on which version of Apache is being used, you may need
to set either the \code{AuthAuthoritative} or \code{AuthBasicAuthoritative}
directive to \code{Off} to tell Apache that you want allow the task of
performing basic authentication to fall through to your handler.
Now we need to write an authentication handler function in Now we need to write an authentication handler function in
\file{myscript.py}. A basic authentication handler would look like \file{myscript.py}. A basic authentication handler would look like
this: this:
...@@ -468,3 +473,12 @@ render your page, and then \code{return(apache.OK)}: ...@@ -468,3 +473,12 @@ render your page, and then \code{return(apache.OK)}:
req.write(pagebuffer) req.write(pagebuffer)
return(apache.OK) return(apache.OK)
\end{verbatim} \end{verbatim}
Note that if wishing to returning an error page from a handler phase other
than the response handler, the value \code{apache.DONE} must be returned
instead of \code{apache.OK}. If this is not done, subsequent handler phases
will still be run. The value of \code{apache.DONE} indicates that processing
of the request should be stopped immediately. If using stacked response
handlers, then \code{apache.DONE} should also be returned in that situation
to prevent subsequent handlers registered for that phase being run if
appropriate.
This diff is collapsed.
...@@ -16,8 +16,18 @@ Multiple handlers can be specified on a single line, in which case ...@@ -16,8 +16,18 @@ Multiple handlers can be specified on a single line, in which case
they will be called sequentially, from left to right. Same handler they will be called sequentially, from left to right. Same handler
directives can be specified multiple times as well, with the same directives can be specified multiple times as well, with the same
result - all handlers listed will be executed sequentially, from first result - all handlers listed will be executed sequentially, from first
to last. If any handler in the sequence returns a value other than to last.
\code{apache.OK}, then execution of all subsequent handlers is aborted.
If any handler in the sequence returns a value other than \code{apache.OK}
or \code{apache.DECLINED}, then execution of all subsequent handlers for
that phase are aborted. What happens when either \code{apache.OK} or
\code{apache.DECLINED} is returned is dependent on which phase is
executing.
Note that prior to mod_python 3.3, if any handler in the sequence, no
matter which phase was executing, returned a value other than
\code{apache.OK}, then execution of all subsequent handlers for that phase
was aborted.
The list of handlers can optionally be followed by a \code{|} followed The list of handlers can optionally be followed by a \code{|} followed
by one or more file extensions. This would restrict the execution of by one or more file extensions. This would restrict the execution of
...@@ -29,9 +39,13 @@ A \emph{handler} has the following syntax: ...@@ -29,9 +39,13 @@ A \emph{handler} has the following syntax:
\code{module[::object]} \code{module[::object]}
Where \var{module} can be a full module name (package dot notation is Where \var{module} can be a full module name (package dot notation is
accepted), and the optional \var{object} is the name of an object accepted) or an actual path to a module code file. The module is loaded
inside the module. using the mod_python module importer as implemented by the
\code{apache.import_module()} function. Reference should be made to
the documentation of that function for further details of how module
importing is managed.
The optional \var{object} is the name of an object inside the module.
Object can also contain dots, in which case it will be resolved from Object can also contain dots, in which case it will be resolved from
left to right. During resolution, if mod_python encounters an object left to right. During resolution, if mod_python encounters an object
of type \code{<class>}, it will try instantiating it passing it a single of type \code{<class>}, it will try instantiating it passing it a single
...@@ -75,6 +89,10 @@ This handler is called after the request has been read but before any ...@@ -75,6 +89,10 @@ This handler is called after the request has been read but before any
other phases have been processed. This is useful to make decisions other phases have been processed. This is useful to make decisions
based upon the input header fields. based upon the input header fields.
Where multiple handlers are specified, if any handler in the sequence
returns a value other than \code{apache.OK} or \code{apache.DECLINED}, then
execution of all subsequent handlers for this phase are aborted.
\begin{notice} \begin{notice}
When this phase of the request is processed, the URI has not yet When this phase of the request is processed, the URI has not yet
been translated into a path name, therefore this directive could never been translated into a path name, therefore this directive could never
...@@ -109,6 +127,10 @@ This handler gives allows for an opportunity to translate the URI into ...@@ -109,6 +127,10 @@ This handler gives allows for an opportunity to translate the URI into
an actual filename, before the server's default rules (Alias an actual filename, before the server's default rules (Alias
directives and the like) are followed. directives and the like) are followed.
Where multiple handlers are specified, if any handler in the sequence
returns a value other than \code{apache.DECLINED}, then execution of all
subsequent handlers for this phase are aborted.
\begin{notice} \begin{notice}
At the time when this phase of the request is being processed, the At the time when this phase of the request is being processed, the
URI has not been translated into a path name, therefore this URI has not been translated into a path name, therefore this
...@@ -135,6 +157,10 @@ This handler is called to give the module a chance to look at the ...@@ -135,6 +157,10 @@ This handler is called to give the module a chance to look at the
request headers and take any appropriate specific actions early in the request headers and take any appropriate specific actions early in the
processing sequence. processing sequence.
Where multiple handlers are specified, if any handler in the sequence
returns a value other than \code{apache.OK} or \code{apache.DECLINED}, then
execution of all subsequent handlers for this phase are aborted.
\subsection{PythonInitHandler\label{dir-handlers-pih}} \subsection{PythonInitHandler\label{dir-handlers-pih}}
\index{PythonInitHandler} \index{PythonInitHandler}
...@@ -151,6 +177,10 @@ This handler is the first handler called in the request processing ...@@ -151,6 +177,10 @@ This handler is the first handler called in the request processing
phases that is allowed both inside and outside \file{.htaccess} and phases that is allowed both inside and outside \file{.htaccess} and
directory. directory.
Where multiple handlers are specified, if any handler in the sequence
returns a value other than \code{apache.OK} or \code{apache.DECLINED}, then
execution of all subsequent handlers for this phase are aborted.
This handler is actually an alias to two different handlers. When This handler is actually an alias to two different handlers. When
specified in the main config file outside any directory tags, it is an specified in the main config file outside any directory tags, it is an
alias to \code{PostReadRequestHandler}. When specified inside directory alias to \code{PostReadRequestHandler}. When specified inside directory
...@@ -174,6 +204,10 @@ mod_python.c ...@@ -174,6 +204,10 @@ mod_python.c
This routine is called to check for any module-specific restrictions This routine is called to check for any module-specific restrictions
placed upon the requested resource. placed upon the requested resource.
Where multiple handlers are specified, if any handler in the sequence
returns a value other than \code{apache.OK} or \code{apache.DECLINED}, then
execution of all subsequent handlers for this phase are aborted.
For example, this can be used to restrict access by IP number. To do For example, this can be used to restrict access by IP number. To do
so, you would return \code{HTTP_FORBIDDEN} or some such to indicate so, you would return \code{HTTP_FORBIDDEN} or some such to indicate
that access is not allowed. that access is not allowed.
...@@ -195,6 +229,10 @@ with the request (such as looking up the user in a database and ...@@ -195,6 +229,10 @@ with the request (such as looking up the user in a database and
verifying that the [encrypted] password sent matches the one in the verifying that the [encrypted] password sent matches the one in the
database). database).
Where multiple handlers are specified, if any handler in the sequence
returns a value other than \code{apache.DECLINED}, then execution of all
subsequent handlers for this phase are aborted.
To obtain the username, use \code{req.user}. To obtain the password To obtain the username, use \code{req.user}. To obtain the password
entered by the user, use the \code{req.get_basic_auth_pw()} function. entered by the user, use the \code{req.get_basic_auth_pw()} function.
...@@ -241,6 +279,10 @@ This handler runs after AuthenHandler and is intended for checking ...@@ -241,6 +279,10 @@ This handler runs after AuthenHandler and is intended for checking
whether a user is allowed to access a particular resource. But more whether a user is allowed to access a particular resource. But more
often than not it is done right in the AuthenHandler. often than not it is done right in the AuthenHandler.
Where multiple handlers are specified, if any handler in the sequence
returns a value other than \code{apache.DECLINED}, then execution of all
subsequent handlers for this phase are aborted.
\subsection{PythonTypeHandler\label{dir-handlers-tph}} \subsection{PythonTypeHandler\label{dir-handlers-tph}}
\index{PythonTypeHandler} \index{PythonTypeHandler}
...@@ -257,6 +299,10 @@ This routine is called to determine and/or set the various document ...@@ -257,6 +299,10 @@ This routine is called to determine and/or set the various document
type information bits, like Content-type (via \code{r->content_type}), type information bits, like Content-type (via \code{r->content_type}),
language, et cetera. language, et cetera.
Where multiple handlers are specified, if any handler in the sequence
returns a value other than \code{apache.DECLINED}, then execution of all
subsequent handlers for this phase are aborted.
\subsection{PythonFixupHandler\label{dir-handlers-fuh}} \subsection{PythonFixupHandler\label{dir-handlers-fuh}}
\index{PythonFixupHandler} \index{PythonFixupHandler}
...@@ -272,6 +318,10 @@ mod_python.c ...@@ -272,6 +318,10 @@ mod_python.c
This routine is called to perform any module-specific fixing of header This routine is called to perform any module-specific fixing of header
fields, et cetera. It is invoked just before any content-handler. fields, et cetera. It is invoked just before any content-handler.
Where multiple handlers are specified, if any handler in the sequence
returns a value other than \code{apache.OK} or \code{apache.DECLINED}, then
execution of all subsequent handlers for this phase are aborted.
\subsection{PythonHandler\label{dir-handlers-ph}} \subsection{PythonHandler\label{dir-handlers-ph}}
\index{PythonHandler} \index{PythonHandler}
...@@ -287,6 +337,16 @@ mod_python.c ...@@ -287,6 +337,16 @@ mod_python.c
This is the main request handler. Many applications will only provide This is the main request handler. Many applications will only provide
this one handler. this one handler.
Where multiple handlers are specified, if any handler in the sequence
returns a status value other than \code{apache.OK} or
\code{apache.DECLINED}, then execution of subsequent handlers for the phase
are skipped and the return status becomes that for the whole content
handler phase. If all handlers are run, the return status of the final
handler is what becomes the return status of the whole content handler
phase. Where that final status is \code{apache.DECLINED}, Apache will fall
back to using the \code{default-handler} and attempt to serve up the target
as a static file.
\subsection{PythonLogHandler\label{dir-handlers-plh}} \subsection{PythonLogHandler\label{dir-handlers-plh}}
\index{PythonLogHandler} \index{PythonLogHandler}
...@@ -300,7 +360,11 @@ not None\\ ...@@ -300,7 +360,11 @@ not None\\
mod_python.c mod_python.c
This routine is called to perform any module-specific logging This routine is called to perform any module-specific logging
activities. activities.
Where multiple handlers are specified, if any handler in the sequence
returns a value other than \code{apache.OK} or \code{apache.DECLINED}, then
execution of all subsequent handlers for this phase are aborted.
\subsection{PythonCleanupHandler\label{dir-handlers-pch}} \subsection{PythonCleanupHandler\label{dir-handlers-pch}}
\index{PythonCleanupHandler} \index{PythonCleanupHandler}
...@@ -351,6 +415,13 @@ omitted, it will default to \samp{inputfilter}. \var{Name} is the name under ...@@ -351,6 +415,13 @@ omitted, it will default to \samp{inputfilter}. \var{Name} is the name under
which the filter is registered, by convention filter names are usually which the filter is registered, by convention filter names are usually
in all caps. in all caps.
The \var{module} referred to by the handler can be a full module name
(package dot notation is accepted) or an actual path to a module code file.
The module is loaded using the mod_python module importer as implemented by
the \code{apache.import_module()} function. Reference should be made to the
documentation of that function for further details of how module importing
is managed.
To activate the filter, use the \code{AddInputFilter} directive. To activate the filter, use the \code{AddInputFilter} directive.
\subsection{PythonOutputFilter\label{dir-filter-of}} \subsection{PythonOutputFilter\label{dir-filter-of}}
...@@ -370,6 +441,13 @@ omitted, it will default to \samp{outputfilter}. \var{Name} is the name under ...@@ -370,6 +441,13 @@ omitted, it will default to \samp{outputfilter}. \var{Name} is the name under
which the filter is registered, by convention filter names are usually which the filter is registered, by convention filter names are usually
in all caps. in all caps.
The \var{module} referred to by the handler can be a full module name
(package dot notation is accepted) or an actual path to a module code file.
The module is loaded using the mod_python module importer as implemented by
the \code{apache.import_module()} function. Reference should be made to the
documentation of that function for further details of how module importing
is managed.
To activate the filter, use the \code{AddOutputFilter} directive. To activate the filter, use the \code{AddOutputFilter} directive.
\section{Connection Handler\label{dir-conn}} \section{Connection Handler\label{dir-conn}}
...@@ -392,6 +470,13 @@ the connection object. ...@@ -392,6 +470,13 @@ the connection object.
callable object name. If callable object name is omitted, it will callable object name. If callable object name is omitted, it will
default to \samp{connectionhandler}. default to \samp{connectionhandler}.
The \var{module} can be a full module name (package dot notation is
accepted) or an absolute path to a module code file. The module is loaded
using the mod_python module importer as implemented by the
\code{apache.import_module()} function. Reference should be made to the
documentation of that function for further details of how module importing
is managed.
\section{Other Directives\label{dir-other}} \section{Other Directives\label{dir-other}}
\subsection{PythonEnablePdb\label{dir-other-epd}} \subsection{PythonEnablePdb\label{dir-other-epd}}
...@@ -452,13 +537,27 @@ server config\\ ...@@ -452,13 +537,27 @@ server config\\
mod_python.c mod_python.c
Tells the server to import the Python module module at process startup Tells the server to import the Python module module at process startup
under the specified interpreter name. This is useful for under the specified interpreter name. The import takes place at child
initialization tasks that could be time consuming and should not be process initialization, so the module will actually be imported once for
done at the request processing time, e.g. initializing a database every child process spawned.
connection.
The import takes place at child process initialization, so the module The \var{module} can be a full module name (package dot notation is
will actually be imported once for every child process spawned. accepted) or an absolute path to a module code file. The module is loaded
using the mod_python module importer as implemented by the
\code{apache.import_module()} function. Reference should be made to
the documentation of that function for further details of how module
importing is managed.
The \code{PythonImport} directive is useful for initialization tasks that
could be time consuming and should not be done at the time of processing a
request, e.g. initializing a database connection. Where such initialization
code could fail and cause the importing of the module to fail, it should be
placed in its own function and the alternate syntax used:
\code{PythonImport \emph{module::function} \emph{interpreter_name}}
The named function will be called only after the module has been imported
successfully. The function will be called with no arguments.
\begin{notice} \begin{notice}
At the time when the import takes place, the configuration is not At the time when the import takes place, the configuration is not
...@@ -665,6 +764,50 @@ between the apache configuration files (\file{httpd.conf}, ...@@ -665,6 +764,50 @@ between the apache configuration files (\file{httpd.conf},
\file{.htaccess}, etc) and the Python programs. If the value is omitted or empty (\code{""}), \file{.htaccess}, etc) and the Python programs. If the value is omitted or empty (\code{""}),
then the key is removed from the local configuration. then the key is removed from the local configuration.
\strong{Reserved PythonOption Keywords}
Some PythonOption keywords are used for configuring various aspects of
mod_python. Any keyword starting with mod_python.* should be considered
as reserved for internal mod_python use.
Users are encouraged to use their own namespace qualifiers when creating
add-on modules, and not pollute the global namespace.
The following PythonOption keys are currently used by mod_python.
% Note - Make sure you put a space character in any empty tables cells.
% Otherwise the formatting will be messed up.
\begin{tableiii}{l|c|l}{textrm}{Key}{Required Value}{Notes}
\lineiii{mod_python.legacy.importer}{*}{Enables the obsolete importer.}
\lineiii{mod_python.mutex_directory}{ }{ }
\lineiii{mod_python.mutex_locks}{ }{ }
\lineiii{mod_python.psp.cache_database_filename}{ }{ }
\lineiii{mod_python.session.session_type}{ }{ }
\lineiii{mod_python.session.cookie_name}{ }{ }
\lineiii{mod_python.session.application_domain}{ }{ }
\lineiii{mod_python.session.application_path}{ }{ }
\lineiii{mod_python.session.database_directory}{ }{ }
\lineiii{mod_python.dbm_session.database_filename}{ }{ }
\lineiii{mod_python.dbm_session.database_directory}{ }{ }
\lineiii{mod_python.file_session.enable_fast_cleanup}{ }{ }
\lineiii{mod_python.file_session.verify_session_timeout}{ }{ }
\lineiii{mod_python.file_session.cleanup_grace_period}{ }{ }
\lineiii{mod_python.file_session.cleanup_time_limit}{ }{ }
\lineiii{mod_python.file_session.database_directory}{ }{ }
\lineiii{session}{ }{Deprecated in 3.3, use mod_python.session.session_type}
\lineiii{ApplicationPath}{ }{Deprecated in 3.3, use mod_python.session.application_path}
\lineiii{session_cookie_name}{ }{Deprecated in 3.3, use mod_python.session.cookie_name}
\lineiii{session_directory}{ }{Deprecated in 3.3, use mod_python.session.database_directory}
\lineiii{session_dbm}{ }{Deprecated in 3.3, use mod_python.dbm_session.database_filename}
\lineiii{session_cleanup_time_limit}{ }{Deprecated in 3.3, use mod_python.file_session.cleanup_time_limit}
\lineiii{session_fast_cleanup}{ }{Deprecated in 3.3, use mod_python.file_session.enable_fast_cleanup}
\lineiii{session_grace_period}{ }{Deprecated in 3.3, use mod_python.file_session.cleanup_grace_period}
\lineiii{session_verify_cleanup}{ }{Deprecated in 3.3, use mod_python.file_session.cleanup_session_timeout}
\lineiii{PSPDbmCache}{ }{Deprecated in 3.3, use mod_python.psp.cache_database_filename}
\end{tableiii}
\subsection{PythonPath\label{dir-other-pp}} \subsection{PythonPath\label{dir-other-pp}}
\index{PythonPath} \index{PythonPath}
......
\chapter{Server Side Includes\label{ssi}}
\section{Overview of SSI\label{ssi-overview}}
SSI (Server Side Includes) are directives that are placed in HTML pages,
and evaluated on the server while the pages are being served. They let you
add dynamically generated content to an existing HTML page, without having
to serve the entire page via a CGI program, or other dynamic technology
such as a mod_python handler.
SSI directives have the following syntax:
\begin{verbatim}
<!--#element attribute=value attribute=value ... -->
\end{verbatim}
It is formatted like an HTML comment, so if you don't have SSI correctly
enabled, the browser will ignore it, but it will still be visible in the
HTML source. If you have SSI correctly configured, the directive will be
replaced with its results.
For a more thorough description of the SSI mechanism and how to enable it,
see the \citetitle[http://httpd.apache.org/docs/2.0/howto/ssi.html]{SSI
tutorial} provided with the Apache documentation.
Version 3.3 of mod_python introduces support for using Python code within
SSI files. Note that mod_python honours the intent of the Apache
\code{IncludesNOEXEC} option to the \code{Options} directive. That is, if
\code{IncludesNOEXEC} is enabled, then Python code within a SSI file will
not be executed.
\section{Using Python Code\label{ssi-python-code}}
The extensions to mod_python to allow Python code to be used in conjunction
with SSI introduces the new SSI directive called 'python'. This directive
can be used in two forms, these being 'eval' and 'exec' modes. In the case
of 'eval', a Python expression is used and it is the result of that
expression which is substituted in place into the page.
\begin{verbatim}
<!--#python eval="10*'HELLO '" -->
<!--#python eval="len('HELLO')" -->
\end{verbatim}
Where the result of the expression is not a string, the value will be
automatically converted to a string by applying \code{str()} to the value.
In the case of 'exec' a block of Python code may be included. For any
output from this code to appear in the page, it must be written back
explicitly as being part of the response. As SSI are processed by an Apache
output filter, this is done by using an instance of the mod_python
\code{filter} object which is pushed into the global data set available to
the code.
\begin{verbatim}
<!--#python exec="
filter.write(10*'HELLO ')
filter.write(str(len('HELLO')))
" -->
\end{verbatim}
Any Python code within the 'exec' block must have a zero first level
indent. You cannot start the code block with an arbitrary level of indent
such that it lines up with any indenting used for surrounding HTML
elements.
Although the mod_python \code{filter} object is not a true file object, that
it provides the \code{write()} method is sufficient to allow the \code{print}
statement to be used on it directly. This will avoid the need to explicitly
convert non string objects to a string before being output.
\begin{verbatim}
<!--#python exec="
print >> filter, len('HELLO')
" -->
\end{verbatim}
\section{Scope of Global Data\label{ssi-data-scope}}
Multiple instances of 'eval' or 'exec' code blocks may be used within the
one page. Any changes to or creation of global data which is performed
within one code block will be reflected in any following code blocks.
Global data constitutes variables as well as module imports, function and
class definitions.
\begin{verbatim}
<!--#python exec="
import cgi, time, os
def _escape(object):
return cgi.escape(str(object))
now = time.time()
" -->
<html>
<body>
<pre>
<!--#python eval="_escape(time.asctime(time.localtime(now)))"-->
<!--#python exec="
keys = os.environ.keys()
keys.sort()
for key in keys:
print >> filter, _escape(key),
print >> filter, '=',
print >> filter, _escape(repr(os.environ.get(key)))
" -->
</pre>
</body>
</html>
\end{verbatim}
The lifetime of any global data is for the current request only. If data
must persist between requests, it must reside in external modules and as
necessary be protected against multithreaded access in the event that a
multithreaded Apache MPM is used.
\section{Pre-propulating Globals\label{ssi-globals}}
Any Python code which appears within the page has to be compiled each time
the page is accessed before it is executed. In other words, the compiled
code is not cached between requests. To limit such recompilation and to
avoid duplication of common code amongst many pages, it is preferable to
pre-populate the global data from within a mod_python handler prior to the
page being processed.
In most cases, a fixup handler would be used for this purpose. For this to
work, first need to configure Apache so that it knows to call the fixup
handler.
\begin{verbatim}
PythonFixupHandler _handlers
\end{verbatim}
The implementation of the fixup handler contained in \code{_handlers.py}
then needs to create an instance of a Python dictionary, store that in the
mod_python request object as \code{ssi_globals} and then populate that
dictionary with any data to be available to the Python code executing
within the page.
\begin{verbatim}
from mod_python import apache
import cgi, time
def _escape(object):
return cgi.escape(str(object))
def _header(filter):
print >> filter, '...'
def _footer(filter):
print >> filter, '...'
def fixuphandler(req):
req.ssi_globals = {}
req.ssi_globals['time'] = time
req.ssi_globals['_escape'] = _escape
req.ssi_globals['_header'] = _header
req.ssi_globals['_footer'] = _footer
return apache.OK
\end{verbatim}
This is most useful where it is necessary to insert common information such
as headers, footers or menu panes which are dynamically generated into many
pages.
\begin{verbatim}
<!--#python exec="
now = time.time()
" -->
<html>
<body>
<!--#python exec="_header(filter)" -->
<pre>
<!--#python eval="_escape(time.asctime(time.localtime(now)))"-->
</pre>
<!--#python exec="_footer(filter)" -->
</body>
</html>
\end{verbatim}
\section{Conditional Expressions\label{ssi-conditionals}}
SSI allows for some programmability in its own right through the use of
conditional expressions. The structure of this conditional construct is:
\begin{verbatim}
<!--#if expr="test_condition" -->
<!--#elif expr="test_condition" -->
<!--#else -->
<!--#endif -->
\end{verbatim}
A test condition can be any sort of logical comparison, either comparing
values to one another, or testing the 'truth' of a particular value.
The source of variables used in conditional expressions is distinct from
the set of global data used by the Python code executed within a page.
Instead, the variables are sourced from the \code{subprocess_env} table
object contained within the request object. The values of these variables
can be set from within a page using the SSI 'set' directive, or by a range
of other Apache directives within the Apache configuration files such as
\code{BrowserMatchNoCase} and \code{SetEnvIf}.
To set these variables from within a mod_python handler, the
\code{subprocess_env} table object would be manipulated directly through
the request object.
\begin{verbatim}
from mod_python import apache
def fixuphandler(req):
debug = req.get_config().get('PythonDebug', '0')
req.subprocess_env['DEBUG'] = debug
return apache.OK
\end{verbatim}
If being done from within Python code contained within the page itself, the
request object would first have to be accessed via the filter object.
\begin{verbatim}
<!--#python exec="
debug = filter.req.get_config().get('PythonDebug', '0')
filter.req.subprocess_env['DEBUG'] = debug
" -->
<html>
<body>
<!--#if expr="${DEBUG} != 0" -->
DEBUG ENABLED
<!--#else -->
DEBUG DISABLED
<!--#endif -->
</body>
</html>
\end{verbatim}
\section{Enabling INCLUDES Filter\label{ssi-output-filter}}
SSI is traditionally enabled using the \code{AddOutputFilter} directive in
the Apache configuration files. Normally this would be where the request
mapped to a static file.
\begin{verbatim}
AddOutputFilter INCLUDES .shtml
\end{verbatim}
When mod_python is being used, the ability to dynamically enable output
filters for the current request can instead be used. This could be done
just for where the request maps to a static file, but may just as easily be
carried out where the content of a response is generated dynamically. In
either case, to enable SSI for the current request, the
\code{add_output_filter()} method of the mod_python request object would be
used.
\begin{verbatim}
from mod_python import apache
def fixuphandler(req):
req.add_output_filter('INCLUDES')
return apache.OK
\end{verbatim}
\chapter{Standard Handlers\label{handlers}} \chapter{Standard Handlers\label{handlers}}
\section{Publisher Handler\label{hand-pub}} \section{Publisher Handler\label{hand-pub}}
...@@ -13,7 +274,7 @@ To use the handler, you need the following lines in your configuration ...@@ -13,7 +274,7 @@ To use the handler, you need the following lines in your configuration
<Directory /some/path> <Directory /some/path>
SetHandler mod_python SetHandler mod_python
PythonHandler mod_python.publisher PythonHandler mod_python.publisher
</Directory> </Directory>
\end{verbatim} \end{verbatim}
This handler allows access to functions and variables within a module This handler allows access to functions and variables within a module
...@@ -24,7 +285,7 @@ via URL's. For example, if you have the following module, called ...@@ -24,7 +285,7 @@ via URL's. For example, if you have the following module, called
""" Publisher example """ """ Publisher example """
def say(req, what="NOTHING"): def say(req, what="NOTHING"):
return "I am saying %s" % what return "I am saying %s" % what
\end{verbatim} \end{verbatim}
...@@ -87,8 +348,8 @@ For example, given the following configuration: ...@@ -87,8 +348,8 @@ For example, given the following configuration:
DocumentRoot /some/dir DocumentRoot /some/dir
<Directory /some/dir> <Directory /some/dir>
SetHandler mod_python SetHandler mod_python
PythonHandler mod_python.publisher PythonHandler mod_python.publisher
</Directory> </Directory>
\end{verbatim} \end{verbatim}
...@@ -96,12 +357,11 @@ And the following \file{/some/dir/index.py} file: ...@@ -96,12 +357,11 @@ And the following \file{/some/dir/index.py} file:
\begin{verbatim} \begin{verbatim}
def index(req): def index(req):
return "We are in index()"
return "We are in index()"
def hello(req): def hello(req):
return "We are in hello()"
return "We are in hello()"
\end{verbatim} \end{verbatim}
Then: Then:
...@@ -183,20 +443,20 @@ can access the \code{hello} function: ...@@ -183,20 +443,20 @@ can access the \code{hello} function:
def __auth__(req, user, passwd): def __auth__(req, user, passwd):
if user == "eggs" and passwd == "spam" or \ if user == "eggs" and passwd == "spam" or \
user == "joe" and passwd == "eoj": user == "joe" and passwd == "eoj":
return 1 return 1
else: else:
return 0 return 0
def __access__(req, user): def __access__(req, user):
if user == "eggs": if user == "eggs":
return 1 return 1
else: else:
return 0 return 0
def hello(req): def hello(req):
return "hello" return "hello"
\end{verbatim} \end{verbatim}
...@@ -209,7 +469,7 @@ Here is the same functionality, but using an alternative technique: ...@@ -209,7 +469,7 @@ Here is the same functionality, but using an alternative technique:
__access__ = ["eggs"] __access__ = ["eggs"]
def hello(req): def hello(req):
return "hello" return "hello"
\end{verbatim} \end{verbatim}
...@@ -220,16 +480,16 @@ the function, e.g.: ...@@ -220,16 +480,16 @@ the function, e.g.:
\begin{verbatim} \begin{verbatim}
def sensitive(req): def sensitive(req):
def __auth__(req, user, password): def __auth__(req, user, password):
if user == 'spam' and password == 'eggs': if user == 'spam' and password == 'eggs':
# let them in # let them in
return 1 return 1
else: else:
# no access # no access
return 0 return 0
# something involving sensitive information # something involving sensitive information
return 'sensitive information` return 'sensitive information`
\end{verbatim} \end{verbatim}
Note that this technique will also work if \code{__auth__} or Note that this technique will also work if \code{__auth__} or
...@@ -284,7 +544,13 @@ If \code{PythonDebug} server configuration is \code{On}, then by ...@@ -284,7 +544,13 @@ If \code{PythonDebug} server configuration is \code{On}, then by
appending an underscore (\samp{_}) to the end of the url you can get a appending an underscore (\samp{_}) to the end of the url you can get a
nice side-by-side listing of original PSP code and resulting Python nice side-by-side listing of original PSP code and resulting Python
code generated by the \code{psp} module. This is very useful for code generated by the \code{psp} module. This is very useful for
debugging. debugging. You'll need to adjust your httpd configuration:
\begin{verbatim}
AddHandler mod_python .psp .psp_
PythonHandler mod_python.psp
PythonDebug On
\end{verbatim}
\begin{notice} \begin{notice}
Leaving debug on in a production environment will allow remote users Leaving debug on in a production environment will allow remote users
......
\chapter{Security\label{security}}
Considerations on using mod_python in a secure manner can be found
in the \citetitle[http://wiki.apache.org/mod_python]{mod_python wiki}
at \citetitle[http://wiki.apache.org/mod_python/CategorySecurity]{CategorySecurity}.
...@@ -74,12 +74,16 @@ install_py_lib: ...@@ -74,12 +74,16 @@ install_py_lib:
clean: clean:
cd src && $(MAKE) clean cd src && $(MAKE) clean
cd dist && $(MAKE) clean cd dist && $(MAKE) clean
cd test && $(MAKE) clean
rm -f core rm -f core
distclean: clean distclean: clean
cd src && $(MAKE) distclean cd src && $(MAKE) distclean
cd Doc && $(MAKE) distclean cd Doc && $(MAKE) distclean
cd dist && $(MAKE) distclean cd dist && $(MAKE) distclean
cd test && $(MAKE) distclean
rm -rf Makefile config.h config.status config.cache config.log \ rm -rf Makefile config.h config.status config.cache config.log \
test/testconf.py test/testconf.py
check:
cd test && $(MAKE) check
July 19 2006 - 3.2.10 is being tagged Jan 29 2007 - 3.3.1 is being tagged
Dec 9 2006 - 3.3.0b is being tagged
Aug 7 2006 - 3.2.10 released
July 19 2006 - 3.2.10 is being tagged from branches/3.2.x
July 19 2006 - The public release of 3.2.9 is being abandoned due to some July 19 2006 - The public release of 3.2.9 is being abandoned due to some
recently reported memory leaks. Although 3.2.9 is ready for recently reported memory leaks. Although 3.2.9 is ready for
...@@ -6,12 +12,15 @@ July 19 2006 - The public release of 3.2.9 is being abandoned due to some ...@@ -6,12 +12,15 @@ July 19 2006 - The public release of 3.2.9 is being abandoned due to some
and proceed immediately to 3.2.10. See MODPYTHON-172 for and proceed immediately to 3.2.10. See MODPYTHON-172 for
on the specific details on the issues. on the specific details on the issues.
June 29 2006 - 3.2.9 is being tagged June 29 2006 - 3.2.9 is being tagged from branches/3.2.x
Feb 19 2006 - 3.2.8 is being tagged Feb 19 2006 - 3.2.8 is being tagged from branches/3.2.x
3.2.8 is a security release to fix the possible 3.2.8 is a security release to fix the possible
directory traversal attack in FileSession. directory traversal attack in FileSession.
Feb 9 2006 - Created 3.2.x stable bugfix branch in svn as
branches/3.2.x
Feb 3 2006 - 3.2.7 is being tagged Feb 3 2006 - 3.2.7 is being tagged
Jan 16 2006 - 3.2.6 final is being tagged (no changes from 3.2.6b) Jan 16 2006 - 3.2.6 final is being tagged (no changes from 3.2.6b)
......
...@@ -4,7 +4,7 @@ This is the Mod_Python README file. It consists of the following parts: ...@@ -4,7 +4,7 @@ This is the Mod_Python README file. It consists of the following parts:
1. Getting Started 1. Getting Started
2. Flex 2. Flex
3. New in 3.2 3. New in 3.3
4. New in 3.0 4. New in 3.0
5. Migrating from Mod_Python 2.7.8 5. Migrating from Mod_Python 2.7.8
6. OS Hints 6. OS Hints
...@@ -23,14 +23,17 @@ If you can't read instructions: ...@@ -23,14 +23,17 @@ If you can't read instructions:
$ su $ su
# make install # make install
Edit httpd.conf like instructions at the end of "make install" Edit httpd.conf as instructed at the end of "make install".
tell you.
If the above worked - read the tutorial in the doc directory. If the above worked - read the tutorial in the doc directory.
2. ./configure will generate a WARNING if it cannot find flex, or it 2. ./configure will generate a WARNING if it cannot find flex, or it
is the wrong version. Generally you can ignore this warning and still is the wrong version. Generally you can ignore this warning and still
successfully compile mod_python. successfully compile mod_python as the timestamp of the src/psp_parser.c
file will be newer than that for the src/psp_parser.l file. If for some
reason it still tries to run flex to regenerate the src/psp_parser.c
file, running 'touch src/psp_parser.c' to update the timestamp should
stop this and it will use the provided file.
The parser used by psp is written in C generated using flex. This The parser used by psp is written in C generated using flex. This
requires a reentrant version of flex, which at this time is 2.5.31. requires a reentrant version of flex, which at this time is 2.5.31.
...@@ -42,7 +45,7 @@ src/psp_parser.c file, you must get the correct flex version. ...@@ -42,7 +45,7 @@ src/psp_parser.c file, you must get the correct flex version.
You can specify the path the flex binary by using You can specify the path the flex binary by using
./configure --with-flex=/path/to/flex/binary. ./configure --with-flex=/path/to/flex/binary.
3. New in 3.2 3. New in 3.3
Please refer to doc-html/ for more information. Please refer to doc-html/ for more information.
4. New in 3.0 4. New in 3.0
......
...@@ -3213,7 +3213,7 @@ echo "$as_me: WARNING: flex $LEX not found ...@@ -3213,7 +3213,7 @@ echo "$as_me: WARNING: flex $LEX not found
See the README for more information." >&2;} See the README for more information." >&2;}
fi fi
ac_config_files="$ac_config_files Makefile src/Makefile Doc/Makefile src/include/mod_python.h test/testconf.py dist/setup.py dist/Makefile" ac_config_files="$ac_config_files Makefile src/Makefile Doc/Makefile src/include/mod_python.h test/Makefile test/testconf.py dist/setup.py dist/Makefile"
cat >confcache <<\_ACEOF cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure # This file is a shell script that caches the results of configure
# tests run on this system so they can be shared between configure # tests run on this system so they can be shared between configure
...@@ -3769,6 +3769,7 @@ do ...@@ -3769,6 +3769,7 @@ do
"src/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; "src/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/Makefile" ;;
"Doc/Makefile" ) CONFIG_FILES="$CONFIG_FILES Doc/Makefile" ;; "Doc/Makefile" ) CONFIG_FILES="$CONFIG_FILES Doc/Makefile" ;;
"src/include/mod_python.h" ) CONFIG_FILES="$CONFIG_FILES src/include/mod_python.h" ;; "src/include/mod_python.h" ) CONFIG_FILES="$CONFIG_FILES src/include/mod_python.h" ;;
"test/Makefile" ) CONFIG_FILES="$CONFIG_FILES test/Makefile" ;;
"test/testconf.py" ) CONFIG_FILES="$CONFIG_FILES test/testconf.py" ;; "test/testconf.py" ) CONFIG_FILES="$CONFIG_FILES test/testconf.py" ;;
"dist/setup.py" ) CONFIG_FILES="$CONFIG_FILES dist/setup.py" ;; "dist/setup.py" ) CONFIG_FILES="$CONFIG_FILES dist/setup.py" ;;
"dist/Makefile" ) CONFIG_FILES="$CONFIG_FILES dist/Makefile" ;; "dist/Makefile" ) CONFIG_FILES="$CONFIG_FILES dist/Makefile" ;;
......
...@@ -383,7 +383,7 @@ else ...@@ -383,7 +383,7 @@ else
See the README for more information.]) See the README for more information.])
fi fi
AC_OUTPUT(Makefile src/Makefile Doc/Makefile src/include/mod_python.h test/testconf.py dist/setup.py dist/Makefile) AC_OUTPUT(Makefile src/Makefile Doc/Makefile src/include/mod_python.h test/Makefile test/testconf.py dist/setup.py dist/Makefile)
...@@ -15,7 +15,7 @@ rem limitations under the License. ...@@ -15,7 +15,7 @@ rem limitations under the License.
rem rem
rem Originally developed by Gregory Trubetskoy. rem Originally developed by Gregory Trubetskoy.
rem rem
rem $Id: build_installer.bat 345063 2005-11-16 17:16:41Z nlehuen $ rem $Id: build_installer.bat 420292 2006-07-09 13:09:28Z nlehuen $
rem rem
rem This script builds the installer for Windows rem This script builds the installer for Windows
...@@ -25,10 +25,20 @@ if not exist "%APACHESRC%\include" GOTO BADAPACHESRC ...@@ -25,10 +25,20 @@ if not exist "%APACHESRC%\include" GOTO BADAPACHESRC
rem Cleanup rem Cleanup
rmdir /s /q build rmdir /s /q build
del ..\src\*.obj ..\src\*.lib ..\src\*.exp ..\src\*.res del /s ..\src\*.obj ..\src\*.lib ..\src\*.exp ..\src\*.res
rem Build rem Build
python setup.py.in bdist_wininst --install-script win32_postinstall.py python setup.py.in bdist_wininst --install-script win32_postinstall.py
GOTO END
rem Use this instead of the previous line to create a debug build
rem For this you need a Python debug build. The .py files will be installed
rem directly in the Python debug build's site-packages. The .so file will remain
rem in build/lib.win32-2.4, so you'll have to make sure your testconf.py file
rem points to it instead of the copy that may already reside in LIBEXECDIR.
rem python_d setup.py.in build --debug install
rem GOTO END
rem Compress the installer if possible rem Compress the installer if possible
upx.exe --no-color --no-progress --best dist\*.exe upx.exe --no-color --no-progress --best dist\*.exe
...@@ -36,7 +46,8 @@ GOTO END ...@@ -36,7 +46,8 @@ GOTO END
:BADAPACHESRC :BADAPACHESRC
echo Currently APACHESRC points to %APACHESRC% echo Currently APACHESRC points to %APACHESRC%
echo This value seems wrong as we could not find a proper Apache installation here. echo This value seems wrong as we could not find a proper
echo Apache installation here.
:NOAPACHESRC :NOAPACHESRC
echo Please set the APACHESRC variable to point to your Apache setup echo Please set the APACHESRC variable to point to your Apache setup
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
# limitations under the License. # limitations under the License.
# #
# #
# $Id: setup.py.in 374030 2006-02-01 09:48:37Z nlehuen $ # $Id: setup.py.in 475516 2006-11-16 01:12:40Z grahamd $
from distutils.core import setup, Extension from distutils.core import setup, Extension
...@@ -115,7 +115,7 @@ PSPModule = PSPExtension(getmp_srcdir(), [getmp_includedir()]) ...@@ -115,7 +115,7 @@ PSPModule = PSPExtension(getmp_srcdir(), [getmp_includedir()])
modpy_src_files = ("mod_python.c", "_apachemodule.c", "connobject.c", "filterobject.c", modpy_src_files = ("mod_python.c", "_apachemodule.c", "connobject.c", "filterobject.c",
"hlist.c", "hlistobject.c", "requestobject.c", "serverobject.c", "tableobject.c", "hlist.c", "hlistobject.c", "requestobject.c", "serverobject.c", "tableobject.c",
"util.c") "util.c", "finfoobject.c")
class finallist(list): class finallist(list):
"""this represents a list that cannot be appended to...""" """this represents a list that cannot be appended to..."""
...@@ -126,7 +126,14 @@ class ModPyExtension(Extension): ...@@ -126,7 +126,14 @@ class ModPyExtension(Extension):
"""a class that actually builds the mod_python.so extension for Apache (yikes)""" """a class that actually builds the mod_python.so extension for Apache (yikes)"""
def __init__(self, source_dir, include_dirs, library_dirs): def __init__(self, source_dir, include_dirs, library_dirs):
if winbuild: if winbuild:
libraries = ['libhttpd', 'libapr', 'libaprutil', 'ws2_32'] apr1 = 0
for dir in library_dirs:
if os.path.exists(os.path.join(dir, 'libapr-1.lib')):
apr1 = 1
if apr1:
libraries = ['libhttpd', 'libapr-1', 'libaprutil-1', 'ws2_32']
else:
libraries = ['libhttpd', 'libapr', 'libaprutil', 'ws2_32']
else: else:
libraries = ['apr-0', 'aprutil-0'] libraries = ['apr-0', 'aprutil-0']
......
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html> <html>
<head> <head>
<link rel="STYLESHEET" href="modpython.css" type='text/css'> <link rel="STYLESHEET" href="modpython.css" type='text/css' />
<link rel="first" href="modpython.html" title='Mod_python Manual'> <link rel="first" href="modpython.html" title='Mod_python Manual' />
<link rel='contents' href='contents.html' title="Contents"> <link rel='contents' href='contents.html' title="Contents" />
<link rel='index' href='genindex.html' title='Index'> <link rel='index' href='genindex.html' title='Index' />
<link rel='last' href='about.html' title='About this document...'> <link rel='last' href='about.html' title='About this document...' />
<link rel='help' href='about.html' title='About this document...'> <link rel='help' href='about.html' title='About this document...' />
<LINK REL="prev" href="genindex.html"> <link rel="prev" href="genindex.html" />
<LINK REL="parent" HREF="modpython.html"> <link rel="parent" href="modpython.html" />
<meta name='aesop' content='information'> <meta name='aesop' content='information' />
<META NAME="description" CONTENT="About this document ...">
<META NAME="keywords" CONTENT="modpython">
<META NAME="resource-type" CONTENT="document">
<META NAME="distribution" CONTENT="global">
<title>About this document ...</title> <title>About this document ...</title>
</head> </head>
<body> <body>
<DIV CLASS="navigation"> <DIV CLASS="navigation">
<div id='top-navigation-panel' xml:id='top-navigation-panel'>
<table align="center" width="100%" cellpadding="0" cellspacing="2"> <table align="center" width="100%" cellpadding="0" cellspacing="2">
<tr> <tr>
<td><a rel="prev" title="Index" <td class='online-navigation'><a rel="prev" title="Index"
href="genindex.html"><img src='previous.gif' href="genindex.html"><img src='previous.png'
border='0' height='32' alt='Previous Page' width='32'></A></td> border='0' height='32' alt='Previous Page' width='32' /></A></td>
<td><a rel="parent" title="Mod_python Manual" <td class='online-navigation'><a rel="parent" title="Mod_python Manual"
HREF="modpython.html"><img src='up.gif' href="modpython.html"><img src='up.png'
border='0' height='32' alt='Up One Level' width='32'></A></td> border='0' height='32' alt='Up One Level' width='32' /></A></td>
<td><img src='blank.gif' <td class='online-navigation'><img src='next.png'
border='0' height='32' alt='' width='32'></td> border='0' height='32' alt='Next Page' width='32' /></td>
<td align="center" width="100%">Mod_python Manual</td> <td align="center" width="100%">Mod_python Manual</td>
<td><a rel="contents" title="Table of Contents" <td class='online-navigation'><a rel="contents" title="Table of Contents"
href="contents.html"><img src='contents.gif' href="contents.html"><img src='contents.png'
border='0' height='32' alt='Contents' width='32'></A></td> border='0' height='32' alt='Contents' width='32' /></A></td>
<td><img src='blank.gif' <td class='online-navigation'><img src='blank.png'
border='0' height='32' alt='' width='32'></td> border='0' height='32' alt='' width='32' /></td>
<td><a rel="index" title="Index" <td class='online-navigation'><a rel="index" title="Index"
href="genindex.html"><img src='index.gif' href="genindex.html"><img src='index.png'
border='0' height='32' alt='Index' width='32'></A></td> border='0' height='32' alt='Index' width='32' /></A></td>
</tr></table> </tr></table>
<div class='online-navigation'>
<b class="navlabel">Previous:</b> <b class="navlabel">Previous:</b>
<a class="sectref" rel="prev" href="genindex.html">Index</A> <a class="sectref" rel="prev" href="genindex.html">Index</A>
<b class="navlabel">Up:</b> <b class="navlabel">Up:</b>
<a class="sectref" rel="parent" HREF="modpython.html">Mod_python Manual</A> <a class="sectref" rel="parent" href="modpython.html">Mod_python Manual</A>
<br><hr> </div>
<hr /></div>
</DIV> </DIV>
<!--End of Navigation Panel--> <!--End of Navigation Panel-->
<H1><A NAME="SECTION0014000000000000000000"> <H1><A NAME="SECTION0017000000000000000000">
About this document ...</A> About this document ...</A>
</H1> </H1>
<strong>Mod_python Manual</strong>, <strong>Mod_python Manual</strong>,
July 19, 2006, Release 3.2.10 January 29, 2007, Release 3.3.1
<p> This document was generated using the <a <p> This document was generated using the <a
href="http://saftsack.fs.uni-bayreuth.de/~latex2ht/"> href="http://saftsack.fs.uni-bayreuth.de/~latex2ht/">
<strong>LaTeX</strong>2<tt>HTML</tt></a> translator. <strong>LaTeX</strong>2<tt>HTML</tt></a> translator.
...@@ -77,37 +76,37 @@ July 19, 2006, Release 3.2.10 ...@@ -77,37 +76,37 @@ July 19, 2006, Release 3.2.10
</p> </p>
<DIV CLASS="navigation"> <DIV CLASS="navigation">
<p><hr> <div class='online-navigation'>
<p></p><hr />
<table align="center" width="100%" cellpadding="0" cellspacing="2"> <table align="center" width="100%" cellpadding="0" cellspacing="2">
<tr> <tr>
<td><a rel="prev" title="Index" <td class='online-navigation'><a rel="prev" title="Index"
rel="prev" title="Index" href="genindex.html"><img src='previous.png'
href="genindex.html"><img src='previous.gif' border='0' height='32' alt='Previous Page' width='32' /></A></td>
border='0' height='32' alt='Previous Page' width='32'></A></td> <td class='online-navigation'><a rel="parent" title="Mod_python Manual"
<td><a rel="parent" title="Mod_python Manual" href="modpython.html"><img src='up.png'
rel="parent" title="Mod_python Manual" border='0' height='32' alt='Up One Level' width='32' /></A></td>
HREF="modpython.html"><img src='up.gif' <td class='online-navigation'><img src='next.png'
border='0' height='32' alt='Up One Level' width='32'></A></td> border='0' height='32' alt='Next Page' width='32' /></td>
<td><img src='blank.gif'
border='0' height='32' alt='' width='32'></td>
<td align="center" width="100%">Mod_python Manual</td> <td align="center" width="100%">Mod_python Manual</td>
<td><a rel="contents" title="Table of Contents" <td class='online-navigation'><a rel="contents" title="Table of Contents"
rel="contents" title="Table of Contents" href="contents.html"><img src='contents.png'
href="contents.html"><img src='contents.gif' border='0' height='32' alt='Contents' width='32' /></A></td>
border='0' height='32' alt='Contents' width='32'></A></td> <td class='online-navigation'><img src='blank.png'
<td><img src='blank.gif' border='0' height='32' alt='' width='32' /></td>
border='0' height='32' alt='' width='32'></td> <td class='online-navigation'><a rel="index" title="Index"
<td><a rel="index" title="Index" href="genindex.html"><img src='index.png'
rel="index" title="Index" border='0' height='32' alt='Index' width='32' /></A></td>
href="genindex.html"><img src='index.gif'
border='0' height='32' alt='Index' width='32'></A></td>
</tr></table> </tr></table>
<div class='online-navigation'>
<b class="navlabel">Previous:</b> <b class="navlabel">Previous:</b>
<a class="sectref" rel="prev" href="genindex.html">Index</A> <a class="sectref" rel="prev" href="genindex.html">Index</A>
<b class="navlabel">Up:</b> <b class="navlabel">Up:</b>
<a class="sectref" rel="parent" HREF="modpython.html">Mod_python Manual</A> <a class="sectref" rel="parent" href="modpython.html">Mod_python Manual</A>
<hr> </div>
<span class="release-info">Release 3.2.10, documentation updated on July 19, 2006.</span> </div>
<hr />
<span class="release-info">Release 3.3.1, documentation updated on January 29, 2007.</span>
</DIV> </DIV>
<!--End of Navigation Panel--> <!--End of Navigation Panel-->
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment