mod_python, multiple calls to PythonAuthenHandler

Rune Hansen rune.hansen at scanmine.com
Mon Nov 8 10:26:05 EST 2004


On Mon, 08 Nov 2004 08:18:45 -0500, Steve Holden wrote:

> Rune Hansen wrote:
> 
>> I've posted this question on the mod_python mailing list but didn't get 
>> much response, so I thought I'd post it here.
>> 
>> (My first attempt connected to an unrelated thread..sorry.
>> Note-to-self:-must-get-more-coffee-before-posting-)
>> 
>> It seems to me that for each path element in a URI a mod_python handler
>> will be invoked. This applies to PythonAuthenHandler,
>> PythonHeaderParserHandler and so on.
>> 
>> Since I'm making a database request in my PythonAuthenHandler, this 
>> quickly becomes a problem.
>> 
>> Example:
>> http://lucene.moonspawn.scanmine.com/ =>
>> 	AuthenHandler::authenhandler called: 1
>> 	index got called once
>> 
>> http://lucene.moonspawn.scanmine.com/SearchHandler.py/search =>
>> 	AuthenHandler::authenhandler called: 1
>> 	AuthenHandler::authenhandler called: 2
>> 	/search got called once
>> 
>> http://lucene.moonspawn.scanmine.com/search.html => (using mod_rewrite)
>> 	AuthenHandler::authenhandler called: 1
>> 	AuthenHandler::authenhandler called: 2
>> 	AuthenHandler::authenhandler called: 3
>> 	/search got called once
>> 
>> I get the same behavior on three separate installations
>> 
>> So, either I've got a miss-configuration which results in multiple calls 
>> to handlers or.., this is expected behavior, and there is a technique to 
>> avoid this or..., this is expected and, for reasons that escapes me, 
>> desired behavior.
>> 
>> I'd greatly appreciate any help and suggestion
>> 
>> regards
>> 
>> /rune
> 
> Well, the thing that's missing here is the code of your AuthenHandler 
> (or some detail about which standard component you think is being used). 
> Is it possible you are making internal redirects, for example?
> 
> The information about using mod_rewrite does imply you are spending time 
> on authentication rather more frequently than you strictly need to, but 
> it's difficult to figure out from just the information given.
> 
> regards
>   Steve

Hi Steve, 
The configuration and "files" shown below results in the "Example" of my
orignal post.

httpd.conf:
"""
<VirtualHost *:80>
	ServerName lucene.moonspawn.scanmine.com
	ServerAdmin rune.hansen at scanmine.com
	DocumentRoot /Users/roderik/Sites/Lucene
	ErrorLog logs/lucene_error.log
	CustomLog logs/lucene_access.log common
</VirtualHost>
<Directory "/Users/roderik/Sites/Lucene">
	Options Indexes FollowSymLinks
        AllowOverride None
        Order allow,deny
        Allow from all
        RewriteEngine On
        RewriteBase /
        RewriteRule search.html "SearchHandler.py/search"
	AddHandler mod_python .py
        DirectoryIndex SearchHandler.py
	PythonHandler mod_python.publisher
        PythonAuthenHandler AuthenHandler
        AuthType Basic
        AuthName "Restricted Area"
        require valid-user	
        PythonPath "sys.path+['/Users/roderik/Sites/Lucene']"
	PythonDebug On
</Directory>
"""

AuthenHandler.py
"""
from mod_python import apache

count=0

def authenhandler(req,**args):
    global count

    count +=1
    req.write("AuthenHandler::authenhandler called: "+str(count)+"\n")

    pw = req.get_basic_auth_pw()
    user = req.user

    if user == "mrX" and pw == "1234":
        return apache.OK
    else:
        return apache.HTTP_UNAUTHORIZED
"""

SearchHandler.py
"""
from mod_python import apache

def index(req,**args):
    req.content_type = "text/html"
    req.write("<html><head><title>Search Index Page</title><head><body>## 'index' got called once</body></html>")

def search(req,**args):
    req.content_type = "text/html"
    req.write("<html><head><title>Search /search Page</title><head><body>## '/search' got called once</body></html>")
"""

Now, I've "solved it" with a single PythonHandler (dropping
PythonAuthenHandler and publisher):

def handler(req):
    if not req.headers_in.get("Authorization",0):
    	req.err_headers_out["WWW-Authenticate"] = 'Basic realm="Restricted\
    	area"'
        raise apache.SERVER_RETURN, apache.HTTP_UNAUTHORIZED
    meth,auth = req.headers_in.get("Authorization").split(" ") 
    user,pw = decodestring(auth).split(":")
    args = dict([(a[0],a[1]) for a in util.parse_qsl(req.args or '')]) 
    if dbmdbValidate(user,pw,req.server):
	return myMethod(req,**args)
    else:
	return apache.HTTP_UNAUTHORIZED

This seems to do exactly what I want. Guess I should have tried a litle
harder before posting.
How ever, I'm still curious to why the PythonAuthenHandler is called for
each path element.

regards
/rune



More information about the Python-list mailing list