On 10/10/2005 11:13 PM, Ruediger Pluem wrote:



[..cut..]

> 
> Thus ap_proxy_get_worker would be called with the URL 
> http://backend.com/rsync/bar
> which would lead to a no match. I guess instead of a simple strcasecmp
> we need something like a "longest match" here since I think we cannot rely
> on the order the workers got stored. Do you know if a "longest match" function

Attached a new version which does a longest match and should fix the problem.

[..cut..]

BTW: Tomorrow I will have a look a the log messages, where it makes sense to 
exchange
worker->hostname against worker->name.

Regards

RĂ¼diger
Index: modules/proxy/mod_proxy_balancer.c
===================================================================
--- modules/proxy/mod_proxy_balancer.c  (Revision 312708)
+++ modules/proxy/mod_proxy_balancer.c  (Arbeitskopie)
@@ -477,8 +477,12 @@
                 *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 @@
         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 @@
                       balancer->name + sizeof("balancer://") - 1,
                       "\">", NULL); 
             ap_rvputs(r, balancer->name, "</a></h3>\n\n", NULL);
-            ap_rputs("\n\n<table border=\"0\"><tr>"
+            ap_rputs("\n\n<table border=\"0\" style=\"text-align: left;\"><tr>"
                 
"<th>StickySession</th><th>Timeout</th><th>FailoverAttempts</th><th>Method</th>"
                 "</tr>\n<tr>", r);                
             ap_rvputs(r, "<td>", balancer->sticky, NULL);
@@ -622,9 +622,9 @@
             ap_rprintf(r, "<td>%d</td>\n", balancer->max_attempts);
             ap_rprintf(r, "<td>%s</td>\n",
                        balancer->lbmethod->name);
-            ap_rputs("</table>\n", r);
-            ap_rputs("\n\n<table border=\"0\"><tr>"
-                "<th>Scheme</th><th>Host</th>"
+            ap_rputs("</table>\n<br />", r);
+            ap_rputs("\n\n<table border=\"0\" style=\"text-align: left;\"><tr>"
+                "<th>Worker URL</th>"
                 "<th>Route</th><th>RouteRedir</th>"
                 "<th>Factor</th><th>Status</th>"
                 "</tr>\n", r);
@@ -632,12 +632,11 @@
             worker = (proxy_worker *)balancer->workers->elts;
             for (n = 0; n < balancer->workers->nelts; n++) {
 
-                ap_rvputs(r, "<tr>\n<td>", worker->scheme, "</td><td>", NULL);
-                ap_rvputs(r, "<a href=\"", r->uri, "?b=", 
-                          balancer->name + sizeof("balancer://") - 1,
-                          "&s=", worker->scheme, "&w=", worker->hostname,
+                ap_rvputs(r, "<tr>\n<td><a href=\"", r->uri, "?b=",
+                          balancer->name + sizeof("balancer://") - 1, "&w=",
+                          ap_escape_uri(r->pool, worker->name),
                           "\">", NULL); 
-                ap_rvputs(r, worker->hostname, "</a></td>", NULL);
+                ap_rvputs(r, worker->name, "</a></td>", NULL);
                 ap_rvputs(r, "<td>", worker->s->route, NULL);
                 ap_rvputs(r, "</td><td>", worker->s->redirect, NULL);
                 ap_rprintf(r, "</td><td>%d</td><td>", worker->s->lbfactor);
@@ -678,10 +677,8 @@
                 ap_rputs(" checked", r);
             ap_rputs("></td><tr>\n", r);            
             ap_rputs("<tr><td colspan=2><input type=submit 
value=\"Submit\"></td></tr>\n", r);
-            ap_rvputs(r, "</table>\n<input type=hidden name=\"s\" ", NULL);
-            ap_rvputs(r, "value=\"", wsel->scheme, "\">\n", NULL);
-            ap_rvputs(r, "<input type=hidden name=\"w\" ", NULL);
-            ap_rvputs(r, "value=\"", wsel->hostname, "\">\n", NULL);
+            ap_rvputs(r, "</table>\n<input type=hidden name=\"w\" ",  NULL);
+            ap_rvputs(r, "value=\"", ap_escape_uri(r->pool, wsel->name), 
"\">\n", NULL); 
             ap_rvputs(r, "<input type=hidden name=\"b\" ", NULL);
             ap_rvputs(r, "value=\"", bsel->name + sizeof("balancer://") - 1,
                       "\">\n</form>\n", NULL);
Index: modules/proxy/proxy_util.c
===================================================================
--- modules/proxy/proxy_util.c  (Revision 312708)
+++ modules/proxy/proxy_util.c  (Arbeitskopie)
@@ -1212,24 +1212,34 @@
                                                   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

Reply via email to