This is a topic that's been discussed occasionally, though not
(AFAIR) on this list.
A few weeks back, I implemented a patch to support interpolating
per-request environment variables in reverse proxying directives.
Note that this goes beyond what mod_rewrite already supports,
because it also interpolates response headers per
ProxyPassReverse and family.
Do we want this in /trunk/ ?
--
Nick Kew
Index: proxy_util.c
===
--- proxy_util.c (revision 421119)
+++ proxy_util.c (working copy)
@@ -1015,6 +1015,7 @@
PROXY_DECLARE(const char *) ap_proxy_location_reverse_map(request_rec *r,
proxy_dir_conf *conf, const char *url)
{
+proxy_req_conf *rconf;
struct proxy_alias *ent;
int i, l1, l2;
char *u;
@@ -1023,9 +1024,18 @@
* XXX FIXME: Make sure this handled the ambiguous case of the :PORT
* after the hostname
*/
+if (r-proxyreq != PROXYREQ_REVERSE) {
+return url;
+}
l1 = strlen(url);
-ent = (struct proxy_alias *)conf-raliases-elts;
+if (conf-interpolate_env == 1) {
+rconf = ap_get_module_config(r-request_config, proxy_module);
+ent = (struct proxy_alias *)rconf-raliases-elts;
+}
+else {
+ent = (struct proxy_alias *)conf-raliases-elts;
+}
for (i = 0; i conf-raliases-nelts; i++) {
l2 = strlen(ent[i].real);
if (l1 = l2 strncasecmp(ent[i].real, url, l2) == 0) {
@@ -1047,6 +1057,8 @@
PROXY_DECLARE(const char *) ap_proxy_cookie_reverse_map(request_rec *r,
proxy_dir_conf *conf, const char *str)
{
+proxy_req_conf *rconf = ap_get_module_config(r-request_config,
+ proxy_module);
struct proxy_alias *ent;
size_t len = strlen(str);
const char *newpath = NULL;
@@ -1061,6 +1073,10 @@
int pdiff = 0;
char *ret;
+if (r-proxyreq != PROXYREQ_REVERSE) {
+return str;
+}
+
/*
* Find the match and replacement, but save replacing until we've done
* both path and domain so we know the new strlen
@@ -1071,7 +1087,12 @@
pathe = ap_strchr_c(pathp, ';');
l1 = pathe ? (pathe - pathp) : strlen(pathp);
pathe = pathp + l1 ;
-ent = (struct proxy_alias *)conf-cookie_paths-elts;
+if (conf-interpolate_env == 1) {
+ent = (struct proxy_alias *)rconf-cookie_paths-elts;
+}
+else {
+ent = (struct proxy_alias *)conf-cookie_paths-elts;
+}
for (i = 0; i conf-cookie_paths-nelts; i++) {
l2 = strlen(ent[i].fake);
if (l1 = l2 strncmp(ent[i].fake, pathp, l2) == 0) {
@@ -1088,7 +1109,12 @@
domaine = ap_strchr_c(domainp, ';');
l1 = domaine ? (domaine - domainp) : strlen(domainp);
domaine = domainp + l1;
-ent = (struct proxy_alias *)conf-cookie_domains-elts;
+if (conf-interpolate_env == 1) {
+ent = (struct proxy_alias *)rconf-cookie_domains-elts;
+}
+else {
+ent = (struct proxy_alias *)conf-cookie_domains-elts;
+}
for (i = 0; i conf-cookie_domains-nelts; i++) {
l2 = strlen(ent[i].fake);
if (l1 = l2 strncasecmp(ent[i].fake, domainp, l2) == 0) {
Index: mod_proxy.c
===
--- mod_proxy.c (revision 421119)
+++ mod_proxy.c (working copy)
@@ -410,6 +410,57 @@
return DECLINED;
}
+static const char *proxy_interpolate(request_rec *r, const char *str)
+{
+/* Interpolate an env str in a configuration string
+ * Syntax ${var} -- value_of(var)
+ * Method: replace one var, and recurse on remainder of string
+ * Nothing clever here, and crap like nested vars may do silly things
+ * but we'll at least avoid sending the unwary into a loop
+ */
+const char *start;
+const char *end;
+const char *var;
+const char *val;
+const char *firstpart;
+
+start = ap_strstr(str, ${);
+if (start == NULL) {
+return str;
+}
+end = ap_strchr(start+2, '}');
+if (end == NULL) {
+return str;
+}
+/* OK, this is syntax we want to interpolate. Is there such a var ? */
+var = apr_pstrndup(r-pool, start+2, end-(start+2));
+val = apr_table_get(r-subprocess_env, var);
+firstpart = apr_pstrndup(r-pool, str, (start-str));
+
+if (val == NULL) {
+return apr_pstrcat(r-pool, firstpart,
+ proxy_interpolate(r, end+1), NULL);
+}
+else {
+return apr_pstrcat(r-pool, firstpart, val,
+ proxy_interpolate(r, end+1), NULL);
+}
+}
+static apr_array_header_t *proxy_vars(request_rec *r,
+ apr_array_header_t *hdr)
+{
+int i;
+apr_array_header_t *ret = apr_array_make(r-pool, hdr-nelts,
+