You are viewing a plain text version of this content. The canonical link for it is here.
Posted to mod_python-commits@quetz.apache.org by gr...@apache.org on 2006/05/06 08:30:28 UTC
svn commit: r400247 - in /httpd/mod_python/trunk: Doc/appendixc.tex
Doc/modpython5.tex lib/python/mod_python/__init__.py
lib/python/mod_python/apache.py src/include/mpversion.h
test/htdocs/tests.py test/test.py
Author: grahamd
Date: Fri May 5 23:30:26 2006
New Revision: 400247
URL: http://svn.apache.org/viewcvs?rev=400247&view=rev
Log:
When specifying multiple handlers for phases other than the content phase
as defined by PythonHandler, the status returned by each handler is now
treated the same as how Apache would treat the status if the handler was
registered using the low level C API. What this means is that whereas
previously stacked handlers of any phase would in turn be executed as long
as they returned apache.OK, this is no longer the case and now only occurs
for PythonHandler. What happens for other phases is dependent on the phase,
but in all cases, a handler returning apache.DECLINED no longer causes the
execution of subsequent handlers for the phase to be skipped. Instead, it
will move to the next of the stacked handlers. In the case of
PythonTransHandler, PythonAuthenHandler, PythonAuthzHandler and
PythonTypeHandler, as soon as apache.OK is returned, subsequent handlers
for the phase will be skipped, as the result indicates that any processing
pertinent to that phase has been completed. For other phases, stacked
handlers will continue to be executed if apache.OK is returned as well as
when apache.DECLINED is returned. (MODPYTHON-129)
Modified:
httpd/mod_python/trunk/Doc/appendixc.tex
httpd/mod_python/trunk/Doc/modpython5.tex
httpd/mod_python/trunk/lib/python/mod_python/__init__.py
httpd/mod_python/trunk/lib/python/mod_python/apache.py
httpd/mod_python/trunk/src/include/mpversion.h
httpd/mod_python/trunk/test/htdocs/tests.py
httpd/mod_python/trunk/test/test.py
Modified: httpd/mod_python/trunk/Doc/appendixc.tex
URL: http://svn.apache.org/viewcvs/httpd/mod_python/trunk/Doc/appendixc.tex?rev=400247&r1=400246&r2=400247&view=diff
==============================================================================
--- httpd/mod_python/trunk/Doc/appendixc.tex (original)
+++ httpd/mod_python/trunk/Doc/appendixc.tex Fri May 5 23:30:26 2006
@@ -170,6 +170,26 @@
rather than creating a new distinct Python request object. This means
that any data added explicitly to a request object can be passed
between such requests.
+ \item
+ (\citetitle[http://issues.apache.org/jira/browse/MODPYTHON-129]{MODPYTHON-129})
+ When specifying multiple handlers for phases other than the content
+ phase as defined by \code{PythonHandler}, the status returned by each
+ handler is now treated the same as how Apache would treat the status
+ if the handler was registered using the low level C API. What this
+ means is that whereas previously stacked handlers of any phase would
+ in turn be executed as long as they returned \code{apache.OK}, this
+ is no longer the case and now only occurs for \code{PythonHandler}.
+ What happens for other phases is dependent on the phase, but in all
+ cases, a handler returning \code{apache.DECLINED} no longer causes
+ the execution of subsequent handlers for the phase to be skipped.
+ Instead, it will move to the next of the stacked handlers. In the
+ case of \code{PythonTransHandler}, \code{PythonAuthenHandler},
+ \code{PythonAuthzHandler} and \code{PythonTypeHandler}, as soon
+ as \code{apache.OK} is returned, subsequent handlers for the phase
+ will be skipped, as the result indicates that any processing pertinent
+ to that phase has been completed. For other phases, stacked handlers
+ will continue to be executed if \code{apache.OK} is returned as well
+ as when \code{apache.DECLINED} is returned.
\end{itemize}
Bug Fixes
Modified: httpd/mod_python/trunk/Doc/modpython5.tex
URL: http://svn.apache.org/viewcvs/httpd/mod_python/trunk/Doc/modpython5.tex?rev=400247&r1=400246&r2=400247&view=diff
==============================================================================
--- httpd/mod_python/trunk/Doc/modpython5.tex (original)
+++ httpd/mod_python/trunk/Doc/modpython5.tex Fri May 5 23:30:26 2006
@@ -16,8 +16,19 @@
they will be called sequentially, from left to right. Same handler
directives can be specified multiple times as well, with the same
result - all handlers listed will be executed sequentially, from first
-to last. If any handler in the sequence returns a value other than
-\code{apache.OK}, then execution of all subsequent handlers is aborted.
+to last.
+
+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. This is now the case only for the \code{PythonHandler}
+directive.
The list of handlers can optionally be followed by a \code{|} followed
by one or more file extensions. This would restrict the execution of
@@ -75,6 +86,10 @@
other phases have been processed. This is useful to make decisions
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}
When this phase of the request is processed, the URI has not yet
been translated into a path name, therefore this directive could never
@@ -109,6 +124,10 @@
an actual filename, before the server's default rules (Alias
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}
At the time when this phase of the request is being processed, the
URI has not been translated into a path name, therefore this
@@ -135,6 +154,10 @@
request headers and take any appropriate specific actions early in the
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}}
\index{PythonInitHandler}
@@ -151,6 +174,10 @@
phases that is allowed both inside and outside \file{.htaccess} and
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
specified in the main config file outside any directory tags, it is an
alias to \code{PostReadRequestHandler}. When specified inside directory
@@ -174,6 +201,10 @@
This routine is called to check for any module-specific restrictions
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
so, you would return \code{HTTP_FORBIDDEN} or some such to indicate
that access is not allowed.
@@ -195,6 +226,10 @@
verifying that the [encrypted] password sent matches the one in the
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
entered by the user, use the \code{req.get_basic_auth_pw()} function.
@@ -241,6 +276,10 @@
whether a user is allowed to access a particular resource. But more
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}}
\index{PythonTypeHandler}
@@ -257,6 +296,10 @@
type information bits, like Content-type (via \code{r->content_type}),
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}}
\index{PythonFixupHandler}
@@ -272,6 +315,10 @@
This routine is called to perform any module-specific fixing of header
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}}
\index{PythonHandler}
@@ -287,6 +334,10 @@
This is the main request handler. Many applications will only provide
this one handler.
+Where multiple handlers are specified, if any handler in the sequence
+returns a value other than \code{apache.OK}, then execution of all
+subsequent handlers for this phase are aborted.
+
\subsection{PythonLogHandler\label{dir-handlers-plh}}
\index{PythonLogHandler}
@@ -300,7 +351,11 @@
mod_python.c
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}}
\index{PythonCleanupHandler}
Modified: httpd/mod_python/trunk/lib/python/mod_python/__init__.py
URL: http://svn.apache.org/viewcvs/httpd/mod_python/trunk/lib/python/mod_python/__init__.py?rev=400247&r1=400246&r2=400247&view=diff
==============================================================================
--- httpd/mod_python/trunk/lib/python/mod_python/__init__.py (original)
+++ httpd/mod_python/trunk/lib/python/mod_python/__init__.py Fri May 5 23:30:26 2006
@@ -20,5 +20,5 @@
__all__ = ["apache", "cgihandler", "psp",
"publisher", "util", "python22"]
-version = "3.3.0-dev-20060503"
+version = "3.3.0-dev-20060506"
Modified: httpd/mod_python/trunk/lib/python/mod_python/apache.py
URL: http://svn.apache.org/viewcvs/httpd/mod_python/trunk/lib/python/mod_python/apache.py?rev=400247&r1=400246&r2=400247&view=diff
==============================================================================
--- httpd/mod_python/trunk/lib/python/mod_python/apache.py (original)
+++ httpd/mod_python/trunk/lib/python/mod_python/apache.py Fri May 5 23:30:26 2006
@@ -301,6 +301,13 @@
config = req.get_config()
debug = int(config.get("PythonDebug", 0))
+ default_object_str = req.phase[len("python"):].lower()
+
+ # Lookup expected status values that allow us to
+ # continue when multiple handlers exist.
+
+ expected = _status_values[default_object_str]
+
try:
hlist = req.hlist
@@ -311,8 +318,8 @@
module_name = l[0]
if len(l) == 1:
- # no oject, provide default
- object_str = req.phase[len("python"):].lower()
+ # no object, provide default
+ object_str = default_object_str
else:
object_str = l[1]
@@ -395,13 +402,15 @@
_result_warning % type(result)
# stop cycling through handlers
- if result != OK:
+ if result not in expected:
break
elif hlist.silent:
- # A faulty handler marked as silent will only
- # propagate DECLINED if it is the first and only handler.
- if result != OK:
+ # A missing handler when in silent mode will
+ # only propagate DECLINED if it is the first
+ # and only handler.
+
+ if result == HTTP_INTERNAL_SERVER_ERROR:
result = DECLINED
hlist.next()
@@ -1005,6 +1014,21 @@
OK = REQ_PROCEED = 0
DONE = -2
DECLINED = REQ_NOACTION = -1
+
+_status_values = {
+ "postreadrequesthandler": [ DECLINED, OK ],
+ "transhandler": [ DECLINED ],
+ "maptostoragehandler": [ DECLINED ],
+ "inithandler": [ DECLINED, OK ],
+ "headerparserhandler": [ DECLINED, OK ],
+ "accesshandler": [ DECLINED, OK ],
+ "authenhandler": [ DECLINED ],
+ "authzhandler": [ DECLINED ],
+ "typehandler": [ DECLINED ],
+ "fixuphandler": [ DECLINED, OK ],
+ "loghandler": [ DECLINED, OK ],
+ "handler": [ OK ],
+}
# constants for get_remote_host
REMOTE_HOST = 0
Modified: httpd/mod_python/trunk/src/include/mpversion.h
URL: http://svn.apache.org/viewcvs/httpd/mod_python/trunk/src/include/mpversion.h?rev=400247&r1=400246&r2=400247&view=diff
==============================================================================
--- httpd/mod_python/trunk/src/include/mpversion.h (original)
+++ httpd/mod_python/trunk/src/include/mpversion.h Fri May 5 23:30:26 2006
@@ -1,5 +1,5 @@
#define MPV_MAJOR 3
#define MPV_MINOR 3
#define MPV_PATCH 0
-#define MPV_BUILD 20060503
-#define MPV_STRING "3.3.0-dev-20060503"
+#define MPV_BUILD 20060506
+#define MPV_STRING "3.3.0-dev-20060506"
Modified: httpd/mod_python/trunk/test/htdocs/tests.py
URL: http://svn.apache.org/viewcvs/httpd/mod_python/trunk/test/htdocs/tests.py?rev=400247&r1=400246&r2=400247&view=diff
==============================================================================
--- httpd/mod_python/trunk/test/htdocs/tests.py (original)
+++ httpd/mod_python/trunk/test/htdocs/tests.py Fri May 5 23:30:26 2006
@@ -1095,6 +1095,46 @@
req.write("test ok")
return apache.OK
+def phase_status_1(req):
+ apache.log_error("phase_status_1")
+ req.phases = [1]
+ return apache.DECLINED
+
+def phase_status_2(req):
+ apache.log_error("phase_status_2")
+ req.phases.append(2)
+ req.user = "bogus"
+ req.ap_auth_type = "bogus"
+ return apache.OK
+
+def phase_status_3(req):
+ apache.log_error("phase_status_3")
+ req.phases.append(3)
+ return apache.OK
+
+def phase_status_4(req):
+ apache.log_error("phase_status_4")
+ req.phases.append(4)
+ return apache.DECLINED
+
+def phase_status_5(req):
+ apache.log_error("phase_status_5")
+ req.phases.append(5)
+ return apache.OK
+
+def phase_status_6(req):
+ apache.log_error("phase_status_6")
+ req.phases.append(6)
+ return apache.OK
+
+def phase_status_7(req):
+ apache.log_error("phase_status_7")
+ if req.phases != [1, 2, 4, 5, 6]:
+ req.write("test failed")
+ else:
+ req.write("test ok")
+ return apache.OK
+
def test_sys_argv(req):
import sys
req.write(repr(sys.argv))
Modified: httpd/mod_python/trunk/test/test.py
URL: http://svn.apache.org/viewcvs/httpd/mod_python/trunk/test/test.py?rev=400247&r1=400246&r2=400247&view=diff
==============================================================================
--- httpd/mod_python/trunk/test/test.py (original)
+++ httpd/mod_python/trunk/test/test.py Fri May 5 23:30:26 2006
@@ -2077,6 +2077,33 @@
if (rsp != "test ok"):
self.fail(`rsp`)
+ def test_phase_status_conf(self):
+ c = VirtualHost("*",
+ ServerName("test_phase_status"),
+ DocumentRoot(DOCUMENT_ROOT),
+ Directory(DOCUMENT_ROOT,
+ SetHandler("mod_python"),
+ AuthType("bogus"),
+ AuthName("bogus"),
+ Require("valid-user"),
+ PythonAuthenHandler("tests::phase_status_1"),
+ PythonAuthenHandler("tests::phase_status_2"),
+ PythonAuthenHandler("tests::phase_status_3"),
+ PythonFixupHandler("tests::phase_status_4"),
+ PythonFixupHandler("tests::phase_status_5"),
+ PythonFixupHandler("tests::phase_status_6"),
+ PythonHandler("tests::phase_status_7"),
+ PythonDebug("On")))
+ return str(c)
+
+ def test_phase_status(self):
+
+ print "\n * Testing phase status"
+ rsp = self.vhost_get("test_phase_status")
+
+ if (rsp != "test ok"):
+ self.fail(`rsp`)
+
def test_publisher_conf(self):
c = VirtualHost("*",
ServerName("test_publisher"),
@@ -2568,6 +2595,7 @@
perRequestSuite.addTest(PerRequestTestCase("test_files_directive"))
perRequestSuite.addTest(PerRequestTestCase("test_none_handler"))
perRequestSuite.addTest(PerRequestTestCase("test_server_return"))
+ perRequestSuite.addTest(PerRequestTestCase("test_phase_status"))
perRequestSuite.addTest(PerRequestTestCase("test_publisher"))
perRequestSuite.addTest(PerRequestTestCase("test_publisher_auth_nested"))
perRequestSuite.addTest(PerRequestTestCase("test_publisher_auth_method_nested"))