Issue Details (XML | Word | Printable)

Key: MODPYTHON-98
Type: Bug Bug
Status: Closed Closed
Resolution: Fixed
Priority: Major Major
Assignee: Unassigned
Reporter: Graham Dumpleton
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
mod_python

wrong handler supplied to req.add_handler() generates error

Created: 09/Dec/05 01:50 PM   Updated: 05/Mar/06 02:57 PM
Return to search
Component/s: core
Affects Version/s: 3.1.4, 3.2.7
Fix Version/s: 3.2.7

Time Tracking:
Not Specified

Resolution Date: 14/Jan/06 01:13 AM


 Description  « Hide
The documentation for req.add_handler() states:

  Note: There is no checking being done on the validity of the handler name. If you pass this function an invalid handler it will simply be ignored.

In other words, get the name of the handler wrong and it is supposed to just ignore it. This is not actually the case, instead it will generate an exception when it goes to process the handler:

  Mod_python error: "PythonHandler example::handler_3"

  Traceback (most recent call last):

    File "/System/Library/Frameworks/Python.framework/Versions/2.3/lib/python2.3/site-packages/mod_python/apache.py", line 291, in HandlerDispatch
      arg=req, silent=hlist.silent)

    File "/System/Library/Frameworks/Python.framework/Versions/2.3/lib/python2.3/site-packages/mod_python/apache.py", line 538, in resolve_object
      raise AttributeError, s

  AttributeError: module '/Users/grahamd/Sites/add_handler/example.py' contains no 'handler_3'

This can be seen with .htaccess file of:

  SetHandler mod_python
  PythonAccessHandler example
  PythonHandler example::handler_1
  PythonDebug On

and example.py file containing:

  from mod_python import apache

  def accesshandler(req):
    apache.log_error("accesshandler")
    req.add_handler("PythonHandler","example::handler_3")
    return apache.OK

  def handler_1(req):
    apache.log_error("handler_1")
    req.content_type = 'text/plain'
    req.write("HELLO")
    return apache.OK

  def handler_2(req):
    apache.log_error("handler_2")
    return apache.OK

Either the documentation is wrong and an exception is desired, or more likely this is an extension of the prior problem with hlist.silent as described as being a problem in other ways in MODPYTHON-46.

In that case the logic of SILENT/NOTSILENT was the wrong way around and it was fixed by reversing the definitions of the two. In doing this though, it didn't cover cases where a "silent" flag is passed to hlist_new() and hlist_append() in the req_add_handler() function of requestobject.c.

Specfically, there are calls to hlist_new() and hlist_append() in that function:

        hlist_append(self->request_rec->pool, self->hlo->head,
                     handler, dir, 0);

            hle = hlist_new(self->request_rec->pool, handler, dir, 0);

            hlist_append(self->request_rec->pool, hle, handler, dir, 0);

These should be written as:

        hlist_append(self->request_rec->pool, self->hlo->head,
                     handler, dir, SILENT);

            hle = hlist_new(self->request_rec->pool, handler, dir, SILENT);

            hlist_append(self->request_rec->pool, hle, handler, dir, SILENT);

If this change were made, the code would then behaves conformant with the documentation as far as being silent, however it highlights a further issue.

This further issue is that although it is silent when the handler name is wrong, this results in apache.DECLINED being returned for the handler that couldn't be found. Because apache.DECLINED is returned, Apache will try and interpret the URL again and if possible serve up a static file etc.

For the above example code this then means that if "example.py" was used in the URL, the browser gets back a response of:

  HELLOfrom mod_python import apache

  def accesshandler(req):
    apache.log_error("accesshandler")
    req.add_handler("PythonHandler","example::handler_3")
    return apache.OK

  def handler_1(req):
    apache.log_error("handler_1")
    req.content_type = 'text/plain'
    req.write("HELLO")
    return apache.OK

  def handler_2(req):
    apache.log_error("handler_2")
    return apache.OK

That is, the content as returned by handler_1(), followed by the contents of the example.py file.

If instead the URL wasn't 'example.py' but say 'other.py' with that not existing, get back:

  HELLO
  OK

  The requested URL /~grahamd/add_handler/foo.py was not found on this server.

  Apache/2.0.51 (Unix) mod_python/3.2.5b Python/2.3 Server at localhost Port 8080

In some ways, this behaviour suggests that the behaviour whereby it raised an exception was probably a better way of handling the situtation anyway. Thus, maybe the documentation should instead be changed and the code left as is, or at least the 0 arguments changed to be NOTSLIENT to make it more obvious what it is doing.

The other option is to change the code to use SILENT, but then document the strange things that can result if the specified handler doesn't exist.

Comments??????


 All   Comments   Work Log   Change History   Subversion Commits      Sort Order: Ascending order - Click to sort in descending order
Repository Revision Date User Message
ASF #367833 Tue Jan 10 23:25:21 UTC 2006 jgallacher Documentation changed for req.add_handler. Docs now state that
passing an invalid handler in add_handler will generate an exception
at the time an attempt is made to find the handler.
Ref MODPYTHON-98
Files Changed
MODIFY /httpd/mod_python/trunk/Doc/modpython4.tex

Repository Revision Date User Message
ASF #367834 Tue Jan 10 23:27:22 UTC 2006 jgallacher Changed HandleDispatch in apache.py so that an exception is raised if handler
string is empty.
Ref MODPYTHON-98
Files Changed
MODIFY /httpd/mod_python/trunk/lib/python/mod_python/apache.py

Repository Revision Date User Message
ASF #367835 Tue Jan 10 23:36:37 UTC 2006 jgallacher Fix segfault when adding handler to empty list in python_handler.
Ref MODPYTHON-98
Files Changed
MODIFY /httpd/mod_python/trunk/src/mod_python.c

Repository Revision Date User Message
ASF #367836 Tue Jan 10 23:45:24 UTC 2006 jgallacher Changed HandlerDispatch in apache.py so that a faulty handler
which is marked as silent will propagate DECLINED if it is the
first and only handler.
Ref MODPYTHON-98
Files Changed
MODIFY /httpd/mod_python/trunk/lib/python/mod_python/apache.py

Repository Revision Date User Message
ASF #367839 Wed Jan 11 00:03:06 UTC 2006 jgallacher Changed code in req_add_handler() of requestobject.c to use NOTSILENT
instead of 0. This should make the intent of code clearer in as much as
highlighting that an exception will be raised if handler not found.
Ref MODPYTHON-98
Files Changed
MODIFY /httpd/mod_python/trunk/src/requestobject.c

Repository Revision Date User Message
ASF #368173 Wed Jan 11 23:56:53 UTC 2006 jgallacher Added unit tests for several different uses of req.add_handler.
Ref MODPYTHON-98
Files Changed
MODIFY /httpd/mod_python/trunk/test/htdocs/tests.py
MODIFY /httpd/mod_python/trunk/test/test.py

Repository Revision Date User Message
ASF #368511 Thu Jan 12 23:14:11 UTC 2006 jgallacher Refactored req_add_empty_handler_string to check the response
from the request for evidence of an exception rather than examining
error_log.
Ref MODPYTHON-98
Files Changed
MODIFY /httpd/mod_python/trunk/test/htdocs/tests.py
MODIFY /httpd/mod_python/trunk/test/test.py