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.
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.
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 :-)
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.