[mod_python] multiple requests to authenhandler for a single url

reghigh reghigh at thefactz.org
Wed Oct 5 12:04:37 EDT 2005


I am encountering the following issue (which has already been raised on 
this list about a year ago~[1]) relating to multiple calls to 
authenhandler. To demonstrate I have the following:

apache2 httpd.conf
******************

<VirtualHost *:80>
   ServerName static
   DocumentRoot <omitted>

   PythonPath "['<omitted>'] + sys.path"
   PythonAuthenHandler test
   PythonDebug On

   <Location />
       AuthType Basic
       AuthName "Restricted Area"
       Require valid-user
   </Location>
</VirtualHost>

test.py
*******

from mod_python import apache

count = 0

def authenhandler(req):

     pw = req.get_basic_auth_pw()
     user = req.user
     global count
     count += 1
     raise Exception('%s, %s, %s, %s, %s, %s' % \
         (req.handler, req.unparsed_uri,
         req.path_info, req.used_path_info))

Results
*******

Note output is trimmed for readability~[2]

url: http://static/x

Exception: None, /x, , 2

url: http://static/x/y

Exception: None, /y, , 2
Exception: None, /x/y, /y, 2

url: http://static/x/y/z

Exception: None, /z, , 2
Exception: None, /y/z, /y, 2
Exception: None, /x/y/z, /y/z, 2

etc

Note that this is invariant to url naming used: /<1>/<2>/.../<n>

produces exceptions with unparsed uri sections:
   /<n>
   /<n-1>/<n>
   ......

 From now on will use notation <url> -> (url1, url2, ....) to mean a 
given url produced an exceptions in order with unparsed_uri = url1, url2 
etc

Varying Location Directive
==========================

Now experimentation yielded the following. If Location directive was 
changed say to

<Location /x>

Then

   /x -> (/x) = 1 request
   /xx -> not processed by handler
   /x/y -> (/x/y) = 1 request
   /x/x/y -> (/x/y, /x/x/y) = 2 requests

<Location ~ "^/[xy]">
(NB: this all works with <LocationMatch "^/[xy]">)

Then

   /x -> (/x) = 1R
   /xx -> (/xx) = 1R
   /x/y -> (/y, /x/y) = 2R
   /x/z/ -> (/x/z) = 1R
   /x/y/z -> (/y/z, /x/y/z) = 2R
   /x/y/z/x -> (/y/z/x, /x/y/z/x) = 2R
   /x/y/x -> (/x, /y/x, /x/y/x) = 3R
   /x/y/ -> (/y/, /x/y/) = 2R

This suggests that somehow the Location directive (i have also confirmed 
similar behaviour using the <Directory>) gives rise to multiple requests 
to authenhandler. However this matching to generate requests as shown 
above does not occur in any simple way (it seems to match from the left 
hand side of the url string but once it encounters a non-match it halts).

Multiple calls not only cause serious overhead if authenticating off a 
database but also play havoc with a system based access control via urls 
since you want to match against the full url but the authenhandler gets 
the full url last out of all the urls it gets passed. What i want is for 
the Location directive to generate a single call to the authenhandler 
with the whole uri being passed.

Does anyone have any ideas what is causing this and how I could solve 
the problem.

Regards,

Tristan

------------------

[1] http://www.modpython.org/pipermail/mod_python/2004-November/016750.html
Complete summary here: http://www.scanmine.com/mp/mod_python_b_p.html

[2] For example

Exception: None, /y, , 2, None
Exception: None, /x/y, /y, 2, None

in full was:

<pre>
Mod_python error: "PythonAuthenHandler test"

Traceback (most recent call last):

   File 
"/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-packages/mod_python/apache.py", 
line 299, in HandlerDispatch
     result = object(req)

   File "/Users/rgrp/Sites/python/test.py", line 11, in authenhandler
     raise Exception('%s, %s, %s, %s, %s' % \

Exception: None, /y, , 2, None

</pre>

<pre>
Mod_python error: "PythonAuthenHandler test"

Traceback (most recent call last):

   File 
"/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-packages/mod_python/apache.py", 
line 299, in HandlerDispatch
     result = object(req)

   File "/Users/rgrp/Sites/python/test.py", line 11, in authenhandler
     raise Exception('%s, %s, %s, %s, %s' % \

Exception: None, /x/y, /y, 2, None

</pre>


More information about the Mod_python mailing list