[httpd] allow change state of BalancerMember in mod_proxy_balancer web interface

Jan Kaluža jkaluza at fedoraproject.org
Mon Oct 24 11:31:01 UTC 2011


commit 7d4330ab2c1142698deba5f5a6a34cd3c99f6946
Author: Jan Kaluza <hanzz.k at gmail.com>
Date:   Mon Oct 24 13:28:07 2011 +0200

    allow change state of BalancerMember in mod_proxy_balancer web interface

 httpd-2.2.21-mod_proxy-change-state.patch |  255 +++++++++++++++++++++++++++++
 httpd.spec                                |    7 +-
 2 files changed, 261 insertions(+), 1 deletions(-)
---
diff --git a/httpd-2.2.21-mod_proxy-change-state.patch b/httpd-2.2.21-mod_proxy-change-state.patch
new file mode 100644
index 0000000..db6de97
--- /dev/null
+++ b/httpd-2.2.21-mod_proxy-change-state.patch
@@ -0,0 +1,255 @@
+diff --git a/modules/proxy/mod_proxy.c b/modules/proxy/mod_proxy.c
+index 1efe95c..5276cac 100644
+--- a/modules/proxy/mod_proxy.c
++++ b/modules/proxy/mod_proxy.c
+@@ -2242,14 +2242,7 @@ static int proxy_status_hook(request_rec *r, int flags)
+             char fbuf[50];
+             ap_rvputs(r, "<tr>\n<td>", worker->scheme, "</td>", NULL);
+             ap_rvputs(r, "<td>", worker->hostname, "</td><td>", NULL);
+-            if (worker->s->status & PROXY_WORKER_DISABLED)
+-                ap_rputs("Dis", r);
+-            else if (worker->s->status & PROXY_WORKER_IN_ERROR)
+-                ap_rputs("Err", r);
+-            else if (worker->s->status & PROXY_WORKER_INITIALIZED)
+-                ap_rputs("Ok", r);
+-            else
+-                ap_rputs("-", r);
++            ap_rvputs(r, ap_proxy_parse_wstatus(r->pool, worker), NULL);
+             ap_rvputs(r, "</td><td>", worker->s->route, NULL);
+             ap_rvputs(r, "</td><td>", worker->s->redirect, NULL);
+             ap_rprintf(r, "</td><td>%d</td>", worker->s->lbfactor);
+diff --git a/modules/proxy/mod_proxy.h b/modules/proxy/mod_proxy.h
+index 4a4bf17..1b4ba6d 100644
+--- a/modules/proxy/mod_proxy.h
++++ b/modules/proxy/mod_proxy.h
+@@ -274,6 +274,16 @@ struct proxy_conn_pool {
+ #define PROXY_WORKER_IN_ERROR       0x0080
+ #define PROXY_WORKER_HOT_STANDBY    0x0100
+ 
++/* worker status flags */
++#define PROXY_WORKER_INITIALIZED_FLAG    'O'
++#define PROXY_WORKER_IGNORE_ERRORS_FLAG  'I'
++#define PROXY_WORKER_IN_SHUTDOWN_FLAG    'U'
++#define PROXY_WORKER_DISABLED_FLAG       'D'
++#define PROXY_WORKER_STOPPED_FLAG        'S'
++#define PROXY_WORKER_IN_ERROR_FLAG       'E'
++#define PROXY_WORKER_HOT_STANDBY_FLAG    'H'
++#define PROXY_WORKER_FREE_FLAG           'F'
++
+ #define PROXY_WORKER_NOT_USABLE_BITMAP ( PROXY_WORKER_IN_SHUTDOWN | \
+ PROXY_WORKER_DISABLED | PROXY_WORKER_STOPPED | PROXY_WORKER_IN_ERROR )
+ 
+@@ -776,6 +786,23 @@ PROXY_DECLARE(apr_status_t)
+ ap_proxy_buckets_lifetime_transform(request_rec *r, apr_bucket_brigade *from,
+                                         apr_bucket_brigade *to);
+ 
++/**
++ * Set/unset the worker status bitfield depending on flag
++ * @param c    flag
++ * @param set  set or unset bit
++ * @param w    worker to use
++ * @return     APR_SUCCESS if valid flag
++ */
++PROXY_DECLARE(apr_status_t) ap_proxy_set_wstatus(char c, int set, proxy_worker *w);
++
++/**
++ * Create readable representation of worker status bitfield
++ * @param p  pool
++ * @param w  worker to use
++ * @return   string representation of status
++ */
++PROXY_DECLARE(char *) ap_proxy_parse_wstatus(apr_pool_t *p, proxy_worker *w);
++
+ #define PROXY_LBMETHOD "proxylbmethod"
+ 
+ /* The number of dynamic workers that can be added when reconfiguring.
+diff --git a/modules/proxy/mod_proxy_balancer.c b/modules/proxy/mod_proxy_balancer.c
+index 90f3d08..e58503f 100644
+--- a/modules/proxy/mod_proxy_balancer.c
++++ b/modules/proxy/mod_proxy_balancer.c
+@@ -675,6 +675,18 @@ static int balancer_init(apr_pool_t *p, apr_pool_t *plog,
+     return OK;
+ }
+ 
++static void create_radio(const char *name, unsigned int flag, proxy_worker *w,
++                         request_rec *r)
++{
++    ap_rvputs(r, "<td>Set <input name='", name, "' value='1' type=radio", NULL);
++    if (w->s->status & flag)
++        ap_rputs(" checked", r);
++    ap_rvputs(r, "> <br/> Clear <input name='", name, "' value='0' type=radio", NULL);
++    if (!(w->s->status & flag))
++        ap_rputs(" checked", r);
++    ap_rputs("></td>\n", r);
++}
++
+ /* Manages the loadfactors and member status
+  */
+ static int balancer_handler(request_rec *r)
+@@ -770,11 +782,17 @@ static int balancer_handler(request_rec *r)
+             else
+                 *wsel->s->redirect = '\0';
+         }
+-        if ((val = apr_table_get(params, "dw"))) {
+-            if (!strcasecmp(val, "Disable"))
+-                wsel->s->status |= PROXY_WORKER_DISABLED;
+-            else if (!strcasecmp(val, "Enable"))
+-                wsel->s->status &= ~PROXY_WORKER_DISABLED;
++        if ((val = apr_table_get(params, "status_I"))) {
++            ap_proxy_set_wstatus('I', atoi(val), wsel);
++        }
++        if ((val = apr_table_get(params, "status_N"))) {
++            ap_proxy_set_wstatus('N', atoi(val), wsel);
++        }
++        if ((val = apr_table_get(params, "status_D"))) {
++            ap_proxy_set_wstatus('D', atoi(val), wsel);
++        }
++        if ((val = apr_table_get(params, "status_H"))) {
++            ap_proxy_set_wstatus('H', atoi(val), wsel);
+         }
+         if ((val = apr_table_get(params, "ls"))) {
+             int ival = atoi(val);
+@@ -784,10 +802,11 @@ static int balancer_handler(request_rec *r)
+         }
+ 
+     }
++
+     if (apr_table_get(params, "xml")) {
+         ap_set_content_type(r, "text/xml");
+-        ap_rputs("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n", r);
+-        ap_rputs("<httpd:manager xmlns:httpd=\"http://httpd.apache.org\">\n", r);
++        ap_rputs("<?xml version='1.0' encoding='UTF-8' ?>\n", r);
++        ap_rputs("<httpd:manager xmlns:httpd='http://httpd.apache.org'>\n", r);
+         ap_rputs("  <httpd:balancers>\n", r);
+         balancer = (proxy_balancer *)conf->balancers->elts;
+         for (i = 0; i < conf->balancers->nelts; i++) {
+@@ -865,18 +884,7 @@ static int balancer_handler(request_rec *r)
+                           ap_escape_html(r->pool, worker->s->redirect), NULL);
+                 ap_rprintf(r, "</td><td>%d</td>", worker->s->lbfactor);
+                 ap_rprintf(r, "<td>%d</td><td>", worker->s->lbset);
+-                if (worker->s->status & PROXY_WORKER_DISABLED)
+-                   ap_rputs("Dis ", r);
+-                if (worker->s->status & PROXY_WORKER_IN_ERROR)
+-                   ap_rputs("Err ", r);
+-                if (worker->s->status & PROXY_WORKER_STOPPED)
+-                   ap_rputs("Stop ", r);
+-                if (worker->s->status & PROXY_WORKER_HOT_STANDBY)
+-                   ap_rputs("Stby ", r);
+-                if (PROXY_WORKER_IS_USABLE(worker))
+-                    ap_rputs("Ok", r);
+-                if (!PROXY_WORKER_IS_INITIALIZED(worker))
+-                    ap_rputs("-", r);
++                ap_rvputs(r, ap_proxy_parse_wstatus(r->pool, worker), NULL);
+                 ap_rputs("</td>", r);
+                 ap_rprintf(r, "<td>%" APR_SIZE_T_FMT "</td><td>", worker->s->elected);
+                 ap_rputs(apr_strfsize(worker->s->transferred, fbuf), r);
+@@ -907,21 +915,20 @@ static int balancer_handler(request_rec *r)
+             ap_rvputs(r, "value=\"", ap_escape_html(r->pool, wsel->s->redirect),
+                       NULL);
+             ap_rputs("\"></td></tr>\n", r);
+-            ap_rputs("<tr><td>Status:</td><td>Disabled: <input name=\"dw\" value=\"Disable\" type=radio", r);
+-            if (wsel->s->status & PROXY_WORKER_DISABLED)
+-                ap_rputs(" checked", r);
+-            ap_rputs("> | Enabled: <input name=\"dw\" value=\"Enable\" type=radio", r);
+-            if (!(wsel->s->status & PROXY_WORKER_DISABLED))
+-                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=\"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", NULL);
+-            ap_rvputs(r, "<input type=hidden name=\"nonce\" value=\"", 
+-                      balancer_nonce, "\">\n", NULL);
++            ap_rputs("<tr><td>Status:</td>", r);
++            ap_rputs("<td><table border='1'><tr><th>Ign</th><th>Dis</th><th>Stby</th></tr>\n<tr>", r);
++            create_radio("status_I", PROXY_WORKER_IGNORE_ERRORS, wsel, r);
++            create_radio("status_D", PROXY_WORKER_DISABLED, wsel, r);
++            create_radio("status_H", PROXY_WORKER_HOT_STANDBY, wsel, r);
++            ap_rputs("</tr></table>\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='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", NULL);
++            ap_rvputs(r, "<input type=hidden name='nonce' value='",
++                      balancer_nonce, "'>\n", NULL);
+             ap_rvputs(r, "</form>\n", NULL);
+             ap_rputs("<hr />\n", r);
+         }
+diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c
+index 95f4a78..58f630b 100644
+--- a/modules/proxy/proxy_util.c
++++ b/modules/proxy/proxy_util.c
+@@ -2678,3 +2678,69 @@ ap_proxy_buckets_lifetime_transform(request_rec *r, apr_bucket_brigade *from,
+     }
+     return rv;
+ }
++
++PROXY_DECLARE(apr_status_t) ap_proxy_set_wstatus(const char c, int set, proxy_worker *w)
++{
++    char bit = toupper(c);
++    switch (bit) {
++        case PROXY_WORKER_DISABLED_FLAG :
++            if (set)
++                w->s->status |= PROXY_WORKER_DISABLED;
++            else
++                w->s->status &= ~PROXY_WORKER_DISABLED;
++            break;
++        case PROXY_WORKER_STOPPED_FLAG :
++            if (set)
++                w->s->status |= PROXY_WORKER_STOPPED;
++            else
++                w->s->status &= ~PROXY_WORKER_STOPPED;
++            break;
++        case PROXY_WORKER_IN_ERROR_FLAG :
++            if (set)
++                w->s->status |= PROXY_WORKER_IN_ERROR;
++            else
++                w->s->status &= ~PROXY_WORKER_IN_ERROR;
++            break;
++        case PROXY_WORKER_HOT_STANDBY_FLAG :
++            if (set)
++                w->s->status |= PROXY_WORKER_HOT_STANDBY;
++            else
++                w->s->status &= ~PROXY_WORKER_HOT_STANDBY;
++            break;
++        case PROXY_WORKER_IGNORE_ERRORS_FLAG :
++            if (set)
++                w->s->status |= PROXY_WORKER_IGNORE_ERRORS;
++            else
++                w->s->status &= ~PROXY_WORKER_IGNORE_ERRORS;
++            break;
++        default:
++            return APR_EINVAL;
++            break;
++    }
++    return APR_SUCCESS;
++}
++
++PROXY_DECLARE(char *) ap_proxy_parse_wstatus(apr_pool_t *p, proxy_worker *w)
++{
++    char *ret = NULL;
++    unsigned int status = w->s->status;
++    if (status & PROXY_WORKER_INITIALIZED)
++        ret = apr_pstrcat(p, "Init ", NULL);
++    else
++        ret = apr_pstrcat(p, "!Init ", NULL);
++    if (status & PROXY_WORKER_IGNORE_ERRORS)
++        ret = apr_pstrcat(p, ret, "Ign ", NULL);
++    if (status & PROXY_WORKER_IN_SHUTDOWN)
++        ret = apr_pstrcat(p, ret, "Shut ", NULL);
++    if (status & PROXY_WORKER_DISABLED)
++        ret = apr_pstrcat(p, ret, "Dis ", NULL);
++    if (status & PROXY_WORKER_STOPPED)
++        ret = apr_pstrcat(p, ret, "Stop ", NULL);
++    if (status & PROXY_WORKER_IN_ERROR)
++        ret = apr_pstrcat(p, ret, "Err ", NULL);
++    if (status & PROXY_WORKER_HOT_STANDBY)
++        ret = apr_pstrcat(p, ret, "Stby ", NULL);
++    if (PROXY_WORKER_IS_USABLE(w))
++        ret = apr_pstrcat(p, ret, "Ok ", NULL);
++    return ret;
++}
diff --git a/httpd.spec b/httpd.spec
index a968a36..ab7425b 100644
--- a/httpd.spec
+++ b/httpd.spec
@@ -8,7 +8,7 @@
 Summary: Apache HTTP Server
 Name: httpd
 Version: 2.2.21
