[ http://issues.apache.org/jira/browse/MODPYTHON-112?page=comments#action_12363553 ]
Graham Dumpleton commented on MODPYTHON-112: -------------------------------------------- The implications of this problem could be significant where multiple handlers are specified for a single phase. Ie., as specified in Apache configuration: PythonHandler example1 PythonHandler example2 or if subsequent handlers added use req.add_handler(). The reason for this is that the default handler name is calculated in HandlerDispatch() from req.phase. It does this calculation for each handler to be called instead of just once: while hlist.handler is not None: # split module::handler l = hlist.handler.split('::', 1) module_name = l[0] if len(l) == 1: # no oject, provide default object_str = req.phase[len("python"):].lower() else: object_str = l[1] If the handler example1::handler() were to call req.read()/req.write() where a Python based input/output filter is present, when the HandlerDispatch() calculates object_str for the second handler, it will try and call "inputfilter" or "outputfilter" instead of "handler". This is again solved by caching phase early on: phase = req.phase default_handler = phase[len("python"):].lower() while hlist.handler is not None: # split module::handler l = hlist.handler.split('::', 1) module_name = l[0] if len(l) == 1: # no oject, provide default object_str = default_handler else: object_str = l[1] The latter except blocks can then be changed also to not use req.phase. except PROG_TRACEBACK, traceblock: # Program run-time error try: (etype, value, traceback) = traceblock result = self.ReportError(etype, value, traceback, req=req, phase=phase, hname=hlist.handler, debug=debug) finally: traceback = None except: # Any other rerror (usually parsing) try: exc_type, exc_value, exc_traceback = sys.exc_info() result = self.ReportError(exc_type, exc_value, exc_traceback, req=req, phase=phase, hname=hlist.handler, debug=debug) > 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