Passing information from Apache to CherryPy

8 views
Skip to first unread message

Paul Moore

unread,
Jan 23, 2005, 9:16:29 AM1/23/05
to cherryp...@googlegroups.com
This is probably more of an Apache question, but I'm hoping someone can
help...

Is it possible to pass information from Apache's mod_rewrite, to be
picked up by a CherryPy application running behind Apache? I've tried
using the 'E' (set environment variable) option, but that doesn't work
- presumably because the CherryPy application is a ong-running process,
and not started by Apache.

[Longer explanation follows, for people who want to know *why* I want
this...]

The reason I want to do this is that I'm trying to hide a CherryPy
application behind Apache, like the recipe on the website. However, I
don't have the application at the "root" of the site, so my RewriteRule
looks something like this:

RewriteRule ^/cp/(.*) http://127.0.0.1:8080/$1 [P]

Now, this works fine, as long as all URLs within my application are
relative. When I want an absolute URL (for example, to a login page,
which is always at "/login") I have to make a choice - if I code it as
"/cp/login" it works fine behind Apache, but not when used standalone
(which I prefer to do for testing). But if I use "/login", the code
fails from behind Apache.

This is *almost* what BaseUrlFilter handles, but not quite, as that
affects the host part of the URL. I was hoping to do something like
[E=BASEPATH:/cp/] in the rewrite rule, so that I could set request.base
based on this. But as I say, the CherryPy application doesn't pick up
environment variables like this. Hence my question - is there any other
way of getting Apache to feed something into the request that CherryPy
can pick up?

Thanks,
Paul.

Remi Delon

unread,
Jan 23, 2005, 9:42:45 AM1/23/05
to cherryp...@googlegroups.com
Well, I don't know if you can get Apache to pass random variables to
you, but it sounds to me like your problem *can* be solved with
BaseUrlFilter ... Why don't you just put the baseUrl in the config file
and have BaseUrlFilter get the baseUrl from that config file ?
Then you just put a different value, depending on whether this is your
test setup or your production environment.
Doesn't that do what you want ?

Remi.

Paul Moore

unread,
Jan 23, 2005, 10:06:26 AM1/23/05
to cherryp...@googlegroups.com
> Why don't you just put the baseUrl in the config file
> and have BaseUrlFilter get the baseUrl from that config file ?

Can it go in the config file? That would probably do it - I didn't like
the idea of having to change code when distributing, but a config file
is different. I'll probably still forget at some stage, and only find
out when someone complains (most URLs are relative, so the problem will
be rare) - that's why I was looking for a totally automated answer -
but a 1-line config change is close enough!

Can you give an example of how I'd put something like this in the
config file? I've searched for sample code, but can't find any...
[Once I get this working, I'll add it to the Wiki]

Thanks,
Paul.

Paul Moore

unread,
Jan 23, 2005, 11:44:49 AM1/23/05
to cherryp...@googlegroups.com
[Later]

Looks like I need to do cpg.parsedConfigFile.get(section, keyname) - is
that right? It's not compatible with using a dictionary
(configMap={...}) for quick, throwaway testing.

Then again, there was a big "ConfigParser shootout" thread not long ago
on python-list and python-dev, so it's clear that no-one has come up
with a perfect answer yet!

Paul.

PS Part of me would still prefer an Apache-based solution, so that I
can keep the base URL stored in only one place. Ah, well, another item
for my "things to do when I have infinite time to solve all the world's
problems" list :-)

Paul Moore

unread,
Jan 24, 2005, 9:29:51 AM1/24/05
to cherryp...@googlegroups.com
> PS Part of me would still prefer an Apache-based solution

The following works, for Apache 2:

# CherryPy Demo App
<Location /cp>
ProxyPass http://localhost:8080
ProxyPassReverse http://localhost:8080
RequestHeader set CP-Location /cp
</Location>

Now, I can get the location in my application using

cpg.requesr.headerMap.get('Cp-Location', '')

I have to build absolute URLs as

def build_url(url):
if url.startswith('/'):
location = cpg.request.headerMap.get("Cp-Location", "")
return location + url
return url

This is because urlparse.urljoin doesn't combine the path from the base
URL and the path of an absolute URL. This is correct behaviour, as URL
joining is defined in terms of the "parts" of the URL, but it means you
need a "roll your own" way of building absolute URLs. The above is
pretty simple, though...

Paul.

Reply all
Reply to author
Forward
0 new messages