-Release: 2%{?dist}
+Release: 3%{?dist}
 URL: http://httpd.apache.org/
 Source0: http://www.apache.org/dist/httpd/httpd-%{version}.tar.bz2
 Source1: index.html
@@ -39,6 +39,7 @@ Patch24: httpd-2.2.11-corelimit.patch
 Patch25: httpd-2.2.11-selinux.patch
 Patch26: httpd-2.2.9-suenable.patch
 Patch27: httpd-2.2.19-logresolve-ipv6.patch
+Patch28: httpd-2.2.21-mod_proxy-change-state.patch
 License: ASL 2.0
 Group: System Environment/Daemons
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
@@ -123,6 +124,7 @@ Security (TLS) protocols.
 %patch25 -p1 -b .selinux
 %patch26 -p1 -b .suenable
 %patch27 -p1 -b .logresolve-ipv6
+%patch28 -p1 -b .mod_proxy-change-state
 
 # Patch in vendor/release string
 sed "s/@RELEASE@/%{vstring}/" < %{PATCH20} | patch -p1
@@ -523,6 +525,9 @@ rm -rf $RPM_BUILD_ROOT
 %{_sysconfdir}/rpm/macros.httpd
 
 %changelog
+* Mon Oct 24 2011 Jan Kaluza <jkaluza at redhat.com> - 2.2.21-3
+- allow change state of BalancerMember in mod_proxy_balancer web interface
+
 * Thu Sep 22 2011 Ville Skyttä <ville.skytta at iki.fi> - 2.2.21-2
 - Make mmn available as %%{_httpd_mmn}.
 - Add .svgz to AddEncoding x-gzip example in httpd.conf.


More information about the scm-commits mailing list