Re: [PATCH] support for environment variables in ProxyPassReverse
Carsten Gaebler <[email protected]> Wed, 18 Jun 2003 16:34:27 +0200
| Newsgroups | gmane.comp.apache.mod-proxy |
|---|---|
| Message-ID | <[email protected]> |
Graham Leggett wrote: > Carsten Gaebler wrote: [patch for 1.3.27 to support env vars in ProxyPassReverse] > Is it possible to create a patch for Apache v2.0? It's attached. I encountered one problem with Apache 1.3.27 and mod_ssl: you have to apply the mod_ssl patches (i.e. run configure) *before* the proxy patch. Otherwise the mod_ssl proxy patches don't get applied and any proxy rewrite rules using https fall back to http. Maybe this is something that should be taken care of. cg.
proxypassreverse-env-2.0.patch
(text/plain, 3.3 KB)
--- proxy_http.c.orig Tue Apr 15 18:36:16 2003
+++ proxy_http.c Wed Jun 18 11:35:07 2003
@@ -145,11 +145,75 @@
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;
+ apr_array_header_t* result_array;
+
+ result_array = apr_array_make(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, 0, r->server,
+ "proxy: missing closing '}' in ENV expression: %s",
+ s);
+ return s;
+ }
+
+ var = apr_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 = apr_table_get(r->notes, var);
+ /* second try the internal Apache env structure */
+ if (value == NULL) {
+ value = apr_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, 0, r->server,
+ "proxy: environment variable %s is empty",
+ var);
+ }
+ }
+ }
+
+ *((const char **) apr_array_push(result_array)) =
+ apr_pstrndup(r->pool, p, var_start - p - 6);
+
+ *((const char **) apr_array_push(result_array)) = value;
+
+ p = var_end + 1;
+ }
+
+ if ((p != NULL) && (*p != '\0')) {
+ *((const char **) apr_array_push(result_array)) = p;
+ }
+
+ return apr_array_pstrcat(r->pool, result_array, '\0');
+}
+
static const char *ap_proxy_location_reverse_map(request_rec *r, proxy_server_conf *conf, const char *url)
{
struct proxy_alias *ent;
int i, l1, l2;
char *u;
+ const char* fake;
+ const char* real;
/* XXX FIXME: Make sure this handled the ambiguous case of the :80
* after the hostname */
@@ -157,9 +221,11 @@
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 = apr_pstrcat(r->pool, ent[i].fake, &url[l2], NULL);
+ fake = expand_vars(r, ent[i].fake);
+ real = expand_vars(r, ent[i].real);
+ l2 = strlen(real);
+ if (l1 >= l2 && strncmp(real, url, l2) == 0) {
+ u = apr_pstrcat(r->pool, fake, &url[l2], NULL);
return ap_construct_url(r->pool, u, r);
}
}