[mod_python] Mod_python as replacement for mod_rewrite

Graham Dumpleton grahamd at dscpl.com.au
Wed Dec 20 16:21:43 EST 2006

=?ISO-8859-2?Q?Klokan_Petr_P=F8idal?= wrote ..
> Hello,
> I need to make an intelligent replacement for mod_rewrite, so it will
> count url using quite complicated math a then forward request to
> fast-cgi server...
> In fact I'm going to use it for WMS (Web Map Service) emulation over
> IIPImage (imageserver),
> so url like:
> http://domain/script/?WMTVER=1.0.0&REQUEST=map&LAYERS=RELIEF&STYLES=default&SRS=EPSG:4326&BBOX=-2.197265625,39.55078125,20.302734375,50.80078125&WIDTH=256&HEIGHT=128&FORMAT=JPG
> will be redirected (as fast as possible and internally inside apache)
> to fast cgi request
> http://domain/fastcgi-bin/iipsrv.fcgi?FIF=/tmp/test.tif&WID=256&HEI=128&RGN=0.25,0.25,0.5,0.5&CVT=JPEG
> where I have to transform lat/lon numbers in first url to region on
> the image in the second url... but this wouldn't be so big problem in
> python...
> Question is which apache handlers use to make this internal forward,
> and how to make that as fast as possible...
> Is mod_python the right tool for this task?
> Or do you think it would be better to hack directly mod_rewrite and
> programm the transition of coordinates in C?

You can do it as a PythonTransHandler. This will be before any mapping of
URL to filesystem.

As an example, here is a transhandler() which implements the equivalent of
the Alias directive. I am using this to specify a special document root on the
fly which is then used by the MapToStorage phase of Apache. In your case
you wouldn't necessarily need to be setting DocumentRoot dynamically by
assigning to req.filename, but just rewriting req.uri with a new value. Only
problem with reassigning req.uri is that you are going to need mod_python
version 3.3 as 3.2.X doesn't support reassignment of req.uri. Version 3.3
hasn't been released yet, but you can get first beta snapshot from:


Doing it in the transhandler() means you can avoid having to do an internal
Apache subrequest. If you can't use newer version of mod_python, you will
have to do it as a normal handler and use req.internal_redirect() instead which
will be slower as it is causing a subrequest so effectively handling two full
requests rather than one, albeit the second is internally generated.

As to the example, in httpd.conf file I have:

  #AliasMatch '/sample-(.*)/(.*)' /Users/grahamd/Projects/mod_python-sample/sample-$1/htdocs/$2

  # Implements same as AliasMatch directive above.
  PythonTransHandler /Users/grahamd/Projects/mod_python-sample/location.py

The transhandler() code file is then:


from mod_python import apache
import re, os

# Same as AliasMatch definition mapping:
#   '/sample-(.*)/(.*)'
# to:
#   /Users/grahamd/Projects/mod_python-sample/sample-$1/htdocs/$2

_here = os.path.dirname(__file__)
_location_re = re.compile(r'^/(?P<app>sample-[^/]*)/(?P<path>.*)')

def transhandler(req):
    result = _location_re.match(req.uri)
    if result:
        matches = result.groupdict()
        application = matches['app']
        path = matches['path']
        req.filename = os.path.join(_here, application, 'htdocs', path)
        return apache.OK
    return apache.DECLINED

More information about the Mod_python mailing list