From: Jim Jagielski Date: Tue, 11 Oct 2005 21:40:32 +0000 (+0000) Subject: mod_proxy_balancer: BalancerManager and proxies correctly handle X-Git-Tag: 2.3.0~2887 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=be32e160ac0fdfa80b9b1d9227ade0731b096681;p=thirdparty%2Fapache%2Fhttpd.git mod_proxy_balancer: BalancerManager and proxies correctly handle member workers with paths. PR36816. [Ruediger Pluem, Jim Jagielski] git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@312963 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 97f84618024..0b42b9e6a6a 100644 --- a/CHANGES +++ b/CHANGES @@ -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_balancer: BalancerManager and proxies correctly handle + member workers with paths. PR36816. [Ruediger Pluem, Jim Jagielski] + *) mod_cgid: Refuse to work on Solaris 10 due to OS bugs. PR 34264. [Justin Erenkrantz] diff --git a/modules/proxy/mod_proxy_balancer.c b/modules/proxy/mod_proxy_balancer.c index 6c23a3a98fb..0862854b7b6 100644 --- a/modules/proxy/mod_proxy_balancer.c +++ b/modules/proxy/mod_proxy_balancer.c @@ -477,8 +477,12 @@ static int balancer_handler(request_rec *r) *val++ = '\0'; if ((tok = ap_strchr(val, '&'))) *tok++ = '\0'; + /* + * Special case: workers are allowed path information + */ if ((access_status = ap_unescape_url(val)) != OK) - return access_status; + if (strcmp(args, "w") || (access_status != HTTP_NOT_FOUND)) + return access_status; apr_table_setn(params, args, val); args = tok; } @@ -490,13 +494,9 @@ static int balancer_handler(request_rec *r) bsel = ap_proxy_get_balancer(r->pool, conf, apr_pstrcat(r->pool, "balancer://", name, NULL)); if ((name = apr_table_get(params, "w"))) { - const char *sc = apr_table_get(params, "s"); - char *asname = NULL; - proxy_worker *ws = NULL; - if (sc) { - asname = apr_pstrcat(r->pool, sc, "://", name, NULL); - ws = ap_proxy_get_worker(r->pool, conf, asname); - } + proxy_worker *ws; + + ws = ap_proxy_get_worker(r->pool, conf, name); if (ws) { worker = (proxy_worker *)bsel->workers->elts; for (n = 0; n < bsel->workers->nelts; n++) { @@ -613,7 +613,7 @@ static int balancer_handler(request_rec *r) balancer->name + sizeof("balancer://") - 1, "\">", NULL); ap_rvputs(r, balancer->name, "\n\n", NULL); - ap_rputs("\n\n" + ap_rputs("\n\n
" "" "\n", r); ap_rvputs(r, "\n", balancer->max_attempts); ap_rprintf(r, "\n", balancer->lbmethod->name); - ap_rputs("
StickySessionTimeoutFailoverAttemptsMethod
", balancer->sticky, NULL); @@ -622,9 +622,9 @@ static int balancer_handler(request_rec *r) ap_rprintf(r, "%d%s
\n", r); - ap_rputs("\n\n" - "" + ap_rputs("
SchemeHost
\n
", r); + ap_rputs("\n\n" + "" "" "" "\n", r); @@ -632,12 +632,11 @@ static int balancer_handler(request_rec *r) worker = (proxy_worker *)balancer->workers->elts; for (n = 0; n < balancer->workers->nelts; n++) { - ap_rvputs(r, "\n\n", NULL); + ap_rvputs(r, worker->name, "", NULL); ap_rvputs(r, "\n", r); ap_rputs("\n", r); - ap_rvputs(r, "
Worker URLRouteRouteRedirFactorStatus
", worker->scheme, "", NULL); - ap_rvputs(r, "uri, "?b=", - balancer->name + sizeof("balancer://") - 1, - "&s=", worker->scheme, "&w=", worker->hostname, + ap_rvputs(r, "
uri, "?b=", + balancer->name + sizeof("balancer://") - 1, "&w=", + ap_escape_uri(r->pool, worker->name), "\">", NULL); - ap_rvputs(r, worker->hostname, "", worker->s->route, NULL); ap_rvputs(r, "", worker->s->redirect, NULL); ap_rprintf(r, "%d", worker->s->lbfactor); @@ -678,10 +677,8 @@ static int balancer_handler(request_rec *r) ap_rputs(" checked", r); ap_rputs(">
\nscheme, "\">\n", NULL); - ap_rvputs(r, "hostname, "\">\n", NULL); + ap_rvputs(r, "\npool, wsel->name), "\">\n", NULL); ap_rvputs(r, "name + sizeof("balancer://") - 1, "\">\n\n", NULL); diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c index 950da3eb649..6aa6f288420 100644 --- a/modules/proxy/proxy_util.c +++ b/modules/proxy/proxy_util.c @@ -1212,24 +1212,34 @@ PROXY_DECLARE(proxy_worker *) ap_proxy_get_worker(apr_pool_t *p, const char *url) { proxy_worker *worker; - char *c, *uri = apr_pstrdup(p, url); + proxy_worker *max_worker = NULL; + int max_match = 0; + int url_length; + int worker_name_length; + char *c; int i; - c = strchr(uri, ':'); + c = strchr(url, ':'); if (c == NULL || c[1] != '/' || c[2] != '/' || c[3] == '\0') return NULL; - /* remove path from uri */ - if ((c = strchr(c + 3, '/'))) - *c = '\0'; + url_length = strlen(url); worker = (proxy_worker *)conf->workers->elts; + + /* + * Do a "longest match" on the worker name to find the worker that + * fits best to the URL. + */ for (i = 0; i < conf->workers->nelts; i++) { - if (strcasecmp(worker->name, uri) == 0) { - return worker; + if (((worker_name_length = strlen(worker->name)) <= url_length) + && (strncasecmp(url, worker->name, worker_name_length) == 0) + && (worker_name_length > max_match)) { + max_worker = worker; + max_match = worker_name_length; } worker++; } - return NULL; + return max_worker; } #if APR_HAS_THREADS