Author: jfrederic.clere(a)jboss.com
Date: 2009-01-15 05:39:14 -0500 (Thu, 15 Jan 2009)
New Revision: 2168
Modified:
trunk/mod_cluster/native/mod_manager/mod_manager.c
Log:
Improve the "status" page.
Modified: trunk/mod_cluster/native/mod_manager/mod_manager.c
===================================================================
--- trunk/mod_cluster/native/mod_manager/mod_manager.c 2009-01-14 19:32:26 UTC (rev 2167)
+++ trunk/mod_cluster/native/mod_manager/mod_manager.c 2009-01-15 10:39:14 UTC (rev 2168)
@@ -27,6 +27,7 @@
#include "apr_strings.h"
#include "apr_lib.h"
+#include "apr_uuid.h"
#define CORE_PRIVATE
#include "httpd.h"
@@ -97,6 +98,8 @@
module AP_MODULE_DECLARE_DATA manager_module;
+static char balancer_nonce[APR_UUID_FORMATTED_LENGTH + 1];
+
typedef struct mod_manager_config
{
/* base name for the shared memory */
@@ -320,6 +323,7 @@
char *sessionid;
void *data;
const char *userdata_key = "mod_manager_init";
+ apr_uuid_t uuid;
mod_manager_config *mconf = ap_get_module_config(s->module_config,
&manager_module);
apr_pool_userdata_get(&data, userdata_key, s->process->pool);
if (!data) {
@@ -385,6 +389,13 @@
if (balancerhandler == NULL) {
ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, s, "can't find
a ping/pong logic");
}
+
+ /*
+ * Retrieve a UUID and store the nonce.
+ */
+ apr_uuid_get(&uuid);
+ apr_uuid_format(balancer_nonce, &uuid);
+
return OK;
}
static char **process_buff(request_rec *r, char *buff)
@@ -1255,7 +1266,166 @@
return DECLINED;
}
+/*
+ * Process the parameter and display corresponding information.
+ */
+static void manager_info_contexts(request_rec *r, int node, int host)
+{
+ int size, i;
+ int *id;
+ /* Process the Contexts */
+ ap_rprintf(r, "<h3>Contexts:</h3>");
+ ap_rprintf(r, "<pre>");
+ size = get_max_size_context(contextstatsmem);
+ id = apr_palloc(r->pool, sizeof(int) * size);
+ size = get_ids_used_context(contextstatsmem, id);
+ for (i=0; i<size; i++) {
+ contextinfo_t *ou;
+ char *status;
+ get_context(contextstatsmem, &ou, id[i]);
+ if (ou->node != node && ou->vhost != host)
+ continue;
+ status = "REMOVED";
+ switch (ou->status) {
+ case ENABLED:
+ status = "ENABLED";
+ break;
+ case DISABLED:
+ status = "DISABLED";
+ break;
+ case STOPPED:
+ status = "STOPPED";
+ break;
+ }
+ ap_rprintf(r, "%s, Status: %s\n", ou->context, status);
+ }
+ ap_rprintf(r, "</pre>");
+}
+static void manager_info_hosts(request_rec *r, int node)
+{
+ int size, i;
+ int *id;
+ int vhost = 0;
+ /* Process the Vhosts */
+ size = get_max_size_host(hoststatsmem);
+ id = apr_palloc(r->pool, sizeof(int) * size);
+ size = get_ids_used_host(hoststatsmem, id);
+ for (i=0; i<size; i++) {
+ hostinfo_t *ou;
+ get_host(hoststatsmem, &ou, id[i]);
+ if (ou->node != node)
+ continue;
+ if (ou->vhost != vhost) {
+ if (vhost)
+ ap_rprintf(r, "</pre>");
+ ap_rprintf(r, "<h2> Virtual Host %d:</h2>",
ou->vhost);
+ manager_info_contexts(r, ou->node, ou->vhost);
+ ap_rprintf(r, "<h3>Aliases:</h3>");
+ ap_rprintf(r, "<pre>");
+ vhost = ou->vhost;
+ }
+ ap_rprintf(r, "%s\n", ou->host);
+ }
+ ap_rprintf(r, "</pre>");
+
+}
+static int manager_info(request_rec *r)
+{
+ int size, i;
+ int *id;
+ apr_table_t *params = apr_table_make(r->pool, 10);
+ int access_status;
+ const char *name;
+
+ if (r->args) {
+ char *args = apr_pstrdup(r->pool, r->args);
+ char *tok, *val;
+ while (args && *args) {
+ if ((val = ap_strchr(args, '='))) {
+ *val++ = '\0';
+ if ((tok = ap_strchr(val, '&')))
+ *tok++ = '\0';
+ /*
+ * Special case: contexts contain path information
+ */
+ if ((access_status = ap_unescape_url(val)) != OK)
+ if (strcmp(args, "context") || (access_status !=
HTTP_NOT_FOUND))
+ return access_status;
+ apr_table_setn(params, args, val);
+ args = tok;
+ }
+ else
+ return HTTP_BAD_REQUEST;
+ }
+ }
+
+ /*
+ * Check that the supplied nonce matches this server's nonce;
+ * otherwise ignore all parameters, to prevent a CSRF attack.
+ */
+ if ((name = apr_table_get(params, "nonce")) == NULL
+ || strcmp(balancer_nonce, name) != 0) {
+ apr_table_clear(params);
+ }
+
+ /* process the parameters */
+ if (r->args) {
+ /* Process the Refresh parameter */
+ const char *val = apr_table_get(params, "Refresh");
+ if (val) {
+ long t = atol(val);
+ apr_table_set(r->headers_out, "Refresh", apr_ltoa(r->pool,t
< 1 ? 10 : t));
+ }
+ }
+
+ ap_set_content_type(r, "text/html; charset=ISO-8859-1");
+ ap_rputs(DOCTYPE_HTML_3_2
+ "<html><head>\n<title>Mod_cluster
Status</title>\n</head><body>\n",
+ r);
+ ap_rvputs(r, "<a href=\"", r->uri, "?nonce=",
balancer_nonce,
+ "&refresh=10",
+ "\">Auto Refresh</a>", NULL);
+
+ ap_rputs("<pre>", r);
+ size = get_max_size_node(nodestatsmem);
+ id = apr_palloc(r->pool, sizeof(int) * size);
+ size = get_ids_used_node(nodestatsmem, id);
+ for (i=0; i<size; i++) {
+ nodeinfo_t *ou;
+ proxy_worker_stat *proxystat;
+ char *flushpackets;
+ get_node(nodestatsmem, &ou, id[i]);
+ ap_rprintf(r, "<h1> Node %s (%s://%s:%s):</h1>\n",
+ ou->mess.JVMRoute, ou->mess.Type, ou->mess.Host,
ou->mess.Port);
+
+ ap_rprintf(r, "Balancer: %s,Domain: %s", ou->mess.balancer,
ou->mess.Domain);
+
+ flushpackets = "Off";
+ switch (ou->mess.flushpackets) {
+ case flush_on:
+ flushpackets = "On";
+ break;
+ case flush_auto:
+ flushpackets = "Auto";
+ }
+ ap_rprintf(r, ",Flushpackets: %s,Flushwait: %d,Ping: %d,Smax: %d,Ttl:
%d",
+ flushpackets, ou->mess.flushwait,
+ ou->mess.ping, ou->mess.smax, ou->mess.ttl);
+ proxystat = (proxy_worker_stat *) ou->stat;
+ ap_rprintf(r, ",Elected: %d,Read: %d,Transfered: %d,Connected: %d,Load:
%d\n",
+ proxystat->elected, proxystat->read, proxystat->transferred,
+ proxystat->busy, proxystat->lbfactor);
+
+ /* Process the Vhosts */
+ manager_info_hosts(r, id[i]);
+ }
+
+
+ ap_rputs("</body></html>\n", r);
+ return OK;
+}
+
/* Process the requests from the ModClusterService */
static int manager_handler(request_rec *r)
{
@@ -1270,10 +1440,7 @@
/* Display the nodes information */
if (r->method_number != M_GET)
return DECLINED;
- process_info(r, NULL, NULL);
- /* refresh it every 10 seconds */
- apr_table_set(r->headers_out, "Refresh", "10");
- return OK;
+ return(manager_info(r));
}
if (strcmp(r->handler, "mod-cluster"))