jean-frederic clere wrote:
Hi,

I would like to fix a problem in mod_proxy_balancer when the configuration is something like:
+++
  <Location /myapp>
ProxyPass balancer://mycluster/myapp stickysession=JESSSIONID|jsessionid nofailover=On
  </Location>

  <Location /titi>
ProxyPass balancer://mytiti/titi stickysession=JESSSIONID|jsessionid nofailover=On
  </Location>

  <Proxy balancer://mytiti>
    BalancerMember ajp://jfcpc:8009 smax=10 timeout=10 route=test2
  </Proxy>
  <Proxy balancer://mycluster>
    BalancerMember ajp://neo:8009 smax=10 timeout=10 route=toto
  </Proxy>
+++
When jumping from /myapp with a JSESSIONID=id.test2 to /titi httpd returns 500 but it should have ignored the route test2 because it doesn't belong to any of the members of the balancer corresponding to the location.

Find attached a patch to fix the problem.



Here is my version of the patch.
In essence it return 503 only when there is session route
and this session route is not part of any load balancer member.

It will allow to have the different load balancers with
nofailover=On. Nofailover will work only for the load balancer
members.


Index: mod_proxy_balancer.c
===================================================================
--- mod_proxy_balancer.c        (revision 556817)
+++ mod_proxy_balancer.c        (working copy)
@@ -180,7 +180,7 @@
     int i;
     int checking_standby;
     int checked_standby;
-
+
     proxy_worker *worker;

     checking_standby = checked_standby = 0;
@@ -389,7 +389,7 @@
     for (i = 0; i < balancer->workers->nelts; i++, worker++) {
         if (!(worker->s->status & PROXY_WORKER_IN_ERROR)) {
             ok = 1;
-            break;
+            break;
         }
     }
     if (!ok) {
@@ -470,15 +470,32 @@
         *worker = runtime;
     }
     else if (route && (*balancer)->sticky_force) {
-        ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
-                     "proxy: BALANCER: (%s). All workers are in error state for 
route (%s)",
-                     (*balancer)->name, route);
-        if ((rv = PROXY_THREAD_UNLOCK(*balancer)) != APR_SUCCESS) {
-            ap_log_error(APLOG_MARK, APLOG_ERR, rv, r->server,
-                         "proxy: BALANCER: (%s). Unlock failed for 
pre_request",
-                         (*balancer)->name);
+        int i, member_of = 0;
+        proxy_worker *workers;
+        /*
+         * We have a route provided that doesn't match the
+         * balancer name. See if the provider route is the
+         * member of the same balancer in which case return 503
+         */
+        workers = (proxy_worker *)(*balancer)->workers->elts;
+        for (i = 0; i < (*balancer)->workers->nelts; i++) {
+            if (*(worker->s->route) && strcmp(worker->s->route, route) == 0) {
+                member_of = 1;
+                break;
+            }
+            workers++;
         }
-        return HTTP_SERVICE_UNAVAILABLE;
+        if (member_of) {
+            ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
+                         "proxy: BALANCER: (%s). All workers are in error state for 
route (%s)",
+                         (*balancer)->name, route);
+            if ((rv = PROXY_THREAD_UNLOCK(*balancer)) != APR_SUCCESS) {
+                ap_log_error(APLOG_MARK, APLOG_ERR, rv, r->server,
+                             "proxy: BALANCER: (%s). Unlock failed for 
pre_request",
+                             (*balancer)->name);
+            }
+            return HTTP_SERVICE_UNAVAILABLE;
+        }
     }

     if ((rv = PROXY_THREAD_UNLOCK(*balancer)) != APR_SUCCESS) {
@@ -910,7 +927,7 @@
     int max_lbset = 0;
     int checking_standby;
     int checked_standby;
-
+
     ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
                  "proxy: Entering byrequests for BALANCER (%s)",
                  balancer->name);

Reply via email to