You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by ni...@apache.org on 2006/07/13 21:00:26 UTC
svn commit: r421686 - in /httpd/httpd/trunk: CHANGES
docs/manual/mod/mod_proxy.xml modules/proxy/mod_proxy.c
modules/proxy/mod_proxy.h modules/proxy/proxy_util.c
Author: niq
Date: Thu Jul 13 12:00:26 2006
New Revision: 421686
URL: http://svn.apache.org/viewvc?rev=421686&view=rev
Log:
Support environment variable interpolation in reverse proxy configuration
Modified:
httpd/httpd/trunk/CHANGES
httpd/httpd/trunk/docs/manual/mod/mod_proxy.xml
httpd/httpd/trunk/modules/proxy/mod_proxy.c
httpd/httpd/trunk/modules/proxy/mod_proxy.h
httpd/httpd/trunk/modules/proxy/proxy_util.c
Modified: httpd/httpd/trunk/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/CHANGES?rev=421686&r1=421685&r2=421686&view=diff
==============================================================================
--- httpd/httpd/trunk/CHANGES [utf-8] (original)
+++ httpd/httpd/trunk/CHANGES [utf-8] Thu Jul 13 12:00:26 2006
@@ -2,6 +2,9 @@
Changes with Apache 2.3.0
[Remove entries to the current 2.0 and 2.2 section below, when backported]
+ *) mod_proxy: Support environment variable interpolation in reverse
+ proxying directives [Nick Kew]
+
*) mod_proxy_balancer: Workers can now be defined as "hot standby" which
will only be used if all other workers are unusable (eg: in
error or disabled). Also, the balancer-manager displays the election
Modified: httpd/httpd/trunk/docs/manual/mod/mod_proxy.xml
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/manual/mod/mod_proxy.xml?rev=421686&r1=421685&r2=421686&view=diff
==============================================================================
--- httpd/httpd/trunk/docs/manual/mod/mod_proxy.xml (original)
+++ httpd/httpd/trunk/docs/manual/mod/mod_proxy.xml Thu Jul 13 12:00:26 2006
@@ -1143,4 +1143,30 @@
</usage>
</directivesynopsis>
+<directivesynopsis>
+<name>ProxyPassInterpolateEnv</name>
+<description>Enable Environment Variable interpolation in Reverse Proxy configurations</description>
+<syntax>ProxyPassInterpolateEnv On|Off</syntax>
+<default>ProxyErrorOverride Off</default>
+<contextlist><context>server config</context>
+<context>virtual host</context>
+<context>Location</context>
+</contextlist>
+<compatibility>Available in trunk only</compatibility>
+
+<usage>
+ <p>This directive enables reverse proxies to be dynamically
+ configured using environment variables, which may be set by
+ another module such as <module>mod_rewrite</module>.
+ It affects the <directive>ProxyPass</directive>,
+ <directive>ProxyPassReverse</directive>,
+ <directive>ProxyPassReverseCookieDomain</directive>, and
+ <directive>ProxyPassReverseCookiePath</directive> directives,
+ and causes them to substitute the value of an environment
+ variable <code>varname</code> for the string <code>${varname}</code>
+ in configuration directives.</p>
+ <p>Keep this turned off (for server performance) unless you need it!</p>
+</usage>
+</directivesynopsis>
+
</modulesynopsis>
Modified: httpd/httpd/trunk/modules/proxy/mod_proxy.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/proxy/mod_proxy.c?rev=421686&r1=421685&r2=421686&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/proxy/mod_proxy.c (original)
+++ httpd/httpd/trunk/modules/proxy/mod_proxy.c Thu Jul 13 12:00:26 2006
@@ -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,
+ sizeof (struct proxy_alias));
+ struct proxy_alias *old = (struct proxy_alias *) hdr->elts;
+
+ for (i = 0; i < hdr->nelts; ++i) {
+ struct proxy_alias *newcopy = apr_array_push(ret);
+ newcopy->fake = proxy_interpolate(r, old[i].fake);
+ newcopy->real = proxy_interpolate(r, old[i].real);
+ }
+ return ret;
+}
static int proxy_trans(request_rec *r)
{
void *sconf = r->server->module_config;
@@ -417,6 +468,10 @@
(proxy_server_conf *) ap_get_module_config(sconf, &proxy_module);
int i, len;
struct proxy_alias *ent = (struct proxy_alias *) conf->aliases->elts;
+ proxy_dir_conf *dconf = ap_get_module_config(r->per_dir_config,
+ &proxy_module);
+ const char *fake;
+ const char *real;
if (r->proxyreq) {
/* someone has already set up the proxy, it was possibly ourselves
@@ -431,14 +486,22 @@
*/
for (i = 0; i < conf->aliases->nelts; i++) {
- len = alias_match(r->uri, ent[i].fake);
+ if (dconf->interpolate_env == 1) {
+ fake = proxy_interpolate(r, ent[i].fake);
+ real = proxy_interpolate(r, ent[i].real);
+ }
+ else {
+ fake = ent[i].fake;
+ real = ent[i].real;
+ }
+ len = alias_match(r->uri, fake);
if (len > 0) {
- if ((ent[i].real[0] == '!') && (ent[i].real[1] == 0)) {
+ if ((real[0] == '!') && (real[1] == 0)) {
return DECLINED;
}
- r->filename = apr_pstrcat(r->pool, "proxy:", ent[i].real,
+ r->filename = apr_pstrcat(r->pool, "proxy:", real,
r->uri + len, NULL);
r->handler = "proxy-server";
r->proxyreq = PROXYREQ_REVERSE;
@@ -506,6 +569,7 @@
return OK;
}
+
/* -------------------------------------------------------------- */
/* Fixup the filename */
@@ -516,6 +580,8 @@
{
char *url, *p;
int access_status;
+ proxy_dir_conf *dconf = ap_get_module_config(r->per_dir_config,
+ &proxy_module);
if (!r->proxyreq || !r->filename || strncmp(r->filename, "proxy:", 6) != 0)
return DECLINED;
@@ -523,6 +589,17 @@
/* XXX: Shouldn't we try this before we run the proxy_walk? */
url = &r->filename[6];
+ if ((dconf->interpolate_env == 1) && (r->proxyreq == PROXYREQ_REVERSE)) {
+ /* create per-request copy of reverse proxy conf,
+ * and interpolate vars in it
+ */
+ proxy_req_conf *rconf = apr_palloc(r->pool, sizeof(proxy_req_conf));
+ ap_set_module_config(r->request_config, &proxy_module, rconf);
+ rconf->raliases = proxy_vars(r, dconf->raliases);
+ rconf->cookie_paths = proxy_vars(r, dconf->cookie_paths);
+ rconf->cookie_domains = proxy_vars(r, dconf->cookie_domains);
+ }
+
/* canonicalise each specific scheme */
if ((access_status = proxy_run_canon_handler(r, url))) {
return access_status;
@@ -905,6 +982,7 @@
new->cookie_domains = apr_array_make(p, 10, sizeof(struct proxy_alias));
new->cookie_path_str = apr_strmatch_precompile(p, "path=", 0);
new->cookie_domain_str = apr_strmatch_precompile(p, "domain=", 0);
+ new->interpolate_env = -1; /* unset */
return (void *) new;
}
@@ -927,6 +1005,8 @@
= apr_array_append(p, base->cookie_domains, add->cookie_domains);
new->cookie_path_str = base->cookie_path_str;
new->cookie_domain_str = base->cookie_domain_str;
+ new->interpolate_env = (add->interpolate_env == -1) ? base->interpolate_env
+ : add->interpolate_env;
return new;
}
@@ -1052,7 +1132,7 @@
arr = apr_table_elts(params);
elts = (const apr_table_entry_t *)arr->elts;
- /* Distinguish the balancer from woker */
+ /* Distinguish the balancer from worker */
if (strncasecmp(r, "balancer:", 9) == 0) {
proxy_balancer *balancer = ap_proxy_get_balancer(cmd->pool, conf, r);
if (!balancer) {
@@ -1672,6 +1752,9 @@
"a scheme, partial URL or '*' and a proxy server"),
AP_INIT_TAKE2("ProxyRemoteMatch", add_proxy_regex, NULL, RSRC_CONF,
"a regex pattern and a proxy server"),
+ AP_INIT_FLAG("ProxyPassInterpolateEnv", ap_set_flag_slot,
+ (void*)APR_OFFSETOF(proxy_dir_conf, interpolate_env),
+ RSRC_CONF|ACCESS_CONF, "Interpolate Env Vars in reverse Proxy") ,
AP_INIT_RAW_ARGS("ProxyPass", add_pass, NULL, RSRC_CONF|ACCESS_CONF,
"a virtual path and a URL"),
AP_INIT_TAKE12("ProxyPassReverse", add_pass_reverse, NULL, RSRC_CONF|ACCESS_CONF,
@@ -1913,7 +1996,6 @@
proxy_lb_workers = 0;
return OK;
}
-
static void register_hooks(apr_pool_t *p)
{
/* fixup before mod_rewrite, so that the proxied url will not
Modified: httpd/httpd/trunk/modules/proxy/mod_proxy.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/proxy/mod_proxy.h?rev=421686&r1=421685&r2=421686&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/proxy/mod_proxy.h (original)
+++ httpd/httpd/trunk/modules/proxy/mod_proxy.h Thu Jul 13 12:00:26 2006
@@ -206,7 +206,17 @@
apr_array_header_t* cookie_domains;
const apr_strmatch_pattern* cookie_path_str;
const apr_strmatch_pattern* cookie_domain_str;
+ int interpolate_env;
} proxy_dir_conf;
+
+/* if we interpolate env vars per-request, we'll need a per-request
+ * copy of the reverse proxy config
+ */
+typedef struct {
+ apr_array_header_t *raliases;
+ apr_array_header_t* cookie_paths;
+ apr_array_header_t* cookie_domains;
+} proxy_req_conf;
typedef struct {
conn_rec *connection;
Modified: httpd/httpd/trunk/modules/proxy/proxy_util.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/proxy/proxy_util.c?rev=421686&r1=421685&r2=421686&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/proxy/proxy_util.c (original)
+++ httpd/httpd/trunk/modules/proxy/proxy_util.c Thu Jul 13 12:00:26 2006
@@ -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) {
Re: svn commit: r421686 - in /httpd/httpd/trunk: CHANGES docs/manual/mod/mod_proxy.xml modules/proxy/mod_proxy.c modules/proxy/mod_proxy.h modules/proxy/proxy_util.c
Posted by Garrett Rooney <ro...@electricjellyfish.net>.
On 7/14/06, Nick Kew <ni...@webthing.com> wrote:
> On Friday 14 July 2006 14:16, Joe Orton wrote:
>
> > This introduced compiler warnings:
> >
> > cc1: warnings being treated as errors
> > mod_proxy.c: In function `proxy_interpolate':
> > mod_proxy.c:427: warning: passing arg 1 of `ap_strstr' discards qualifiers
> > from pointer target type mod_proxy.c:431: warning: passing arg 1 of
> > `ap_strchr' discards qualifiers from pointer target type make[4]: ***
> > [mod_proxy.slo] Error 1
>
> Ugh.
>
> It's being used in those lines with "const char*" arguments.
> That's what the <string.h> strstr and strchr take. Depending
> on the AP_DEBUG setting, ap_strstr may be #defined to strstr
> and ap_strchr to strchr.
>
> So the fact that that *can* generate those warnings looks like
> an over-engineered and inconsistent httpd.h.
You can avoid those warnings by using ap_strchr_c.
-garrett
Re: svn commit: r421686 - in /httpd/httpd/trunk: CHANGES docs/manual/mod/mod_proxy.xml modules/proxy/mod_proxy.c modules/proxy/mod_proxy.h modules/proxy/proxy_util.c
Posted by Joe Orton <jo...@redhat.com>.
On Fri, Jul 14, 2006 at 03:35:53PM +0100, Nick Kew wrote:
> On Friday 14 July 2006 14:16, Joe Orton wrote:
>
> > This introduced compiler warnings:
> >
> > cc1: warnings being treated as errors
> > mod_proxy.c: In function `proxy_interpolate':
> > mod_proxy.c:427: warning: passing arg 1 of `ap_strstr' discards qualifiers
> > from pointer target type mod_proxy.c:431: warning: passing arg 1 of
> > `ap_strchr' discards qualifiers from pointer target type make[4]: ***
> > [mod_proxy.slo] Error 1
>
> Ugh.
>
> It's being used in those lines with "const char*" arguments.
> That's what the <string.h> strstr and strchr take. Depending
> on the AP_DEBUG setting, ap_strstr may be #defined to strstr
> and ap_strchr to strchr.
Sorry, I always assume everyone knows about the magic strchr tricks,
should have mentioned this. This is a type-safety feature which catches
places where traditional strchr() throws away const qualifiers - use
ap_strchr_c() if passing in a const string.
Re: svn commit: r421686 - in /httpd/httpd/trunk: CHANGES docs/manual/mod/mod_proxy.xml modules/proxy/mod_proxy.c modules/proxy/mod_proxy.h modules/proxy/proxy_util.c
Posted by Nick Kew <ni...@webthing.com>.
On Friday 14 July 2006 14:16, Joe Orton wrote:
> This introduced compiler warnings:
>
> cc1: warnings being treated as errors
> mod_proxy.c: In function `proxy_interpolate':
> mod_proxy.c:427: warning: passing arg 1 of `ap_strstr' discards qualifiers
> from pointer target type mod_proxy.c:431: warning: passing arg 1 of
> `ap_strchr' discards qualifiers from pointer target type make[4]: ***
> [mod_proxy.slo] Error 1
Ugh.
It's being used in those lines with "const char*" arguments.
That's what the <string.h> strstr and strchr take. Depending
on the AP_DEBUG setting, ap_strstr may be #defined to strstr
and ap_strchr to strchr.
So the fact that that *can* generate those warnings looks like
an over-engineered and inconsistent httpd.h.
--
Nick Kew
Re: svn commit: r421686 - in /httpd/httpd/trunk: CHANGES docs/manual/mod/mod_proxy.xml modules/proxy/mod_proxy.c modules/proxy/mod_proxy.h modules/proxy/proxy_util.c
Posted by Joe Orton <jo...@redhat.com>.
On Thu, Jul 13, 2006 at 07:00:26PM -0000, niq@apache.org wrote:
> Author: niq
> Date: Thu Jul 13 12:00:26 2006
> New Revision: 421686
>
> URL: http://svn.apache.org/viewvc?rev=421686&view=rev
> Log:
> Support environment variable interpolation in reverse proxy configuration
This introduced compiler warnings:
cc1: warnings being treated as errors
mod_proxy.c: In function `proxy_interpolate':
mod_proxy.c:427: warning: passing arg 1 of `ap_strstr' discards qualifiers from pointer target type
mod_proxy.c:431: warning: passing arg 1 of `ap_strchr' discards qualifiers from pointer target type
make[4]: *** [mod_proxy.slo] Error 1
Re: svn commit: r421686 - in /httpd/httpd/trunk: CHANGES docs/manual/mod/mod_proxy.xml modules/proxy/mod_proxy.c modules/proxy/mod_proxy.h modules/proxy/proxy_util.c
Posted by Nick Kew <ni...@webthing.com>.
On Thursday 13 July 2006 22:57, Robert Ionescu wrote:
> niq@apache.org wrote:
> > Author: niq
> > Date: Thu Jul 13 12:00:26 2006
> > New Revision: 421686
> > Modified: httpd/httpd/trunk/docs/manual/mod/mod_proxy.xml
> > +<default>ProxyErrorOverride Off</default>
>
> Just a trivial think: Shouldn't that be
> ProxyPassInterpolateEnv Off?
Urgh. Comes of cut&pasting the template for it:-(
Thanks:-)
--
Nick Kew
Re: svn commit: r421686 - in /httpd/httpd/trunk: CHANGES docs/manual/mod/mod_proxy.xml
modules/proxy/mod_proxy.c modules/proxy/mod_proxy.h modules/proxy/proxy_util.c
Posted by Robert Ionescu <ro...@googlemail.com>.
niq@apache.org wrote:
> Author: niq
> Date: Thu Jul 13 12:00:26 2006
> New Revision: 421686
> Modified: httpd/httpd/trunk/docs/manual/mod/mod_proxy.xml
> +<default>ProxyErrorOverride Off</default>
Just a trivial think: Shouldn't that be
ProxyPassInterpolateEnv Off?
--
Robert