Author: jfrederic.clere(a)jboss.com
Date: 2009-07-14 10:21:56 -0400 (Tue, 14 Jul 2009)
New Revision: 2495
Modified:
trunk/mod_cluster/native/mod_proxy_cluster/mod_proxy_cluster.c
Log:
Fix for MODCLUSTER-37.
Modified: trunk/mod_cluster/native/mod_proxy_cluster/mod_proxy_cluster.c
===================================================================
--- trunk/mod_cluster/native/mod_proxy_cluster/mod_proxy_cluster.c 2009-07-14 09:10:44 UTC
(rev 2494)
+++ trunk/mod_cluster/native/mod_proxy_cluster/mod_proxy_cluster.c 2009-07-14 14:21:56 UTC
(rev 2495)
@@ -1506,6 +1506,97 @@
return NULL;
}
+/* Copied from httpd mod_proxy */
+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_c(str, "${");
+ if (start == NULL) {
+ return str;
+ }
+ end = ap_strchr_c(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);
+ }
+}
+/* Copied from httpd mod_proxy */
+static int alias_match(const char *uri, const char *alias_fakename)
+{
+ const char *end_fakename = alias_fakename + strlen(alias_fakename);
+ const char *aliasp = alias_fakename, *urip = uri;
+ const char *end_uri = uri + strlen(uri);
+
+ while (aliasp < end_fakename && urip < end_uri) {
+ if (*aliasp == '/') {
+ /* any number of '/' in the alias matches any number in
+ * the supplied URI, but there must be at least one...
+ */
+ if (*urip != '/')
+ return 0;
+
+ while (*aliasp == '/')
+ ++aliasp;
+ while (*urip == '/')
+ ++urip;
+ }
+ else {
+ /* Other characters are compared literally */
+ if (*urip++ != *aliasp++)
+ return 0;
+ }
+ }
+
+ /* fixup badly encoded stuff (e.g. % as last character) */
+ if (aliasp > end_fakename) {
+ aliasp = end_fakename;
+ }
+ if (urip > end_uri) {
+ urip = end_uri;
+ }
+
+ /* We reach the end of the uri before the end of "alias_fakename"
+ * for example uri is "/" and alias_fakename "/examples"
+ */
+ if (urip == end_uri && aliasp!=end_fakename) {
+ return 0;
+ }
+
+ /* Check last alias path component matched all the way */
+ if (aliasp[-1] != '/' && *urip != '\0' && *urip !=
'/')
+ return 0;
+
+ /* Return number of characters from URI which matched (may be
+ * greater than length of alias, since we may have matched
+ * doubled slashes)
+ */
+
+ return urip - uri;
+}
+
/*
* See if we could map the request.
* first check is we have a balancer corresponding to the route.
@@ -1534,6 +1625,35 @@
balancer = get_context_host_balancer(r);
if (balancer) {
+ int i;
+ struct proxy_alias *ent = (struct proxy_alias *) conf->aliases->elts;
+ /* Check that we don't have a ProxyPassMatch ^(/.*\.gif)$ ! or something
similar */
+ for (i = 0; i < conf->aliases->nelts; i++) {
+ if (ent[i].real[0] == '!' && ent[i].real[1] == '\0')
{
+ ap_regmatch_t regm[AP_MAX_REG_MATCH];
+ if (ent[i].regex) {
+ if (!ap_regexec(ent[i].regex, r->uri, AP_MAX_REG_MATCH, regm, 0))
{
+ return DECLINED;
+ }
+ }
+ else {
+ const char *fake;
+ proxy_dir_conf *dconf = ap_get_module_config(r->per_dir_config,
+ &proxy_module);
+ if ((dconf->interpolate_env == 1)
+ && (ent[i].flags & PROXYPASS_INTERPOLATE)) {
+ fake = proxy_interpolate(r, ent[i].fake);
+ }
+ else {
+ fake = ent[i].fake;
+ }
+ if (alias_match(r->uri, fake)) {
+ return DECLINED;
+ }
+ }
+ }
+ }
+
r->filename = apr_pstrcat(r->pool, "proxy:balancer://",
balancer, r->unparsed_uri, NULL);
r->handler = "proxy-server";
r->proxyreq = PROXYREQ_REVERSE;
Show replies by date