[mod_python] Help with mod_python, mod_proxy & cookies

Graham Dumpleton grahamd at dscpl.com.au
Wed Jan 24 18:56:38 EST 2007


Graham Dumpleton wrote ..
> Marc Boorshtein wrote ..
> > All,
> > 
> > I am trying to figure out a way to use mod python to change the Cookie
> > header of a request and then pass the request off to mod_proxy.  When
> > the response comes I wish to be able to adjust any Set-Cookie headers
> > in the response back to the client.  I did something similar in
> > mod_perl using filters and am assuming it would be a similar process.
> > I wrote a quick input filter to trace the data going through the
> > filter and found a few issues:
> > 
> > 1.  When I have a ProxyPass in my httpd config, apache doesn't fire my
> > filter
> > 2.  When I remove the ProxyPass rule my filter fires, but no data
> > seems to be going through it
> > 3.  When I specify AddInputFilter, is there anyway to have it apply
> > globally (as opposed to for a particular file extension)?
> 
> Use SetInputFilter. This should be mentioned in Apache documentation
> where AddInputFilter is described.
> 
> > Here's my code:
> > 
> > from mod_python import apache
> > 
> > def inputfilter(filter):
> >     apache.log_error('in filter');
> >     s = filter.read()
> >     apache.log_error('begin data');
> >     while s:
> >         apache.log_error('data : ' + s);
> >         filter.write(s.upper())
> >         s = filter.read()
> >     apache.log_error('end data');
> > 
> >     if s is None:
> >         filter.close()
> > 
> > Here's my apache config:
> > <VirtualHost *>
> >   PythonDebug On
> >   PythonPath "sys.path + ['/home/mlb/workspace/Python\ CookieFilter/src']"
> >   PythonInputFilter CookieFilterInbound COOKIEINBOUND
> >   AddInputFilter COOKIEINBOUND .html
> >    ProxyPass / http://localhost:8080/
> > </VirtualHost>
> > 
> > Here's my log:
> > 
> > [Wed Jan 24 16:28:25 2007] [notice] Apache/2.2.3 (Fedora) configured
> > -- resuming normal operations
> > [Wed Jan 24 16:28:28 2007] [notice] mod_python: (Re)importing module
> > 'CookieFilterInbound'
> > [Wed Jan 24 16:28:28 2007] [error] in filter
> > [Wed Jan 24 16:28:28 2007] [error] begin data
> > [Wed Jan 24 16:28:28 2007] [error] end data
> > [Wed Jan 24 16:28:28 2007] [error] [client 127.0.0.1] File does not
> > exist: /var/www/html/showcookie.html
> > [Wed Jan 24 16:28:28 2007] [error] in filter
> > [Wed Jan 24 16:28:28 2007] [error] begin data
> > [Wed Jan 24 16:28:28 2007] [error] end data
> > [Wed Jan 24 16:29:23 2007] [notice] caught SIGTERM, shutting down
> > 
> > Any help would be greatly appreciated.
> 
> I don't believe you need to use an input filter, you could instead use
> a
> fixup handler to do everything, including enabling of the proxy itself.
> 
>  <VirtualHost *>
>    PythonDebug On
>    PythonPath "sys.path + ['/home/mlb/workspace/Python CookieFilter/src']"
>    PythonFixupHandler myredirectandcookiefixup
>  </VirtualHost>
> 
> For starters, below (myredirectandcookiefixup.py) is how you initiate proxying.
> 
> import posixpath
> 
> from mod_python import apache
> 
> def fixuphandler(req):
> 
>   if req.proxyreq:
>     return apache.DECLINED
> 
>   normalised_uri = posixpath.normpath(req.uri)
> 
>   if normalised_uri:
>     if normalised_uri != '/' and req.uri[-1] == '/':
>       normalised_uri += '/'
> 
>   length = len(req.filename)
>   length -= len(req.hlist.directory) - 1
>   length += len(req.path_info or '')
> 
>   baseurl = normalised_uri[:-length]
>   path = normalised_uri[len(baseurl):]
> 
>   req.proxyreq = apache.PROXYREQ_REVERSE
>   req.uri = 'http://localhost:8080' + path
>   req.filename = 'proxy:%s' % req.uri
>   req.handler = 'proxy-server'
> 
>   return apache.OK
> 
> All you then need to do is incorporate into this some code which uses
> req.headers_in to get to the cookie headers, strip them apart, change
> them as needed and then reassign them back into req.headers_in.
> When the "proxy-server" handler is run, it will take the headers from
> req.headers_in and use them when passing data through to backend.
> 
> You will need to have mod_python 3.3.0b for this to work though.
> 
> For more on enabling proxying in this way, see:
> 
>   http://issues.apache.org/jira/browse/MODPYTHON-141
> 
> and the mailing list discussion linked to it.

Forgot the second half of the problem. In the same file add:

  def mycookiefixup(filter):
    # interrogate req.headers_out, get out cookie headers, change
    # them and ressign it.
    filter.pass_on()

Then in the fixuphandler() have:

  req.register_output_filter("MYCOOKIEFIXUP", mycookiefixup)
  req.add_output_filter("MYCOOKIEFIXUP")

This will register the filter function as an output filter from within
the handler, allow you to change the cookies on the way back as
well.

Again, this requires mod_python 3.3.0b.

Graham


More information about the Mod_python mailing list