[PATCH] support for environment variables in ProxyPassReverse
Carsten Gaebler <[email protected]> Mon, 16 Jun 2003 18:14:34 +0200
| Newsgroups | gmane.comp.apache.mod-proxy |
|---|---|
| Message-ID | <[email protected]> |
Hi there,
the book "Linux Server Hacks" by Rob Flickenger contains an example on
how to use environment variables with the ProxyPassReverse directive. Of
course it doesn't work because it's not implemented. :-) But since it's
very useful for the proxy I'm maintaining and would also strip down this
ugly reverse mapping list in the URL Rewriting Guide, I wrote a patch
for Apache 1.3.27.
Basically it allows you to setup something like this:
RewriteRule ^/(.*)/ http://$1/ [P,E=WHERETO:$1]
ProxyPassReverse /%{ENV:WHERETO}/ http://%{ENV:WHERETO}/
The logical consequence would be for ProxyPass to support that, too. But
since this directive is handled in a different file and I don't know a
centralized place to put the expand_vars() function, I didn't do that.
Feel free to send comments.
Regards
Carsten.
proxypassreverse-env.patch
(text/plain, 3.7 KB)
--- src/modules/proxy/proxy_http.c.orig Tue Sep 3 09:12:46 2002
+++ src/modules/proxy/proxy_http.c Mon Jun 16 14:36:49 2003
@@ -114,6 +114,68 @@
return OK;
}
+/* Substitute %{ENV:VARIABLE} with the value of the environment variable */
+/* VARIABLE (enhancement of the ProxyPassReverse directive). */
+/* I found this "feature" in the first edition of Rob Flickenger's */
+/* Linux Server Hacks book (O'Reilly) but it wasn't actually supported */
+/* by Apache, so I implemented it. :-) */
+static const char *expand_vars(request_rec *r, const char* s)
+{
+ const char* p;
+ char* var_start;
+ char* var_end;
+ char* var;
+ const char* value;
+ array_header* result_array;
+
+ result_array = ap_make_array(r->pool, 4, sizeof(char *));
+ p = s;
+
+ while ((var_start = strstr(p, "%{ENV:")) != NULL) {
+ var_start += 6;
+
+ if ((var_end = strchr(var_start, '}')) == NULL) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, r->server,
+ "proxy: missing closing '}' in ENV expression: %s",
+ s);
+ return s;
+ }
+
+ var = ap_pstrndup(r->pool, var_start, var_end - var_start);
+
+ /* get env-variable from the parent Apache process */
+ /* first try the internal Apache notes structure */
+ value = ap_table_get(r->notes, var);
+ /* second try the internal Apache env structure */
+ if (value == NULL) {
+ value = ap_table_get(r->subprocess_env, var);
+ /* third try the external OS env */
+ if (value == NULL) {
+ value = getenv(var);
+ if (value == NULL) {
+ value = "";
+ ap_log_error(APLOG_MARK, APLOG_WARNING, r->server,
+ "proxy: environment variable %s is empty",
+ var);
+ }
+ }
+ }
+
+ *((const char **) ap_push_array(result_array)) =
+ ap_pstrndup(r->pool, p, var_start - p - 6);
+
+ *((const char **) ap_push_array(result_array)) = value;
+
+ p = var_end + 1;
+ }
+
+ if ((p != NULL) && (*p != '\0')) {
+ *((const char **) ap_push_array(result_array)) = p;
+ }
+
+ return ap_array_pstrcat(r->pool, result_array, '\0');
+}
+
/* handle the conversion of URLs in the ProxyPassReverse function */
static const char *proxy_location_reverse_map(request_rec *r, const char *url)
{
@@ -122,15 +184,25 @@
struct proxy_alias *ent;
int i, l1, l2;
char *u;
+ const char* fake;
+ const char* real;
sconf = r->server->module_config;
conf = (proxy_server_conf *)ap_get_module_config(sconf, &proxy_module);
l1 = strlen(url);
ent = (struct proxy_alias *)conf->raliases->elts;
for (i = 0; i < conf->raliases->nelts; i++) {
- l2 = strlen(ent[i].real);
- if (l1 >= l2 && strncmp(ent[i].real, url, l2) == 0) {
- u = ap_pstrcat(r->pool, ent[i].fake, &url[l2], NULL);
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, r->server,
+ "proxy: pre_expand_vars: real: %s, fake: %s",
+ ent[i].real, ent[i].fake);
+ fake = expand_vars(r, ent[i].fake);
+ real = expand_vars(r, ent[i].real);
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, r->server,
+ "proxy: post_expand_vars: real: %s, fake: %s",
+ real, fake);
+ l2 = strlen(real);
+ if (l1 >= l2 && strncmp(real, url, l2) == 0) {
+ u = ap_pstrcat(r->pool, fake, &url[l2], NULL);
return ap_construct_url(r->pool, u, r);
}
}