If using filters value of req.phase only valid up till first 
req.read()/req.write().
------------------------------------------------------------------------------------

         Key: MODPYTHON-112
         URL: http://issues.apache.org/jira/browse/MODPYTHON-112
     Project: mod_python
        Type: Bug
  Components: core  
    Versions: 3.1.4, 3.2    
    Reporter: Graham Dumpleton


The request object provides a member variable called 'phase' described as:

  The phase currently being being processed, e.g. "PythonHandler". (Read-Only)

If no Python based input and output filters are used, the value of req.phase 
will be constant for the life of a request phase. If however you use an input 
or output filter, the value of req.phase can change.

Consider that we are in the content handler phase and where there is a Python 
based output filter, but no Python based input filter. On initially entering 
the request handler, the value of req.phase will be "PythonHandler". As soon as 
req.write() is called however, the value of req.phase changes to 
"PythonOutputFilter".

Now, if there is a Python based input filter, but no Python based output 
filter, the value of req.phase will change to "PythonInputFilter" as soon as 
req.read() is called.

If there are both Python based input and output filters, the value of req.phase 
will in turn change to "PythonInputFilter" and "PythonOutputFilter" as 
req.read() and then req.write() are in turn called.

The reason for all this is that in the get_request_object() function of 
src/mod_python.c, it contains code:

    /* make a note of which phase we are in right now */
    Py_XDECREF(request_obj->phase);
    if (phase)
        request_obj->phase = PyString_FromString(phase);
    else
        request_obj->phase = PyString_FromString("");

That is, whenever called to get the request object, it will update req.phase. 
This will occur even if the request object had already been created, as will be 
the case when there is a Python based content handler and either a Python based 
input or output filter.

Overall this behaviour is a bit strange and unexpected. It would seem to me 
that it if there is both a handler and a filter, that the value of req.phase 
would be left as the name of the handler phase. Ie., it would stay for example 
as "PythonHandler" and not be changed to "PythonInputFilter" or 
"PythonOutFilter".

One can't just change the code in get_request_object() not to update it if 
already set, as it has to be updated when one moves from one phase to another. 
One has to contend with where this function is called in python_filter() 
function, namely:

    /* create/acquire request object */
    request_obj = get_request_object(req, interp_name,
                                     
is_input?"PythonInputFilter":"PythonOutputFilter");

First step may be simply not to pass in "PythonInputFilter" or 
"PythonOutputFilter" and instead just call it as:

    request_obj = get_request_object(req, interp_name,0);

At the same time change get_request_object() to:

    Py_XDECREF(request_obj->phase);
    if (phase)
        request_obj->phase = PyString_FromString(phase);
    else if (!request_obj->phase)
        request_obj->phase = PyString_FromString("");

Ie., result will be that if req.phase is set, leave it alone when called by 
python_filter() with phase set 0. If req.phase isn't already set, set it to the 
empty string.

The consequences of this are that if there are filters but no Python based 
handlers, then req.phase will get set to an empty string in that case. Another 
strange case is that if the only Python based handler was for an early phase 
than what is consuming or generating the content to be processed, then 
req.phase will be set to a value corresponding to that earlier phase and not 
where the current action is. For example, if there was an AccessHandler but 
then content came from a static file, output filter would see "AccessHandler".

Thus, whatever is done, there will be some strangeness. Thus, question remains 
of what should be done, or if it should be left that way and that documentation 
changed to say that req.phase is only valid up until first call to req.read() 
or req.write() within a handler.

This is not an ideal situation though as a handler may want to interogate 
req.phase after req.read() or req.write() has been called for some reason, 
which would yield incorrect results if a filter is being used. An example of 
where this occurs is in error reporting in the HandlerDispatch of 
mod_python.apache itself. When it is generating an error message, the phase 
shown in the error message will be wrong if there was a filter. It should 
perhaps at least be changed to save away req.phase at start of dispatch so it 
knows it is correct later for any error messages.

Any comments?????


-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira

Reply via email to