--- modules/proxy/mod_proxy.c.orig	2006-09-29 16:46:00.000000000 +0200
+++ modules/proxy/mod_proxy.c	2006-09-29 16:46:37.000000000 +0200
@@ -76,11 +76,11 @@
     int ival;
     if (!strcasecmp(key, "loadfactor")) {
         /* Normalized load factor. Used with BalancerMamber,
-         * it is a number between 1 and 100.
+         * it is a number between 0 and 100.
          */
         worker->lbfactor = atoi(val);
-        if (worker->lbfactor < 1 || worker->lbfactor > 100)
-            return "LoadFactor must be number between 1..100";
+        if (worker->lbfactor < 0 || worker->lbfactor > 100)
+            return "LoadFactor must be number between 0..100";
     }
     else if (!strcasecmp(key, "retry")) {
         /* If set it will give the retry timeout for the worker
--- modules/proxy/mod_proxy_balancer.c.orig	2006-09-29 16:45:54.000000000 +0200
+++ modules/proxy/mod_proxy_balancer.c	2006-09-29 16:47:07.000000000 +0200
@@ -92,7 +92,7 @@
     for (i = 0; i < balancer->workers->nelts; i++) {
         /* Set to the original configuration */
         workers[i].s->lbstatus = workers[i].s->lbfactor =
-          (workers[i].lbfactor ? workers[i].lbfactor : 1);
+          (workers[i].lbfactor >= 0 ? workers[i].lbfactor : 1);
     }
     /* Set default number of attempts to the number of
      * workers.
@@ -216,17 +216,15 @@
          */
         worker = find_route_worker(balancer, *route);
         if (worker && !PROXY_WORKER_IS_USABLE(worker)) {
-            /* We have a worker that is unusable.
-             * It can be in error or disabled, but in case
-             * it has a redirection set use that redirection worker.
-             * This enables to safely remove the member from the
-             * balancer. Of course you will need a some kind of
-             * session replication between those two remote.
-             */
-            if (*worker->s->redirect)
-                worker = find_route_worker(balancer, worker->s->redirect);
-            /* Check if the redirect worker is usable */
-            if (worker && !PROXY_WORKER_IS_USABLE(worker))
+	    /*
+	     * Worker is unusable, attempt a retry
+	     */
+            ap_proxy_retry_worker("BALANCER", worker, r->server);
+
+	    /*
+	     * Worker is still not usable, bail out;
+	     */
+            if (!PROXY_WORKER_IS_USABLE(worker))
                 worker = NULL;
         }
         return worker;
