]> granicus.if.org Git - apache/commitdiff
Proxy balancer: support setting error status according to
authorNick Kew <niq@apache.org>
Thu, 1 Apr 2010 22:48:38 +0000 (22:48 +0000)
committerNick Kew <niq@apache.org>
Thu, 1 Apr 2010 22:48:38 +0000 (22:48 +0000)
HTTP response code from a backend.
PR 48939 [Daniel Ruggeri <DRuggeri primary.net>]

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@930125 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
modules/proxy/mod_proxy.c
modules/proxy/mod_proxy.h
modules/proxy/mod_proxy_balancer.c

diff --git a/CHANGES b/CHANGES
index af2920d0e444398132eb01c3c9c2eb5b03f1b399..833fda02c6551c9201f542b253eff47f998ead24 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -28,6 +28,10 @@ Changes with Apache 2.3.7
      processing is completed, avoiding orphaned callback pointers.
      [Brett Gervasoni <brettg senseofsecurity.com>, Jeff Trawick]
 
+  *) Proxy balancer: support setting error status according to
+     HTTP response code from a backend.
+     PR 48939 [Daniel Ruggeri <DRuggeri primary.net>]
+
   *) htcacheclean: Introduce the ability to clean specific URLs from the
      cache, if provided as an optional parameter on the command line.
      [Graham Leggett]
index cb5336f20224b6d0f5c065b3f853776bf6ae209c..92975c4c995ccc6cacd59dc3d27796d38787754e 100644 (file)
@@ -381,6 +381,27 @@ static const char *set_balancer_param(proxy_server_conf *conf,
         else
             return "scolonpathdelim must be On|Off";
     }
+    else if (!strcasecmp(key, "erroronstatus")) {
+        char valSplit[strlen(val)+1];
+        char *status;
+        char *tok_state;
+
+        strcpy(valSplit, val);
+        balancer->errstatuses = apr_array_make(p, 1, sizeof(int));
+
+        status = apr_strtok(valSplit, ", ", &tok_state);
+        while (status != NULL) {
+            ival = atoi(status);
+            if (ap_is_HTTP_VALID_RESPONSE(ival)) {
+                *(int*)apr_array_push(balancer->errstatuses) = ival;
+            }
+            else {
+                return "erroronstatus must be one or more HTTP response code";
+            }
+            status = apr_strtok(NULL, ", ", &tok_state);
+        }
+
+    }
     else {
         return "unknown Balancer parameter";
     }
index adf1376367c4e8a8645153539dd2ecfb65ac8b1e..f5452700fe0eef5bdf4490e2771b26b0b603a610 100644 (file)
@@ -373,6 +373,7 @@ struct proxy_balancer {
     void            *context;   /* general purpose storage */
     const char      *sticky_path;  /* URL sticky session identifier */
     int             scolonsep;     /* true if ';' seps sticky session paths */
+    apr_array_header_t *errstatuses; /* statuses to force members into error */
 };
 
 struct proxy_balancer_method {
index 03ed92288b2c57fddf3959e879ef3470c76a32ec..1258f003a12275f81a6902abf5bb7e0abbb6a23f 100644 (file)
@@ -600,7 +600,6 @@ static int proxy_balancer_post_request(proxy_worker *worker,
                                        proxy_server_conf *conf)
 {
 
-#if 0
     apr_status_t rv;
 
     if ((rv = PROXY_THREAD_LOCK(balancer)) != APR_SUCCESS) {
@@ -609,8 +608,20 @@ static int proxy_balancer_post_request(proxy_worker *worker,
             balancer->name);
         return HTTP_INTERNAL_SERVER_ERROR;
     }
-    /* TODO: placeholder for post_request actions
-     */
+
+    if (!apr_is_empty_array(balancer->errstatuses)){
+        int i;
+        for (i = 0; i < balancer->errstatuses->nelts; i++) {
+            int val=((int*)balancer->errstatuses->elts)[i];
+            if (r->status == val) {
+                ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, r->server,
+                    "Detected ErrorOnState (%d) for member (%s). Forcing worker into error state.", val, worker->name);
+                worker->s->status |= PROXY_WORKER_IN_ERROR;
+                worker->s->error_time = apr_time_now();
+                break;
+            }
+        }
+    }
 
     if ((rv = PROXY_THREAD_UNLOCK(balancer)) != APR_SUCCESS) {
         ap_log_error(APLOG_MARK, APLOG_ERR, rv, r->server,
@@ -620,8 +631,6 @@ static int proxy_balancer_post_request(proxy_worker *worker,
     ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
                  "proxy_balancer_post_request for (%s)", balancer->name);
 
-#endif
-
     if (worker && worker->s->busy)
         worker->s->busy--;