quetz-mod_python-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Graham Dumpleton <grah...@dscpl.com.au>
Subject Re: Regex based publisher proposal
Date Fri, 08 Sep 2006 07:15:07 GMT

On 08/09/2006, at 3:42 PM, Graham Dumpleton wrote:
>> In regards to:
>>
>> path,module_name =  os.path.split(req.filename)
>>
>>     # Trimming the front part of req.uri
>>     if module_name=='':
>>         req_url = ''
>>     else:
>>         req_url = req.uri[req.uri.index(module_name):]
>>
>> It is bringing a question I have had for a long time in  
>> mod_python. Is there a way to identify accurately the relative  
>> virtual path of a request other than comparing to the physical  
>> path, especially when using apache definition such as VirtualHost  
>> & Location?  For example let's say you define something like:
>> <Location /myapp/admin/>
>> 	AddHandler mod_python .py .html
>> 	PythonHandler mod_python.publisher
>> </Location>
>>
>> And there comes a request such as http://myserver/myapp/admin/ 
>> login.html
>>
>> How do you determine accurately that the part of the path /myapp/ 
>> admin/ is in fact the virtual root of your application ?
>
> If a Directory directive is used, or the handler directives appear  
> in a .htaccess file,
> the you can use req.hlist.directory.
>
> Caveats to this are that prior to mod_python 3.3, if the handler  
> directive appears
> inside of a Files/FileMatch directive within those two contexts,  
> the value was wrong
> and could not be used. Further, prior to mod_python 3.3, the result  
> would be wrong
> if use wildcards in the Directory directive, or the DirectoryMatch  
> variant was used.
>
> When the Location directive is used, there is no physical directory  
> which corresponds
> to it and so req.hlist.directory wouldn't be valid as its purpose  
> is to denote the physical
> directory a directive was associated with. A caveat to this though,  
> is that prior to
> mod_python 3.3, req.hlist.directory would actually list the path  
> specified in the
> Location directive. This isn't the case though in mod_python 3.3  
> and it will instead
> be None when used in the Location or LocationMatch directives as it  
> causes problems
> otherwise with a non existent path being used as a location to  
> search for Python
> modules.
>
> With my brain being clouded at the moment, I cant remember off the  
> top of my head
> what the correct way is and I would have to check things, but when  
> you use the
> Location directive, isn't req.path_info the part of the URL which  
> lies below where the
> Location directive was specified for. If my memory is correct, this  
> doesn't mean you
> can simply take the length of req.path_info and drop off that much  
> off req.uri though.
> The problem is that req.uri isn't normalised in the way that  
> req.path_info is, so it may
> contain repeating slashes and other crud that can stuff things up.  
> You need to address

Now I am well and truly confused and not sure if I have broken  
mod_python 3.3
or not. Short of it is, that I cannot get something like:

   <Location /location>
   AddHandler mod_python .xxx
   PythonHandler /Users/grahamd/Projects/testing/xxx.py
   </Location>

to work. If I use SetHandler instead of AddHandler inside of the  
Location directive,
ie.:

   <Location /location>
   SetHandler mod_python
   PythonHandler /Users/grahamd/Projects/testing/xxx.py
   </Location>

then it works as I expected, with handler containing:

   from mod_python import apache

   def handler(req):
       req.content_type = 'text/plain'
       req.write('req.filename = %s\n' % req.filename)
       req.write('req.uri = %s\n' % req.uri)
       req.write('req.path_info = %s\n' % req.path_info)
       return apache.OK

producing:

   req.filename = /usr/local/apache-2.2/htdocs/location
   req.uri = /location/cat/dog.xxx
   req.path_info = /cat/dog.xxx

Because Location directive is used, then req.filename is sort of  
meaningless, although
one could do:

       req.write('req.document_root() = %s\n' % req.document_root())
       req.write('location = %s\n' % req.filename[len 
(req.document_root()):])

and get:

   req.document_root() = /usr/local/apache-2.2/htdocs
   location = /location

Now the question is whether AddHandler should work within a Location  
directive. Since
it doesn't, my first guess is that it can't because no matching  
against actual files is being
performed and so no extension for a target could be derived.

I note that using an extension qualifier to the PythonHandler  
directive doesn't work
either. Ie., following doesn't call the handler if request is / 
dog.xxx or /dog/cat.xxx.

   <Location /location>
   SetHandler mod_python
   PythonHandler /Users/grahamd/Projects/testing/xxx.py | .xxx
   </Location>

All probably quite logical and the only way to do something different  
based on extension
in the URL would be to specify a fixup handler and not a response  
handler, and for
the fixup handler to know it is being used in a location directive,  
map the URL itself
somehow and then set req.handler to 'mod_python' and call  
req.add_handler() to give
the handler to be called.

Ie., Apache configuration of:

   <Location /location>
   PythonFixupHandler /Users/grahamd/Projects/testing/xxx.py
   </Location>

and handler file containing:

   from mod_python import apache
   import posixpath

   def handler(req):
       req.content_type = 'text/plain'
       req.write('req.filename = %s\n' % req.filename)
       req.write('req.uri = %s\n' % req.uri)
       req.write('req.path_info = %s\n' % req.path_info)
       req.write('req.document_root() = %s\n' % req.document_root())
       req.write('location = %s\n' % req.filename[len 
(req.document_root()):])
       return apache.OK

   # This doesn't copy with concept of path info after extension.

   def fixuphandler(req):
       extension = posixpath.splitext(req.path_info)[1]
       if extension == '.xxx':
           req.handler = 'mod_python'
           req.add_handler('PythonHandler', handler)
           return apache.OK
       return apache.DECLINED

BTW, using an absolute path for a handler is new in mod_python 3.3.  
Assigning to
req.handler also only works from 3.3 onwards, so don't expect this to  
work on older
versions of mod_python.

Having said all that, when you said:

>> <Location /myapp/admin/>
>> 	AddHandler mod_python .py .html
>> 	PythonHandler mod_python.publisher
>> </Location>

is that what you are using and I should actually expect AddHandler to  
work inside
of a Location directive?

Graham

Mime
View raw message