From: Jim Jagielski Date: Thu, 21 May 2009 17:30:07 +0000 (+0000) Subject: Merge r771587, r771610 from trunk: X-Git-Tag: 2.2.12~108 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=08af7c0241f40bd503817fe5855884f496d4ae58;p=thirdparty%2Fapache%2Fhttpd.git Merge r771587, r771610 from trunk: As mentioned inline in comments, correctly handle more sophisticated transformations which currently fail for balancer://foo targets, but work just fine with other ProxyReverse targets. The balancer comparison is a bit trickier. Given the context BalancerMember balancer://alias http://example.com/foo ProxyPassReverse /bash balancer://alias/bar translate url http://example.com/foo/bar/that to /bash/that E.g. there may be several different url-suffixes (1st order) of any particular BalancerMember set e.g. /app1, /app1 and /appbeta while there may be additional suffixes associated with the actual ProxyPassReverse directive. Neither were properly reversed, now both should be properly handled. One *critical* assumption; BalancerMember balancer://alias/foo http://example.com/bar should be documented as a meaningless construct, since one cannot have two members, balancer://alias/foo and balancer://alias/bar, and the balancer member structures discard this path. Note one more existing error case as an XXX comment due to invalid uri comparisons. * Silence compiler warning. Reviewed/backported by: jim git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.2.x@777191 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c index d3ec39aba45..a565c0d5992 100644 --- a/modules/proxy/proxy_util.c +++ b/modules/proxy/proxy_util.c @@ -1049,6 +1049,7 @@ PROXY_DECLARE(const char *) ap_proxy_location_reverse_map(request_rec *r, /* * XXX FIXME: Make sure this handled the ambiguous case of the : * after the hostname + * XXX FIXME: Ensure the /uri component is a case sensitive match */ if (r->proxyreq != PROXYREQ_REVERSE) { return url; @@ -1066,56 +1067,57 @@ PROXY_DECLARE(const char *) ap_proxy_location_reverse_map(request_rec *r, proxy_server_conf *sconf = (proxy_server_conf *) ap_get_module_config(r->server->module_config, &proxy_module); proxy_balancer *balancer; - const char *real; - real = ent[i].real; - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "ppr: real: %s", real); + const char *real = ent[i].real; /* * First check if mapping against a balancer and see * if we have such a entity. If so, then we need to * find the particulars of the actual worker which may * or may not be the right one... basically, we need * to find which member actually handled this request. - * - * TODO: Recover the path from real and use that - * for more exact matching */ - if ((strncasecmp(real, "balancer:", 9) == 0) && + if ((strncasecmp(real, "balancer://", 11) == 0) && (balancer = ap_proxy_get_balancer(r->pool, sconf, real))) { - int n; - proxy_worker *worker; - worker = (proxy_worker *)balancer->workers->elts; - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "ppr: checking balancer: %s", - balancer->name); + int n, l3 = 0; + proxy_worker *worker = (proxy_worker *)balancer->workers->elts; + const char *urlpart = ap_strchr_c(real + 11, '/'); + if (urlpart) { + if (!urlpart[1]) + urlpart = NULL; + else + l3 = strlen(urlpart); + } + /* The balancer comparison is a bit trickier. Given the context + * BalancerMember balancer://alias http://example.com/foo + * ProxyPassReverse /bash balancer://alias/bar + * translate url http://example.com/foo/bar/that to /bash/that + */ for (n = 0; n < balancer->workers->nelts; n++) { - if (worker->port) { - u = apr_psprintf(r->pool, "%s://%s:%d/", worker->scheme, - worker->hostname, worker->port); + l2 = strlen(worker->name); + if (urlpart) { + /* urlpart (l3) assuredly starts with its own '/' */ + if (worker->name[l2 - 1] == '/') + --l2; + if (l1 >= l2 + l3 + && strncasecmp(worker->name, url, l2) == 0 + && strncmp(urlpart, url + l2, l3) == 0) { + u = apr_pstrcat(r->pool, ent[i].fake, &url[l2 + l3], + NULL); + return ap_construct_url(r->pool, u, r); + } } - else { - u = apr_psprintf(r->pool, "%s://%s/", worker->scheme, - worker->hostname); - } - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "ppr: matching member (%s) and URL (%s)", - u, url); - - l2 = strlen(u); - if (l1 >= l2 && strncasecmp(u, url, l2) == 0) { + else if (l1 >= l2 && strncasecmp(worker->name, url, l2) == 0) { u = apr_pstrcat(r->pool, ent[i].fake, &url[l2], NULL); - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "ppr: matched member (%s)", u); return ap_construct_url(r->pool, u, r); } worker++; } } - - l2 = strlen(real); - if (l1 >= l2 && strncasecmp(real, url, l2) == 0) { - u = apr_pstrcat(r->pool, ent[i].fake, &url[l2], NULL); - return ap_construct_url(r->pool, u, r); + else { + l2 = strlen(real); + if (l1 >= l2 && strncasecmp(real, url, l2) == 0) { + u = apr_pstrcat(r->pool, ent[i].fake, &url[l2], NULL); + return ap_construct_url(r->pool, u, r); + } } }