@@ -443,7 +441,11 @@
      * load factor will always be 1
      */
     if (balancer->workers->nelts == 1) {
-        workers->s->lbstatus = workers->s->lbfactor = 1;
+	if (workers->s->lbfactor == 0) {
+	  workers->s->lbstatus = 0;
+	} else {
+	  workers->s->lbstatus = workers->s->lbfactor = 1;
+	}
         return;
     }
     for (i = 0; i < balancer->workers->nelts; i++) {
@@ -544,7 +546,7 @@
         const char *val;
         if ((val = apr_table_get(params, "lf"))) {
             int ival = atoi(val);
-            if (ival >= 1 && ival <= 100) {
+            if (ival >= 0 && ival <= 100) {
                 wsel->s->lbfactor = ival;
                 if (bsel)
                     recalc_factors(bsel);
@@ -810,23 +812,67 @@
 
     /* First try to see if we have available candidate */
     for (i = 0; i < balancer->workers->nelts; i++) {
-        /* If the worker is in error state run
-         * retry on that worker. It will be marked as
-         * operational if the retry timeout is elapsed.
-         * The worker might still be unusable, but we try
-         * anyway.
-         */
-        if (!PROXY_WORKER_IS_USABLE(worker))
-            ap_proxy_retry_worker("BALANCER", worker, r->server);
-        /* Take into calculation only the workers that are
-         * not in error state or not disabled.
-         */
-        if (PROXY_WORKER_IS_USABLE(worker)) {
-            worker->s->lbstatus += worker->s->lbfactor;
-            total_factor += worker->s->lbfactor;
-            if (!mycandidate || worker->s->lbstatus > mycandidate->s->lbstatus)
-                mycandidate = worker;
-        }
+	/*
+	 * Ignore workers with lbfactor = 0
+	 */
+	if (worker->s->lbfactor == 0) {
+	    worker++;
+	    continue;
+	}
+	/*
+	 * Only consider worker if it is not redirected
+	 */
+	if(!*worker->s->redirect) {
+            /* If the worker is in error state run
+             * retry on that worker. It will be marked as
+             * operational if the retry timeout is elapsed.
+             * The worker might still be unusable, but we try
+             * anyway.
+             */
+            if (!PROXY_WORKER_IS_USABLE(worker))
+                ap_proxy_retry_worker("BALANCER", worker, r->server);
+            /* Take into calculation only the workers that are
+             * not in error state or not disabled.
+             */
+            if (PROXY_WORKER_IS_USABLE(worker)) {
+                worker->s->lbstatus += worker->s->lbfactor;
+                total_factor += worker->s->lbfactor;
+                if (!mycandidate || worker->s->lbstatus > mycandidate->s->lbstatus)
+                    mycandidate = worker;
+            }
+	} else {
+	    /*
+	     * We hit a redirected worker,
+	     * hop to the redirect target. We do not take into account multiple redirections.
+	     */
+
+	    proxy_worker * tmpworker;
+	
+	    tmpworker = find_route_worker(balancer, worker->s->redirect); 
+
+	    /*
+	     * Ignore worker if its lbfactor is 0
+	     */
+	    if (tmpworker->s->lbfactor != 0) {
+	        /*
+	         * We found a candidate worker, check if it is usable
+	         */
+                if (tmpworker && !PROXY_WORKER_IS_USABLE(tmpworker))
+                    ap_proxy_retry_worker("BALANCER", tmpworker, r->server);
+                /* Take into calculation only the workers that are
+                 * not in error state or not disabled.
+                 */
+                if (tmpworker && PROXY_WORKER_IS_USABLE(tmpworker)) {
+	            /* We induce here a slight lbstatus error as we might already have increased
+	             * this worker's lbstatus (since we chose this worker by redirection).
+	             */
+                    tmpworker->s->lbstatus += tmpworker->s->lbfactor;
+                    total_factor += tmpworker->s->lbfactor;
+                    if (!mycandidate || tmpworker->s->lbstatus > mycandidate->s->lbstatus)
+                        mycandidate = tmpworker;
+	        }
+	    }
+	}
         worker++;
     }
 
@@ -870,25 +916,71 @@
 
     /* First try to see if we have available candidate */
     for (i = 0; i < balancer->workers->nelts; i++) {
-        /* If the worker is in error state run
-         * retry on that worker. It will be marked as
-         * operational if the retry timeout is elapsed.
-         * The worker might still be unusable, but we try
-         * anyway.
-         */
-        if (!PROXY_WORKER_IS_USABLE(worker))
-            ap_proxy_retry_worker("BALANCER", worker, r->server);
-        /* Take into calculation only the workers that are
-         * not in error state or not disabled.
-         */
-        if (PROXY_WORKER_IS_USABLE(worker)) {
-            mytraffic = (worker->s->transferred/worker->s->lbfactor) +
-                        (worker->s->read/worker->s->lbfactor);
-            if (!mycandidate || mytraffic < curmin) {
-                mycandidate = worker;
-                curmin = mytraffic;
+	/*
+	 * Ignore workers with lbfactor = 0
+	 */
+	if (worker->s->lbfactor == 0) {
+	    worker++;
+	    continue;
+	}
+	/*
+	 * Only consider worker if it is not redirected
+	 */
+	if(!*worker->s->redirect) {
+            /* If the worker is in error state run
+             * retry on that worker. It will be marked as
+             * operational if the retry timeout is elapsed.
+             * The worker might still be unusable, but we try
+             * anyway.
+             */
+            if (!PROXY_WORKER_IS_USABLE(worker))
+                ap_proxy_retry_worker("BALANCER", worker, r->server);
+            /* Take into calculation only the workers that are
+             * not in error state or not disabled.
+             */
+            if (PROXY_WORKER_IS_USABLE(worker)) {
+                mytraffic = (worker->s->transferred/worker->s->lbfactor) +
+                            (worker->s->read/worker->s->lbfactor);
+                if (!mycandidate || mytraffic < curmin) {
+                    mycandidate = worker;
+                    curmin = mytraffic;
+                }
             }
-        }
+	} else {
+	    /*
+	     * We hit a redirected worker,
+	     * hop to the redirect target. We do not take into account multiple redirections.
+	     */
+
+	    proxy_worker * tmpworker = worker;
+
+	    tmpworker = find_route_worker(balancer, worker->s->redirect); 
+
+	    /*
+	     * Ignore worker if its lbfactor is 0
+	     */
+	    if (tmpworker->s->lbfactor != 0) {
+	        /*
+	         * We found a candidate worker, check if it is usable
+	         */
+                if (tmpworker && !PROXY_WORKER_IS_USABLE(tmpworker))
+                    ap_proxy_retry_worker("BALANCER", tmpworker, r->server);
+                /* Take into calculation only the workers that are
+                 * not in error state or not disabled.
+                 */
+                if (tmpworker && PROXY_WORKER_IS_USABLE(tmpworker)) {
+	            /* We induce here a slight traffic size error as we might already have taken into account
+	             * this worker's metrics (since we chose this worker by redirection).
+	             */
+                    mytraffic = (tmpworker->s->transferred/tmpworker->s->lbfactor) +
+                                (tmpworker->s->read/tmpworker->s->lbfactor);
+                    if (!mycandidate || mytraffic < curmin) {
+                        mycandidate = tmpworker;
+                        curmin = mytraffic;
+                    }
+	        }
+	    }
+	}
         worker++;
     }
 
