Issue Details (XML | Word | Printable)

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

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

Wrong interpreter chosen with req.add_handler()/PythonInterpPerDirective.

Created: 16/Apr/06 02:32 PM   Updated: 17/Apr/07 10:38 AM
Component/s: core
Affects Version/s: 3.3.x
Fix Version/s: 3.3.1

Time Tracking:
Not Specified

Resolution Date: 07/May/06 05:15 PM


 Description  « Hide
Having fixed MODPYTHON-160, if using:

# .htaccess

SetHandler mod_python
PythonInterpPerDirective On
PythonFixupHandler interpreter_1

# interpreter_1.py

from mod_python import apache
import os, sys

directory = os.path.dirname(__file__)

def fixuphandler(req):
    req.log_error("fixuphandler")
    req.log_error("interpreter=%s"%req.interpreter)
    req.log_error("directory=%s"%req.hlist.directory)
    req.add_handler("PythonHandler","interpreter_1",directory)
    return apache.OK

def handler(req):
    req.log_error("handler")
    req.log_error("interpreter=%s"%req.interpreter)
    req.log_error("directory=%s"%req.hlist.directory)
    req.content_type = 'text/plain'
    req.write('hello')
    return apache.OK

when select_interp_name() in src/mod_python.c tries to determine the interpreter name, for PythonInterPerDirective, it will use the value as supplied as directory argument to req.add_handler(). In doing this though, it doesn't consider the fact that the directory may not have a trailing slash and since interpreter names for PythonInterpPerDirective always have a trailing slash, the handler will not be executed in correct interpreter context.

[Sun Apr 16 17:20:00 2006] [notice] mod_python: (Re)importing module 'interpreter_1'
[Sun Apr 16 17:20:00 2006] [error] [client ::1] fixuphandler
[Sun Apr 16 17:20:00 2006] [error] [client ::1] interpreter=/Users/grahamd/Workspaces/testing/interpreter-1/
[Sun Apr 16 17:20:00 2006] [error] [client ::1] directory=/Users/grahamd/Workspaces/testing/interpreter-1/
[Sun Apr 16 17:20:00 2006] [notice] mod_python: (Re)importing module 'interpreter_1'
[Sun Apr 16 17:20:00 2006] [error] [client ::1] handler
[Sun Apr 16 17:20:00 2006] [error] [client ::1] interpreter=/Users/grahamd/Workspaces/testing/interpreter-1
[Sun Apr 16 17:20:00 2006] [error] [client ::1] directory=/Users/grahamd/Workspaces/testing/interpreter-1

A further problem is that normally the path indicating where a directive was defined is internally calculated from Apache configuration and thus always uses POSIX directory conventions, ie., forward slash. If the above code were run on Win32, the directory calculated from __file__ is going to most likely use DOS directory conventions, ie., backward slash. Thus, even if a trailing slash were to be added, it still will not work because the remainder of the path is going to use backward slash and thus the interpreter name still will not match what it probably should be.

The main purpose of the directory argument to req.add_handler() is to know where to find the module referenced in the handler argument. In this case it is also used to determine the Python interpreter name. The fix may be that the interpreter name be determined in some other way based on the interpreter in use when the req.add_handler() call was made.

This is just part of problems I can possibly see with calculation of interpreter names for handlers. More on this another time. :-)






 All   Comments   Work Log   Change History   Subversion Commits      Sort Order: Ascending order - Click to sort in descending order
Graham Dumpleton added a comment - 16/Apr/06 02:44 PM
An even better example of why using the directory argument to req.add_handler() is wrong in this situation is that the module and thus the directory provided could be completely outside of the document tree. For example:

    req.add_handler("PythonHandler","xxx","/tmp")

In this case you get:

[Sun Apr 16 17:43:00 2006] [error] [client ::1] handler
[Sun Apr 16 17:43:00 2006] [error] [client ::1] interpreter=/tmp
[Sun Apr 16 17:43:00 2006] [error] [client ::1] directory=/tmp

Ie., interpreter name ends up being "/tmp".

Graham Dumpleton added a comment - 16/Apr/06 06:22 PM
FWIW, problems can also arise with PythonInterpPerDirectory. In this case the issue is that the interpreter name in that case is derived from the value of req.filename at the time the handler is called. The same issues as above can therefore arise in that req.filename could be given a value that doesn't have a trailing slash or which uses Win32 forward slashes instead of backslashes. This could therefore mean a different interpreter to that which was expected might be used for a subsequent handler phase if req.filename was modified.

Graham Dumpleton added a comment - 18/Apr/06 06:07 PM
In general there are possible also issues with req.hlist.directory derived from Apache configuration on Win32 when a user uses backslash instead of foward slash in Directory directive. See:

  http://www.mail-archive.com/python-dev@httpd.apache.org/msg01839.html

for examples.

What mod_python probably needs to do is to ensure that it normalises paths to a POSIX style path, with allowance for drive specifier on Win32, in the same sort of format that Apache uses when it sets up req.filename. This would bring some consistency to interpreter naming.

Graham Dumpleton added a comment - 07/May/06 01:48 PM
The directory supplied to req.register_input_filter() and req.register_output_filter() also needs to be canonicalised (made POSIX style) and trailing slash added to fix issues with PythonInterpPerDirective.

The issues with Win32 backward slash versus forward slash are a non issue for directory derived from directive specified in configuration as that was to do with incomplete changes related to MODPYTHON-126, which has since been addressed.


Graham Dumpleton added a comment - 07/May/06 03:35 PM
I am going to break out the problem of non POSIX style names being assigned to req.filename as a separate issue as there are wider implications in that which potentially need to be discussed.

In respect of the fact that arbitrary directories supplied to req.add_handler(), req.register_input_filter() and req.register_output_filter() can be interpreted as a directory associated with a directive when PythonInterpPerDirective is used, when in fact they aren't linked to any directive, is probably just a quirk that has to be accepted and left as is. Especially with the new importer where modules can be specified by full path, there are other options to ensure things can be made to work how desired.