📄 jk_status.c
字号:
/*
* Copyright 1999-2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/***************************************************************************
* Description: Status worker, display and manages JK workers *
* Author: Mladen Turk <mturk@jboss.com> *
* Version: $Revision: 386279 $ *
***************************************************************************/
#include "jk_pool.h"
#include "jk_service.h"
#include "jk_util.h"
#include "jk_worker.h"
#include "jk_status.h"
#include "jk_mt.h"
#include "jk_shm.h"
#include "jk_ajp_common.h"
#include "jk_lb_worker.h"
#include "jk_ajp13_worker.h"
#include "jk_ajp14_worker.h"
#include "jk_connect.h"
#include "jk_uri_worker_map.h"
#define HUGE_BUFFER_SIZE (8*1024)
#define JK_STATUS_HEAD "<!DOCTYPE HTML PUBLIC \"-//W3C//" \
"DTD HTML 3.2 Final//EN\">\n" \
"<html><head><title>JK Status Manager</title>"
#define JK_STATUS_HEND "</head>\n<body>\n"
#define JK_STATUS_BEND "</body>\n</html>\n"
#define JK_STATUS_XMLH "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n" \
"<jk:status xmlns:jk=\"http://jakarta.apache.org\">\n"
#define JK_STATUS_XMLE "</jk:status>\n"
#define JK_STATUS_TEXTUPDATE_RESPONCE "OK - jk status worker updated\n"
typedef struct status_worker status_worker_t;
struct status_endpoint
{
jk_endpoint_t *e;
status_worker_t *s_worker;
jk_endpoint_t endpoint;
};
typedef struct status_endpoint status_endpoint_t;
struct status_worker
{
jk_pool_t p;
jk_pool_atom_t buf[TINY_POOL_SIZE];
const char *name;
const char *css;
jk_worker_t worker;
status_endpoint_t ep;
jk_worker_env_t *we;
};
static const char *worker_type[] = {
"unknown",
"ajp12",
"ajp13",
"ajp14",
"jni",
"lb",
"status",
NULL
};
static const char *headers_names[] = {
"Content-Type",
"Cache-Control",
"Pragma",
NULL
};
static const char *lb_method_type[] = {
JK_LB_METHOD_REQUESTS,
JK_LB_METHOD_TRAFFIC,
JK_LB_METHOD_BUSYNESS,
"unknown",
NULL
};
#define HEADERS_NO_CACHE "no-cache", "no-cache", NULL
static const char *headers_vhtml[] = {
"text/html",
HEADERS_NO_CACHE
};
static const char *headers_vxml[] = {
"text/xml",
HEADERS_NO_CACHE
};
static const char *headers_vtxt[] = {
"text/plain",
HEADERS_NO_CACHE
};
#if !defined(HAVE_VSNPRINTF) && !defined(HAVE_APR)
static FILE *f = NULL;
static int vsnprintf(char *str, size_t n, const char *fmt, va_list ap)
{
int res;
if (f == NULL)
f = fopen("/dev/null", "w");
if (f == NULL)
return -1;
setvbuf(f, str, _IOFBF, n);
res = vfprintf(f, fmt, ap);
if (res > 0 && res < n) {
res = vsprintf(str, fmt, ap);
}
return res;
}
#endif
static int jk_printf(jk_ws_service_t *s, const char *fmt, ...)
{
int rc = 0;
va_list args;
#ifdef NETWARE
/* On NetWare, this can get called on a thread that has a limited stack so */
/* we will allocate and free the temporary buffer in this function */
char *buf;
#else
char buf[HUGE_BUFFER_SIZE];
#endif
if (!s || !fmt) {
return -1;
}
va_start(args, fmt);
#ifdef NETWARE
buf = (char *)malloc(HUGE_BUFFER_SIZE);
if (NULL == buf)
return -1;
#endif
#ifdef USE_VSPRINTF /* until we get a vsnprintf function */
rc = vsprintf(buf, fmt, args);
#else
rc = vsnprintf(buf, HUGE_BUFFER_SIZE, fmt, args);
#endif
va_end(args);
if (rc > 0)
s->write(s, buf, rc);
#ifdef NETWARE
free(buf);
#endif
return rc;
}
/* Actually APR's apr_strfsize */
static char *status_strfsize(jk_u64_t size, char *buf)
{
const char ord[] = "KMGTPE";
const char *o = ord;
unsigned int remain, siz;
if (size < 973) {
if (sprintf(buf, "%3d ", (int) size) < 0)
return strcpy(buf, "****");
return buf;
}
do {
remain = (unsigned int)(size & 0x03FF);
size >>= 10;
if (size >= 973) {
++o;
continue;
}
siz = (unsigned int)(size & 0xFFFF);
if (siz < 9 || (siz == 9 && remain < 973)) {
if ((remain = ((remain * 5) + 256) / 512) >= 10)
++siz, remain = 0;
if (sprintf(buf, "%d.%d%c", siz, remain, *o) < 0)
return strcpy(buf, "****");
return buf;
}
if (remain >= 512)
++siz;
if (sprintf(buf, "%3d%c", siz, *o) < 0)
return strcpy(buf, "****");
return buf;
} while (1);
}
static const char *status_worker_type(int t)
{
if (t < 0 || t > 6)
t = 0;
return worker_type[t];
}
static const char *status_val_bool(int v)
{
if (v == 0)
return "False";
else
return "True";
}
static const char *status_val_status(int s, int d, int e, int r, int b)
{
if (s)
return "Stopped";
else if (d)
return "Disabled";
else if (r)
return "Recovering";
else if (e)
return "Error";
else if (b)
return "Busy";
else
return "OK";
}
static const char *status_val_match(unsigned int match)
{
if (match & MATCH_TYPE_STOPPED)
return "Stopped";
else if (match & MATCH_TYPE_DISABLED)
return "Disabled";
else if (match & MATCH_TYPE_NO_MATCH)
return "Unmount";
else if (match & MATCH_TYPE_EXACT)
return "Exact";
else if (match & MATCH_TYPE_CONTEXT)
return "Context";
else if (match & MATCH_TYPE_CONTEXT_PATH)
return "Context Path";
else if (match & MATCH_TYPE_SUFFIX)
return "Suffix";
else if (match & MATCH_TYPE_GENERAL_SUFFIX)
return "General Suffix";
else if (match & MATCH_TYPE_WILDCHAR_PATH)
return "Wildchar";
else
return "Error";
}
static void jk_puts(jk_ws_service_t *s, const char *str)
{
if (str)
s->write(s, str, strlen(str));
else
s->write(s, "(null)", 6);
}
static void jk_putv(jk_ws_service_t *s, ...)
{
va_list va;
const char *str;
va_start(va, s);
while (1) {
str = va_arg(va, const char *);
if (str == NULL)
break;
s->write(s, str, strlen(str));
}
va_end(va);
}
static const char *status_cmd(const char *param, const char *req, char *buf, size_t len)
{
char ps[32];
char *p;
size_t l = 0;
*buf = '\0';
if (!req)
return NULL;
sprintf(ps, "&%s=", param);
p = strstr(req, ps);
if (p) {
p += strlen(ps);
while (*p) {
if (*p != '&')
buf[l++] = *p;
else
break;
if (l + 2 > len)
break;
p++;
}
buf[l] = '\0';
if (l)
return buf;
else
return NULL;
}
else
return NULL;
}
static int status_int(const char *param, const char *req, int def)
{
const char *v;
char buf[32];
int rv = def;
if ((v = status_cmd(param, req, buf, sizeof(buf) -1))) {
rv = atoi(v);
}
return rv;
}
static int status_bool(const char *param, const char *req)
{
const char *v;
char buf[32];
int rv = 0;
if ((v = status_cmd(param, req, buf, sizeof(buf)))) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -