2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
18 /***************************************************************************
19 * Description: Status worker, display and manages JK workers *
20 * Author: Mladen Turk <mturk@jboss.com> *
21 * Author: Rainer Jung <rjung@apache.org> *
22 * Version: $Revision: 1054603 $ *
23 ***************************************************************************/
26 #include "jk_service.h"
28 #include "jk_worker.h"
29 #include "jk_status.h"
32 #include "jk_ajp_common.h"
33 #include "jk_lb_worker.h"
34 #include "jk_ajp13_worker.h"
35 #include "jk_ajp14_worker.h"
36 #include "jk_connect.h"
37 #include "jk_uri_worker_map.h"
39 #define HUGE_BUFFER_SIZE (8*1024)
42 * Command line reference:
43 * cmd=list (default) display configuration
44 * cmd=show display detailed configuration
45 * cmd=edit form to change configuration
46 * cmd=update commit update configuration
47 * cmd=reset reset lb runtime states, or lb member runtime states
48 * cmd=version show only software version
50 * re=n (refresh time in seconds, n=0: disabled)
51 * w=worker (cmd should be executed for worker "worker")
52 * sw=sub_worker (cmd should be executed for "sub_worker" of worker "worker")
53 * from=lastcmd (the last viewing command was "lastcmd")
54 * opt=option (changes meaning of edit and list/show)
57 #define JK_STATUS_ARG_CMD "cmd"
58 #define JK_STATUS_ARG_MIME "mime"
59 #define JK_STATUS_ARG_FROM "from"
60 #define JK_STATUS_ARG_REFRESH "re"
61 #define JK_STATUS_ARG_WORKER "w"
62 #define JK_STATUS_ARG_SUB_WORKER "sw"
63 #define JK_STATUS_ARG_PREV_SUB_WORKER "psw"
64 #define JK_STATUS_ARG_ATTRIBUTE "att"
65 #define JK_STATUS_ARG_MULT_VALUE_BASE "val"
66 #define JK_STATUS_ARG_OPTIONS "opt"
68 #define JK_STATUS_ARG_OPTION_NO_MEMBERS 0x0001
69 #define JK_STATUS_ARG_OPTION_NO_MAPS 0x0002
70 #define JK_STATUS_ARG_OPTION_NO_LEGEND 0x0004
71 #define JK_STATUS_ARG_OPTION_NO_LB 0x0008
72 #define JK_STATUS_ARG_OPTION_NO_AJP 0x0010
73 #define JK_STATUS_ARG_OPTION_READ_ONLY 0x0020
74 #define JK_STATUS_ARG_OPTION_NO_LB_CONF 0x0040
75 #define JK_STATUS_ARG_OPTION_NO_LB_SUMMARY 0x0080
76 #define JK_STATUS_ARG_OPTION_NO_AJP_CONF 0x0100
78 #define JK_STATUS_ARG_LB_RETRIES ("vlr")
79 #define JK_STATUS_ARG_LB_RETRY_INT ("vlri")
80 #define JK_STATUS_ARG_LB_RECOVER_TIME ("vlt")
81 #define JK_STATUS_ARG_LB_ERROR_ESCALATION_TIME ("vlee")
82 #define JK_STATUS_ARG_LB_MAX_REPLY_TIMEOUTS ("vlx")
83 #define JK_STATUS_ARG_LB_STICKY ("vls")
84 #define JK_STATUS_ARG_LB_STICKY_FORCE ("vlf")
85 #define JK_STATUS_ARG_LB_METHOD ("vlm")
86 #define JK_STATUS_ARG_LB_LOCK ("vll")
88 #define JK_STATUS_ARG_LB_TEXT_RETRIES "Retries"
89 #define JK_STATUS_ARG_LB_TEXT_RETRY_INT "Retry Interval"
90 #define JK_STATUS_ARG_LB_TEXT_RECOVER_TIME "Recover Wait Time"
91 #define JK_STATUS_ARG_LB_TEXT_ERROR_ESCALATION_TIME "Error Escalation Time"
92 #define JK_STATUS_ARG_LB_TEXT_MAX_REPLY_TIMEOUTS "Max Reply Timeouts"
93 #define JK_STATUS_ARG_LB_TEXT_STICKY "Sticky Sessions"
94 #define JK_STATUS_ARG_LB_TEXT_STICKY_FORCE "Force Sticky Sessions"
95 #define JK_STATUS_ARG_LB_TEXT_METHOD "LB Method"
96 #define JK_STATUS_ARG_LB_TEXT_LOCK "Locking"
98 #define JK_STATUS_ARG_LBM_ACTIVATION ("vwa")
99 #define JK_STATUS_ARG_LBM_FACTOR ("vwf")
100 #define JK_STATUS_ARG_LBM_ROUTE ("vwn")
101 #define JK_STATUS_ARG_LBM_REDIRECT ("vwr")
102 #define JK_STATUS_ARG_LBM_DOMAIN ("vwc")
103 #define JK_STATUS_ARG_LBM_DISTANCE ("vwd")
105 #define JK_STATUS_ARG_LBM_TEXT_ACTIVATION "Activation"
106 #define JK_STATUS_ARG_LBM_TEXT_FACTOR "LB Factor"
107 #define JK_STATUS_ARG_LBM_TEXT_ROUTE "Route"
108 #define JK_STATUS_ARG_LBM_TEXT_REDIRECT "Redirect Route"
109 #define JK_STATUS_ARG_LBM_TEXT_DOMAIN "Cluster Domain"
110 #define JK_STATUS_ARG_LBM_TEXT_DISTANCE "Distance"
112 #define JK_STATUS_ARG_AJP_CACHE_TO "vacpt"
113 #define JK_STATUS_ARG_AJP_PING_TO "vapng"
114 #define JK_STATUS_ARG_AJP_CONNECT_TO "vact"
115 #define JK_STATUS_ARG_AJP_PREPOST_TO "vapt"
116 #define JK_STATUS_ARG_AJP_REPLY_TO "vart"
117 #define JK_STATUS_ARG_AJP_RETRIES "var"
118 #define JK_STATUS_ARG_AJP_RETRY_INT "vari"
119 #define JK_STATUS_ARG_AJP_REC_OPTS "varo"
120 #define JK_STATUS_ARG_AJP_MAX_PK_SZ "vamps"
121 #define JK_STATUS_ARG_AJP_CPING_INT "vacpi"
122 #define JK_STATUS_ARG_AJP_HOST_STR "vahst"
123 #define JK_STATUS_ARG_AJP_PORT "vaprt"
125 #define JK_STATUS_ARG_AJP_TEXT_CACHE_TO "Connection Pool Timeout"
126 #define JK_STATUS_ARG_AJP_TEXT_PING_TO "Ping Timeout"
127 #define JK_STATUS_ARG_AJP_TEXT_CONNECT_TO "Connect Timeout"
128 #define JK_STATUS_ARG_AJP_TEXT_PREPOST_TO "Prepost Timeout"
129 #define JK_STATUS_ARG_AJP_TEXT_REPLY_TO "Reply Timeout"
130 #define JK_STATUS_ARG_AJP_TEXT_RETRIES "Retries"
131 #define JK_STATUS_ARG_AJP_TEXT_RETRY_INT "Retry Interval"
132 #define JK_STATUS_ARG_AJP_TEXT_REC_OPTS "Recovery Options"
133 #define JK_STATUS_ARG_AJP_TEXT_MAX_PK_SZ "Max Packet Size"
134 #define JK_STATUS_ARG_AJP_TEXT_CPING_INT "Connection Ping Interval"
135 #define JK_STATUS_ARG_AJP_TEXT_HOST_STR "Hostname"
136 #define JK_STATUS_ARG_AJP_TEXT_PORT "Port"
137 #define JK_STATUS_ARG_AJP_TEXT_ADDR_STR "Address:Port"
139 #define JK_STATUS_CMD_UNKNOWN (0)
140 #define JK_STATUS_CMD_LIST (1)
141 #define JK_STATUS_CMD_SHOW (2)
142 #define JK_STATUS_CMD_EDIT (3)
143 #define JK_STATUS_CMD_UPDATE (4)
144 #define JK_STATUS_CMD_RESET (5)
145 #define JK_STATUS_CMD_VERSION (6)
146 #define JK_STATUS_CMD_RECOVER (7)
147 #define JK_STATUS_CMD_DUMP (8)
148 #define JK_STATUS_CMD_DEF (JK_STATUS_CMD_LIST)
149 #define JK_STATUS_CMD_MAX (JK_STATUS_CMD_DUMP)
150 #define JK_STATUS_CMD_TEXT_UNKNOWN ("unknown")
151 #define JK_STATUS_CMD_TEXT_LIST ("list")
152 #define JK_STATUS_CMD_TEXT_SHOW ("show")
153 #define JK_STATUS_CMD_TEXT_EDIT ("edit")
154 #define JK_STATUS_CMD_TEXT_UPDATE ("update")
155 #define JK_STATUS_CMD_TEXT_RESET ("reset")
156 #define JK_STATUS_CMD_TEXT_VERSION ("version")
157 #define JK_STATUS_CMD_TEXT_RECOVER ("recover")
158 #define JK_STATUS_CMD_TEXT_DUMP ("dump")
159 #define JK_STATUS_CMD_TEXT_DEF (JK_STATUS_CMD_TEXT_LIST)
161 #define JK_STATUS_CMD_PROP_CHECK_WORKER 0x00000001
162 #define JK_STATUS_CMD_PROP_READONLY 0x00000002
163 #define JK_STATUS_CMD_PROP_HEAD 0x00000004
164 #define JK_STATUS_CMD_PROP_REFRESH 0x00000008
165 #define JK_STATUS_CMD_PROP_BACK_LINK 0x00000010
166 #define JK_STATUS_CMD_PROP_BACK_LIST 0x00000020
167 #define JK_STATUS_CMD_PROP_FMT 0x00000040
168 #define JK_STATUS_CMD_PROP_SWITCH_RO 0x00000080
169 #define JK_STATUS_CMD_PROP_DUMP_LINK 0x00000100
170 #define JK_STATUS_CMD_PROP_LINK_HELP 0x00000200
171 #define JK_STATUS_CMD_PROP_LEGEND 0x00000400
172 #define JK_STATUS_CMD_PROP_WILDCARD 0x00000800
174 #define JK_STATUS_MIME_UNKNOWN (0)
175 #define JK_STATUS_MIME_HTML (1)
176 #define JK_STATUS_MIME_XML (2)
177 #define JK_STATUS_MIME_TXT (3)
178 #define JK_STATUS_MIME_PROP (4)
179 #define JK_STATUS_MIME_DEF (JK_STATUS_MIME_HTML)
180 #define JK_STATUS_MIME_MAX (JK_STATUS_MIME_PROP)
181 #define JK_STATUS_MIME_TEXT_UNKNOWN ("unknown")
182 #define JK_STATUS_MIME_TEXT_HTML ("html")
183 #define JK_STATUS_MIME_TEXT_XML ("xml")
184 #define JK_STATUS_MIME_TEXT_TXT ("txt")
185 #define JK_STATUS_MIME_TEXT_PROP ("prop")
186 #define JK_STATUS_MIME_TEXT_DEF (JK_STATUS_MIME_TEXT_HTML)
188 #define JK_STATUS_MASK_ACTIVE 0x000000FF
189 #define JK_STATUS_MASK_DISABLED 0x0000FF00
190 #define JK_STATUS_MASK_STOPPED 0x00FF0000
191 #define JK_STATUS_MASK_OK 0x00010101
192 #define JK_STATUS_MASK_IDLE 0x00020202
193 #define JK_STATUS_MASK_BUSY 0x00040404
194 #define JK_STATUS_MASK_RECOVER 0x00080808
195 #define JK_STATUS_MASK_ERROR 0x00101010
196 #define JK_STATUS_MASK_GOOD_DEF 0x0000000F
197 #define JK_STATUS_MASK_BAD_DEF 0x00FF1010
199 #define JK_STATUS_NEEDS_PUSH 0x00000001
200 #define JK_STATUS_NEEDS_RESET_LB_VALUES 0x00000002
201 #define JK_STATUS_NEEDS_UPDATE_MULT 0x00000004
202 #define JK_STATUS_NEEDS_ADDR_PUSH 0x00000008
204 #define JK_STATUS_WAIT_AFTER_UPDATE "3"
205 #define JK_STATUS_REFRESH_DEF "10"
206 #define JK_STATUS_ESC_CHARS ("<>?\"")
207 #define JK_STATUS_TIME_FMT_HTML "%a, %d %b %Y %X %Z"
208 #define JK_STATUS_TIME_FMT_TEXT "%Y%m%d%H%M%S"
209 #define JK_STATUS_TIME_FMT_TZ "%Z"
210 #define JK_STATUS_TIME_BUF_SZ (80)
212 #define JK_STATUS_HEAD "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n" \
213 "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"" \
214 " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n" \
215 "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">" \
216 "<head><title>JK Status Manager</title>"
218 #define JK_STATUS_COPYRIGHT "Copyright © 1999-2011, The Apache Software Foundation<br />" \
219 "Licensed under the <a href=\"http://www.apache.org/licenses/LICENSE-2.0\">" \
220 "Apache License, Version 2.0</a>."
222 #define JK_STATUS_HEND "</head>\n<body>\n"
223 #define JK_STATUS_BEND "</body>\n</html>\n"
225 #define JK_STATUS_XMLH "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
227 #define JK_STATUS_NS_DEF "jk:"
228 #define JK_STATUS_XMLNS_DEF "xmlns:jk=\"http://tomcat.apache.org\""
229 #define JK_STATUS_PREFIX_DEF "worker"
231 #define JK_STATUS_FORM_START "<form method=\"%s\" action=\"%s\">\n"
232 #define JK_STATUS_FORM_HIDDEN_INT "<input type=\"hidden\" name=\"%s\" value=\"%d\"/>\n"
233 #define JK_STATUS_FORM_HIDDEN_STRING "<input type=\"hidden\" name=\"%s\" value=\"%s\"/>\n"
234 #define JK_STATUS_URI_MAP_TABLE_HEAD "<tr><th>%s</th><th>%s</th><th>%s</th><th>%s</th><th>%s</th><th>%s</th><th>%s</th><th>%s</th><th>%s</th></tr>\n"
235 #define JK_STATUS_URI_MAP_TABLE_ROW "<tr><td>%s</td><td>%s</td><td>%s</td><td>%d</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%d</td></tr>\n"
236 #define JK_STATUS_URI_MAP_TABLE_HEAD2 "<tr><th>%s</th><th>%s</th><th>%s</th><th>%s</th><th>%s</th><th>%s</th><th>%s</th><th>%s</th><th>%s</th><th>%s</th></tr>\n"
237 #define JK_STATUS_URI_MAP_TABLE_ROW2 "<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%d</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%d</td></tr>\n"
238 #define JK_STATUS_SHOW_AJP_CONF_HEAD "<tr>" \
240 "<th>" JK_STATUS_ARG_AJP_TEXT_HOST_STR "</th>" \
241 "<th>" JK_STATUS_ARG_AJP_TEXT_ADDR_STR "</th>" \
242 "<th>" JK_STATUS_ARG_AJP_TEXT_CACHE_TO "</th>" \
243 "<th>" JK_STATUS_ARG_AJP_TEXT_CONNECT_TO "</th>" \
244 "<th>" JK_STATUS_ARG_AJP_TEXT_PREPOST_TO "</th>" \
245 "<th>" JK_STATUS_ARG_AJP_TEXT_REPLY_TO "</th>" \
246 "<th>" JK_STATUS_ARG_AJP_TEXT_RETRIES "</th>" \
247 "<th>" JK_STATUS_ARG_AJP_TEXT_REC_OPTS "</th>" \
248 "<th>" JK_STATUS_ARG_AJP_TEXT_MAX_PK_SZ "</th>" \
250 #define JK_STATUS_SHOW_AJP_CONF_ROW "<tr>" \
262 #define JK_STATUS_SHOW_AJP_HEAD "<tr>" \
265 "<th>Err</th><th>CE</th><th>RE</th>" \
266 "<th>Wr</th><th>Rd</th><th>Busy</th><th>Max</th><th>Con</th><th>LR</th><th>LE</th>" \
268 #define JK_STATUS_SHOW_AJP_ROW "<tr>" \
270 "<td>%" JK_UINT64_T_FMT " (%d/sec)</td>" \
271 "<td>%" JK_UINT32_T_FMT "</td>" \
272 "<td>%" JK_UINT32_T_FMT "</td>" \
273 "<td>%" JK_UINT32_T_FMT "</td>" \
274 "<td>%s (%s/sec)</td>" \
275 "<td>%s (%s/sec)</td>" \
282 #define JK_STATUS_SHOW_LB_HEAD "<tr>" \
284 "<th>" JK_STATUS_ARG_LB_TEXT_STICKY "</th>" \
285 "<th>" JK_STATUS_ARG_LB_TEXT_STICKY_FORCE "</th>" \
286 "<th>" JK_STATUS_ARG_LB_TEXT_RETRIES "</th>" \
287 "<th>" JK_STATUS_ARG_LB_TEXT_METHOD "</th>" \
288 "<th>" JK_STATUS_ARG_LB_TEXT_LOCK "</th>" \
289 "<th>" JK_STATUS_ARG_LB_TEXT_RECOVER_TIME "</th>" \
290 "<th>" JK_STATUS_ARG_LB_TEXT_ERROR_ESCALATION_TIME "</th>" \
291 "<th>" JK_STATUS_ARG_LB_TEXT_MAX_REPLY_TIMEOUTS "</th>" \
293 #define JK_STATUS_SHOW_LB_ROW "<tr>" \
305 #define JK_STATUS_SHOW_MEMBER_HEAD "<tr>" \
306 "<th> </th><th>Name</th>" \
307 "<th>Act</th><th>State</th>" \
308 "<th>D</th><th>F</th><th>M</th>" \
309 "<th>V</th><th>Acc</th>" \
310 "<th>Err</th><th>CE</th><th>RE</th>" \
311 "<th>Wr</th><th>Rd</th><th>Busy</th><th>Max</th><th>Con</th>" \
312 "<th>" JK_STATUS_ARG_LBM_TEXT_ROUTE "</th>" \
313 "<th>RR</th><th>Cd</th><th>Rs</th><th>LR</th><th>LE</th>" \
315 #define JK_STATUS_SHOW_MEMBER_ROW "<td>%s</td>" \
320 "<td>%" JK_UINT64_T_FMT "</td>" \
321 "<td>%" JK_UINT64_T_FMT "</td>" \
322 "<td>%" JK_UINT64_T_FMT " (%d/sec)</td>" \
323 "<td>%" JK_UINT32_T_FMT "</td>" \
324 "<td>%" JK_UINT32_T_FMT "</td>" \
325 "<td>%" JK_UINT32_T_FMT "</td>" \
326 "<td>%s (%s/sec)</td>" \
327 "<td>%s (%s/sec)</td>" \
338 #define JK_STATUS_SHOW_MEMBER_CONF_HEAD "<tr>" \
339 "<th>Name</th><th>Type</th>" \
340 "<th>" JK_STATUS_ARG_AJP_TEXT_HOST_STR "</th>" \
341 "<th>" JK_STATUS_ARG_AJP_TEXT_ADDR_STR "</th>" \
342 "<th>" JK_STATUS_ARG_AJP_TEXT_CACHE_TO "</th>" \
343 "<th>" JK_STATUS_ARG_AJP_TEXT_CONNECT_TO "</th>" \
344 "<th>" JK_STATUS_ARG_AJP_TEXT_PREPOST_TO "</th>" \
345 "<th>" JK_STATUS_ARG_AJP_TEXT_REPLY_TO "</th>" \
346 "<th>" JK_STATUS_ARG_AJP_TEXT_RETRIES "</th>" \
347 "<th>" JK_STATUS_ARG_AJP_TEXT_REC_OPTS "</th>" \
348 "<th>" JK_STATUS_ARG_AJP_TEXT_MAX_PK_SZ "</th>" \
350 #define JK_STATUS_SHOW_MEMBER_CONF_ROW "<tr>" \
365 typedef struct status_worker status_worker_t;
367 struct status_endpoint
369 status_worker_t *worker;
372 jk_map_t *req_params;
375 jk_endpoint_t endpoint;
379 typedef struct status_endpoint status_endpoint_t;
384 jk_pool_atom_t buf[TINY_POOL_SIZE];
393 unsigned int num_of_users;
394 int user_case_insensitive;
395 jk_uint32_t good_mask;
396 jk_uint32_t bad_mask;
401 static const char *worker_type[] = {
412 static const char *headers_names[] = {
419 static const char *cmd_type[] = {
420 JK_STATUS_CMD_TEXT_UNKNOWN,
421 JK_STATUS_CMD_TEXT_LIST,
422 JK_STATUS_CMD_TEXT_SHOW,
423 JK_STATUS_CMD_TEXT_EDIT,
424 JK_STATUS_CMD_TEXT_UPDATE,
425 JK_STATUS_CMD_TEXT_RESET,
426 JK_STATUS_CMD_TEXT_VERSION,
427 JK_STATUS_CMD_TEXT_RECOVER,
428 JK_STATUS_CMD_TEXT_DUMP,
432 static const char *mime_type[] = {
433 JK_STATUS_MIME_TEXT_UNKNOWN,
434 JK_STATUS_MIME_TEXT_HTML,
435 JK_STATUS_MIME_TEXT_XML,
436 JK_STATUS_MIME_TEXT_TXT,
437 JK_STATUS_MIME_TEXT_PROP,
441 #define HEADERS_NO_CACHE "no-cache", "no-cache", NULL
443 static const char *headers_vhtml[] = {
448 static const char *headers_vxml[] = {
453 static const char *headers_vtxt[] = {
458 static void jk_puts(jk_ws_service_t *s, const char *str)
461 s->write(s, str, (unsigned int)strlen(str));
463 s->write(s, "(null)", 6);
466 static void jk_putv(jk_ws_service_t *s, ...)
473 str = va_arg(va, const char *);
476 s->write(s, str, (unsigned int)strlen(str));
481 static int jk_printf(jk_ws_service_t *s, const char *fmt, ...)
486 /* On NetWare, this can get called on a thread that has a limited stack so */
487 /* we will allocate and free the temporary buffer in this function */
490 char buf[HUGE_BUFFER_SIZE];
499 buf = (char *)malloc(HUGE_BUFFER_SIZE);
503 rc = vsnprintf(buf, HUGE_BUFFER_SIZE, fmt, args);
506 s->write(s, buf, rc);
513 static void jk_print_xml_start_elt(jk_ws_service_t *s, status_worker_t *w,
514 int indentation, int close_tag,
518 jk_printf(s, "%*s<%s%s>\n", indentation, "", w->ns, name);
521 jk_printf(s, "%*s<%s%s\n", indentation, "", w->ns, name);
525 static void jk_print_xml_close_elt(jk_ws_service_t *s, status_worker_t *w,
529 jk_printf(s, "%*s</%s%s>\n", indentation, "", w->ns, name);
532 static void jk_print_xml_stop_elt(jk_ws_service_t *s,
533 int indentation, int close_tag)
536 jk_printf(s, "%*s/>\n", indentation, "");
539 jk_printf(s, "%*s>\n", indentation, "");
543 static void jk_print_xml_att_string(jk_ws_service_t *s,
545 const char *key, const char *value)
547 jk_printf(s, "%*s%s=\"%s\"\n", indentation, "", key, value ? value : "");
550 static void jk_print_xml_att_int(jk_ws_service_t *s,
552 const char *key, int value)
554 jk_printf(s, "%*s%s=\"%d\"\n", indentation, "", key, value);
557 static void jk_print_xml_att_uint(jk_ws_service_t *s,
559 const char *key, unsigned int value)
561 jk_printf(s, "%*s%s=\"%u\"\n", indentation, "", key, value);
564 static void jk_print_xml_att_long(jk_ws_service_t *s,
566 const char *key, long value)
568 jk_printf(s, "%*s%s=\"%ld\"\n", indentation, "", key, value);
571 static void jk_print_xml_att_uint32(jk_ws_service_t *s,
573 const char *key, jk_uint32_t value)
575 jk_printf(s, "%*s%s=\"%" JK_UINT32_T_FMT "\"\n", indentation, "", key, value);
578 static void jk_print_xml_att_uint64(jk_ws_service_t *s,
580 const char *key, jk_uint64_t value)
582 jk_printf(s, "%*s%s=\"%" JK_UINT64_T_FMT "\"\n", indentation, "", key, value);
585 static void jk_print_prop_att_string(jk_ws_service_t *s, status_worker_t *w,
587 const char *key, const char *value)
590 jk_printf(s, "%s.%s.%s=%s\n", w->prefix, name, key, value ? value : "");
593 jk_printf(s, "%s.%s=%s\n", w->prefix, key, value ? value : "");
597 static void jk_print_prop_att_int(jk_ws_service_t *s, status_worker_t *w,
599 const char *key, int value)
602 jk_printf(s, "%s.%s.%s=%d\n", w->prefix, name, key, value);
605 jk_printf(s, "%s.%s=%d\n", w->prefix, key, value);
609 static void jk_print_prop_att_uint(jk_ws_service_t *s, status_worker_t *w,
611 const char *key, unsigned int value)
614 jk_printf(s, "%s.%s.%s=%u\n", w->prefix, name, key, value);
617 jk_printf(s, "%s.%s=%u\n", w->prefix, key, value);
621 static void jk_print_prop_att_long(jk_ws_service_t *s, status_worker_t *w,
623 const char *key, long value)
626 jk_printf(s, "%s.%s.%s=%ld\n", w->prefix, name, key, value);
629 jk_printf(s, "%s.%s=%ld\n", w->prefix, key, value);
633 static void jk_print_prop_att_uint32(jk_ws_service_t *s, status_worker_t *w,
635 const char *key, jk_uint32_t value)
638 jk_printf(s, "%s.%s.%s=%" JK_UINT32_T_FMT "\n", w->prefix, name, key, value);
641 jk_printf(s, "%s.%s=%" JK_UINT32_T_FMT "\n", w->prefix, key, value);
645 static void jk_print_prop_att_uint64(jk_ws_service_t *s, status_worker_t *w,
647 const char *key, jk_uint64_t value)
650 jk_printf(s, "%s.%s.%s=%" JK_UINT64_T_FMT "\n", w->prefix, name, key, value);
653 jk_printf(s, "%s.%s=%" JK_UINT64_T_FMT "\n", w->prefix, key, value);
657 static void jk_print_prop_item_int(jk_ws_service_t *s, status_worker_t *w,
658 const char *name, const char *list, int num,
659 const char *key, int value)
662 jk_printf(s, "%s.%s.%s.%d.%s=%d\n", w->prefix, name, list, num, key, value);
665 jk_printf(s, "%s.%s.%d.%s=%d\n", w->prefix, list, num, key, value);
669 static void jk_print_prop_item_string(jk_ws_service_t *s, status_worker_t *w,
670 const char *name, const char *list, int num,
671 const char *key, const char *value)
674 jk_printf(s, "%s.%s.%s.%d.%s=%s\n", w->prefix, name, list, num, key, value ? value : "");
677 jk_printf(s, "%s.%s.%d.%s=%s\n", w->prefix, list, num, key, value ? value : "");
681 /* Actually APR's apr_strfsize */
682 static char *status_strfsize(jk_uint64_t size, char *buf)
684 const char ord[] = "KMGTPE";
686 unsigned int remain, siz;
689 if (sprintf(buf, "%d ", (int) size) < 0)
690 return strcpy(buf, "****");
694 remain = (unsigned int)(size & 0x03FF);
700 siz = (unsigned int)(size & 0xFFFF);
701 if (siz < 9 || (siz == 9 && remain < 973)) {
702 if ((remain = ((remain * 5) + 256) / 512) >= 10)
704 if (sprintf(buf, "%d.%d%c", siz, remain, *o) < 0)
705 return strcpy(buf, "****");
710 if (sprintf(buf, "%d%c", siz, *o) < 0)
711 return strcpy(buf, "****");
716 static int status_strftime(time_t clock, int mime, char *buf_time, char *buf_tz,
720 #ifdef _MT_CODE_PTHREAD
722 struct tm *tms = localtime_r(&clock, &res);
724 struct tm *tms = localtime(&clock);
729 if (mime == JK_STATUS_MIME_HTML)
730 rc_time = strftime(buf_time, JK_STATUS_TIME_BUF_SZ, JK_STATUS_TIME_FMT_HTML, tms);
732 rc_time = strftime(buf_time, JK_STATUS_TIME_BUF_SZ, JK_STATUS_TIME_FMT_TEXT, tms);
734 strftime(buf_tz, JK_STATUS_TIME_BUF_SZ, JK_STATUS_TIME_FMT_TZ, tms);
741 static int status_rate(lb_sub_worker_t *wr, status_worker_t *w,
744 jk_uint32_t mask = 0;
745 int activation = wr->activation;
746 int state = wr->s->state;
747 jk_uint32_t good = w->good_mask;
748 jk_uint32_t bad = w->bad_mask;
753 case JK_LB_ACTIVATION_ACTIVE:
754 mask = JK_STATUS_MASK_ACTIVE;
756 case JK_LB_ACTIVATION_DISABLED:
757 mask = JK_STATUS_MASK_DISABLED;
759 case JK_LB_ACTIVATION_STOPPED:
760 mask = JK_STATUS_MASK_STOPPED;
763 jk_log(l, JK_LOG_WARNING,
764 "Status worker '%s' unknown activation type '%d'",
765 w->name, activation);
769 case JK_LB_STATE_IDLE:
770 mask &= JK_STATUS_MASK_IDLE;
773 mask &= JK_STATUS_MASK_OK;
775 case JK_LB_STATE_RECOVER:
776 mask &= JK_STATUS_MASK_RECOVER;
778 case JK_LB_STATE_FORCE:
779 mask &= JK_STATUS_MASK_RECOVER;
781 case JK_LB_STATE_BUSY:
782 mask &= JK_STATUS_MASK_BUSY;
784 case JK_LB_STATE_ERROR:
785 mask &= JK_STATUS_MASK_ERROR;
787 case JK_LB_STATE_PROBE:
788 mask &= JK_STATUS_MASK_RECOVER;
791 jk_log(l, JK_LOG_WARNING,
792 "Status worker '%s' unknown state type '%d'",
801 if (JK_IS_DEBUG_LEVEL(l))
802 jk_log(l, JK_LOG_DEBUG,
803 "Status worker '%s' rating of activation '%s' and state '%s' for good '%08" JK_UINT32_T_HEX_FMT
804 "' and bad '%08" JK_UINT32_T_HEX_FMT "' is %d",
805 w->name, jk_lb_get_activation(wr, l), jk_lb_get_state(wr, l),
810 static jk_uint32_t status_get_single_rating(const char rating, jk_logger_t *l)
812 if (JK_IS_DEBUG_LEVEL(l))
813 jk_log(l, JK_LOG_DEBUG,
814 "rating retrieval for '%c'",
820 return JK_STATUS_MASK_ACTIVE;
823 return JK_STATUS_MASK_DISABLED;
826 return JK_STATUS_MASK_STOPPED;
829 return JK_STATUS_MASK_OK;
834 return JK_STATUS_MASK_IDLE;
837 return JK_STATUS_MASK_BUSY;
840 return JK_STATUS_MASK_RECOVER;
843 return JK_STATUS_MASK_ERROR;
845 jk_log(l, JK_LOG_WARNING,
846 "Unknown rating type '%c'",
852 static jk_uint32_t status_get_rating(const char *rating,
856 jk_uint32_t mask = 0;
858 while (rating[off] == ' ' || rating[off] == '\t' || rating[off] == '.') {
861 mask = status_get_single_rating(rating[off], l);
862 while (rating[off] != '\0' && rating[off] != '.') {
865 if (rating[off] == '.') {
868 if (rating[off] != '\0') {
869 mask &= status_get_single_rating(rating[off], l);
871 if (JK_IS_DEBUG_LEVEL(l))
872 jk_log(l, JK_LOG_DEBUG,
873 "rating for '%s' is '%08" JK_UINT32_T_HEX_FMT "'",
878 static const char *status_worker_type(int t)
882 return worker_type[t];
886 static int status_get_string(status_endpoint_t *p,
894 *result = jk_map_get_string(p->req_params,
903 if (JK_IS_DEBUG_LEVEL(l))
904 jk_log(l, JK_LOG_DEBUG,
905 "retrieved string arg '%s' as '%s'%s",
906 param, *result ? *result : "(null)",
907 rv == JK_FALSE ? " (default)" : "");
911 static int status_get_int(status_endpoint_t *p,
919 if (status_get_string(p, param, NULL, &arg, l) == JK_TRUE) {
925 static int status_get_bool(status_endpoint_t *p,
932 if (status_get_string(p, param, NULL, &arg, l) == JK_TRUE) {
933 return jk_get_bool_code(arg, def);
938 static const char *status_cmd_text(int cmd)
940 return cmd_type[cmd];
943 static int status_cmd_int(const char *cmd)
946 return JK_STATUS_CMD_DEF;
947 if (!strcmp(cmd, JK_STATUS_CMD_TEXT_LIST))
948 return JK_STATUS_CMD_LIST;
949 else if (!strcmp(cmd, JK_STATUS_CMD_TEXT_SHOW))
950 return JK_STATUS_CMD_SHOW;
951 else if (!strcmp(cmd, JK_STATUS_CMD_TEXT_EDIT))
952 return JK_STATUS_CMD_EDIT;
953 else if (!strcmp(cmd, JK_STATUS_CMD_TEXT_UPDATE))
954 return JK_STATUS_CMD_UPDATE;
955 else if (!strcmp(cmd, JK_STATUS_CMD_TEXT_RESET))
956 return JK_STATUS_CMD_RESET;
957 else if (!strcmp(cmd, JK_STATUS_CMD_TEXT_VERSION))
958 return JK_STATUS_CMD_VERSION;
959 else if (!strcmp(cmd, JK_STATUS_CMD_TEXT_RECOVER))
960 return JK_STATUS_CMD_RECOVER;
961 else if (!strcmp(cmd, JK_STATUS_CMD_TEXT_DUMP))
962 return JK_STATUS_CMD_DUMP;
963 return JK_STATUS_CMD_UNKNOWN;
966 static const char *status_mime_text(int mime)
968 return mime_type[mime];
971 static int status_mime_int(const char *mime)
974 return JK_STATUS_MIME_DEF;
975 if (!strcmp(mime, JK_STATUS_MIME_TEXT_HTML))
976 return JK_STATUS_MIME_HTML;
977 else if (!strcmp(mime, JK_STATUS_MIME_TEXT_XML))
978 return JK_STATUS_MIME_XML;
979 else if (!strcmp(mime, JK_STATUS_MIME_TEXT_TXT))
980 return JK_STATUS_MIME_TXT;
981 else if (!strcmp(mime, JK_STATUS_MIME_TEXT_PROP))
982 return JK_STATUS_MIME_PROP;
983 return JK_STATUS_MIME_UNKNOWN;
986 static jk_uint32_t status_cmd_props(int cmd)
988 jk_uint32_t props = 0;
990 if (cmd == JK_STATUS_CMD_LIST ||
991 cmd == JK_STATUS_CMD_SHOW)
992 props |= JK_STATUS_CMD_PROP_REFRESH |
993 JK_STATUS_CMD_PROP_SWITCH_RO |
994 JK_STATUS_CMD_PROP_LINK_HELP |
995 JK_STATUS_CMD_PROP_LEGEND;
996 if (cmd == JK_STATUS_CMD_LIST ||
997 cmd == JK_STATUS_CMD_SHOW ||
998 cmd == JK_STATUS_CMD_VERSION)
999 props |= JK_STATUS_CMD_PROP_DUMP_LINK;
1000 if (cmd == JK_STATUS_CMD_LIST ||
1001 cmd == JK_STATUS_CMD_SHOW ||
1002 cmd == JK_STATUS_CMD_VERSION ||
1003 cmd == JK_STATUS_CMD_DUMP)
1004 props |= JK_STATUS_CMD_PROP_HEAD |
1005 JK_STATUS_CMD_PROP_FMT;
1006 if (cmd == JK_STATUS_CMD_SHOW ||
1007 cmd == JK_STATUS_CMD_VERSION ||
1008 cmd == JK_STATUS_CMD_DUMP)
1009 props |= JK_STATUS_CMD_PROP_BACK_LIST;
1010 if (cmd == JK_STATUS_CMD_SHOW ||
1011 cmd == JK_STATUS_CMD_EDIT ||
1012 cmd == JK_STATUS_CMD_VERSION ||
1013 cmd == JK_STATUS_CMD_DUMP)
1014 props |= JK_STATUS_CMD_PROP_BACK_LINK;
1015 if (cmd == JK_STATUS_CMD_UPDATE)
1016 props |= JK_STATUS_CMD_PROP_WILDCARD;
1017 if (cmd != JK_STATUS_CMD_EDIT &&
1018 cmd != JK_STATUS_CMD_UPDATE &&
1019 cmd != JK_STATUS_CMD_RESET &&
1020 cmd != JK_STATUS_CMD_RECOVER)
1021 props |= JK_STATUS_CMD_PROP_READONLY;
1022 if (cmd != JK_STATUS_CMD_LIST &&
1023 cmd != JK_STATUS_CMD_VERSION &&
1024 cmd != JK_STATUS_CMD_DUMP)
1025 props |= JK_STATUS_CMD_PROP_CHECK_WORKER;
1030 static void status_start_form(jk_ws_service_t *s,
1031 status_endpoint_t *p,
1034 const char *overwrite,
1040 jk_map_t *m = p->req_params;
1043 jk_printf(s, JK_STATUS_FORM_START, method, s->req_uri);
1046 if (cmd != JK_STATUS_CMD_UNKNOWN) {
1047 jk_printf(s, JK_STATUS_FORM_HIDDEN_STRING,
1048 JK_STATUS_ARG_CMD, status_cmd_text(cmd));
1051 sz = jk_map_size(m);
1052 for (i = 0; i < sz; i++) {
1053 const char *k = jk_map_name_at(m, i);
1054 const char *v = jk_map_value_at(m, i);
1055 if ((strcmp(k, JK_STATUS_ARG_CMD) ||
1056 cmd == JK_STATUS_CMD_UNKNOWN) &&
1058 strcmp(k, overwrite))) {
1059 jk_printf(s, JK_STATUS_FORM_HIDDEN_STRING, k, v);
1064 static void status_write_uri(jk_ws_service_t *s,
1065 status_endpoint_t *p,
1068 const char *worker, const char *sub_worker,
1069 unsigned int add_options, unsigned int rm_options,
1070 const char *attribute,
1077 int restore_sub_worker = JK_FALSE;
1078 int save_sub_worker = JK_FALSE;
1080 unsigned int opt = 0;
1082 jk_map_t *m = p->req_params;
1085 jk_puts(s, "<a href=\"");
1086 jk_puts(s, s->req_uri);
1087 status_get_string(p, JK_STATUS_ARG_FROM, NULL, &arg, l);
1088 from = status_cmd_int(arg);
1089 status_get_string(p, JK_STATUS_ARG_CMD, NULL, &arg, l);
1090 prev = status_cmd_int(arg);
1091 if (cmd == JK_STATUS_CMD_SHOW && prev == JK_STATUS_CMD_EDIT) {
1092 restore_sub_worker = JK_TRUE;
1094 if (cmd == JK_STATUS_CMD_UNKNOWN) {
1095 if (prev == JK_STATUS_CMD_UPDATE ||
1096 prev == JK_STATUS_CMD_RESET ||
1097 prev == JK_STATUS_CMD_RECOVER) {
1099 restore_sub_worker = JK_TRUE;
1102 if (cmd != JK_STATUS_CMD_UNKNOWN) {
1103 jk_printf(s, "%s%s=%s", started ? "&" : "?",
1104 JK_STATUS_ARG_CMD, status_cmd_text(cmd));
1105 if (cmd == JK_STATUS_CMD_EDIT ||
1106 cmd == JK_STATUS_CMD_RESET ||
1107 cmd == JK_STATUS_CMD_RECOVER) {
1108 jk_printf(s, "%s%s=%s", "&",
1109 JK_STATUS_ARG_FROM, status_cmd_text(prev));
1110 save_sub_worker = JK_TRUE;
1114 if (mime != JK_STATUS_MIME_UNKNOWN) {
1115 jk_printf(s, "%s%s=%s", started ? "&" : "?",
1116 JK_STATUS_ARG_MIME, status_mime_text(mime));
1119 if (worker && worker[0]) {
1120 jk_printf(s, "%s%s=%s", started ? "&" : "?",
1121 JK_STATUS_ARG_WORKER, worker);
1124 if (sub_worker && sub_worker[0] && cmd != JK_STATUS_CMD_LIST) {
1125 jk_printf(s, "%s%s=%s", started ? "&" : "?",
1126 JK_STATUS_ARG_SUB_WORKER, sub_worker);
1129 if (attribute && attribute[0]) {
1130 jk_printf(s, "%s%s=%s", started ? "&" : "?",
1131 JK_STATUS_ARG_ATTRIBUTE, attribute);
1135 sz = jk_map_size(m);
1136 for (i = 0; i < sz; i++) {
1137 const char *k = jk_map_name_at(m, i);
1138 const char *v = jk_map_value_at(m, i);
1139 if (!strcmp(k, JK_STATUS_ARG_CMD) && cmd != JK_STATUS_CMD_UNKNOWN) {
1142 if (!strcmp(k, JK_STATUS_ARG_MIME) && mime != JK_STATUS_MIME_UNKNOWN) {
1145 if (!strcmp(k, JK_STATUS_ARG_FROM)) {
1148 if (!strcmp(k, JK_STATUS_ARG_WORKER) && worker) {
1151 if (!strcmp(k, JK_STATUS_ARG_SUB_WORKER)) {
1152 if (save_sub_worker == JK_TRUE) {
1153 jk_printf(s, "%s%s=%s", started ? "&" : "?",
1154 JK_STATUS_ARG_PREV_SUB_WORKER, v);
1158 else if (sub_worker || cmd == JK_STATUS_CMD_LIST) {
1161 else if (restore_sub_worker == JK_TRUE) {
1165 if (!strcmp(k, JK_STATUS_ARG_PREV_SUB_WORKER) && restore_sub_worker == JK_TRUE && cmd != JK_STATUS_CMD_LIST) {
1166 jk_printf(s, "%s%s=%s", started ? "&" : "?",
1167 JK_STATUS_ARG_SUB_WORKER, v);
1171 if (!strcmp(k, JK_STATUS_ARG_ATTRIBUTE) && attribute) {
1174 if (!strcmp(k, JK_STATUS_ARG_ATTRIBUTE) && cmd != JK_STATUS_CMD_UPDATE && cmd != JK_STATUS_CMD_EDIT) {
1177 if (!strncmp(k, JK_STATUS_ARG_MULT_VALUE_BASE, 3) && cmd != JK_STATUS_CMD_UPDATE) {
1180 if (k[0] == 'v' && cmd != JK_STATUS_CMD_UPDATE) {
1183 if (!strcmp(k, JK_STATUS_ARG_OPTIONS)) {
1187 jk_printf(s, "%s%s=%s", started ? "&" : "?", k, v);
1190 if (opt | add_options | rm_options)
1191 jk_printf(s, "%s%s=%u", started ? "&" : "?",
1192 JK_STATUS_ARG_OPTIONS, (opt | add_options) & ~rm_options);
1194 jk_putv(s, "\">", text, "</a>", NULL);
1197 static int status_parse_uri(jk_ws_service_t *s,
1198 status_endpoint_t *p,
1202 status_worker_t *w = p->worker;
1203 #ifdef _MT_CODE_PTHREAD
1211 if (!s->query_string) {
1212 if (JK_IS_DEBUG_LEVEL(l))
1213 jk_log(l, JK_LOG_DEBUG,
1214 "Status worker '%s' query string is empty",
1220 p->query_string = jk_pool_strdup(s->pool, s->query_string);
1221 if (!p->query_string) {
1222 jk_log(l, JK_LOG_ERROR,
1223 "Status worker '%s' could not copy query string",
1229 /* XXX We simply mask special chars n the query string with '@' to prevent cross site scripting */
1230 query = p->query_string;
1231 while ((query = strpbrk(query, JK_STATUS_ESC_CHARS)))
1234 if (!jk_map_alloc(&(p->req_params))) {
1235 jk_log(l, JK_LOG_ERROR,
1236 "Status worker '%s' could not alloc map for request parameters",
1243 query = jk_pool_strdup(s->pool, p->query_string);
1245 jk_log(l, JK_LOG_ERROR,
1246 "Status worker '%s' could not copy query string",
1252 #ifdef _MT_CODE_PTHREAD
1253 for (param = strtok_r(query, "&", &lasts);
1254 param; param = strtok_r(NULL, "&", &lasts)) {
1256 for (param = strtok(query, "&"); param; param = strtok(NULL, "&")) {
1258 char *key = jk_pool_strdup(s->pool, param);
1261 jk_log(l, JK_LOG_ERROR,
1262 "Status worker '%s' could not copy string",
1267 value = strchr(key, '=');
1271 /* XXX Depending on the params values, we might need to trim and decode */
1273 if (JK_IS_DEBUG_LEVEL(l))
1274 jk_log(l, JK_LOG_DEBUG,
1275 "Status worker '%s' adding request param '%s' with value '%s'",
1276 w->name, key, value);
1277 jk_map_put(m, key, value, NULL);
1286 static void write_html_refresh_response(jk_ws_service_t *s,
1287 status_endpoint_t *p,
1292 jk_puts(s, "\n<meta http-equiv=\"Refresh\" content=\""
1293 JK_STATUS_WAIT_AFTER_UPDATE ";url=");
1294 status_write_uri(s, p, NULL, JK_STATUS_CMD_UNKNOWN, JK_STATUS_MIME_UNKNOWN,
1295 NULL, NULL, 0, 0, NULL, l);
1297 jk_putv(s, "<p><b>Result: OK - You will be redirected in "
1298 JK_STATUS_WAIT_AFTER_UPDATE " seconds.</b><p/>", NULL);
1302 static int fetch_worker_and_sub_worker(status_endpoint_t *p,
1303 const char *operation,
1304 const char **worker,
1305 const char **sub_worker,
1308 status_worker_t *w = p->worker;
1311 status_get_string(p, JK_STATUS_ARG_WORKER, NULL, worker, l);
1312 status_get_string(p, JK_STATUS_ARG_SUB_WORKER, NULL, sub_worker, l);
1313 if (JK_IS_DEBUG_LEVEL(l))
1314 jk_log(l, JK_LOG_DEBUG,
1315 "Status worker '%s' %s worker '%s' sub worker '%s'",
1317 *worker ? *worker : "(null)", *sub_worker ? *sub_worker : "(null)");
1318 if (!*worker || !(*worker)[0]) {
1319 jk_log(l, JK_LOG_WARNING,
1320 "Status worker '%s' NULL or EMPTY worker param",
1322 p->msg = "NULL or EMPTY worker param";
1326 if (*sub_worker && !(*sub_worker)[0]) {
1327 jk_log(l, JK_LOG_WARNING,
1328 "Status worker '%s' EMPTY sub worker param",
1330 p->msg = "EMPTY sub worker param";
1338 static int check_valid_lb(jk_ws_service_t *s,
1339 status_endpoint_t *p,
1346 status_worker_t *w = p->worker;
1349 if (jw->type != JK_LB_WORKER_TYPE) {
1351 jk_log(l, JK_LOG_WARNING,
1352 "Status worker '%s' worker type of worker '%s' has no sub workers",
1354 p->msg = "worker type has no sub workers";
1357 jk_log(l, JK_LOG_WARNING,
1358 "Status worker '%s' worker type of worker '%s' not implemented",
1360 p->msg = "worker type not implemented";
1365 *lbp = (lb_worker_t *)jw->worker_private;
1367 jk_log(l, JK_LOG_WARNING,
1368 "Status worker '%s' lb structure of worker '%s' is (null)",
1370 p->msg = "lb structure is (null)";
1379 static int search_worker(jk_ws_service_t *s,
1380 status_endpoint_t *p,
1385 status_worker_t *w = p->worker;
1389 if (JK_IS_DEBUG_LEVEL(l))
1390 jk_log(l, JK_LOG_DEBUG,
1391 "Status worker '%s' searching worker '%s'",
1392 w->name, worker ? worker : "(null)");
1393 if (!worker || !worker[0]) {
1394 jk_log(l, JK_LOG_WARNING,
1395 "Status worker '%s' NULL or EMPTY worker param",
1397 p->msg = "NULL or EMPTY worker param";
1401 *jwp = wc_get_worker_for_name(worker, l);
1403 jk_log(l, JK_LOG_WARNING,
1404 "Status worker '%s' could not find worker '%s'",
1406 p->msg = "Could not find given worker";
1415 static int search_sub_worker(jk_ws_service_t *s,
1416 status_endpoint_t *p,
1419 lb_sub_worker_t **wrp,
1420 const char *sub_worker,
1424 lb_worker_t *lb = NULL;
1425 lb_sub_worker_t *wr = NULL;
1426 status_worker_t *w = p->worker;
1430 if (JK_IS_DEBUG_LEVEL(l))
1431 jk_log(l, JK_LOG_DEBUG,
1432 "Status worker '%s' searching sub worker '%s' of worker '%s'",
1433 w->name, sub_worker ? sub_worker : "(null)",
1434 worker ? worker : "(null)");
1435 if (!sub_worker || !sub_worker[0]) {
1436 jk_log(l, JK_LOG_WARNING,
1437 "Status worker '%s' NULL or EMPTY sub_worker param",
1439 p->msg = "NULL or EMPTY sub_worker param";
1443 if (check_valid_lb(s, p, jw, worker, &lb, 1, l) == JK_FALSE) {
1449 for (; i < lb->num_of_workers; i++) {
1450 wr = &(lb->lb_workers[i]);
1452 if (jk_wildchar_match(wr->name, sub_worker, 0) == 0) {
1457 else if (strcmp(sub_worker, wr->name) == 0)
1461 if (!wr || i == lb->num_of_workers) {
1462 jk_log(l, JK_LOG_WARNING,
1463 "Status worker '%s' could not find sub worker '%s' of worker '%s'",
1464 w->name, sub_worker, worker ? worker : "(null)");
1465 p->msg = "could not find sub worker";
1474 static int count_map(jk_uri_worker_map_t *uw_map,
1483 for (i = 0; i < uw_map->size[uw_map->index]; i++) {
1484 uri_worker_record_t *uwr = uw_map->maps[uw_map->index][i];
1485 if (strcmp(uwr->worker_name, worker) &&
1486 strcmp(uwr->worker_name, "*")) {
1496 static int count_maps(jk_ws_service_t *s,
1503 if (s->next_vhost) {
1505 for (srv = s->next_vhost(NULL); srv; srv = s->next_vhost(srv)) {
1506 count += count_map(s->vhost_to_uw_map(srv), worker, l);
1510 count = count_map(s->uw_map, worker, l);
1515 static void display_map(jk_ws_service_t *s,
1516 status_endpoint_t *p,
1517 jk_uri_worker_map_t *uw_map,
1519 const char *server_name,
1527 status_worker_t *w = p->worker;
1531 if (uw_map->fname) {
1532 uri_worker_map_update(uw_map, 1, l);
1534 for (i = 0; i < uw_map->size[uw_map->index]; i++) {
1535 uri_worker_record_t *uwr = uw_map->maps[uw_map->index][i];
1537 if (strcmp(uwr->worker_name, worker) &&
1538 strcmp(uwr->worker_name, "*")) {
1544 if (mime == JK_STATUS_MIME_HTML) {
1546 jk_printf(s, JK_STATUS_URI_MAP_TABLE_ROW2,
1549 uri_worker_map_get_match(uwr, buf, l),
1550 uri_worker_map_get_source(uwr, l),
1551 uwr->extensions.reply_timeout,
1552 uwr->extensions.fail_on_status_str ? uwr->extensions.fail_on_status_str : "-",
1553 uwr->extensions.active ? uwr->extensions.active : "-",
1554 uwr->extensions.disabled ? uwr->extensions.disabled : "-",
1555 uwr->extensions.stopped ? uwr->extensions.stopped : "-",
1556 uwr->extensions.use_server_error_pages);
1558 jk_printf(s, JK_STATUS_URI_MAP_TABLE_ROW,
1560 uri_worker_map_get_match(uwr, buf, l),
1561 uri_worker_map_get_source(uwr, l),
1562 uwr->extensions.reply_timeout,
1563 uwr->extensions.fail_on_status_str ? uwr->extensions.fail_on_status_str : "-",
1564 uwr->extensions.active ? uwr->extensions.active : "-",
1565 uwr->extensions.disabled ? uwr->extensions.disabled : "-",
1566 uwr->extensions.stopped ? uwr->extensions.stopped : "-",
1567 uwr->extensions.use_server_error_pages);
1569 else if (mime == JK_STATUS_MIME_XML) {
1570 jk_print_xml_start_elt(s, w, 6, 0, "map");
1571 jk_print_xml_att_int(s, 8, "id", count);
1573 jk_print_xml_att_string(s, 8, "server", server_name);
1574 jk_print_xml_att_string(s, 8, "uri", uwr->uri);
1575 jk_print_xml_att_string(s, 8, "type", uri_worker_map_get_match(uwr, buf, l));
1576 jk_print_xml_att_string(s, 8, "source", uri_worker_map_get_source(uwr, l));
1577 jk_print_xml_att_int(s, 8, "reply_timeout", uwr->extensions.reply_timeout);
1578 jk_print_xml_att_string(s, 8, "fail_on_status", uwr->extensions.fail_on_status_str);
1579 jk_print_xml_att_string(s, 8, "active", uwr->extensions.active);
1580 jk_print_xml_att_string(s, 8, "disabled", uwr->extensions.disabled);
1581 jk_print_xml_att_string(s, 8, "stopped", uwr->extensions.stopped);
1582 jk_print_xml_att_int(s, 8, "use_server_errors", uwr->extensions.use_server_error_pages);
1583 jk_print_xml_stop_elt(s, 6, 1);
1585 else if (mime == JK_STATUS_MIME_TXT) {
1587 jk_printf(s, " id=%d", count);
1589 jk_printf(s, " server=\"%s\"", server_name);
1590 jk_printf(s, " uri=\"%s\"", uwr->uri);
1591 jk_printf(s, " type=\"%s\"", uri_worker_map_get_match(uwr, buf, l));
1592 jk_printf(s, " source=\"%s\"", uri_worker_map_get_source(uwr, l));
1593 jk_printf(s, " reply_timeout=\"%d\"", uwr->extensions.reply_timeout);
1594 jk_printf(s, " fail_on_status=\"%s\"", uwr->extensions.fail_on_status_str ? uwr->extensions.fail_on_status_str : "");
1595 jk_printf(s, " active=\"%s\"", uwr->extensions.active ? uwr->extensions.active : "");
1596 jk_printf(s, " disabled=\"%s\"", uwr->extensions.disabled ? uwr->extensions.disabled : "");
1597 jk_printf(s, " stopped=\"%s\"", uwr->extensions.stopped ? uwr->extensions.stopped : "");
1598 jk_printf(s, " use_server_errors=\"%d\"", uwr->extensions.use_server_error_pages);
1601 else if (mime == JK_STATUS_MIME_PROP) {
1603 jk_print_prop_item_string(s, w, worker, "map", count, "server", server_name);
1604 jk_print_prop_item_string(s, w, worker, "map", count, "uri", uwr->uri);
1605 jk_print_prop_item_string(s, w, worker, "map", count, "type", uri_worker_map_get_match(uwr, buf, l));
1606 jk_print_prop_item_string(s, w, worker, "map", count, "source", uri_worker_map_get_source(uwr, l));
1607 jk_print_prop_item_int(s, w, worker, "map", count, "reply_timeout", uwr->extensions.reply_timeout);
1608 jk_print_prop_item_string(s, w, worker, "map", count, "fail_on_status", uwr->extensions.fail_on_status_str);
1609 jk_print_prop_item_string(s, w, worker, "map", count, "active", uwr->extensions.active);
1610 jk_print_prop_item_string(s, w, worker, "map", count, "disabled", uwr->extensions.disabled);
1611 jk_print_prop_item_string(s, w, worker, "map", count, "stopped", uwr->extensions.stopped);
1612 jk_print_prop_item_int(s, w, worker, "map", count, "use_server_errors", uwr->extensions.use_server_error_pages);
1618 static void display_maps(jk_ws_service_t *s,
1619 status_endpoint_t *p,
1625 int has_server_iterator = 0;
1628 status_worker_t *w = p->worker;
1629 jk_uri_worker_map_t *uw_map;
1630 char server_name[80];
1634 status_get_string(p, JK_STATUS_ARG_MIME, NULL, &arg, l);
1635 mime = status_mime_int(arg);
1636 hide = status_get_int(p, JK_STATUS_ARG_OPTIONS, 0, l) &
1637 JK_STATUS_ARG_OPTION_NO_MAPS;
1639 has_server_iterator = 1;
1641 count = count_maps(s, worker, l);
1644 if (count && mime == JK_STATUS_MIME_HTML) {
1645 jk_puts(s, "<p>\n");
1646 status_write_uri(s, p, "Show URI Mappings", JK_STATUS_CMD_UNKNOWN, JK_STATUS_MIME_UNKNOWN,
1647 NULL, NULL, 0, JK_STATUS_ARG_OPTION_NO_MAPS, NULL, l);
1648 jk_puts(s, "</p>\n");
1655 if (mime == JK_STATUS_MIME_HTML) {
1656 jk_printf(s, "<hr/><h3>URI Mappings for %s (%d maps) [", worker, count);
1657 status_write_uri(s, p, "Hide", JK_STATUS_CMD_UNKNOWN, JK_STATUS_MIME_UNKNOWN,
1658 NULL, NULL, JK_STATUS_ARG_OPTION_NO_MAPS, 0, NULL, l);
1659 jk_puts(s, "]</h3><table>\n");
1660 if (has_server_iterator)
1661 jk_printf(s, JK_STATUS_URI_MAP_TABLE_HEAD2,
1662 "Server", "URI", "Match Type", "Source", "Reply Timeout", "Fail on Status", "Active", "Disabled", "Stopped", "Use Server Errors");
1664 jk_printf(s, JK_STATUS_URI_MAP_TABLE_HEAD,
1665 "URI", "Match Type", "Source", "Reply Timeout", "Fail on Status", "Active", "Disabled", "Stopped", "Use Server Errors");
1668 if (has_server_iterator) {
1669 for (srv = s->next_vhost(NULL); srv; srv = s->next_vhost(srv)) {
1670 uw_map = s->vhost_to_uw_map(srv);
1672 s->vhost_to_text(srv, server_name, 80);
1673 display_map(s, p, uw_map, worker, server_name, &count, mime, l);
1680 display_map(s, p, uw_map, worker, NULL, &count, mime, l);
1683 if (mime == JK_STATUS_MIME_HTML) {
1684 jk_puts(s, "</table>\n");
1688 if (mime == JK_STATUS_MIME_HTML) {
1689 jk_putv(s, "<hr/><h3>Warning: No URI Mappings defined for ",
1690 worker, " !</h3>\n", NULL);
1693 if (JK_IS_DEBUG_LEVEL(l))
1694 jk_log(l, JK_LOG_DEBUG,
1695 "Status worker '%s' displayed %d maps for worker '%s'",
1696 w->name, count, worker);
1700 static const char *dump_ajp_addr(ajp_worker_t *aw, char *buf)
1703 return jk_dump_hinfo(&aw->worker_inet_addr, buf);
1705 if (aw->addr_sequence != aw->s->addr_sequence)
1706 return "unresolved";
1712 static void display_worker_ajp_conf_details(jk_ws_service_t *s,
1713 status_endpoint_t *p,
1724 jk_printf(s, JK_STATUS_SHOW_MEMBER_CONF_ROW,
1726 status_worker_type(type),
1728 dump_ajp_addr(aw, buf),
1730 aw->connect_timeout,
1731 aw->prepost_timeout,
1735 aw->max_packet_size);
1737 jk_printf(s, JK_STATUS_SHOW_AJP_CONF_ROW,
1738 status_worker_type(type),
1740 dump_ajp_addr(aw, buf),
1742 aw->connect_timeout,
1743 aw->prepost_timeout,
1747 aw->max_packet_size);
1752 static void display_worker_ajp_details(jk_ws_service_t *s,
1753 status_endpoint_t *p,
1755 lb_sub_worker_t *wr,
1764 char buf_rd_sec[32];
1766 char buf_wr_sec[32];
1769 time_t now = time(NULL);
1770 const char *name = NULL;
1771 const char *sub_name = NULL;
1772 const char *ajp_name = NULL;
1773 status_worker_t *w = p->worker;
1776 int delta_reset = (int)difftime(now, aw->s->last_reset);
1777 int delta_error = -1;
1778 char buf_time[JK_STATUS_TIME_BUF_SZ];
1779 char buf_tz[JK_STATUS_TIME_BUF_SZ];
1780 time_t error_time = 0;
1785 status_get_string(p, JK_STATUS_ARG_MIME, NULL, &arg, l);
1786 mime = status_mime_int(arg);
1790 sub_name = wr->name;
1791 ajp_name = wr->name;
1792 error_time = wr->s->error_time;
1793 if (wr->s->state == JK_LB_STATE_ERROR) {
1794 rs_min = lb->recover_wait_time - (int)difftime(now, wr->s->error_time);
1798 rs_max = rs_min + lb->maintain_time;
1799 if (rs_min < ms_min) {
1807 ajp_name = aw->name;
1808 error_time = aw->s->error_time;
1811 if (error_time > 0) {
1812 delta_error = (int)difftime(now, error_time);
1813 rc_time = status_strftime(error_time, mime, buf_time, buf_tz, l);
1816 if (mime == JK_STATUS_MIME_HTML) {
1819 jk_printf(s, JK_STATUS_SHOW_MEMBER_ROW,
1821 jk_lb_get_activation(wr, l),
1822 jk_lb_get_state(wr, l),
1828 delta_reset > 0 ? (int)(aw->s->used / delta_reset) : -1,
1830 aw->s->client_errors,
1831 aw->s->reply_timeouts,
1832 status_strfsize(aw->s->transferred, buf_wr),
1833 delta_reset > 0 ? status_strfsize(aw->s->transferred / delta_reset, buf_wr_sec) : "-",
1834 status_strfsize(aw->s->readed, buf_rd),
1835 delta_reset > 0 ? status_strfsize(aw->s->readed / delta_reset , buf_rd_sec) : "-",
1840 wr->redirect ? (*wr->redirect ? wr->redirect : " ") : " ",
1841 wr->domain ? (*wr->domain ? wr->domain : " ") : " ",
1845 rc_time > 0 ? buf_time : " ");
1847 jk_printf(s, JK_STATUS_SHOW_AJP_ROW,
1848 jk_ajp_get_state(aw, l),
1850 delta_reset > 0 ? (int)(aw->s->used / delta_reset) : -1,
1852 aw->s->client_errors,
1853 aw->s->reply_timeouts,
1854 status_strfsize(aw->s->transferred, buf_wr),
1855 delta_reset > 0 ? status_strfsize(aw->s->transferred / delta_reset, buf_wr_sec) : "-",
1856 status_strfsize(aw->s->readed, buf_rd),
1857 delta_reset > 0 ? status_strfsize(aw->s->readed / delta_reset , buf_rd_sec) : "-",
1862 rc_time > 0 ? buf_time : " ");
1866 else if (mime == JK_STATUS_MIME_XML) {
1872 jk_print_xml_start_elt(s, w, off, 0, "member");
1873 jk_print_xml_att_string(s, off+2, "name", sub_name);
1874 jk_print_xml_att_string(s, off+2, "type", status_worker_type(wr->worker->type));
1877 jk_print_xml_start_elt(s, w, off, 0, "ajp");
1878 jk_print_xml_att_string(s, off+2, "name", ajp_name);
1879 jk_print_xml_att_string(s, off+2, "type", status_worker_type(aw->worker.type));
1881 jk_print_xml_att_string(s, off+2, "host", aw->host);
1882 jk_print_xml_att_int(s, off+2, "port", aw->port);
1883 jk_print_xml_att_string(s, off+2, "address", dump_ajp_addr(aw, buf));
1884 jk_print_xml_att_int(s, off+2, "connection_pool_timeout", aw->cache_timeout);
1885 jk_print_xml_att_int(s, off+2, "ping_timeout", aw->ping_timeout);
1886 jk_print_xml_att_int(s, off+2, "connect_timeout", aw->connect_timeout);
1887 jk_print_xml_att_int(s, off+2, "prepost_timeout", aw->prepost_timeout);
1888 jk_print_xml_att_int(s, off+2, "reply_timeout", aw->reply_timeout);
1889 jk_print_xml_att_int(s, off+2, "connection_ping_interval", aw->conn_ping_interval);
1890 jk_print_xml_att_int(s, off+2, "retries", aw->retries);
1891 jk_print_xml_att_uint(s, off+2, "recovery_options", aw->recovery_opts);
1892 jk_print_xml_att_uint(s, off+2, "max_packet_size", aw->max_packet_size);
1894 jk_print_xml_att_string(s, off+2, "activation", jk_lb_get_activation(wr, l));
1895 jk_print_xml_att_int(s, off+2, "lbfactor", wr->lb_factor);
1896 jk_print_xml_att_string(s, off+2, "route", wr->route);
1897 jk_print_xml_att_string(s, off+2, "redirect", wr->redirect);
1898 jk_print_xml_att_string(s, off+2, "domain", wr->domain);
1899 jk_print_xml_att_int(s, off+2, "distance", wr->distance);
1900 jk_print_xml_att_string(s, off+2, "state", jk_lb_get_state(wr, l));
1901 jk_print_xml_att_uint64(s, off+2, "lbmult", wr->lb_mult);
1902 jk_print_xml_att_uint64(s, off+2, "lbvalue", wr->s->lb_value);
1903 jk_print_xml_att_uint64(s, off+2, "elected", aw->s->used);
1904 jk_print_xml_att_uint32(s, off+2, "errors", wr->s->errors);
1907 jk_print_xml_att_uint64(s, off+2, "used", aw->s->used);
1908 jk_print_xml_att_uint32(s, off+2, "errors", aw->s->errors);
1910 jk_print_xml_att_uint32(s, off+2, "client_errors", aw->s->client_errors);
1911 jk_print_xml_att_uint32(s, off+2, "reply_timeouts", aw->s->reply_timeouts);
1912 jk_print_xml_att_uint64(s, off+2, "transferred", aw->s->transferred);
1913 jk_print_xml_att_uint64(s, off+2, "read", aw->s->readed);
1914 jk_print_xml_att_int(s, off+2, "busy", aw->s->busy);
1915 jk_print_xml_att_int(s, off+2, "max_busy", aw->s->max_busy);
1916 jk_print_xml_att_int(s, off+2, "connected", aw->s->connected);
1918 jk_print_xml_att_int(s, off+2, "time_to_recover_min", rs_min);
1919 jk_print_xml_att_int(s, off+2, "time_to_recover_max", rs_max);
1922 jk_print_xml_att_int(s, off+2, "map_count", map_count);
1923 jk_print_xml_att_long(s, off+2, "last_reset_at", (long)aw->s->last_reset);
1924 jk_print_xml_att_int(s, off+2, "last_reset_ago", delta_reset);
1926 jk_print_xml_att_string(s, off+2, "error_time_datetime", buf_time);
1927 jk_print_xml_att_string(s, off+2, "error_time_tz", buf_tz);
1928 jk_print_xml_att_int(s, off+2, "error_time_unix_seconds", (int)error_time);
1929 jk_print_xml_att_int(s, off+2, "error_time_ago", delta_error);
1931 /* Terminate the tag */
1932 jk_print_xml_stop_elt(s, off, 1);
1935 else if (mime == JK_STATUS_MIME_TXT) {
1938 jk_puts(s, "Member:");
1939 jk_printf(s, " name=%s", sub_name);
1940 jk_printf(s, " type=%s", status_worker_type(wr->worker->type));
1943 jk_puts(s, "AJP Worker:");
1944 jk_printf(s, " name=%s", ajp_name);
1945 jk_printf(s, " type=%s", status_worker_type(aw->worker.type));
1947 jk_printf(s, " host=%s", aw->host);
1948 jk_printf(s, " port=%d", aw->port);
1949 jk_printf(s, " address=%s", dump_ajp_addr(aw, buf));
1950 jk_printf(s, " connection_pool_timeout=%d", aw->cache_timeout);
1951 jk_printf(s, " ping_timeout=%d", aw->ping_timeout);
1952 jk_printf(s, " connect_timeout=%d", aw->connect_timeout);
1953 jk_printf(s, " prepost_timeout=%d", aw->prepost_timeout);
1954 jk_printf(s, " reply_timeout=%d", aw->reply_timeout);
1955 jk_printf(s, " retries=%d", aw->retries);
1956 jk_printf(s, " connection_ping_interval=%d", aw->conn_ping_interval);
1957 jk_printf(s, " recovery_options=%u", aw->recovery_opts);
1958 jk_printf(s, " max_packet_size=%u", aw->max_packet_size);
1960 jk_printf(s, " activation=%s", jk_lb_get_activation(wr, l));
1961 jk_printf(s, " lbfactor=%d", wr->lb_factor);
1962 jk_printf(s, " route=\"%s\"", wr->route ? wr->route : "");
1963 jk_printf(s, " redirect=\"%s\"", wr->redirect ? wr->redirect : "");
1964 jk_printf(s, " domain=\"%s\"", wr->domain ? wr->domain : "");
1965 jk_printf(s, " distance=%d", wr->distance);
1966 jk_printf(s, " state=%s", jk_lb_get_state(wr, l));
1967 jk_printf(s, " lbmult=%" JK_UINT64_T_FMT, wr->lb_mult);
1968 jk_printf(s, " lbvalue=%" JK_UINT64_T_FMT, wr->s->lb_value);
1969 jk_printf(s, " elected=%" JK_UINT64_T_FMT, aw->s->used);
1970 jk_printf(s, " errors=%" JK_UINT32_T_FMT, wr->s->errors);
1973 jk_printf(s, " used=%" JK_UINT64_T_FMT, aw->s->used);
1974 jk_printf(s, " errors=%" JK_UINT32_T_FMT, aw->s->errors);
1976 jk_printf(s, " client_errors=%" JK_UINT32_T_FMT, aw->s->client_errors);
1977 jk_printf(s, " reply_timeouts=%" JK_UINT32_T_FMT, aw->s->reply_timeouts);
1978 jk_printf(s, " transferred=%" JK_UINT64_T_FMT, aw->s->transferred);
1979 jk_printf(s, " read=%" JK_UINT64_T_FMT, aw->s->readed);
1980 jk_printf(s, " busy=%d", aw->s->busy);
1981 jk_printf(s, " max_busy=%d", aw->s->max_busy);
1982 jk_printf(s, " connected=%d", aw->s->connected);
1984 jk_printf(s, " time_to_recover_min=%d", rs_min);
1985 jk_printf(s, " time_to_recover_max=%d", rs_max);
1988 jk_printf(s, " map_count=%d", map_count);
1989 jk_printf(s, " last_reset_at=%ld", (long)aw->s->last_reset);
1990 jk_printf(s, " last_reset_ago=%d", delta_reset);
1992 jk_printf(s, " error_time_datetime=%s", buf_time);
1993 jk_printf(s, " error_time_tz=%s", buf_tz);
1994 jk_printf(s, " error_time_unix_seconds=%d", error_time);
1995 jk_printf(s, " error_time_ago=%d", delta_error);
2000 else if (mime == JK_STATUS_MIME_PROP) {
2003 jk_print_prop_att_string(s, w, name, "balance_workers", sub_name);
2004 jk_print_prop_att_string(s, w, ajp_name, "type", status_worker_type(wr->worker->type));
2007 jk_print_prop_att_string(s, w, name, "list", ajp_name);
2008 jk_print_prop_att_string(s, w, ajp_name, "type", status_worker_type(aw->worker.type));
2010 jk_print_prop_att_string(s, w, ajp_name, "host", aw->host);
2011 jk_print_prop_att_int(s, w, ajp_name, "port", aw->port);
2012 jk_print_prop_att_string(s, w, ajp_name, "address", dump_ajp_addr(aw, buf));
2013 jk_print_prop_att_int(s, w, ajp_name, "connection_pool_timeout", aw->cache_timeout);
2014 jk_print_prop_att_int(s, w, ajp_name, "ping_timeout", aw->ping_timeout);
2015 jk_print_prop_att_int(s, w, ajp_name, "connect_timeout", aw->connect_timeout);
2016 jk_print_prop_att_int(s, w, ajp_name, "prepost_timeout", aw->prepost_timeout);
2017 jk_print_prop_att_int(s, w, ajp_name, "reply_timeout", aw->reply_timeout);
2018 jk_print_prop_att_int(s, w, ajp_name, "retries", aw->retries);
2019 jk_print_prop_att_int(s, w, ajp_name, "connection_ping_interval", aw->conn_ping_interval);
2020 jk_print_prop_att_uint(s, w, ajp_name, "recovery_options", aw->recovery_opts);
2021 jk_print_prop_att_uint(s, w, ajp_name, "max_packet_size", aw->max_packet_size);
2023 jk_print_prop_att_string(s, w, ajp_name, "activation", jk_lb_get_activation(wr, l));
2024 jk_print_prop_att_int(s, w, ajp_name, "lbfactor", wr->lb_factor);
2025 jk_print_prop_att_string(s, w, ajp_name, "route", wr->route);
2026 jk_print_prop_att_string(s, w, ajp_name, "redirect", wr->redirect);
2027 jk_print_prop_att_string(s, w, ajp_name, "domain", wr->domain);
2028 jk_print_prop_att_int(s, w, ajp_name, "distance", wr->distance);
2029 jk_print_prop_att_string(s, w, ajp_name, "state", jk_lb_get_state(wr, l));
2030 jk_print_prop_att_uint64(s, w, ajp_name, "lbmult", wr->lb_mult);
2031 jk_print_prop_att_uint64(s, w, ajp_name, "lbvalue", wr->s->lb_value);
2032 jk_print_prop_att_uint64(s, w, ajp_name, "elected", aw->s->used);
2033 jk_print_prop_att_uint32(s, w, ajp_name, "errors", wr->s->errors);
2036 jk_print_prop_att_uint64(s, w, ajp_name, "used", aw->s->used);
2037 jk_print_prop_att_uint32(s, w, ajp_name, "errors", aw->s->errors);
2039 jk_print_prop_att_uint32(s, w, ajp_name, "client_errors", aw->s->client_errors);
2040 jk_print_prop_att_uint32(s, w, ajp_name, "reply_timeouts", aw->s->reply_timeouts);
2041 jk_print_prop_att_uint64(s, w, ajp_name, "transferred", aw->s->transferred);
2042 jk_print_prop_att_uint64(s, w, ajp_name, "read", aw->s->readed);
2043 jk_print_prop_att_int(s, w, ajp_name, "busy", aw->s->busy);
2044 jk_print_prop_att_int(s, w, ajp_name, "max_busy", aw->s->max_busy);
2045 jk_print_prop_att_int(s, w, ajp_name, "connected", aw->s->connected);
2047 jk_print_prop_att_int(s, w, ajp_name, "time_to_recover_min", rs_min);
2048 jk_print_prop_att_int(s, w, ajp_name, "time_to_recover_max", rs_max);
2051 jk_print_prop_att_int(s, w, name, "map_count", map_count);
2052 jk_print_prop_att_long(s, w, name, "last_reset_at", (long)aw->s->last_reset);
2053 jk_print_prop_att_int(s, w, name, "last_reset_ago", delta_reset);
2055 jk_print_prop_att_string(s, w, name, "error_time_datetime", buf_time);
2056 jk_print_prop_att_string(s, w, name, "error_time_tz", buf_tz);
2057 jk_print_prop_att_int(s, w, name, "error_time_unix seconds", (int)error_time);
2058 jk_print_prop_att_int(s, w, name, "error_time_ago seconds", delta_error);
2066 static void display_worker_lb(jk_ws_service_t *s,
2067 status_endpoint_t *p,
2069 lb_sub_worker_t *swr,
2076 unsigned int hide_members;
2077 unsigned int hide_lb_conf;
2078 unsigned int hide_lb_summary;
2079 unsigned int hide_ajp_conf;
2081 time_t now = time(NULL);
2082 unsigned int good = 0;
2083 unsigned int degraded = 0;
2084 unsigned int bad = 0;
2089 int pstart = JK_FALSE;
2090 const char *name = lb->name;
2091 status_worker_t *w = p->worker;
2094 status_get_string(p, JK_STATUS_ARG_CMD, NULL, &arg, l);
2095 cmd = status_cmd_int(arg);
2096 status_get_string(p, JK_STATUS_ARG_MIME, NULL, &arg, l);
2097 mime = status_mime_int(arg);
2098 hide_members = status_get_int(p, JK_STATUS_ARG_OPTIONS, 0, l) &
2099 JK_STATUS_ARG_OPTION_NO_MEMBERS;
2100 hide_lb_conf = status_get_int(p, JK_STATUS_ARG_OPTIONS, 0, l) &
2101 JK_STATUS_ARG_OPTION_NO_LB_CONF;
2102 hide_lb_summary = status_get_int(p, JK_STATUS_ARG_OPTIONS, 0, l) &
2103 JK_STATUS_ARG_OPTION_NO_LB_SUMMARY;
2104 hide_ajp_conf = status_get_int(p, JK_STATUS_ARG_OPTIONS, 0, l) &
2105 JK_STATUS_ARG_OPTION_NO_AJP_CONF;
2110 read_only = status_get_int(p, JK_STATUS_ARG_OPTIONS, 0, l) &
2111 JK_STATUS_ARG_OPTION_READ_ONLY;
2113 if (cmd == JK_STATUS_CMD_SHOW) {
2117 if (lb->sequence != lb->s->h.sequence)
2118 jk_lb_pull(lb, JK_FALSE, l);
2120 for (j = 0; j < lb->num_of_workers; j++) {
2121 lb_sub_worker_t *wr = &(lb->lb_workers[j]);
2123 rate = status_rate(wr, w, l);
2132 map_count = count_maps(s, name, l);
2133 ms_min = lb->maintain_time - (int)difftime(now, lb->s->last_maintain_time);
2134 ms_max = ms_min + lb->maintain_time;
2135 ms_min -= JK_LB_MAINTAIN_TOLERANCE;
2143 if (mime == JK_STATUS_MIME_HTML) {
2145 jk_puts(s, "<hr/><h3>[");
2150 status_write_uri(s, p, "S", JK_STATUS_CMD_SHOW, JK_STATUS_MIME_UNKNOWN,
2151 name, "", 0, 0, "", l);
2155 status_write_uri(s, p, "E", JK_STATUS_CMD_EDIT, JK_STATUS_MIME_UNKNOWN,
2156 name, "", 0, 0, "", l);
2158 status_write_uri(s, p, "R", JK_STATUS_CMD_RESET, JK_STATUS_MIME_UNKNOWN,
2159 name, "", 0, 0, "", l);
2161 jk_puts(s, "] ");
2162 jk_putv(s, "Worker Status for ", name, "</h3>\n", NULL);
2165 jk_puts(s, "<p>\n");
2167 status_write_uri(s, p, "Show LB Configuration", JK_STATUS_CMD_SHOW, JK_STATUS_MIME_UNKNOWN,
2168 NULL, NULL, 0, JK_STATUS_ARG_OPTION_NO_LB_CONF, "", l);
2171 status_write_uri(s, p, "Show LB Configuration", JK_STATUS_CMD_LIST, JK_STATUS_MIME_UNKNOWN,
2172 NULL, NULL, 0, JK_STATUS_ARG_OPTION_NO_LB_CONF, "", l);
2175 if (hide_lb_summary) {
2176 if (pstart == JK_FALSE)
2177 jk_puts(s, "<p>\n");
2179 jk_puts(s, " | ");
2182 status_write_uri(s, p, "Show LB Summary", JK_STATUS_CMD_SHOW, JK_STATUS_MIME_UNKNOWN,
2183 NULL, NULL, 0, JK_STATUS_ARG_OPTION_NO_LB_SUMMARY, "", l);
2186 status_write_uri(s, p, "Show LB Summary", JK_STATUS_CMD_LIST, JK_STATUS_MIME_UNKNOWN,
2187 NULL, NULL, 0, JK_STATUS_ARG_OPTION_NO_LB_SUMMARY, "", l);
2190 if (!hide_members && hide_ajp_conf) {
2191 if (pstart == JK_FALSE)
2192 jk_puts(s, "<p>\n");
2194 jk_puts(s, " | ");
2197 status_write_uri(s, p, "Show AJP Configuration", JK_STATUS_CMD_SHOW, JK_STATUS_MIME_UNKNOWN,
2198 NULL, NULL, 0, JK_STATUS_ARG_OPTION_NO_AJP_CONF, "", l);
2201 status_write_uri(s, p, "Show AJP Configuration", JK_STATUS_CMD_LIST, JK_STATUS_MIME_UNKNOWN,
2202 NULL, NULL, 0, JK_STATUS_ARG_OPTION_NO_AJP_CONF, "", l);
2206 if (pstart == JK_FALSE)
2207 jk_puts(s, "<p>\n");
2209 jk_puts(s, " | ");
2212 status_write_uri(s, p, "Show Balancer Members", JK_STATUS_CMD_SHOW, JK_STATUS_MIME_UNKNOWN,
2213 NULL, NULL, 0, JK_STATUS_ARG_OPTION_NO_MEMBERS, "", l);
2216 status_write_uri(s, p, "Show Balancer Members", JK_STATUS_CMD_LIST, JK_STATUS_MIME_UNKNOWN,
2217 NULL, NULL, 0, JK_STATUS_ARG_OPTION_NO_MEMBERS, "", l);
2220 if (pstart == JK_TRUE)
2221 jk_puts(s, "</p>\n");
2223 if (!hide_lb_conf) {
2224 jk_puts(s, "<table>" JK_STATUS_SHOW_LB_HEAD);
2226 status_write_uri(s, p, "Hide", JK_STATUS_CMD_UNKNOWN, JK_STATUS_MIME_UNKNOWN,
2227 NULL, NULL, JK_STATUS_ARG_OPTION_NO_LB_CONF, 0, NULL, l);
2228 jk_puts(s, "]</th></tr>");
2229 jk_printf(s, JK_STATUS_SHOW_LB_ROW,
2230 status_worker_type(JK_LB_WORKER_TYPE),
2231 jk_get_bool(lb->sticky_session),
2232 jk_get_bool(lb->sticky_session_force),
2234 jk_lb_get_method(lb, l),
2235 jk_lb_get_lock(lb, l),
2236 lb->recover_wait_time,
2237 lb->error_escalation_time,
2238 lb->max_reply_timeouts);
2239 jk_puts(s, "</table>\n<br/>\n");
2242 if (!hide_lb_summary) {
2243 jk_puts(s, "<table><tr>"
2244 "<th>Good</th><th>Degraded</th><th>Bad/Stopped</th><th>Busy</th><th>Max Busy</th><th>Next Maintenance</th><th>Last Reset</th><th>[");
2245 status_write_uri(s, p, "Hide", JK_STATUS_CMD_UNKNOWN, JK_STATUS_MIME_UNKNOWN,
2246 NULL, NULL, JK_STATUS_ARG_OPTION_NO_LB_SUMMARY, 0, NULL, l);
2247 jk_puts(s, "]</th></tr>\n<tr>");
2248 jk_printf(s, "<td>%d</td>", good);
2249 jk_printf(s, "<td>%d</td>", degraded);
2250 jk_printf(s, "<td>%d</td>", bad);
2251 jk_printf(s, "<td>%d</td>", lb->s->busy);
2252 jk_printf(s, "<td>%d</td>", lb->s->max_busy);
2253 jk_printf(s, "<td>%d/%d</td>", ms_min, ms_max);
2254 jk_printf(s, "<td>%d</td>", (int)difftime(now, lb->s->last_reset));
2255 jk_puts(s, "<td></td></tr>\n</table>\n\n");
2258 else if (mime == JK_STATUS_MIME_XML) {
2260 jk_print_xml_start_elt(s, w, 2, 0, "balancer");
2261 jk_print_xml_att_string(s, 4, "name", name);
2262 jk_print_xml_att_string(s, 4, "type", status_worker_type(JK_LB_WORKER_TYPE));
2263 jk_print_xml_att_string(s, 4, "sticky_session", jk_get_bool(lb->sticky_session));
2264 jk_print_xml_att_string(s, 4, "sticky_session_force", jk_get_bool(lb->sticky_session_force));
2265 jk_print_xml_att_int(s, 4, "retries", lb->retries);
2266 jk_print_xml_att_int(s, 4, "recover_time", lb->recover_wait_time);
2267 jk_print_xml_att_int(s, 4, "error_escalation_time", lb->error_escalation_time);
2268 jk_print_xml_att_int(s, 4, "max_reply_timeouts", lb->max_reply_timeouts);
2269 jk_print_xml_att_string(s, 4, "method", jk_lb_get_method(lb, l));
2270 jk_print_xml_att_string(s, 4, "lock", jk_lb_get_lock(lb, l));
2271 jk_print_xml_att_int(s, 4, "member_count", lb->num_of_workers);
2272 jk_print_xml_att_int(s, 4, "good", good);
2273 jk_print_xml_att_int(s, 4, "degraded", degraded);
2274 jk_print_xml_att_int(s, 4, "bad", bad);
2275 jk_print_xml_att_int(s, 4, "busy", lb->s->busy);
2276 jk_print_xml_att_int(s, 4, "max_busy", lb->s->max_busy);
2277 jk_print_xml_att_int(s, 4, "map_count", map_count);
2278 jk_print_xml_att_int(s, 4, "time_to_maintenance_min", ms_min);
2279 jk_print_xml_att_int(s, 4, "time_to_maintenance_max", ms_max);
2280 jk_print_xml_att_long(s, 4, "last_reset_at", (long)lb->s->last_reset);
2281 jk_print_xml_att_int(s, 4, "last_reset_ago", (int)difftime(now, lb->s->last_reset));
2282 jk_print_xml_stop_elt(s, 2, 0);
2285 else if (mime == JK_STATUS_MIME_TXT) {
2287 jk_puts(s, "Balancer Worker:");
2288 jk_printf(s, " name=%s", name);
2289 jk_printf(s, " type=%s", status_worker_type(JK_LB_WORKER_TYPE));
2290 jk_printf(s, " sticky_session=%s", jk_get_bool(lb->sticky_session));
2291 jk_printf(s, " sticky_session_force=%s", jk_get_bool(lb->sticky_session_force));
2292 jk_printf(s, " retries=%d", lb->retries);
2293 jk_printf(s, " recover_time=%d", lb->recover_wait_time);
2294 jk_printf(s, " error_escalation_time=%d", lb->error_escalation_time);
2295 jk_printf(s, " max_reply_timeouts=%d", lb->max_reply_timeouts);
2296 jk_printf(s, " method=%s", jk_lb_get_method(lb, l));
2297 jk_printf(s, " lock=%s", jk_lb_get_lock(lb, l));
2298 jk_printf(s, " member_count=%d", lb->num_of_workers);
2299 jk_printf(s, " good=%d", good);
2300 jk_printf(s, " degraded=%d", degraded);
2301 jk_printf(s, " bad=%d", bad);
2302 jk_printf(s, " busy=%d", lb->s->busy);
2303 jk_printf(s, " max_busy=%d", lb->s->max_busy);
2304 jk_printf(s, " map_count=%d", map_count);
2305 jk_printf(s, " time_to_maintenance_min=%d", ms_min);
2306 jk_printf(s, " time_to_maintenance_max=%d", ms_max);
2307 jk_printf(s, " last_reset_at=%ld", (long)lb->s->last_reset);
2308 jk_printf(s, " last_reset_ago=%d", (int)difftime(now, lb->s->last_reset));
2312 else if (mime == JK_STATUS_MIME_PROP) {
2314 jk_print_prop_att_string(s, w, NULL, "list", name);
2315 jk_print_prop_att_string(s, w, name, "type", status_worker_type(JK_LB_WORKER_TYPE));
2316 jk_print_prop_att_string(s, w, name, "sticky_session", jk_get_bool(lb->sticky_session));
2317 jk_print_prop_att_string(s, w, name, "sticky_session_force", jk_get_bool(lb->sticky_session_force));
2318 jk_print_prop_att_int(s, w, name, "retries", lb->retries);
2319 jk_print_prop_att_int(s, w, name, "recover_time", lb->recover_wait_time);
2320 jk_print_prop_att_int(s, w, name, "error_escalation_time", lb->error_escalation_time);
2321 jk_print_prop_att_int(s, w, name, "max_reply_timeouts", lb->max_reply_timeouts);
2322 jk_print_prop_att_string(s, w, name, "method", jk_lb_get_method(lb, l));
2323 jk_print_prop_att_string(s, w, name, "lock", jk_lb_get_lock(lb, l));
2324 jk_print_prop_att_int(s, w, name, "member_count", lb->num_of_workers);
2325 jk_print_prop_att_int(s, w, name, "good", good);
2326 jk_print_prop_att_int(s, w, name, "degraded", degraded);
2327 jk_print_prop_att_int(s, w, name, "bad", bad);
2328 jk_print_prop_att_int(s, w, name, "busy", lb->s->busy);
2329 jk_print_prop_att_int(s, w, name, "max_busy", lb->s->max_busy);
2330 jk_print_prop_att_int(s, w, name, "map_count", map_count);
2331 jk_print_prop_att_int(s, w, name, "time_to_maintenance_min", ms_min);
2332 jk_print_prop_att_int(s, w, name, "time_to_maintenance_max", ms_max);
2333 jk_print_prop_att_long(s, w, name, "last_reset_at", (long)lb->s->last_reset);
2334 jk_print_prop_att_int(s, w, name, "last_reset_ago", (int)difftime(now, lb->s->last_reset));
2338 if (!hide_members) {
2340 if (mime == JK_STATUS_MIME_HTML) {
2342 jk_puts(s, "<h4>Balancer Members [");
2344 status_write_uri(s, p, "Show All Members", JK_STATUS_CMD_SHOW, JK_STATUS_MIME_UNKNOWN,
2345 name, "", 0, 0, "", l);
2346 jk_puts(s, "] [");
2349 status_write_uri(s, p, "Hide", JK_STATUS_CMD_SHOW, JK_STATUS_MIME_UNKNOWN,
2350 NULL, NULL, JK_STATUS_ARG_OPTION_NO_MEMBERS, 0, "", l);
2353 status_write_uri(s, p, "Hide", JK_STATUS_CMD_LIST, JK_STATUS_MIME_UNKNOWN,
2354 NULL, NULL, JK_STATUS_ARG_OPTION_NO_MEMBERS, 0, "", l);
2356 jk_puts(s, "]</h4>\n");
2357 if (!hide_ajp_conf) {
2358 jk_puts(s, "<table>" JK_STATUS_SHOW_MEMBER_CONF_HEAD);
2360 status_write_uri(s, p, "Hide", JK_STATUS_CMD_UNKNOWN, JK_STATUS_MIME_UNKNOWN,
2361 NULL, NULL, JK_STATUS_ARG_OPTION_NO_AJP_CONF, 0, NULL, l);
2362 jk_puts(s, "]</td></tr>");
2364 jk_worker_t *jw = (jk_worker_t *)swr->worker;
2365 ajp_worker_t *aw = (ajp_worker_t *)jw->worker_private;
2366 display_worker_ajp_conf_details(s, p, aw, 1, jw->type, l);
2369 for (j = 0; j < lb->num_of_workers; j++) {
2370 lb_sub_worker_t *wr = &(lb->lb_workers[j]);
2371 jk_worker_t *jw = (jk_worker_t *)wr->worker;
2372 ajp_worker_t *aw = (ajp_worker_t *)jw->worker_private;
2373 display_worker_ajp_conf_details(s, p, aw, 1, jw->type, l);
2375 jk_puts(s, "</table>\n<br/>\n");
2377 jk_puts(s, "<table>" JK_STATUS_SHOW_MEMBER_HEAD);
2382 const char *sub_name = swr->name;
2383 ajp_worker_t *aw = (ajp_worker_t *)swr->worker->worker_private;
2385 if (mime == JK_STATUS_MIME_HTML) {
2386 jk_puts(s, "<tr>\n<td>[");
2390 status_write_uri(s, p, "E", JK_STATUS_CMD_EDIT, JK_STATUS_MIME_UNKNOWN,
2391 name, sub_name, 0, 0, "", l);
2393 status_write_uri(s, p, "R", JK_STATUS_CMD_RESET, JK_STATUS_MIME_UNKNOWN,
2394 name, sub_name, 0, 0, "", l);
2395 if (swr->s->state == JK_LB_STATE_ERROR) {
2397 status_write_uri(s, p, "T", JK_STATUS_CMD_RECOVER, JK_STATUS_MIME_UNKNOWN,
2398 name, sub_name, 0, 0, "", l);
2402 jk_puts(s, " </td>");
2404 display_worker_ajp_details(s, p, aw, swr, lb, ms_min, ms_max, 0, l);
2406 for (j = 0; j < lb->num_of_workers; j++) {
2407 lb_sub_worker_t *wr = &(lb->lb_workers[j]);
2408 const char *sub_name = wr->name;
2409 ajp_worker_t *aw = (ajp_worker_t *)wr->worker->worker_private;
2411 if (mime == JK_STATUS_MIME_HTML) {
2412 jk_puts(s, "<tr>\n<td>[");
2413 status_write_uri(s, p, "S", JK_STATUS_CMD_SHOW, JK_STATUS_MIME_UNKNOWN,
2414 name, sub_name, 0, 0, "", l);
2417 status_write_uri(s, p, "E", JK_STATUS_CMD_EDIT, JK_STATUS_MIME_UNKNOWN,
2418 name, sub_name, 0, 0, "", l);
2420 status_write_uri(s, p, "R", JK_STATUS_CMD_RESET, JK_STATUS_MIME_UNKNOWN,
2421 name, sub_name, 0, 0, "", l);
2422 if (wr->s->state == JK_LB_STATE_ERROR) {
2424 status_write_uri(s, p, "T", JK_STATUS_CMD_RECOVER, JK_STATUS_MIME_UNKNOWN,
2425 name, sub_name, 0, 0, "", l);
2429 jk_puts(s, " </td>");
2431 display_worker_ajp_details(s, p, aw, wr, lb, ms_min, ms_max, 0, l);
2434 if (mime == JK_STATUS_MIME_HTML) {
2436 jk_puts(s, "</table><br/>\n");
2439 status_get_string(p, JK_STATUS_ARG_CMD, NULL, &arg, l);
2440 status_start_form(s, p, "get", JK_STATUS_CMD_EDIT, NULL, l);
2441 jk_printf(s, JK_STATUS_FORM_HIDDEN_STRING, JK_STATUS_ARG_WORKER, name);
2443 jk_printf(s, JK_STATUS_FORM_HIDDEN_STRING, JK_STATUS_ARG_FROM, arg);
2444 jk_puts(s, "<table><tr><td><b>E</b>dit this attribute for all members:</td><td>");
2445 jk_putv(s, "<select name=\"", JK_STATUS_ARG_ATTRIBUTE,
2446 "\" size=\"1\">\n", NULL);
2447 jk_putv(s, "<option value=\"", JK_STATUS_ARG_LBM_ACTIVATION, "\">", JK_STATUS_ARG_LBM_TEXT_ACTIVATION, "</option>\n", NULL);
2448 jk_putv(s, "<option value=\"", JK_STATUS_ARG_LBM_FACTOR, "\">", JK_STATUS_ARG_LBM_TEXT_FACTOR, "</option>\n", NULL);
2449 jk_putv(s, "<option value=\"", JK_STATUS_ARG_LBM_ROUTE, "\">", JK_STATUS_ARG_LBM_TEXT_ROUTE, "</option>\n", NULL);
2450 jk_putv(s, "<option value=\"", JK_STATUS_ARG_LBM_REDIRECT, "\">", JK_STATUS_ARG_LBM_TEXT_REDIRECT, "</option>\n", NULL);
2451 jk_putv(s, "<option value=\"", JK_STATUS_ARG_LBM_DOMAIN, "\">", JK_STATUS_ARG_LBM_TEXT_DOMAIN, "</option>\n", NULL);
2452 jk_putv(s, "<option value=\"", JK_STATUS_ARG_LBM_DISTANCE, "\">", JK_STATUS_ARG_LBM_TEXT_DISTANCE, "</option>\n", NULL);
2453 jk_putv(s, "<option value=\"", JK_STATUS_ARG_AJP_CACHE_TO, "\">", JK_STATUS_ARG_AJP_TEXT_CACHE_TO, "</option>\n", NULL);
2454 jk_putv(s, "<option value=\"", JK_STATUS_ARG_AJP_PING_TO, "\">", JK_STATUS_ARG_AJP_TEXT_PING_TO, "</option>\n", NULL);
2455 jk_putv(s, "<option value=\"", JK_STATUS_ARG_AJP_CONNECT_TO, "\">", JK_STATUS_ARG_AJP_TEXT_CONNECT_TO, "</option>\n", NULL);
2456 jk_putv(s, "<option value=\"", JK_STATUS_ARG_AJP_PREPOST_TO, "\">", JK_STATUS_ARG_AJP_TEXT_PREPOST_TO, "</option>\n", NULL);
2457 jk_putv(s, "<option value=\"", JK_STATUS_ARG_AJP_REPLY_TO, "\">", JK_STATUS_ARG_AJP_TEXT_REPLY_TO, "</option>\n", NULL);
2458 jk_putv(s, "<option value=\"", JK_STATUS_ARG_AJP_RETRIES, "\">", JK_STATUS_ARG_AJP_TEXT_RETRIES, "</option>\n", NULL);
2459 jk_putv(s, "<option value=\"", JK_STATUS_ARG_AJP_RETRY_INT, "\">", JK_STATUS_ARG_AJP_TEXT_RETRY_INT, "</option>\n", NULL);
2460 jk_putv(s, "<option value=\"", JK_STATUS_ARG_AJP_CPING_INT, "\">", JK_STATUS_ARG_AJP_TEXT_CPING_INT, "</option>\n", NULL);
2461 jk_putv(s, "<option value=\"", JK_STATUS_ARG_AJP_REC_OPTS, "\">", JK_STATUS_ARG_AJP_TEXT_REC_OPTS, "</option>\n", NULL);
2462 jk_putv(s, "<option value=\"", JK_STATUS_ARG_AJP_MAX_PK_SZ, "\">", JK_STATUS_ARG_AJP_TEXT_MAX_PK_SZ, "</option>\n", NULL);
2463 jk_puts(s, "</select></td><td><input type=\"submit\" value=\"Go\"/></tr></table></form>\n");
2471 display_maps(s, p, name, l);
2473 if (mime == JK_STATUS_MIME_XML) {
2474 jk_print_xml_close_elt(s, w, 2, "balancer");
2480 static void display_worker_ajp(jk_ws_service_t *s,
2481 status_endpoint_t *p,
2490 unsigned int hide_ajp_conf;
2493 const char *name = aw->name;
2494 status_worker_t *w = p->worker;
2497 status_get_string(p, JK_STATUS_ARG_CMD, NULL, &arg, l);
2498 cmd = status_cmd_int(arg);
2499 status_get_string(p, JK_STATUS_ARG_MIME, NULL, &arg, l);
2500 mime = status_mime_int(arg);
2501 hide_ajp_conf = status_get_int(p, JK_STATUS_ARG_OPTIONS, 0, l) &
2502 JK_STATUS_ARG_OPTION_NO_AJP_CONF;
2507 read_only = status_get_int(p, JK_STATUS_ARG_OPTIONS, 0, l) &
2508 JK_STATUS_ARG_OPTION_READ_ONLY;
2510 if (cmd == JK_STATUS_CMD_SHOW) {
2514 if (aw->sequence != aw->s->h.sequence)
2515 jk_ajp_pull(aw, JK_FALSE, l);
2517 map_count = count_maps(s, name, l);
2519 if (mime == JK_STATUS_MIME_HTML) {
2521 jk_puts(s, "<hr/><h3>[");
2525 status_write_uri(s, p, "S", JK_STATUS_CMD_SHOW, JK_STATUS_MIME_UNKNOWN,
2526 name, "", 0, 0, "", l);
2529 status_write_uri(s, p, "E", JK_STATUS_CMD_EDIT, JK_STATUS_MIME_UNKNOWN,
2530 name, "", 0, 0, "", l);
2532 status_write_uri(s, p, "R", JK_STATUS_CMD_RESET, JK_STATUS_MIME_UNKNOWN,
2533 name, "", 0, 0, "", l);
2535 jk_puts(s, "] ");
2536 jk_putv(s, "Worker Status for ", name, "</h3>\n", NULL);
2537 if (!hide_ajp_conf) {
2538 jk_puts(s, "<table>" JK_STATUS_SHOW_AJP_CONF_HEAD);
2540 status_write_uri(s, p, "Hide", JK_STATUS_CMD_UNKNOWN, JK_STATUS_MIME_UNKNOWN,
2541 NULL, NULL, JK_STATUS_ARG_OPTION_NO_AJP_CONF, 0, NULL, l);
2542 jk_puts(s, "]</td></tr>");
2543 display_worker_ajp_conf_details(s, p, aw, 0, type, l);
2544 jk_puts(s, "</table>\n<br/>\n");
2547 jk_puts(s, "<p>\n");
2549 status_write_uri(s, p, "Show AJP Configuration", JK_STATUS_CMD_SHOW, JK_STATUS_MIME_UNKNOWN,
2550 NULL, NULL, 0, JK_STATUS_ARG_OPTION_NO_AJP_CONF, "", l);
2553 status_write_uri(s, p, "Show AJP Configuration", JK_STATUS_CMD_LIST, JK_STATUS_MIME_UNKNOWN,
2554 NULL, NULL, 0, JK_STATUS_ARG_OPTION_NO_AJP_CONF, "", l);
2556 jk_puts(s, "</p>\n");
2558 jk_puts(s, "<table>" JK_STATUS_SHOW_AJP_HEAD);
2560 display_worker_ajp_details(s, p, aw, NULL, NULL, 0, 0, map_count, l);
2562 if (mime == JK_STATUS_MIME_HTML) {
2563 jk_puts(s, "</table>\n");
2566 display_maps(s, p, name, l);
2571 static void display_worker(jk_ws_service_t *s,
2572 status_endpoint_t *p,
2574 lb_sub_worker_t *swr,
2577 status_worker_t *w = p->worker;
2580 if (jw->type == JK_LB_WORKER_TYPE) {
2581 lb_worker_t *lb = (lb_worker_t *)jw->worker_private;
2583 if (JK_IS_DEBUG_LEVEL(l))
2584 jk_log(l, JK_LOG_DEBUG,
2585 "Status worker '%s' %s lb worker '%s'",
2586 w->name, "displaying", lb->name);
2587 display_worker_lb(s, p, lb, swr, l);
2590 jk_log(l, JK_LOG_WARNING,
2591 "Status worker '%s' lb worker is (null)",
2595 else if (jw->type == JK_AJP13_WORKER_TYPE ||
2596 jw->type == JK_AJP14_WORKER_TYPE) {
2597 ajp_worker_t *aw = (ajp_worker_t *)jw->worker_private;
2599 if (JK_IS_DEBUG_LEVEL(l))
2600 jk_log(l, JK_LOG_DEBUG,
2601 "Status worker '%s' %s ajp worker '%s'",
2602 w->name, "displaying", aw->name);
2603 display_worker_ajp(s, p, aw, jw->type, l);
2606 jk_log(l, JK_LOG_WARNING,
2607 "Status worker '%s' aw worker is (null)",
2612 if (JK_IS_DEBUG_LEVEL(l))
2613 jk_log(l, JK_LOG_DEBUG,
2614 "Status worker '%s' worker type not implemented",
2621 static void form_worker(jk_ws_service_t *s,
2622 status_endpoint_t *p,
2626 const char *name = NULL;
2627 lb_worker_t *lb = NULL;
2628 status_worker_t *w = p->worker;
2631 if (jw->type == JK_LB_WORKER_TYPE) {
2632 lb = (lb_worker_t *)jw->worker_private;
2634 if (JK_IS_DEBUG_LEVEL(l))
2635 jk_log(l, JK_LOG_DEBUG,
2636 "Status worker '%s' producing edit form for lb worker '%s'",
2640 jk_log(l, JK_LOG_WARNING,
2641 "Status worker '%s' worker type not implemented",
2648 jk_log(l, JK_LOG_WARNING,
2649 "Status worker '%s' lb structure is (null)",
2655 jk_putv(s, "<hr/><h3>Edit load balancer settings for ",
2656 name, "</h3>\n", NULL);
2658 status_start_form(s, p, "get", JK_STATUS_CMD_UPDATE, NULL, l);
2660 jk_putv(s, "<table>\n<tr><td>", JK_STATUS_ARG_LB_TEXT_RETRIES,
2661 ":</td><td><input name=\"",
2662 JK_STATUS_ARG_LB_RETRIES, "\" type=\"text\" ", NULL);
2663 jk_printf(s, "value=\"%d\"/></td></tr>\n", lb->retries);
2664 jk_putv(s, "<tr><td>", JK_STATUS_ARG_LB_TEXT_RETRY_INT,
2665 ":</td><td><input name=\"",
2666 JK_STATUS_ARG_LB_RETRY_INT, "\" type=\"text\" ", NULL);
2667 jk_printf(s, "value=\"%d\"/></td></tr>\n", lb->retry_interval);
2668 jk_putv(s, "<tr><td>", JK_STATUS_ARG_LB_TEXT_RECOVER_TIME,
2669 ":</td><td><input name=\"",
2670 JK_STATUS_ARG_LB_RECOVER_TIME, "\" type=\"text\" ", NULL);
2671 jk_printf(s, "value=\"%d\"/></td></tr>\n", lb->recover_wait_time);
2672 jk_putv(s, "<tr><td>", JK_STATUS_ARG_LB_TEXT_ERROR_ESCALATION_TIME,
2673 ":</td><td><input name=\"",
2674 JK_STATUS_ARG_LB_ERROR_ESCALATION_TIME, "\" type=\"text\" ", NULL);
2675 jk_printf(s, "value=\"%d\"/></td></tr>\n", lb->error_escalation_time);
2676 jk_putv(s, "<tr><td>", JK_STATUS_ARG_LB_TEXT_MAX_REPLY_TIMEOUTS,
2677 ":</td><td><input name=\"",
2678 JK_STATUS_ARG_LB_MAX_REPLY_TIMEOUTS, "\" type=\"text\" ", NULL);
2679 jk_printf(s, "value=\"%d\"/></td></tr>\n", lb->max_reply_timeouts);
2680 jk_putv(s, "<tr><td>", JK_STATUS_ARG_LB_TEXT_STICKY,
2681 ":</td><td><input name=\"",
2682 JK_STATUS_ARG_LB_STICKY, "\" type=\"checkbox\"", NULL);
2683 if (lb->sticky_session)
2684 jk_puts(s, " checked=\"checked\"");
2685 jk_puts(s, "/></td></tr>\n");
2686 jk_putv(s, "<tr><td>", JK_STATUS_ARG_LB_TEXT_STICKY_FORCE,
2687 ":</td><td><input name=\"",
2688 JK_STATUS_ARG_LB_STICKY_FORCE, "\" type=\"checkbox\"", NULL);
2689 if (lb->sticky_session_force)
2690 jk_puts(s, " checked=\"checked\"");
2691 jk_puts(s, "/></td></tr>\n");
2692 jk_putv(s, "<tr><td>", JK_STATUS_ARG_LB_TEXT_METHOD,
2693 ":</td><td></td></tr>\n", NULL);
2694 jk_putv(s, "<tr><td> Requests</td><td><input name=\"",
2695 JK_STATUS_ARG_LB_METHOD, "\" type=\"radio\"", NULL);
2696 jk_printf(s, " value=\"%d\"", JK_LB_METHOD_REQUESTS);
2697 if (lb->lbmethod == JK_LB_METHOD_REQUESTS)
2698 jk_puts(s, " checked=\"checked\"");
2699 jk_puts(s, "/></td></tr>\n");
2700 jk_putv(s, "<tr><td> Traffic</td><td><input name=\"",
2701 JK_STATUS_ARG_LB_METHOD, "\" type=\"radio\"", NULL);
2702 jk_printf(s, " value=\"%d\"", JK_LB_METHOD_TRAFFIC);
2703 if (lb->lbmethod == JK_LB_METHOD_TRAFFIC)
2704 jk_puts(s, " checked=\"checked\"");
2705 jk_puts(s, "/></td></tr>\n");
2706 jk_putv(s, "<tr><td> Busyness</td><td><input name=\"",
2707 JK_STATUS_ARG_LB_METHOD, "\" type=\"radio\"", NULL);
2708 jk_printf(s, " value=\"%d\"", JK_LB_METHOD_BUSYNESS);
2709 if (lb->lbmethod == JK_LB_METHOD_BUSYNESS)
2710 jk_puts(s, " checked=\"checked\"");
2711 jk_puts(s, "/></td></tr>\n");
2712 jk_putv(s, "<tr><td> Sessions</td><td><input name=\"",
2713 JK_STATUS_ARG_LB_METHOD, "\" type=\"radio\"", NULL);
2714 jk_printf(s, " value=\"%d\"", JK_LB_METHOD_SESSIONS);
2715 if (lb->lbmethod == JK_LB_METHOD_SESSIONS)
2716 jk_puts(s, " checked=\"checked\"");
2717 jk_puts(s, "/></td></tr>\n");
2718 jk_putv(s, "<tr><td>", JK_STATUS_ARG_LB_TEXT_LOCK,
2719 ":</td><td></td></tr>\n", NULL);
2720 jk_putv(s, "<tr><td> Optimistic</td><td><input name=\"",
2721 JK_STATUS_ARG_LB_LOCK, "\" type=\"radio\"", NULL);
2722 jk_printf(s, " value=\"%d\"", JK_LB_LOCK_OPTIMISTIC);
2723 if (lb->lblock == JK_LB_LOCK_OPTIMISTIC)
2724 jk_puts(s, " checked=\"checked\"");
2725 jk_puts(s, "/></td></tr>\n");
2726 jk_putv(s, "<tr><td> Pessimistic</td><td><input name=\"",
2727 JK_STATUS_ARG_LB_LOCK, "\" type=\"radio\"", NULL);
2728 jk_printf(s, " value=\"%d\"", JK_LB_LOCK_PESSIMISTIC);
2729 if (lb->lblock == JK_LB_LOCK_PESSIMISTIC)
2730 jk_puts(s, " checked=\"checked\"");
2731 jk_puts(s, "/></td></tr>\n");
2732 jk_puts(s, "</table>\n");
2733 jk_puts(s, "<br/><input type=\"submit\" value=\"Update Balancer\"/></form>\n");
2738 static void form_member(jk_ws_service_t *s,
2739 status_endpoint_t *p,
2740 lb_sub_worker_t *wr,
2742 const char *lb_name,
2745 status_worker_t *w = p->worker;
2749 if (JK_IS_DEBUG_LEVEL(l))
2750 jk_log(l, JK_LOG_DEBUG,
2751 "Status worker '%s' producing edit form for sub worker '%s' of lb worker '%s'",
2752 w->name, wr? wr->name : aw->name, lb_name);
2754 jk_putv(s, "<hr/><h3>Edit worker settings for ",
2755 wr? wr->name : aw->name, "</h3>\n", NULL);
2756 status_start_form(s, p, "get", JK_STATUS_CMD_UPDATE, NULL, l);
2759 jk_puts(s, "<table><tbody valign=\"baseline\"><tr><th>Balancing related settings</th>\n");
2760 jk_puts(s, "<th> </th><th>AJP settings</th>\n");
2761 jk_puts(s, "</tr>\n");
2762 jk_puts(s, "<tr><td><table>\n");
2763 jk_putv(s, "<tr><td>", JK_STATUS_ARG_LBM_TEXT_ACTIVATION,
2764 ":</td><td></td></tr>\n", NULL);
2765 jk_putv(s, "<tr><td> Active</td><td><input name=\"",
2766 JK_STATUS_ARG_LBM_ACTIVATION, "\" type=\"radio\"", NULL);
2767 jk_printf(s, " value=\"%d\"", JK_LB_ACTIVATION_ACTIVE);
2768 if (wr->activation == JK_LB_ACTIVATION_ACTIVE)
2769 jk_puts(s, " checked=\"checked\"");
2770 jk_puts(s, "/></td></tr>\n");
2771 jk_putv(s, "<tr><td> Disabled</td><td><input name=\"",
2772 JK_STATUS_ARG_LBM_ACTIVATION, "\" type=\"radio\"", NULL);
2773 jk_printf(s, " value=\"%d\"", JK_LB_ACTIVATION_DISABLED);
2774 if (wr->activation == JK_LB_ACTIVATION_DISABLED)
2775 jk_puts(s, " checked=\"checked\"");
2776 jk_puts(s, "/></td></tr>\n");
2777 jk_putv(s, "<tr><td> Stopped</td><td><input name=\"",
2778 JK_STATUS_ARG_LBM_ACTIVATION, "\" type=\"radio\"", NULL);
2779 jk_printf(s, " value=\"%d\"", JK_LB_ACTIVATION_STOPPED);
2780 if (wr->activation == JK_LB_ACTIVATION_STOPPED)
2781 jk_puts(s, " checked=\"checked\"");
2782 jk_puts(s, "/></td></tr>\n");
2783 jk_putv(s, "<tr><td>", JK_STATUS_ARG_LBM_TEXT_FACTOR,
2784 ":</td><td><input name=\"",
2785 JK_STATUS_ARG_LBM_FACTOR, "\" type=\"text\" ", NULL);
2786 jk_printf(s, "value=\"%d\"/></td></tr>\n", wr->lb_factor);
2787 jk_putv(s, "<tr><td>", JK_STATUS_ARG_LBM_TEXT_ROUTE,
2788 ":</td><td><input name=\"",
2789 JK_STATUS_ARG_LBM_ROUTE, "\" type=\"text\" ", NULL);
2790 jk_printf(s, "value=\"%s\"/></td></tr>\n", wr->route);
2791 jk_putv(s, "<tr><td>", JK_STATUS_ARG_LBM_TEXT_REDIRECT,
2792 ":</td><td><input name=\"",
2793 JK_STATUS_ARG_LBM_REDIRECT, "\" type=\"text\" ", NULL);
2794 jk_putv(s, "value=\"", wr->redirect, NULL);
2795 jk_puts(s, "\"/></td></tr>\n");
2796 jk_putv(s, "<tr><td>", JK_STATUS_ARG_LBM_TEXT_DOMAIN,
2797 ":</td><td><input name=\"",
2798 JK_STATUS_ARG_LBM_DOMAIN, "\" type=\"text\" ", NULL);
2799 jk_putv(s, "value=\"", wr->domain, NULL);
2800 jk_puts(s, "\"/></td></tr>\n");
2801 jk_putv(s, "<tr><td>", JK_STATUS_ARG_LBM_TEXT_DISTANCE,
2802 ":</td><td><input name=\"",
2803 JK_STATUS_ARG_LBM_DISTANCE, "\" type=\"text\" ", NULL);
2804 jk_printf(s, "value=\"%d\"/></td></tr>\n", wr->distance);
2805 jk_puts(s, "</table>\n");
2806 jk_puts(s, "</td><td></td><td>\n");
2809 jk_puts(s, "<table>\n");
2810 jk_putv(s, "<tr><td>", JK_STATUS_ARG_AJP_TEXT_HOST_STR,
2811 ":</td><td><input name=\"",
2812 JK_STATUS_ARG_AJP_HOST_STR, "\" type=\"text\" ", NULL);
2813 jk_printf(s, "value=\"%s\"/></td></tr>\n", aw->host);
2814 jk_putv(s, "<tr><td>", JK_STATUS_ARG_AJP_TEXT_PORT,
2815 ":</td><td><input name=\"",
2816 JK_STATUS_ARG_AJP_PORT, "\" type=\"text\" ", NULL);
2817 jk_printf(s, "value=\"%d\"/></td></tr>\n", aw->port);
2819 jk_putv(s, "<tr><td>", JK_STATUS_ARG_AJP_TEXT_CACHE_TO,
2820 ":</td><td><input name=\"",
2821 JK_STATUS_ARG_AJP_CACHE_TO, "\" type=\"text\" ", NULL);
2822 jk_printf(s, "value=\"%d\"/></td></tr>\n", aw->cache_timeout);
2823 jk_putv(s, "<tr><td>", JK_STATUS_ARG_AJP_TEXT_PING_TO,
2824 ":</td><td><input name=\"",
2825 JK_STATUS_ARG_AJP_PING_TO, "\" type=\"text\" ", NULL);
2826 jk_printf(s, "value=\"%d\"/></td></tr>\n", aw->ping_timeout);
2827 jk_putv(s, "<tr><td>", JK_STATUS_ARG_AJP_TEXT_CONNECT_TO,
2828 ":</td><td><input name=\"",
2829 JK_STATUS_ARG_AJP_CONNECT_TO, "\" type=\"text\" ", NULL);
2830 jk_printf(s, "value=\"%d\"/></td></tr>\n", aw->connect_timeout);
2831 jk_putv(s, "<tr><td>", JK_STATUS_ARG_AJP_TEXT_PREPOST_TO,
2832 ":</td><td><input name=\"",
2833 JK_STATUS_ARG_AJP_PREPOST_TO, "\" type=\"text\" ", NULL);
2834 jk_printf(s, "value=\"%d\"/></td></tr>\n", aw->prepost_timeout);
2835 jk_putv(s, "<tr><td>", JK_STATUS_ARG_AJP_TEXT_REPLY_TO,
2836 ":</td><td><input name=\"",
2837 JK_STATUS_ARG_AJP_REPLY_TO, "\" type=\"text\" ", NULL);
2838 jk_printf(s, "value=\"%d\"/></td></tr>\n", aw->reply_timeout);
2839 jk_putv(s, "<tr><td>", JK_STATUS_ARG_AJP_TEXT_RETRIES,
2840 ":</td><td><input name=\"",
2841 JK_STATUS_ARG_AJP_RETRIES, "\" type=\"text\" ", NULL);
2842 jk_printf(s, "value=\"%d\"/></td></tr>\n", aw->retries);
2843 jk_putv(s, "<tr><td>", JK_STATUS_ARG_AJP_TEXT_RETRY_INT,
2844 ":</td><td><input name=\"",
2845 JK_STATUS_ARG_AJP_RETRY_INT, "\" type=\"text\" ", NULL);
2846 jk_printf(s, "value=\"%d\"/></td></tr>\n", aw->retry_interval);
2847 jk_putv(s, "<tr><td>", JK_STATUS_ARG_AJP_TEXT_CPING_INT,
2848 ":</td><td><input name=\"",
2849 JK_STATUS_ARG_AJP_CPING_INT, "\" type=\"text\" ", NULL);
2850 jk_printf(s, "value=\"%d\"/></td></tr>\n", aw->conn_ping_interval);
2851 jk_putv(s, "<tr><td>", JK_STATUS_ARG_AJP_TEXT_REC_OPTS,
2852 ":</td><td><input name=\"",
2853 JK_STATUS_ARG_AJP_REC_OPTS, "\" type=\"text\" ", NULL);
2854 jk_printf(s, "value=\"%d\"/></td></tr>\n", aw->recovery_opts);
2855 jk_putv(s, "<tr><td>", JK_STATUS_ARG_AJP_TEXT_MAX_PK_SZ,
2856 ":</td><td><input name=\"",
2857 JK_STATUS_ARG_AJP_MAX_PK_SZ, "\" type=\"text\" ", NULL);
2858 jk_printf(s, "value=\"%d\"/></td></tr>\n", aw->max_packet_size);
2859 jk_puts(s, "</table>\n");
2861 jk_puts(s, "</td></tr></table>\n");
2862 jk_puts(s, "<br/><input type=\"submit\" value=\"Update Worker\"/>\n</form>\n");
2866 static void form_all_members(jk_ws_service_t *s,
2867 status_endpoint_t *p,
2869 const char *attribute,
2872 const char *name = NULL;
2873 lb_worker_t *lb = NULL;
2874 status_worker_t *w = p->worker;
2880 jk_log(l, JK_LOG_WARNING,
2881 "Status worker '%s' missing request parameter '%s'",
2882 w->name, JK_STATUS_ARG_ATTRIBUTE);
2887 if (!strcmp(attribute, JK_STATUS_ARG_LBM_ACTIVATION))
2888 aname=JK_STATUS_ARG_LBM_TEXT_ACTIVATION;
2889 else if (!strcmp(attribute, JK_STATUS_ARG_LBM_FACTOR))
2890 aname=JK_STATUS_ARG_LBM_TEXT_FACTOR;
2891 else if (!strcmp(attribute, JK_STATUS_ARG_LBM_ROUTE))
2892 aname=JK_STATUS_ARG_LBM_TEXT_ROUTE;
2893 else if (!strcmp(attribute, JK_STATUS_ARG_LBM_REDIRECT))
2894 aname=JK_STATUS_ARG_LBM_TEXT_REDIRECT;
2895 else if (!strcmp(attribute, JK_STATUS_ARG_LBM_DOMAIN))
2896 aname=JK_STATUS_ARG_LBM_TEXT_DOMAIN;
2897 else if (!strcmp(attribute, JK_STATUS_ARG_LBM_DISTANCE))
2898 aname=JK_STATUS_ARG_LBM_TEXT_DISTANCE;
2899 else if (!strcmp(attribute, JK_STATUS_ARG_AJP_CACHE_TO))
2900 aname=JK_STATUS_ARG_AJP_TEXT_CACHE_TO;
2901 else if (!strcmp(attribute, JK_STATUS_ARG_AJP_PING_TO))
2902 aname=JK_STATUS_ARG_AJP_TEXT_PING_TO;
2903 else if (!strcmp(attribute, JK_STATUS_ARG_AJP_CONNECT_TO))
2904 aname=JK_STATUS_ARG_AJP_TEXT_CONNECT_TO;
2905 else if (!strcmp(attribute, JK_STATUS_ARG_AJP_PREPOST_TO))
2906 aname=JK_STATUS_ARG_AJP_TEXT_PREPOST_TO;
2907 else if (!strcmp(attribute, JK_STATUS_ARG_AJP_REPLY_TO))
2908 aname=JK_STATUS_ARG_AJP_TEXT_REPLY_TO;
2909 else if (!strcmp(attribute, JK_STATUS_ARG_AJP_RETRIES))
2910 aname=JK_STATUS_ARG_AJP_TEXT_RETRIES;
2911 else if (!strcmp(attribute, JK_STATUS_ARG_AJP_RETRY_INT))
2912 aname=JK_STATUS_ARG_AJP_TEXT_RETRY_INT;
2913 else if (!strcmp(attribute, JK_STATUS_ARG_AJP_CPING_INT))
2914 aname=JK_STATUS_ARG_AJP_TEXT_CPING_INT;
2915 else if (!strcmp(attribute, JK_STATUS_ARG_AJP_REC_OPTS))
2916 aname=JK_STATUS_ARG_AJP_TEXT_REC_OPTS;
2917 else if (!strcmp(attribute, JK_STATUS_ARG_AJP_MAX_PK_SZ))
2918 aname=JK_STATUS_ARG_AJP_TEXT_MAX_PK_SZ;
2920 jk_log(l, JK_LOG_WARNING,
2921 "Status worker '%s' unknown attribute '%s'",
2922 w->name, attribute);
2927 if (jw->type == JK_LB_WORKER_TYPE) {
2928 lb = (lb_worker_t *)jw->worker_private;
2930 if (JK_IS_DEBUG_LEVEL(l))
2931 jk_log(l, JK_LOG_DEBUG,
2932 "Status worker '%s' producing edit form for attribute '%s' [%s] of all members of lb worker '%s'",
2933 w->name, attribute, aname, name);
2936 jk_log(l, JK_LOG_WARNING,
2937 "Status worker '%s' worker type not implemented",
2944 jk_putv(s, "<hr/><h3>Edit attribute '", aname,
2945 "' for all members of load balancer ",
2946 name, "</h3>\n", NULL);
2948 status_start_form(s, p, "get", JK_STATUS_CMD_UPDATE, NULL, l);
2950 jk_putv(s, "<table><tr>"
2951 "<th>Balanced Worker</th><th>", aname, "</th>"
2954 for (i = 0; i < lb->num_of_workers; i++) {
2955 lb_sub_worker_t *wr = &(lb->lb_workers[i]);
2956 jk_worker_t *jw = wr->worker;
2957 ajp_worker_t *aw = (ajp_worker_t *)jw->worker_private;;
2959 jk_putv(s, "<tr><td>", wr->name, "</td><td>\n", NULL);
2961 if (!strcmp(attribute, JK_STATUS_ARG_LBM_ACTIVATION)) {
2963 jk_printf(s, "Active: <input name=\"" JK_STATUS_ARG_MULT_VALUE_BASE "%d\" type=\"radio\"", i);
2964 jk_printf(s, " value=\"%d\"", JK_LB_ACTIVATION_ACTIVE);
2965 if (wr->activation == JK_LB_ACTIVATION_ACTIVE)
2966 jk_puts(s, " checked=\"checked\"");
2967 jk_puts(s, "/> | \n");
2968 jk_printf(s, "Disabled: <input name=\"" JK_STATUS_ARG_MULT_VALUE_BASE "%d\" type=\"radio\"", i);
2969 jk_printf(s, " value=\"%d\"", JK_LB_ACTIVATION_DISABLED);
2970 if (wr->activation == JK_LB_ACTIVATION_DISABLED)
2971 jk_puts(s, " checked=\"checked\"");
2972 jk_puts(s, "/> | \n");
2973 jk_printf(s, "Stopped: <input name=\"" JK_STATUS_ARG_MULT_VALUE_BASE "%d\" type=\"radio\"", i);
2974 jk_printf(s, " value=\"%d\"", JK_LB_ACTIVATION_STOPPED);
2975 if (wr->activation == JK_LB_ACTIVATION_STOPPED)
2976 jk_puts(s, " checked=\"checked\"");
2980 else if (!strcmp(attribute, JK_STATUS_ARG_LBM_FACTOR)) {
2981 jk_printf(s, "<input name=\"" JK_STATUS_ARG_MULT_VALUE_BASE "%d\" type=\"text\"", i);
2982 jk_printf(s, "value=\"%d\"/>\n", wr->lb_factor);
2984 else if (!strcmp(attribute, JK_STATUS_ARG_LBM_ROUTE)) {
2985 jk_printf(s, "<input name=\"" JK_STATUS_ARG_MULT_VALUE_BASE "%d\" type=\"text\"", i);
2986 jk_putv(s, "value=\"", wr->route, "\"/>\n", NULL);
2988 else if (!strcmp(attribute, JK_STATUS_ARG_LBM_REDIRECT)) {
2989 jk_printf(s, "<input name=\"" JK_STATUS_ARG_MULT_VALUE_BASE "%d\" type=\"text\"", i);
2990 jk_putv(s, "value=\"", wr->redirect, "\"/>\n", NULL);
2992 else if (!strcmp(attribute, JK_STATUS_ARG_LBM_DOMAIN)) {
2993 jk_printf(s, "<input name=\"" JK_STATUS_ARG_MULT_VALUE_BASE "%d\" type=\"text\"", i);
2994 jk_putv(s, "value=\"", wr->domain, "\"/>\n", NULL);
2996 else if (!strcmp(attribute, JK_STATUS_ARG_LBM_DISTANCE)) {
2997 jk_printf(s, "<input name=\"" JK_STATUS_ARG_MULT_VALUE_BASE "%d\" type=\"text\"", i);
2998 jk_printf(s, "value=\"%d\"/>\n", wr->distance);
3000 else if (!strcmp(attribute, JK_STATUS_ARG_AJP_CACHE_TO)) {
3001 jk_printf(s, "<input name=\"" JK_STATUS_ARG_MULT_VALUE_BASE "%d\" type=\"text\"", i);
3002 jk_printf(s, "value=\"%d\"/>\n", aw->cache_timeout);
3004 else if (!strcmp(attribute, JK_STATUS_ARG_AJP_PING_TO)) {
3005 jk_printf(s, "<input name=\"" JK_STATUS_ARG_MULT_VALUE_BASE "%d\" type=\"text\"", i);
3006 jk_printf(s, "value=\"%d\"/>\n", aw->ping_timeout);
3008 else if (!strcmp(attribute, JK_STATUS_ARG_AJP_CONNECT_TO)) {
3009 jk_printf(s, "<input name=\"" JK_STATUS_ARG_MULT_VALUE_BASE "%d\" type=\"text\"", i);
3010 jk_printf(s, "value=\"%d\"/>\n", aw->connect_timeout);
3012 else if (!strcmp(attribute, JK_STATUS_ARG_AJP_PREPOST_TO)) {
3013 jk_printf(s, "<input name=\"" JK_STATUS_ARG_MULT_VALUE_BASE "%d\" type=\"text\"", i);
3014 jk_printf(s, "value=\"%d\"/>\n", aw->prepost_timeout);
3016 else if (!strcmp(attribute, JK_STATUS_ARG_AJP_REPLY_TO)) {
3017 jk_printf(s, "<input name=\"" JK_STATUS_ARG_MULT_VALUE_BASE "%d\" type=\"text\"", i);
3018 jk_printf(s, "value=\"%d\"/>\n", aw->reply_timeout);
3020 else if (!strcmp(attribute, JK_STATUS_ARG_AJP_RETRIES)) {
3021 jk_printf(s, "<input name=\"" JK_STATUS_ARG_MULT_VALUE_BASE "%d\" type=\"text\"", i);
3022 jk_printf(s, "value=\"%d\"/>\n", aw->retries);
3024 else if (!strcmp(attribute, JK_STATUS_ARG_AJP_RETRY_INT)) {
3025 jk_printf(s, "<input name=\"" JK_STATUS_ARG_MULT_VALUE_BASE "%d\" type=\"text\"", i);
3026 jk_printf(s, "value=\"%d\"/>\n", aw->retry_interval);
3028 else if (!strcmp(attribute, JK_STATUS_ARG_AJP_CPING_INT)) {
3029 jk_printf(s, "<input name=\"" JK_STATUS_ARG_MULT_VALUE_BASE "%d\" type=\"text\"", i);
3030 jk_printf(s, "value=\"%d\"/>\n", aw->conn_ping_interval);
3032 else if (!strcmp(attribute, JK_STATUS_ARG_AJP_REC_OPTS)) {
3033 jk_printf(s, "<input name=\"" JK_STATUS_ARG_MULT_VALUE_BASE "%d\" type=\"text\"", i);
3034 jk_printf(s, "value=\"%d\"/>\n", aw->recovery_opts);
3036 else if (!strcmp(attribute, JK_STATUS_ARG_AJP_MAX_PK_SZ)) {
3037 jk_printf(s, "<input name=\"" JK_STATUS_ARG_MULT_VALUE_BASE "%d\" type=\"text\"", i);
3038 jk_printf(s, "value=\"%d\"/>\n", aw->max_packet_size);
3041 jk_puts(s, "</td></tr>");
3044 jk_puts(s, "</table>\n");
3045 jk_puts(s, "<br/><input type=\"submit\" value=\"Update Balancer\"/></form>\n");
3050 static void commit_worker(jk_ws_service_t *s,
3051 status_endpoint_t *p,
3055 const char *name = NULL;
3056 lb_worker_t *lb = NULL;
3057 status_worker_t *w = p->worker;
3059 int sync_needed = JK_FALSE;
3063 if (jw->type == JK_LB_WORKER_TYPE) {
3064 lb = (lb_worker_t *)jw->worker_private;
3066 if (JK_IS_DEBUG_LEVEL(l))
3067 jk_log(l, JK_LOG_DEBUG,
3068 "Status worker '%s' committing changes for lb worker '%s'",
3072 jk_log(l, JK_LOG_WARNING,
3073 "Status worker '%s' worker type not implemented",
3080 jk_log(l, JK_LOG_WARNING,
3081 "Status worker '%s' lb structure is (null)",
3087 i = status_get_int(p, JK_STATUS_ARG_LB_RETRIES,
3089 if (i != lb->retries && i > 0) {
3090 jk_log(l, JK_LOG_INFO,
3091 "Status worker '%s' setting 'retries' for lb worker '%s' to '%i'",
3094 sync_needed = JK_TRUE;
3096 i = status_get_int(p, JK_STATUS_ARG_LB_RETRY_INT,
3097 lb->retry_interval, l);
3098 if (i != lb->retry_interval && i > 0) {
3099 jk_log(l, JK_LOG_INFO,
3100 "Status worker '%s' setting 'retry_interval' for lb worker '%s' to '%i'",
3102 lb->retry_interval = i;
3103 sync_needed = JK_TRUE;
3105 i = status_get_int(p, JK_STATUS_ARG_LB_RECOVER_TIME,
3106 lb->recover_wait_time, l);
3107 if (i != lb->recover_wait_time && i > 0) {
3108 jk_log(l, JK_LOG_INFO,
3109 "Status worker '%s' setting 'recover_time' for lb worker '%s' to '%i'",
3111 lb->recover_wait_time = i;
3112 sync_needed = JK_TRUE;
3114 i = status_get_int(p, JK_STATUS_ARG_LB_ERROR_ESCALATION_TIME,
3115 lb->error_escalation_time, l);
3116 if (i != lb->error_escalation_time && i > 0) {
3117 jk_log(l, JK_LOG_INFO,
3118 "Status worker '%s' setting 'error_escalation_time' for lb worker '%s' to '%i'",
3120 lb->error_escalation_time = i;
3121 sync_needed = JK_TRUE;
3123 i = status_get_int(p, JK_STATUS_ARG_LB_MAX_REPLY_TIMEOUTS,
3124 lb->max_reply_timeouts, l);
3125 if (i != lb->max_reply_timeouts && i >= 0) {
3126 jk_log(l, JK_LOG_INFO,
3127 "Status worker '%s' setting 'max_reply_timeouts' for lb worker '%s' to '%i'",
3129 lb->max_reply_timeouts = i;
3130 sync_needed = JK_TRUE;
3132 i = status_get_bool(p, JK_STATUS_ARG_LB_STICKY, lb->sticky_session, l);
3133 if (i != lb->sticky_session) {
3134 jk_log(l, JK_LOG_INFO,
3135 "Status worker '%s' setting 'sticky_session' for lb worker '%s' to '%i'",
3137 lb->sticky_session = i;
3138 sync_needed = JK_TRUE;
3140 i = status_get_bool(p, JK_STATUS_ARG_LB_STICKY_FORCE, lb->sticky_session_force, l);
3141 if (i != lb->sticky_session_force) {
3142 jk_log(l, JK_LOG_INFO,
3143 "Status worker '%s' setting 'sticky_session_force' for lb worker '%s' to '%i'",
3145 lb->sticky_session_force = i;
3146 sync_needed = JK_TRUE;
3148 if (status_get_string(p, JK_STATUS_ARG_LB_METHOD, NULL, &arg, l) == JK_TRUE) {
3149 i = jk_lb_get_method_code(arg);
3150 if (i != lb->lbmethod && i >= 0 && i <= JK_LB_METHOD_MAX) {
3151 jk_log(l, JK_LOG_INFO,
3152 "Status worker '%s' setting 'method' for lb worker '%s' to '%s'",
3153 w->name, name, jk_lb_get_method(lb, l));
3155 sync_needed = JK_TRUE;
3158 if (status_get_string(p, JK_STATUS_ARG_LB_LOCK, NULL, &arg, l) == JK_TRUE) {
3159 i = jk_lb_get_lock_code(arg);
3160 if (i != lb->lblock && i >= 0 && i <= JK_LB_LOCK_MAX) {
3161 jk_log(l, JK_LOG_INFO,
3162 "Status worker '%s' setting 'lock' for lb worker '%s' to '%s'",
3163 w->name, name, jk_lb_get_lock(lb, l));
3165 sync_needed = JK_TRUE;
3168 if (sync_needed == JK_TRUE) {
3170 jk_lb_push(lb, JK_TRUE, l);
3174 static int set_int_if_changed(status_endpoint_t *p,
3181 const char *lb_name,
3185 status_worker_t *w = p->worker;
3186 i = status_get_int(p, arg, *param, l);
3187 if (i != *param && i >= min && i <= max) {
3189 jk_log(l, JK_LOG_INFO,
3190 "Status worker '%s' setting '%s' for sub worker '%s' of lb worker '%s' to '%i'",
3191 w->name, att, name, lb_name, i);
3193 jk_log(l, JK_LOG_INFO,
3194 "Status worker '%s' setting '%s' for ajp worker '%s' to '%i'",
3195 w->name, att, name, i);
3202 static int set_uint_if_changed(status_endpoint_t *p,
3208 unsigned int *param,
3209 const char *lb_name,
3213 status_worker_t *w = p->worker;
3214 i = (unsigned)status_get_int(p, arg, *param, l);
3215 if (i != *param && i >= min && i <= max) {
3217 jk_log(l, JK_LOG_INFO,
3218 "Status worker '%s' setting '%s' for sub worker '%s' of lb worker '%s' to '%u'",
3219 w->name, att, name, lb_name, i);
3221 jk_log(l, JK_LOG_INFO,
3222 "Status worker '%s' setting '%s' for ajp worker '%s' to '%u'",
3223 w->name, att, name, i);
3230 static int commit_member(jk_ws_service_t *s,
3231 status_endpoint_t *p,
3233 lb_sub_worker_t *wr,
3239 const char *lb_name = NULL;
3240 status_worker_t *w = p->worker;
3245 int resolve = JK_FALSE;
3246 char host[JK_SHM_STR_SIZ+1];
3252 if (JK_IS_DEBUG_LEVEL(l))
3253 jk_log(l, JK_LOG_DEBUG,
3254 "Status worker '%s' committing changes for sub worker '%s' of lb worker '%s'",
3255 w->name, wr->name, lb_name);
3258 if (JK_IS_DEBUG_LEVEL(l))
3259 jk_log(l, JK_LOG_DEBUG,
3260 "Status worker '%s' committing changes for ajp worker '%s'",
3265 if (status_get_string(p, JK_STATUS_ARG_LBM_ACTIVATION, NULL, &arg, l) == JK_TRUE) {
3266 i = jk_lb_get_activation_code(arg);
3267 if (i != wr->activation && i >= 0 && i <= JK_LB_ACTIVATION_MAX) {
3269 jk_log(l, JK_LOG_INFO,
3270 "Status worker '%s' setting 'activation' for sub worker '%s' of lb worker '%s' to '%s'",
3271 w->name, wr->name, lb_name, jk_lb_get_activation(wr, l));
3272 *side_effect |= JK_STATUS_NEEDS_RESET_LB_VALUES | JK_STATUS_NEEDS_PUSH;
3275 if (set_int_if_changed(p, wr->name, "lbfactor", JK_STATUS_ARG_LBM_FACTOR,
3276 1, INT_MAX, &wr->lb_factor, lb_name, l))
3277 /* Recalculate the load multiplicators wrt. lb_factor */
3278 *side_effect |= JK_STATUS_NEEDS_UPDATE_MULT | JK_STATUS_NEEDS_PUSH;
3279 if ((rv = status_get_string(p, JK_STATUS_ARG_LBM_ROUTE,
3280 NULL, &arg, l)) == JK_TRUE) {
3281 if (strncmp(wr->route, arg, JK_SHM_STR_SIZ)) {
3282 jk_log(l, JK_LOG_INFO,
3283 "Status worker '%s' setting 'route' for sub worker '%s' of lb worker '%s' to '%s'",
3284 w->name, wr->name, lb_name, arg);
3285 strncpy(wr->route, arg, JK_SHM_STR_SIZ);
3286 *side_effect |= JK_STATUS_NEEDS_PUSH;
3287 if (!wr->domain[0]) {
3288 char * id_domain = strchr(wr->route, '.');
3291 strcpy(wr->domain, wr->route);
3297 if ((rv = status_get_string(p, JK_STATUS_ARG_LBM_REDIRECT,
3298 NULL, &arg, l)) == JK_TRUE) {
3299 if (strncmp(wr->redirect, arg, JK_SHM_STR_SIZ)) {
3300 jk_log(l, JK_LOG_INFO,
3301 "Status worker '%s' setting 'redirect' for sub worker '%s' of lb worker '%s' to '%s'",
3302 w->name, wr->name, lb_name, arg);
3303 strncpy(wr->redirect, arg, JK_SHM_STR_SIZ);
3304 *side_effect |= JK_STATUS_NEEDS_PUSH;
3307 if ((rv = status_get_string(p, JK_STATUS_ARG_LBM_DOMAIN,
3308 NULL, &arg, l)) == JK_TRUE) {
3309 if (strncmp(wr->domain, arg, JK_SHM_STR_SIZ)) {
3310 jk_log(l, JK_LOG_INFO,
3311 "Status worker '%s' setting 'domain' for sub worker '%s' of lb worker '%s' to '%s'",
3312 w->name, wr->name, lb_name, arg);
3313 strncpy(wr->domain, arg, JK_SHM_STR_SIZ);
3314 *side_effect |= JK_STATUS_NEEDS_PUSH;
3317 if (set_int_if_changed(p, wr->name, "distance", JK_STATUS_ARG_LBM_DISTANCE,
3318 0, INT_MAX, &wr->distance, lb_name, l))
3319 *side_effect |= JK_STATUS_NEEDS_PUSH;
3321 old = aw->cache_timeout;
3322 if (set_int_if_changed(p, aw->name, "connection_pool_timeout", JK_STATUS_ARG_AJP_CACHE_TO,
3323 0, INT_MAX, &aw->cache_timeout, lb_name, l)) {
3324 *side_effect |= JK_STATUS_NEEDS_PUSH;
3327 for (i = 0; i < aw->ep_cache_sz; i++) {
3328 ajp_endpoint_t *ae = (ajp_endpoint_t *) aw->ep_cache[i];
3330 ae->last_access = time(NULL);
3335 if (set_int_if_changed(p, aw->name, "port", JK_STATUS_ARG_AJP_PORT,
3336 0, INT_MAX, &port, lb_name, l)) {
3337 strncpy(host, aw->host, JK_SHM_STR_SIZ);
3340 if ((rv = status_get_string(p, JK_STATUS_ARG_AJP_HOST_STR,
3341 NULL, &arg, l)) == JK_TRUE) {
3342 if (strncmp(aw->host, arg, JK_SHM_STR_SIZ)) {
3343 jk_log(l, JK_LOG_INFO,
3344 "Status worker '%s' setting 'host' for sub worker '%s' to '%s'",
3345 w->name, aw->name, arg);
3346 strncpy(host, arg, JK_SHM_STR_SIZ);
3350 if (resolve == JK_TRUE) {
3351 struct sockaddr_in inet_addr;
3352 if (!jk_resolve(host, port, &inet_addr,
3353 aw->worker.we->pool, l)) {
3354 const char *msg = "Update failed (at least partially): could not resolve address '%s:%d' for sub worker '%s'.";
3355 size_t size = strlen(msg) + strlen(host) + strlen(aw->name) + 10 + 1;
3356 p->msg = jk_pool_alloc(s->pool, size);
3357 snprintf(p->msg, size, msg, host, port, aw->name);
3358 jk_log(l, JK_LOG_ERROR,
3359 "Status worker '%s' failed resolving address '%s:%d' for sub worker '%s'.",
3360 w->name, host, port, aw->name);
3364 /* This is not atomic and not thread safe */
3366 strncpy(aw->host, host, JK_SHM_STR_SIZ);
3367 memcpy(&(aw->worker_inet_addr), &inet_addr, sizeof(inet_addr));
3368 *side_effect |= JK_STATUS_NEEDS_PUSH | JK_STATUS_NEEDS_ADDR_PUSH;
3371 if (set_int_if_changed(p, aw->name, "ping_timeout", JK_STATUS_ARG_AJP_PING_TO,
3372 0, INT_MAX, &aw->ping_timeout, lb_name, l))
3373 *side_effect |= JK_STATUS_NEEDS_PUSH;
3374 if (set_int_if_changed(p, aw->name, "connect_timeout", JK_STATUS_ARG_AJP_CONNECT_TO,
3375 0, INT_MAX, &aw->connect_timeout, lb_name, l))
3376 *side_effect |= JK_STATUS_NEEDS_PUSH;
3377 if (set_int_if_changed(p, aw->name, "prepost_timeout", JK_STATUS_ARG_AJP_PREPOST_TO,
3378 0, INT_MAX, &aw->prepost_timeout, lb_name, l))
3379 *side_effect |= JK_STATUS_NEEDS_PUSH;
3380 if (set_int_if_changed(p, aw->name, "reply_timeout", JK_STATUS_ARG_AJP_REPLY_TO,
3381 0, INT_MAX, &aw->reply_timeout, lb_name, l))
3382 *side_effect |= JK_STATUS_NEEDS_PUSH;
3383 if (set_int_if_changed(p, aw->name, "retries", JK_STATUS_ARG_AJP_RETRIES,
3384 1, INT_MAX, &aw->retries, lb_name, l))
3385 *side_effect |= JK_STATUS_NEEDS_PUSH;
3386 if (set_int_if_changed(p, aw->name, "retry_interval", JK_STATUS_ARG_AJP_RETRY_INT,
3387 1, INT_MAX, &aw->retry_interval, lb_name, l))
3388 *side_effect |= JK_STATUS_NEEDS_PUSH;
3389 if (set_int_if_changed(p, aw->name, "connection_ping_interval", JK_STATUS_ARG_AJP_CPING_INT,
3390 1, INT_MAX, &aw->conn_ping_interval, lb_name, l))
3391 *side_effect |= JK_STATUS_NEEDS_PUSH;
3392 if (set_uint_if_changed(p, aw->name, "recovery_options", JK_STATUS_ARG_AJP_REC_OPTS,
3393 0, INT_MAX, &aw->recovery_opts, lb_name, l))
3394 *side_effect |= JK_STATUS_NEEDS_PUSH;
3395 if (set_uint_if_changed(p, aw->name, "max_packet_size", JK_STATUS_ARG_AJP_MAX_PK_SZ,
3396 8*1024, 64*1024, &aw->max_packet_size, lb_name, l)) {
3397 *side_effect |= JK_STATUS_NEEDS_PUSH;
3398 if (aw->max_packet_size > lb->max_packet_size) {
3399 lb->max_packet_size = aw->max_packet_size;
3405 static void commit_all_members(jk_ws_service_t *s,
3406 status_endpoint_t *p,
3408 const char *attribute,
3413 const char *name = NULL;
3414 lb_worker_t *lb = NULL;
3415 status_worker_t *w = p->worker;
3423 jk_log(l, JK_LOG_WARNING,
3424 "Status worker '%s' missing request parameter '%s'",
3425 w->name, JK_STATUS_ARG_ATTRIBUTE);
3430 if (!strcmp(attribute, JK_STATUS_ARG_LBM_ACTIVATION))
3431 aname=JK_STATUS_ARG_LBM_TEXT_ACTIVATION;
3432 else if (!strcmp(attribute, JK_STATUS_ARG_LBM_FACTOR))
3433 aname=JK_STATUS_ARG_LBM_TEXT_FACTOR;
3434 else if (!strcmp(attribute, JK_STATUS_ARG_LBM_ROUTE))
3435 aname=JK_STATUS_ARG_LBM_TEXT_ROUTE;
3436 else if (!strcmp(attribute, JK_STATUS_ARG_LBM_REDIRECT))
3437 aname=JK_STATUS_ARG_LBM_TEXT_REDIRECT;
3438 else if (!strcmp(attribute, JK_STATUS_ARG_LBM_DOMAIN))
3439 aname=JK_STATUS_ARG_LBM_TEXT_DOMAIN;
3440 else if (!strcmp(attribute, JK_STATUS_ARG_LBM_DISTANCE))
3441 aname=JK_STATUS_ARG_LBM_TEXT_DISTANCE;
3442 else if (!strcmp(attribute, JK_STATUS_ARG_AJP_CACHE_TO))
3443 aname=JK_STATUS_ARG_AJP_TEXT_CACHE_TO;
3444 else if (!strcmp(attribute, JK_STATUS_ARG_AJP_PING_TO))
3445 aname=JK_STATUS_ARG_AJP_TEXT_PING_TO;
3446 else if (!strcmp(attribute, JK_STATUS_ARG_AJP_CONNECT_TO))
3447 aname=JK_STATUS_ARG_AJP_TEXT_CONNECT_TO;
3448 else if (!strcmp(attribute, JK_STATUS_ARG_AJP_PREPOST_TO))
3449 aname=JK_STATUS_ARG_AJP_TEXT_PREPOST_TO;
3450 else if (!strcmp(attribute, JK_STATUS_ARG_AJP_REPLY_TO))
3451 aname=JK_STATUS_ARG_AJP_TEXT_REPLY_TO;
3452 else if (!strcmp(attribute, JK_STATUS_ARG_AJP_RETRIES))
3453 aname=JK_STATUS_ARG_AJP_TEXT_RETRIES;
3454 else if (!strcmp(attribute, JK_STATUS_ARG_AJP_RETRY_INT))
3455 aname=JK_STATUS_ARG_AJP_TEXT_RETRY_INT;
3456 else if (!strcmp(attribute, JK_STATUS_ARG_AJP_CPING_INT))
3457 aname=JK_STATUS_ARG_AJP_TEXT_CPING_INT;
3458 else if (!strcmp(attribute, JK_STATUS_ARG_AJP_REC_OPTS))
3459 aname=JK_STATUS_ARG_AJP_TEXT_REC_OPTS;
3460 else if (!strcmp(attribute, JK_STATUS_ARG_AJP_MAX_PK_SZ))
3461 aname=JK_STATUS_ARG_AJP_TEXT_MAX_PK_SZ;
3463 jk_log(l, JK_LOG_WARNING,
3464 "Status worker '%s' unknown attribute '%s'",
3465 w->name, attribute);
3470 if (jw->type == JK_LB_WORKER_TYPE) {
3471 lb = (lb_worker_t *)jw->worker_private;
3473 if (JK_IS_DEBUG_LEVEL(l))
3474 jk_log(l, JK_LOG_DEBUG,
3475 "Status worker '%s' committing changes for attribute '%s' [%s] of all members of lb worker '%s'",
3476 w->name, attribute, aname, name);
3479 jk_log(l, JK_LOG_WARNING,
3480 "Status worker '%s' worker type not implemented",
3487 for (j = 0; j < lb->num_of_workers; j++) {
3488 int sync_needed = JK_FALSE;
3489 lb_sub_worker_t *wr = &(lb->lb_workers[j]);
3490 jk_worker_t *jw = wr->worker;
3491 ajp_worker_t *aw = (ajp_worker_t *)jw->worker_private;;
3492 snprintf(vname, 32-1, "" JK_STATUS_ARG_MULT_VALUE_BASE "%d", j);
3494 if (!strcmp(attribute, JK_STATUS_ARG_LBM_FACTOR)) {
3495 if (set_int_if_changed(p, wr->name, "lbfactor", vname,
3496 1, INT_MAX, &wr->lb_factor, name, l)) {
3498 sync_needed = JK_TRUE;
3501 else if (!strcmp(attribute, JK_STATUS_ARG_LBM_DISTANCE)) {
3502 if (set_int_if_changed(p, wr->name, "distance", vname,
3503 0, INT_MAX, &wr->distance, name, l))
3504 sync_needed = JK_TRUE;
3506 else if (!strcmp(attribute, JK_STATUS_ARG_AJP_CACHE_TO)) {
3507 int old = aw->cache_timeout;
3508 if (set_int_if_changed(p, aw->name, "connection_pool_timeout", vname,
3509 0, INT_MAX, &aw->cache_timeout, name, l)) {
3510 sync_needed = JK_TRUE;
3513 for (i = 0; i < aw->ep_cache_sz; i++) {
3514 ajp_endpoint_t *ae = (ajp_endpoint_t *) aw->ep_cache[i];
3516 ae->last_access = time(NULL);
3521 else if (!strcmp(attribute, JK_STATUS_ARG_AJP_PING_TO)) {
3522 if (set_int_if_changed(p, aw->name, "ping_timeout", vname,
3523 0, INT_MAX, &aw->ping_timeout, name, l))
3524 sync_needed = JK_TRUE;
3526 else if (!strcmp(attribute, JK_STATUS_ARG_AJP_CONNECT_TO)) {
3527 if (set_int_if_changed(p, aw->name, "connect_timeout", vname,
3528 0, INT_MAX, &aw->connect_timeout, name, l))
3529 sync_needed = JK_TRUE;
3531 else if (!strcmp(attribute, JK_STATUS_ARG_AJP_PREPOST_TO)) {
3532 if (set_int_if_changed(p, aw->name, "prepost_timeout", vname,
3533 0, INT_MAX, &aw->prepost_timeout, name, l))
3534 sync_needed = JK_TRUE;
3536 else if (!strcmp(attribute, JK_STATUS_ARG_AJP_REPLY_TO)) {
3537 if (set_int_if_changed(p, aw->name, "reply_timeout", vname,
3538 0, INT_MAX, &aw->reply_timeout, name, l))
3539 sync_needed = JK_TRUE;
3541 else if (!strcmp(attribute, JK_STATUS_ARG_AJP_RETRIES)) {
3542 if (set_int_if_changed(p, aw->name, "retries", vname,
3543 1, INT_MAX, &aw->retries, name, l))
3544 sync_needed = JK_TRUE;
3546 else if (!strcmp(attribute, JK_STATUS_ARG_AJP_RETRY_INT)) {
3547 if (set_int_if_changed(p, aw->name, "retry_interval", vname,
3548 1, INT_MAX, &aw->retry_interval, name, l))
3549 sync_needed = JK_TRUE;
3551 else if (!strcmp(attribute, JK_STATUS_ARG_AJP_CPING_INT)) {
3552 if (set_int_if_changed(p, aw->name, "connection_ping_interval", vname,
3553 1, INT_MAX, &aw->conn_ping_interval, name, l))
3554 sync_needed = JK_TRUE;
3556 else if (!strcmp(attribute, JK_STATUS_ARG_AJP_REC_OPTS)) {
3557 if (set_uint_if_changed(p, aw->name, "recovery_options", vname,
3558 0, INT_MAX, &aw->recovery_opts, name, l))
3559 sync_needed = JK_TRUE;
3561 else if (!strcmp(attribute, JK_STATUS_ARG_AJP_MAX_PK_SZ)) {
3562 if (set_uint_if_changed(p, aw->name, "max_packet_size", vname,
3563 8*1024, 64*1024, &aw->max_packet_size, name, l)) {
3564 sync_needed = JK_TRUE;
3565 if (aw->max_packet_size > lb->max_packet_size) {
3566 lb->max_packet_size = aw->max_packet_size;
3571 int rv = status_get_string(p, vname, NULL, &arg, l);
3572 if (!strcmp(attribute, JK_STATUS_ARG_LBM_ACTIVATION)) {
3573 if (rv == JK_TRUE) {
3574 i = jk_lb_get_activation_code(arg);
3575 if (i != wr->activation && i >= 0 && i <= JK_LB_ACTIVATION_MAX) {
3576 jk_log(l, JK_LOG_INFO,
3577 "Status worker '%s' setting 'activation' for sub worker '%s' of lb worker '%s' to '%s'",
3578 w->name, wr->name, name, jk_lb_get_activation(wr, l));
3581 sync_needed = JK_TRUE;
3585 else if (!strcmp(attribute, JK_STATUS_ARG_LBM_ROUTE)) {
3586 if (rv == JK_TRUE) {
3587 if (strncmp(wr->route, arg, JK_SHM_STR_SIZ)) {
3588 jk_log(l, JK_LOG_INFO,
3589 "Status worker '%s' setting 'route' for sub worker '%s' of lb worker '%s' to '%s'",
3590 w->name, wr->name, name, arg);
3591 strncpy(wr->route, arg, JK_SHM_STR_SIZ);
3592 sync_needed = JK_TRUE;
3593 if (!wr->domain[0]) {
3594 char * id_domain = strchr(wr->route, '.');
3597 strcpy(wr->domain, wr->route);
3604 else if (!strcmp(attribute, JK_STATUS_ARG_LBM_REDIRECT)) {
3605 if (rv == JK_TRUE) {
3606 if (strncmp(wr->redirect, arg, JK_SHM_STR_SIZ)) {
3607 jk_log(l, JK_LOG_INFO,
3608 "Status worker '%s' setting 'redirect' for sub worker '%s' of lb worker '%s' to '%s'",
3609 w->name, wr->name, name, arg);
3610 strncpy(wr->redirect, arg, JK_SHM_STR_SIZ);
3611 sync_needed = JK_TRUE;
3615 else if (!strcmp(attribute, JK_STATUS_ARG_LBM_DOMAIN)) {
3616 if (rv == JK_TRUE) {
3617 if (strncmp(wr->domain, arg, JK_SHM_STR_SIZ)) {
3618 jk_log(l, JK_LOG_INFO,
3619 "Status worker '%s' setting 'domain' for sub worker '%s' of lb worker '%s' to '%s'",
3620 w->name, wr->name, name, arg);
3621 strncpy(wr->domain, arg, JK_SHM_STR_SIZ);
3622 sync_needed = JK_TRUE;
3627 if (sync_needed == JK_TRUE) {
3634 reset_lb_values(lb, l);
3636 /* Recalculate the load multiplicators wrt. lb_factor */
3640 jk_lb_push(lb, JK_TRUE, l);
3646 static void display_legend(jk_ws_service_t *s,
3647 status_endpoint_t *p,
3653 unsigned int hide_legend;
3656 status_get_string(p, JK_STATUS_ARG_MIME, NULL, &arg, l);
3657 mime = status_mime_int(arg);
3658 if (mime != JK_STATUS_MIME_HTML) {
3662 hide_legend = status_get_int(p, JK_STATUS_ARG_OPTIONS, 0, l) &
3663 JK_STATUS_ARG_OPTION_NO_LEGEND;
3665 jk_puts(s, "<p>\n");
3666 status_write_uri(s, p, "Show Legend", JK_STATUS_CMD_UNKNOWN, JK_STATUS_MIME_UNKNOWN,
3667 NULL, NULL, 0, JK_STATUS_ARG_OPTION_NO_LEGEND, NULL, l);
3668 jk_puts(s, "</p>\n");
3671 jk_puts(s, "<h2>Legend [");
3672 status_write_uri(s, p, "Hide", JK_STATUS_CMD_UNKNOWN, JK_STATUS_MIME_UNKNOWN,
3673 NULL, NULL, JK_STATUS_ARG_OPTION_NO_LEGEND, 0, NULL, l);
3674 jk_puts(s, "]</h2>\n");
3676 jk_puts(s, "<table>\n"
3677 "<tbody valign=\"baseline\">\n"
3678 "<tr><th>Name</th><td>Worker name</td></tr>\n"
3679 "<tr><th>Type</th><td>Worker type</td></tr>\n"
3680 "<tr><th>Route</th><td>Worker route</td></tr>\n"
3681 "<tr><th>Act</th><td>Worker activation configuration<br/>\n"
3682 "ACT=Active, DIS=Disabled, STP=Stopped</td></tr>\n"
3683 "<tr><th>State</th><td>Worker error status<br/>\n"
3684 "OK=OK, ERR=Error with substates<br/>\n"
3685 "IDLE=No requests handled, BUSY=All connections busy,<br/>\n"
3686 "REC=Recovering, PRB=Probing, FRC=Forced Recovery</td></tr>\n"
3687 "<tr><th>D</th><td>Worker distance</td></tr>\n"
3688 "<tr><th>F</th><td>Load Balancer factor</td></tr>\n"
3689 "<tr><th>M</th><td>Load Balancer multiplicity</td></tr>\n"
3690 "<tr><th>V</th><td>Load Balancer value</td></tr>\n"
3691 "<tr><th>Acc</th><td>Number of requests</td></tr>\n"
3692 "<tr><th>Err</th><td>Number of failed requests</td></tr>\n"
3693 "<tr><th>CE</th><td>Number of client errors</td></tr>\n"
3694 "<tr><th>RE</th><td>Number of reply timeouts (decayed)</td></tr>\n"
3695 "<tr><th>Wr</th><td>Number of bytes transferred</td></tr>\n"
3696 "<tr><th>Rd</th><td>Number of bytes read</td></tr>\n"
3697 "<tr><th>Busy</th><td>Current number of busy connections</td></tr>\n"
3698 "<tr><th>Max</th><td>Maximum number of busy connections</td></tr>\n"
3699 "<tr><th>Con</th><td>Current number of backend connections</td></tr>\n"
3700 "<tr><th>RR</th><td>Route redirect</td></tr>\n"
3701 "<tr><th>Cd</th><td>Cluster domain</td></tr>\n"
3702 "<tr><th>Rs</th><td>Recovery scheduled in app. min/max seconds</td></tr>\n"
3703 "<tr><th>LR</th><td>Seconds since last reset of statistics counters</td></tr>\n"
3704 "<tr><th>LE</th><td>Timestamp of the last error</td></tr>\n"
3712 static int check_worker(jk_ws_service_t *s,
3713 status_endpoint_t *p,
3714 jk_uint32_t allow_wildchars,
3718 const char *sub_worker;
3719 status_worker_t *w = p->worker;
3720 jk_worker_t *jw = NULL;
3721 lb_sub_worker_t *wr = NULL;
3724 if (fetch_worker_and_sub_worker(p, "checking", &worker, &sub_worker, l) == JK_FALSE ||
3725 search_worker(s, p, &jw, worker, l) == JK_FALSE) {
3730 if (sub_worker && sub_worker[0]) {
3731 unsigned int idx = 0;
3732 unsigned int *wi = NULL;
3733 if (strchr(sub_worker, '*') || strchr(sub_worker, '?')) {
3734 /* We have a wildchar matching rule */
3735 if (!allow_wildchars) {
3736 jk_log(l, JK_LOG_ERROR,
3737 "Status worker '%s' wildcards in sub worker '%s' of worker '%s' not allowed for this command",
3738 w->name, sub_worker, worker ? worker : "(null)");
3739 p->msg = "wildcard not allowed in sub worker for this command";
3747 if (search_sub_worker(s, p, jw, worker, &wr, sub_worker,
3748 wi, l) == JK_FALSE) {
3758 static void count_workers(jk_ws_service_t *s,
3759 status_endpoint_t *p,
3760 int *lb_cnt, int *ajp_cnt,
3764 jk_worker_t *jw = NULL;
3765 status_worker_t *w = p->worker;
3770 for (i = 0; i < w->we->num_of_workers; i++) {
3771 jw = wc_get_worker_for_name(w->we->worker_list[i], l);
3773 jk_log(l, JK_LOG_WARNING,
3774 "Status worker '%s' could not find worker '%s'",
3775 w->name, w->we->worker_list[i]);
3778 if (jw->type == JK_LB_WORKER_TYPE) {
3781 else if (jw->type == JK_AJP13_WORKER_TYPE ||
3782 jw->type == JK_AJP14_WORKER_TYPE) {
3789 static void list_workers_type(jk_ws_service_t *s,
3790 status_endpoint_t *p,
3791 int list_lb, int count,
3799 jk_worker_t *jw = NULL;
3800 status_worker_t *w = p->worker;
3804 status_get_string(p, JK_STATUS_ARG_MIME, NULL, &arg, l);
3805 mime = status_mime_int(arg);
3807 hide = status_get_int(p, JK_STATUS_ARG_OPTIONS, 0, l) &
3808 JK_STATUS_ARG_OPTION_NO_LB;
3810 if (mime == JK_STATUS_MIME_HTML) {
3811 jk_puts(s, "<p>\n");
3812 status_write_uri(s, p, "Show Load Balancing Workers", JK_STATUS_CMD_UNKNOWN, JK_STATUS_MIME_UNKNOWN,
3813 NULL, NULL, 0, JK_STATUS_ARG_OPTION_NO_LB, NULL, l);
3814 jk_puts(s, "</p>\n");
3818 if (mime == JK_STATUS_MIME_XML) {
3819 jk_print_xml_start_elt(s, w, 0, 0, "balancers");
3820 jk_print_xml_att_int(s, 2, "count", count);
3821 jk_print_xml_stop_elt(s, 0, 0);
3823 else if (mime == JK_STATUS_MIME_TXT) {
3824 jk_printf(s, "Balancer Workers: count=%d\n", count);
3826 else if (mime == JK_STATUS_MIME_PROP) {
3827 jk_print_prop_att_int(s, w, NULL, "lb_count", count);
3830 jk_printf(s, "<hr/><h2>Listing Load Balancing Worker%s (%d Worker%s) [",
3831 count>1 ? "s" : "", count, count>1 ? "s" : "");
3832 status_write_uri(s, p, "Hide", JK_STATUS_CMD_UNKNOWN, JK_STATUS_MIME_UNKNOWN,
3833 NULL, NULL, JK_STATUS_ARG_OPTION_NO_LB, 0, NULL, l);
3834 jk_puts(s, "]</h2>\n");
3839 hide = status_get_int(p, JK_STATUS_ARG_OPTIONS, 0, l) &
3840 JK_STATUS_ARG_OPTION_NO_AJP;
3842 if (mime == JK_STATUS_MIME_HTML) {
3843 jk_puts(s, "<p>\n");
3844 status_write_uri(s, p, "Show AJP Workers", JK_STATUS_CMD_UNKNOWN, JK_STATUS_MIME_UNKNOWN,
3845 NULL, NULL, 0, JK_STATUS_ARG_OPTION_NO_AJP, NULL, l);
3846 jk_puts(s, "</p>\n");
3850 if (mime == JK_STATUS_MIME_XML) {
3851 jk_print_xml_start_elt(s, w, 0, 0, "ajp_workers");
3852 jk_print_xml_att_int(s, 2, "count", count);
3853 jk_print_xml_stop_elt(s, 0, 0);
3855 else if (mime == JK_STATUS_MIME_TXT) {
3856 jk_printf(s, "AJP Workers: count=%d\n", count);
3858 else if (mime == JK_STATUS_MIME_PROP) {
3859 jk_print_prop_att_int(s, w, NULL, "ajp_count", count);
3862 jk_printf(s, "<hr/><h2>Listing AJP Worker%s (%d Worker%s) [",
3863 count>1 ? "s" : "", count, count>1 ? "s" : "");
3864 status_write_uri(s, p, "Hide", JK_STATUS_CMD_UNKNOWN, JK_STATUS_MIME_UNKNOWN,
3865 NULL, NULL, JK_STATUS_ARG_OPTION_NO_AJP, 0, NULL, l);
3866 jk_puts(s, "]</h2>\n");
3876 for (i = 0; i < w->we->num_of_workers; i++) {
3877 jw = wc_get_worker_for_name(w->we->worker_list[i], l);
3879 jk_log(l, JK_LOG_WARNING,
3880 "Status worker '%s' could not find worker '%s'",
3881 w->name, w->we->worker_list[i]);
3884 if ((list_lb && jw->type == JK_LB_WORKER_TYPE) ||
3885 (!list_lb && jw->type != JK_LB_WORKER_TYPE)) {
3886 display_worker(s, p, jw, NULL, l);
3891 if (mime == JK_STATUS_MIME_XML) {
3892 jk_print_xml_close_elt(s, w, 0, "balancers");
3894 else if (mime == JK_STATUS_MIME_TXT) {
3896 else if (mime == JK_STATUS_MIME_PROP) {
3898 else if (mime == JK_STATUS_MIME_HTML) {
3902 if (mime == JK_STATUS_MIME_XML) {
3903 jk_print_xml_close_elt(s, w, 0, "ajp_workers");
3905 else if (mime == JK_STATUS_MIME_TXT) {
3907 else if (mime == JK_STATUS_MIME_PROP) {
3909 else if (mime == JK_STATUS_MIME_HTML) {
3916 static int list_workers(jk_ws_service_t *s,
3917 status_endpoint_t *p,
3924 count_workers(s, p, &lb_cnt, &ajp_cnt, l);
3927 list_workers_type(s, p, 1, lb_cnt, l);
3931 list_workers_type(s, p, 0, ajp_cnt, l);
3938 static int show_worker(jk_ws_service_t *s,
3939 status_endpoint_t *p,
3943 const char *sub_worker;
3944 jk_worker_t *jw = NULL;
3945 lb_sub_worker_t *wr = NULL;
3948 if (fetch_worker_and_sub_worker(p, "showing", &worker, &sub_worker, l) == JK_FALSE ||
3949 search_worker(s, p, &jw, worker, l) == JK_FALSE) {
3953 if (sub_worker && sub_worker[0]) {
3954 if (search_sub_worker(s, p, jw, worker, &wr, sub_worker,
3955 NULL, l) == JK_FALSE) {
3960 display_worker(s, p, jw, wr, l);
3966 static int edit_worker(jk_ws_service_t *s,
3967 status_endpoint_t *p,
3971 const char *sub_worker;
3972 status_worker_t *w = p->worker;
3973 jk_worker_t *jw = NULL;
3974 lb_worker_t *lb = NULL;
3975 lb_sub_worker_t *wr = NULL;
3976 ajp_worker_t *aw = NULL;
3979 if (fetch_worker_and_sub_worker(p, "editing", &worker, &sub_worker, l) == JK_FALSE ||
3980 search_worker(s, p, &jw, worker, l) == JK_FALSE) {
3985 if (jw->type == JK_LB_WORKER_TYPE) {
3986 if (check_valid_lb(s, p, jw, worker, &lb, 0, l) == JK_FALSE) {
3991 if (lb->sequence != lb->s->h.sequence)
3992 jk_lb_pull(lb, JK_FALSE, l);
3993 if (!sub_worker || !sub_worker[0]) {
3995 if (status_get_string(p, JK_STATUS_ARG_ATTRIBUTE,
3996 NULL, &arg, l) == JK_TRUE) {
3997 if (JK_IS_DEBUG_LEVEL(l))
3998 jk_log(l, JK_LOG_DEBUG,
3999 "Status worker '%s' %s lb worker '%s' with all sub workers",
4000 w->name, "editing", lb->name);
4001 form_all_members(s, p, jw, arg, l);
4004 if (JK_IS_DEBUG_LEVEL(l))
4005 jk_log(l, JK_LOG_DEBUG,
4006 "Status worker '%s' %s lb worker '%s'",
4007 w->name, "editing", lb->name);
4008 form_worker(s, p, jw, l);
4014 if (search_sub_worker(s, p, jw, worker, &wr, sub_worker,
4015 NULL, l) == JK_FALSE) {
4019 if (JK_IS_DEBUG_LEVEL(l))
4020 jk_log(l, JK_LOG_DEBUG,
4021 "Status worker '%s' %s lb worker '%s' sub worker '%s'",
4022 w->name, "editing", lb->name, wr->name);
4023 aw = (ajp_worker_t *)wr->worker->worker_private;
4024 form_member(s, p, wr, aw, worker, l);
4029 else if (jw->type == JK_AJP13_WORKER_TYPE ||
4030 jw->type == JK_AJP14_WORKER_TYPE) {
4031 ajp_worker_t *aw = (ajp_worker_t *)jw->worker_private;
4033 if (JK_IS_DEBUG_LEVEL(l))
4034 jk_log(l, JK_LOG_DEBUG,
4035 "Status worker '%s' %s ajp worker '%s'",
4036 w->name, "editing", aw->name);
4037 if (aw->sequence != aw->s->h.sequence)
4038 jk_ajp_pull(aw, JK_FALSE, l);
4039 form_member(s, p, NULL, aw, worker, l);
4044 jk_log(l, JK_LOG_WARNING,
4045 "Status worker '%s' aw worker is (null)",
4050 if (JK_IS_DEBUG_LEVEL(l))
4051 jk_log(l, JK_LOG_DEBUG,
4052 "Status worker '%s' worker type not implemented",
4059 static int update_worker(jk_ws_service_t *s,
4060 status_endpoint_t *p,
4064 const char *sub_worker;
4065 status_worker_t *w = p->worker;
4066 jk_worker_t *jw = NULL;
4067 lb_worker_t *lb = NULL;
4068 lb_sub_worker_t *wr = NULL;
4069 ajp_worker_t *aw = NULL;
4074 if (fetch_worker_and_sub_worker(p, "updating", &worker, &sub_worker, l) == JK_FALSE ||
4075 search_worker(s, p, &jw, worker, l) == JK_FALSE) {
4080 if (jw->type == JK_LB_WORKER_TYPE) {
4081 if (check_valid_lb(s, p, jw, worker, &lb, 0, l) == JK_FALSE) {
4086 if (lb->sequence != lb->s->h.sequence)
4087 jk_lb_pull(lb, JK_TRUE, l);
4088 if (!sub_worker || !sub_worker[0]) {
4090 if (status_get_string(p, JK_STATUS_ARG_ATTRIBUTE,
4091 NULL, &arg, l) == JK_TRUE) {
4092 if (JK_IS_DEBUG_LEVEL(l))
4093 jk_log(l, JK_LOG_DEBUG,
4094 "Status worker '%s' %s lb worker '%s' with all sub workers",
4095 w->name, "updating", lb->name);
4096 commit_all_members(s, p, jw, arg, l);
4099 if (JK_IS_DEBUG_LEVEL(l))
4100 jk_log(l, JK_LOG_DEBUG,
4101 "Status worker '%s' %s lb worker '%s'",
4102 w->name, "updating", lb->name);
4103 commit_worker(s, p, jw, l);
4109 unsigned int idx = 0;
4110 unsigned int *wi = NULL;
4111 int is_wildchar = JK_FALSE;
4113 if (strchr(sub_worker, '*') || strchr(sub_worker, '?')) {
4114 /* We have a wildchar matching rule */
4116 is_wildchar = JK_TRUE;
4119 if (search_sub_worker(s, p, jw, worker, &wr, sub_worker,
4120 wi, l) == JK_FALSE) {
4126 /* We have found at least one match previously */
4131 if (JK_IS_DEBUG_LEVEL(l))
4132 jk_log(l, JK_LOG_DEBUG,
4133 "Status worker '%s' %s lb worker '%s' sub worker '%s'",
4134 w->name, "updating", lb->name, wr->name);
4135 aw = (ajp_worker_t *)wr->worker->worker_private;
4137 rc = commit_member(s, p, lb, wr, aw, &rv, l);
4138 if (rv & JK_STATUS_NEEDS_ADDR_PUSH) {
4139 aw->addr_sequence++;
4141 if (rv & (JK_STATUS_NEEDS_PUSH | JK_STATUS_NEEDS_ADDR_PUSH)) {
4144 jk_lb_push(lb, JK_TRUE, l);
4146 if (rv & JK_STATUS_NEEDS_RESET_LB_VALUES)
4147 reset_lb_values(lb, l);
4148 if (rv & JK_STATUS_NEEDS_UPDATE_MULT)
4149 /* Recalculate the load multiplicators wrt. lb_factor */
4151 if (rc == JK_FALSE) {
4152 jk_log(l, JK_LOG_ERROR,
4153 "Status worker '%s' failed updating sub worker '%s' (at least partially).%s",
4154 w->name, aw->name, (is_wildchar == JK_TRUE) ? " Aborting further wildcard updates." : "");
4155 if (!strncmp("OK", p->msg, 3)) {
4156 const char *msg = "Update failed (at least partially) for sub worker '%s'";
4157 size_t size = strlen(msg) + strlen(aw->name) + 1;
4158 p->msg = jk_pool_alloc(s->pool, size);
4159 snprintf(p->msg, size, msg, aw->name);
4161 if (is_wildchar == JK_TRUE) {
4162 const char *msg = " Aborting further wildcard updates.";
4163 size_t size = strlen(msg) + strlen(p->msg) + 1;
4164 p->msg = jk_pool_realloc(s->pool, size, p->msg, strlen(p->msg) + 1);
4165 strcat(p->msg, msg);
4176 else if (jw->type == JK_AJP13_WORKER_TYPE ||
4177 jw->type == JK_AJP14_WORKER_TYPE) {
4178 ajp_worker_t *aw = (ajp_worker_t *)jw->worker_private;
4180 if (JK_IS_DEBUG_LEVEL(l))
4181 jk_log(l, JK_LOG_DEBUG,
4182 "Status worker '%s' %s ajp worker '%s'",
4183 w->name, "updating", aw->name);
4184 if (aw->sequence != aw->s->h.sequence)
4185 jk_ajp_pull(aw, JK_TRUE, l);
4187 rc = commit_member(s, p, NULL, NULL, aw, &rv, l);
4188 if (rv & JK_STATUS_NEEDS_ADDR_PUSH) {
4189 aw->addr_sequence++;
4191 if (rv & (JK_STATUS_NEEDS_PUSH | JK_STATUS_NEEDS_ADDR_PUSH)) {
4193 jk_ajp_push(aw, JK_TRUE, l);
4195 if (rc == JK_FALSE) {
4196 jk_log(l, JK_LOG_ERROR,
4197 "Status worker '%s' failed updating worker '%s' (at least partially).",
4199 if (!strncmp("OK", p->msg, 3)) {
4200 const char *msg = "Update failed (at least partially) for worker '%s'";
4201 size_t size = strlen(msg) + strlen(aw->name) + 1;
4202 p->msg = jk_pool_alloc(s->pool, size);
4203 snprintf(p->msg, size, msg, aw->name);
4210 jk_log(l, JK_LOG_WARNING,
4211 "Status worker '%s' aw worker is (null)",
4216 if (JK_IS_DEBUG_LEVEL(l))
4217 jk_log(l, JK_LOG_DEBUG,
4218 "Status worker '%s' worker type not implemented",
4225 static int reset_worker(jk_ws_service_t *s,
4226 status_endpoint_t *p,
4231 const char *sub_worker;
4232 status_worker_t *w = p->worker;
4233 jk_worker_t *jw = NULL;
4234 lb_worker_t *lb = NULL;
4235 lb_sub_worker_t *wr = NULL;
4236 ajp_worker_t *aw = NULL;
4240 if (fetch_worker_and_sub_worker(p, "resetting", &worker, &sub_worker, l) == JK_FALSE ||
4241 search_worker(s, p, &jw, worker, l) == JK_FALSE) {
4247 if (jw->type == JK_LB_WORKER_TYPE) {
4248 if (check_valid_lb(s, p, jw, worker, &lb, 0, l) == JK_FALSE) {
4253 if (!sub_worker || !sub_worker[0]) {
4254 if (JK_IS_DEBUG_LEVEL(l))
4255 jk_log(l, JK_LOG_DEBUG,
4256 "Status worker '%s' %s lb worker '%s' with all sub workers",
4257 w->name, "resetting", lb->name);
4258 lb->s->max_busy = 0;
4259 lb->s->last_reset = now;
4260 for (i = 0; i < lb->num_of_workers; i++) {
4261 wr = &(lb->lb_workers[i]);
4262 aw = (ajp_worker_t *)wr->worker->worker_private;
4263 wr->s->state = JK_LB_STATE_IDLE;
4264 wr->s->elected_snapshot = 0;
4265 wr->s->error_time = 0;
4267 wr->s->lb_value = 0;
4269 aw->s->client_errors = 0;
4270 aw->s->reply_timeouts = 0;
4271 aw->s->transferred = 0;
4273 aw->s->max_busy = 0;
4274 aw->s->last_reset = now;
4280 if (search_sub_worker(s, p, jw, worker, &wr, sub_worker,
4281 NULL, l) == JK_FALSE) {
4285 if (JK_IS_DEBUG_LEVEL(l))
4286 jk_log(l, JK_LOG_DEBUG,
4287 "Status worker '%s' %s lb worker '%s' sub worker '%s'",
4288 w->name, "resetting", lb->name, wr->name);
4289 aw = (ajp_worker_t *)wr->worker->worker_private;
4290 wr->s->state = JK_LB_STATE_IDLE;
4291 wr->s->elected_snapshot = 0;
4292 wr->s->error_time = 0;
4294 wr->s->lb_value = 0;
4296 aw->s->client_errors = 0;
4297 aw->s->reply_timeouts = 0;
4298 aw->s->transferred = 0;
4300 aw->s->max_busy = 0;
4301 aw->s->last_reset = now;
4306 else if (jw->type == JK_AJP13_WORKER_TYPE ||
4307 jw->type == JK_AJP14_WORKER_TYPE) {
4308 ajp_worker_t *aw = (ajp_worker_t *)jw->worker_private;
4310 if (JK_IS_DEBUG_LEVEL(l))
4311 jk_log(l, JK_LOG_DEBUG,
4312 "Status worker '%s' %s ajp worker '%s'",
4313 w->name, "resetting", aw->name);
4316 aw->s->client_errors = 0;
4317 aw->s->reply_timeouts = 0;
4318 aw->s->transferred = 0;
4320 aw->s->max_busy = 0;
4321 aw->s->last_reset = now;
4326 jk_log(l, JK_LOG_WARNING,
4327 "Status worker '%s' aw worker is (null)",
4332 if (JK_IS_DEBUG_LEVEL(l))
4333 jk_log(l, JK_LOG_DEBUG,
4334 "Status worker '%s' worker type not implemented",
4341 static int recover_worker(jk_ws_service_t *s,
4342 status_endpoint_t *p,
4346 const char *sub_worker;
4347 jk_worker_t *jw = NULL;
4348 lb_sub_worker_t *wr = NULL;
4349 ajp_worker_t *aw = NULL;
4350 status_worker_t *w = p->worker;
4353 if (fetch_worker_and_sub_worker(p, "recovering", &worker, &sub_worker, l) == JK_FALSE ||
4354 search_worker(s, p, &jw, worker, l) == JK_FALSE) {
4359 if (search_sub_worker(s, p, jw, worker, &wr, sub_worker,
4360 NULL, l) == JK_FALSE) {
4365 aw = (ajp_worker_t *)wr->worker->worker_private;
4366 if (wr->s->state == JK_LB_STATE_ERROR) {
4367 lb_worker_t *lb = NULL;
4369 /* We need an lb to correct the lb_value */
4370 if (check_valid_lb(s, p, jw, worker, &lb, 0, l) == JK_FALSE) {
4375 if (lb->lbmethod != JK_LB_METHOD_BUSYNESS) {
4377 jk_uint64_t curmax = 0;
4379 for (i = 0; i < lb->num_of_workers; i++) {
4380 if (lb->lb_workers[i].s->lb_value > curmax) {
4381 curmax = lb->lb_workers[i].s->lb_value;
4384 wr->s->lb_value = curmax;
4387 aw->s->reply_timeouts = 0;
4388 wr->s->state = JK_LB_STATE_RECOVER;
4389 jk_log(l, JK_LOG_INFO,
4390 "Status worker '%s' marked worker '%s' sub worker '%s' for recovery",
4391 w->name, worker ? worker : "(null)", sub_worker ? sub_worker : "(null)");
4395 jk_log(l, JK_LOG_WARNING,
4396 "Status worker '%s' could not mark worker '%s' sub worker '%s' for recovery - state %s is not an error state",
4397 w->name, worker ? worker : "(null)", sub_worker ? sub_worker : "(null)",
4398 jk_lb_get_state(wr, l));
4403 static int dump_config(jk_ws_service_t *s,
4404 status_endpoint_t *p,
4405 int mime, jk_logger_t *l)
4407 status_worker_t *w = p->worker;
4408 jk_worker_env_t *we = w->we;
4409 jk_map_t *init_data = we->init_data;
4414 int l = jk_map_size(init_data);
4416 if (mime == JK_STATUS_MIME_HTML) {
4417 jk_puts(s, "<hr/><h2>Configuration Data</h2><hr/>\n");
4418 jk_puts(s, "This dump does not include any changes applied by the status worker\n");
4419 jk_puts(s, "to the configuration after the initial startup\n");
4420 jk_puts(s, "<PRE>\n");
4422 else if (mime == JK_STATUS_MIME_XML) {
4423 jk_print_xml_start_elt(s, w, 2, 0, "configuration");
4425 else if (mime == JK_STATUS_MIME_TXT) {
4426 jk_puts(s, "Configuration:\n");
4429 const char *name = jk_map_name_at(init_data, i);
4432 size_t nl = strlen(name);
4433 if (nl > sizeof(".secret") &&
4434 strcmp(name + nl - 7, ".secret") == 0) {
4437 value = jk_map_value_at(init_data, i);
4440 if (mime == JK_STATUS_MIME_HTML ||
4441 mime == JK_STATUS_MIME_PROP ||
4442 mime == JK_STATUS_MIME_TXT) {
4443 jk_putv(s, name, "=", value, "\n", NULL);
4445 else if (mime == JK_STATUS_MIME_XML) {
4446 jk_print_xml_att_string(s, 4, name, value);
4450 if (mime == JK_STATUS_MIME_HTML) {
4451 jk_puts(s, "</PRE>\n");
4453 else if (mime == JK_STATUS_MIME_XML) {
4454 jk_print_xml_stop_elt(s, 2, 1);
4467 * Return values of service() method for status worker:
4468 * return value is_error reason
4469 * JK_FALSE JK_HTTP_SERVER_ERROR Invalid parameters (null values)
4470 * JK_TRUE JK_HTTP_OK All other cases
4472 static int JK_METHOD service(jk_endpoint_t *e,
4474 jk_logger_t *l, int *is_error)
4477 jk_uint32_t cmd_props;
4483 status_endpoint_t *p;
4489 if (!e || !e->endpoint_private || !s || !is_error) {
4490 JK_LOG_NULL_PARAMS(l);
4492 *is_error = JK_HTTP_SERVER_ERROR;
4497 p = e->endpoint_private;
4500 /* Set returned error to OK */
4501 *is_error = JK_HTTP_OK;
4503 if (w->num_of_users) {
4504 if (s->remote_user) {
4507 for (i = 0; i < w->num_of_users; i++) {
4508 if (w->user_case_insensitive) {
4509 if (!strcasecmp(s->remote_user, w->user_names[i])) {
4515 if (!strcmp(s->remote_user, w->user_names[i])) {
4527 /* Step 1: Process GET params and update configuration */
4528 if (status_parse_uri(s, p, l) != JK_TRUE) {
4529 err = "Error during parsing of URI";
4531 status_get_string(p, JK_STATUS_ARG_CMD, NULL, &arg, l);
4532 cmd = status_cmd_int(arg);
4533 cmd_props = status_cmd_props(cmd);
4534 status_get_string(p, JK_STATUS_ARG_MIME, NULL, &arg, l);
4535 mime = status_mime_int(arg);
4536 refresh = status_get_int(p, JK_STATUS_ARG_REFRESH, 0, l);
4541 read_only = status_get_int(p, JK_STATUS_ARG_OPTIONS, 0, l) &
4542 JK_STATUS_ARG_OPTION_READ_ONLY;
4545 if (mime == JK_STATUS_MIME_HTML) {
4546 s->start_response(s, 200, "OK", headers_names, headers_vhtml, 3);
4547 jk_puts(s, JK_STATUS_HEAD);
4549 else if (mime == JK_STATUS_MIME_XML) {
4550 s->start_response(s, 200, "OK", headers_names, headers_vxml, 3);
4551 jk_puts(s, JK_STATUS_XMLH);
4553 jk_putv(s, w->doctype, "\n", NULL);
4555 jk_print_xml_start_elt(s, w, 0, 0, "status");
4556 if (w->xmlns && strlen(w->xmlns))
4557 jk_putv(s, " ", w->xmlns, NULL);
4558 jk_print_xml_stop_elt(s, 0, 0);
4561 s->start_response(s, 200, "OK", headers_names, headers_vtxt, 3);
4565 if (JK_IS_DEBUG_LEVEL(l))
4566 jk_log(l, JK_LOG_DEBUG,
4567 "Status worker '%s' service allowed for user '%s' [%s] from %s [%s]",
4569 s->remote_user ? s->remote_user : "(null)",
4570 s->auth_type ? s->auth_type : "(null)",
4571 s->remote_addr ? s->remote_addr : "(null)",
4572 s->remote_host ? s->remote_host : "(null)");
4574 else if (denied == 1) {
4575 err = "Access denied.";
4576 jk_log(l, JK_LOG_WARNING,
4577 "Status worker '%s' service denied for user '%s' [%s] from %s [%s]",
4579 s->remote_user ? s->remote_user : "(null)",
4580 s->auth_type ? s->auth_type : "(null)",
4581 s->remote_addr ? s->remote_addr : "(null)",
4582 s->remote_host ? s->remote_host : "(null)");
4584 else if (denied == 2) {
4585 err = "Access denied.";
4586 jk_log(l, JK_LOG_WARNING,
4587 "Status worker '%s' service denied (no user) [%s] from %s [%s]",
4589 s->remote_user ? s->remote_user : "(null)",
4590 s->auth_type ? s->auth_type : "(null)",
4591 s->remote_addr ? s->remote_addr : "(null)",
4592 s->remote_host ? s->remote_host : "(null)");
4595 err = "Access denied.";
4596 jk_log(l, JK_LOG_WARNING,
4597 "Status worker '%s' service denied (unknown reason) for user '%s' [%s] from %s [%s]",
4599 s->remote_user ? s->remote_user : "(null)",
4600 s->auth_type ? s->auth_type : "(null)",
4601 s->remote_addr ? s->remote_addr : "(null)",
4602 s->remote_host ? s->remote_host : "(null)");
4606 if (read_only && !(cmd_props & JK_STATUS_CMD_PROP_READONLY)) {
4607 err = "This command is not allowed in read only mode.";
4612 if (cmd == JK_STATUS_CMD_UNKNOWN) {
4613 err = "Invalid command.";
4615 else if (mime == JK_STATUS_MIME_UNKNOWN) {
4616 err = "Invalid mime type.";
4618 else if (cmd_props & JK_STATUS_CMD_PROP_CHECK_WORKER &&
4619 (check_worker(s, p, cmd_props & JK_STATUS_CMD_PROP_WILDCARD, l) != JK_TRUE)) {
4625 char buf_time[JK_STATUS_TIME_BUF_SZ];
4626 char buf_tz[JK_STATUS_TIME_BUF_SZ];
4627 time_t clock = time(NULL);
4628 long unix_seconds = (long)clock;
4629 int rc_time = status_strftime(clock, mime, buf_time, buf_tz, l);
4630 if (cmd == JK_STATUS_CMD_UPDATE) {
4631 /* lock shared memory */
4633 if (update_worker(s, p, l) == JK_FALSE) {
4634 if (strncmp("OK", p->msg, 3))
4637 err = "Update failed";
4639 /* unlock the shared memory */
4641 if (mime == JK_STATUS_MIME_HTML) {
4642 write_html_refresh_response(s, p, err, l);
4645 else if (cmd == JK_STATUS_CMD_RESET) {
4646 /* lock shared memory */
4648 if (reset_worker(s, p, l) == JK_FALSE) {
4649 err = "Reset failed";
4651 /* unlock the shared memory */
4653 if (mime == JK_STATUS_MIME_HTML) {
4654 write_html_refresh_response(s, p, err, l);
4657 else if (cmd == JK_STATUS_CMD_RECOVER) {
4658 /* lock shared memory */
4660 if (recover_worker(s, p, l) == JK_FALSE) {
4661 err = "Marking worker for recovery failed";
4663 /* unlock the shared memory */
4665 if (mime == JK_STATUS_MIME_HTML) {
4666 write_html_refresh_response(s, p, err, l);
4670 if (mime == JK_STATUS_MIME_XML) {
4671 jk_print_xml_start_elt(s, w, 0, 0, "server");
4672 jk_print_xml_att_string(s, 2, "name", s->server_name);
4673 jk_print_xml_att_int(s, 2, "port", s->server_port);
4674 jk_print_xml_stop_elt(s, 0, 1);
4675 if (cmd_props & JK_STATUS_CMD_PROP_HEAD) {
4677 jk_print_xml_start_elt(s, w, 0, 0, "time");
4678 jk_print_xml_att_string(s, 2, "datetime", buf_time);
4679 jk_print_xml_att_string(s, 2, "tz", buf_tz);
4680 jk_print_xml_att_long(s, 2, "unix", unix_seconds);
4681 jk_print_xml_stop_elt(s, 0, 1);
4683 jk_print_xml_start_elt(s, w, 0, 0, "software");
4684 jk_print_xml_att_string(s, 2, "web_server", s->server_software);
4685 jk_print_xml_att_string(s, 2, "jk_version", JK_FULL_EXPOSED_VERSION);
4686 jk_print_xml_stop_elt(s, 0, 1);
4688 if (cmd == JK_STATUS_CMD_LIST) {
4689 /* Step 2: Display configuration */
4690 if (list_workers(s, p, l) != JK_TRUE) {
4691 err = "Error in listing the workers.";
4694 else if (cmd == JK_STATUS_CMD_SHOW) {
4695 /* Step 2: Display detailed configuration */
4696 if (show_worker(s, p, l) != JK_TRUE) {
4697 err = "Error in showing this worker.";
4701 else if (mime == JK_STATUS_MIME_TXT) {
4702 jk_puts(s, "Server:");
4703 jk_printf(s, " name=%s", s->server_name);
4704 jk_printf(s, " port=%d", s->server_port);
4706 if (cmd_props & JK_STATUS_CMD_PROP_HEAD) {
4708 jk_puts(s, "Time:");
4709 jk_printf(s, " datetime=%s", buf_time);
4710 jk_printf(s, " tz=%s", buf_tz);
4711 jk_printf(s, " unix=%ld", unix_seconds);
4714 jk_puts(s, "Software:");
4715 jk_printf(s, " web_server=\"%s\"", s->server_software);
4716 jk_printf(s, " jk_version=%s", JK_FULL_EXPOSED_VERSION);
4719 if (cmd == JK_STATUS_CMD_LIST) {
4720 /* Step 2: Display configuration */
4721 if (list_workers(s, p, l) != JK_TRUE) {
4722 err = "Error in listing the workers.";
4725 else if (cmd == JK_STATUS_CMD_SHOW) {
4726 /* Step 2: Display detailed configuration */
4727 if (show_worker(s, p, l) != JK_TRUE) {
4728 err = "Error in showing this worker.";
4732 else if (mime == JK_STATUS_MIME_PROP) {
4733 jk_print_prop_att_string(s, w, NULL, "server_name", s->server_name);
4734 jk_print_prop_att_int(s, w, NULL, "server_port", s->server_port);
4735 if (cmd_props & JK_STATUS_CMD_PROP_HEAD) {
4737 jk_print_prop_att_string(s, w, NULL, "time_datetime", buf_time);
4738 jk_print_prop_att_string(s, w, NULL, "time_tz", buf_tz);
4739 jk_print_prop_att_long(s, w, NULL, "time_unix", unix_seconds);
4741 jk_print_prop_att_string(s, w, NULL, "web_server", s->server_software);
4742 jk_print_prop_att_string(s, w, NULL, "jk_version", JK_FULL_EXPOSED_VERSION);
4744 if (cmd == JK_STATUS_CMD_LIST) {
4745 /* Step 2: Display configuration */
4746 if (list_workers(s, p, l) != JK_TRUE) {
4747 err = "Error in listing the workers.";
4750 else if (cmd == JK_STATUS_CMD_SHOW) {
4751 /* Step 2: Display detailed configuration */
4752 if (show_worker(s, p, l) != JK_TRUE) {
4753 err = "Error in showing this worker.";
4757 else if (mime == JK_STATUS_MIME_HTML) {
4758 if (cmd_props & JK_STATUS_CMD_PROP_REFRESH &&
4760 jk_printf(s, "\n<meta http-equiv=\"Refresh\" content=\"%d;url=%s?%s\">",
4761 refresh, s->req_uri, p->query_string);
4764 jk_putv(s, "\n<link rel=\"stylesheet\" type=\"text/css\" href=\"",
4765 w->css, "\" />\n", NULL);
4767 jk_puts(s, JK_STATUS_HEND);
4768 jk_puts(s, "<h1>JK Status Manager for ");
4769 jk_puts(s, s->server_name);
4770 jk_printf(s, ":%d", s->server_port);
4772 jk_puts(s, " (read only)");
4774 jk_puts(s, "</h1>\n\n");
4775 if (cmd_props & JK_STATUS_CMD_PROP_HEAD) {
4776 jk_putv(s, "<table><tr><td>Server Version:</td><td>",
4777 s->server_software, "</td><td> </td><td>", NULL);
4779 jk_putv(s, "Server Time:</td><td>", buf_time, NULL);
4781 jk_puts(s, "</td></tr>\n");
4782 jk_putv(s, "<tr><td>JK Version:</td><td>",
4783 JK_FULL_EXPOSED_VERSION, "</td><td></td><td>", NULL);
4784 jk_printf(s, "Unix Seconds:</td><td>%d", unix_seconds);
4785 jk_puts(s, "</td></tr></table>\n<hr/>\n");
4787 jk_puts(s, "<table><tbody valign=\"baseline\"><tr>\n");
4788 if (cmd_props & JK_STATUS_CMD_PROP_REFRESH) {
4791 const char *str = p->query_string;
4792 char *buf = jk_pool_alloc(s->pool, sizeof(char *) * (strlen(str)+1));
4795 size_t len = strlen(JK_STATUS_ARG_REFRESH);
4797 while (str[scan] != '\0') {
4798 if (strncmp(&str[scan], JK_STATUS_ARG_REFRESH, len) == 0 &&
4799 str[scan+len] == '=') {
4801 while (str[scan] != '\0' && str[scan] != '&')
4803 if (str[scan] == '&')
4807 if (result > 0 && str[scan] != '\0' && str[scan] != '&') {
4811 while (str[scan] != '\0' && str[scan] != '&') {
4812 buf[result] = str[scan];
4816 if (str[scan] == '&')
4822 jk_putv(s, "[<a href=\"", s->req_uri, NULL);
4824 jk_putv(s, "?", buf, NULL);
4825 jk_puts(s, "\">Stop auto refresh</a>]");
4828 status_start_form(s, p, "get", JK_STATUS_CMD_UNKNOWN, JK_STATUS_ARG_REFRESH, l);
4829 jk_puts(s, "<input type=\"submit\" value=\"Start auto refresh\"/>\n");
4830 jk_putv(s, "(every ",
4831 "<input name=\"", JK_STATUS_ARG_REFRESH,
4832 "\" type=\"text\" size=\"3\" value=\"",
4833 JK_STATUS_REFRESH_DEF "\"/> ",
4835 jk_puts(s, "</form>\n");
4837 jk_puts(s, "</td><td> | </td>\n");
4839 if (cmd_props & JK_STATUS_CMD_PROP_FMT) {
4840 jk_puts(s, "<td>\n");
4841 status_start_form(s, p, "get", JK_STATUS_CMD_UNKNOWN, JK_STATUS_ARG_MIME, l);
4842 jk_puts(s, "<input type=\"submit\" value=\"Change format\"/>\n");
4843 jk_putv(s, "<select name=\"", JK_STATUS_ARG_MIME, "\" size=\"1\">", NULL);
4844 jk_putv(s, "<option value=\"", JK_STATUS_MIME_TEXT_XML, "\">XML</option>", NULL);
4845 jk_putv(s, "<option value=\"", JK_STATUS_MIME_TEXT_PROP, "\">Properties</option>", NULL);
4846 jk_putv(s, "<option value=\"", JK_STATUS_MIME_TEXT_TXT, "\">Text</option>", NULL);
4847 jk_puts(s, "</select></form>\n");
4848 jk_puts(s, "</td>\n");
4850 jk_puts(s, "</tr></table>\n");
4851 jk_puts(s, "<table><tbody valign=\"baseline\"><tr>\n");
4852 if (cmd_props & JK_STATUS_CMD_PROP_BACK_LINK) {
4854 jk_puts(s, "<td>\n");
4855 status_get_string(p, JK_STATUS_ARG_FROM, NULL, &arg, l);
4856 from = status_cmd_int(arg);
4858 if (cmd_props & JK_STATUS_CMD_PROP_BACK_LIST ||
4859 from == JK_STATUS_CMD_LIST) {
4860 status_write_uri(s, p, "Back to worker list", JK_STATUS_CMD_LIST, JK_STATUS_MIME_UNKNOWN,
4861 "", "", 0, 0, "", l);
4864 status_write_uri(s, p, "Back to worker view", JK_STATUS_CMD_SHOW, JK_STATUS_MIME_UNKNOWN,
4865 NULL, NULL, 0, 0, "", l);
4867 jk_puts(s, "] ");
4868 jk_puts(s, "</td>\n");
4870 if (cmd_props & JK_STATUS_CMD_PROP_SWITCH_RO) {
4871 jk_puts(s, "<td>\n");
4872 if (!w->read_only) {
4875 status_write_uri(s, p, "Read/Write", 0, JK_STATUS_MIME_UNKNOWN,
4876 NULL, NULL, 0, JK_STATUS_ARG_OPTION_READ_ONLY, NULL, l);
4879 status_write_uri(s, p, "Read Only", 0, JK_STATUS_MIME_UNKNOWN,
4880 NULL, NULL, JK_STATUS_ARG_OPTION_READ_ONLY, 0, NULL, l);
4882 jk_puts(s, "] \n");
4884 jk_puts(s, "</td>\n");
4886 if (cmd_props & JK_STATUS_CMD_PROP_DUMP_LINK) {
4887 jk_puts(s, "<td>\n");
4889 status_write_uri(s, p, "Dump", JK_STATUS_CMD_DUMP, JK_STATUS_MIME_UNKNOWN,
4890 NULL, NULL, 0, 0, NULL, l);
4891 jk_puts(s, "] \n");
4892 jk_puts(s, "</td>\n");
4894 if (cmd_props & JK_STATUS_CMD_PROP_LINK_HELP &&
4895 (cmd == JK_STATUS_CMD_LIST || !read_only)) {
4896 jk_puts(s, "<td>\n");
4898 if (cmd == JK_STATUS_CMD_LIST) {
4899 jk_puts(s, "<b>S</b>=Show only this worker, ");
4901 jk_puts(s, "<b>E</b>=Edit worker, <b>R</b>=Reset worker state, <b>T</b>=Try worker recovery");
4902 jk_puts(s, "]<br/>\n");
4903 jk_puts(s, "</td>\n");
4905 jk_puts(s, "</tr></table>\n");
4906 if (cmd == JK_STATUS_CMD_LIST) {
4907 /* Step 2: Display configuration */
4908 if (list_workers(s, p, l) != JK_TRUE) {
4909 err = "Error in listing the workers.";
4912 else if (cmd == JK_STATUS_CMD_SHOW) {
4913 /* Step 2: Display detailed configuration */
4914 if (show_worker(s, p, l) != JK_TRUE) {
4915 err = "Error in showing this worker.";
4918 else if (cmd == JK_STATUS_CMD_EDIT) {
4919 /* Step 2: Display edit form */
4920 if (edit_worker(s, p, l) != JK_TRUE) {
4921 err = "Error in generating this worker's configuration form.";
4925 if (cmd == JK_STATUS_CMD_DUMP) {
4926 if (dump_config(s, p, mime, l) == JK_FALSE) {
4927 err = "Dumping configuration failed";
4930 if (cmd_props & JK_STATUS_CMD_PROP_LEGEND) {
4931 display_legend(s, p, l);
4936 jk_log(l, JK_LOG_WARNING, "Status worker '%s': %s", w->name, err);
4937 if (mime == JK_STATUS_MIME_HTML) {
4938 jk_putv(s, "<p><b>Result: ERROR - ", err, "</b><br/>", NULL);
4939 jk_putv(s, "<a href=\"", s->req_uri, "\">JK Status Manager Start Page</a></p>", NULL);
4941 else if (mime == JK_STATUS_MIME_XML) {
4942 jk_print_xml_start_elt(s, w, 2, 0, "result");
4943 jk_print_xml_att_string(s, 4, "type", "ERROR");
4944 jk_print_xml_att_string(s, 4, "message", err);
4945 jk_print_xml_stop_elt(s, 2, 1);
4947 else if (mime == JK_STATUS_MIME_TXT) {
4948 jk_puts(s, "Result:");
4949 jk_printf(s, " type=%s", "ERROR");
4950 jk_printf(s, " message=\"%s\"", err);
4954 jk_print_prop_att_string(s, w, "result", "type", "ERROR");
4955 jk_print_prop_att_string(s, w, "result", "message", err);
4959 if (mime == JK_STATUS_MIME_HTML) {
4960 jk_putv(s, "<p><a href=\"", s->req_uri, "\">JK Status Manager Start Page</a></p>", NULL);
4962 else if (mime == JK_STATUS_MIME_XML) {
4963 jk_print_xml_start_elt(s, w, 2, 0, "result");
4964 jk_print_xml_att_string(s, 4, "type", "OK");
4965 jk_print_xml_att_string(s, 4, "message", "Action finished");
4966 jk_print_xml_stop_elt(s, 2, 1);
4968 else if (mime == JK_STATUS_MIME_TXT) {
4969 jk_puts(s, "Result:");
4970 jk_printf(s, " type=%s", "OK");
4971 jk_printf(s, " message=\"%s\"", "Action finished");
4975 jk_print_prop_att_string(s, w, "result", "type", "OK");
4976 jk_print_prop_att_string(s, w, "result", "message", "Action finished");
4979 if (mime == JK_STATUS_MIME_HTML) {
4981 jk_putv(s, "<hr/><div class=\"footer\">", JK_STATUS_COPYRIGHT,
4985 jk_putv(s, "<hr/><p align=\"center\"><small>", JK_STATUS_COPYRIGHT,
4986 "</small></p>\n", NULL);
4988 jk_puts(s, JK_STATUS_BEND);
4990 else if (mime == JK_STATUS_MIME_XML) {
4991 jk_print_xml_close_elt(s, w, 0, "status");
4997 static int JK_METHOD done(jk_endpoint_t **e, jk_logger_t *l)
5001 if (e && *e && (*e)->endpoint_private) {
5002 status_endpoint_t *p = (*e)->endpoint_private;
5004 jk_map_free(&(p->req_params));
5011 JK_LOG_NULL_PARAMS(l);
5016 static int JK_METHOD validate(jk_worker_t *pThis,
5018 jk_worker_env_t *we, jk_logger_t *l)
5022 if (pThis && pThis->worker_private) {
5027 JK_LOG_NULL_PARAMS(l);
5032 static int JK_METHOD init(jk_worker_t *pThis,
5034 jk_worker_env_t *we, jk_logger_t *l)
5037 if (pThis && pThis->worker_private) {
5038 status_worker_t *p = pThis->worker_private;
5040 unsigned int num_of_good;
5042 unsigned int num_of_bad;
5045 p->css = jk_get_worker_style_sheet(props, p->name, NULL);
5046 p->prefix = jk_get_worker_prop_prefix(props, p->name, JK_STATUS_PREFIX_DEF);
5047 p->ns = jk_get_worker_name_space(props, p->name, JK_STATUS_NS_DEF);
5048 p->xmlns = jk_get_worker_xmlns(props, p->name, JK_STATUS_XMLNS_DEF);
5049 p->doctype = jk_get_worker_xml_doctype(props, p->name, NULL);
5050 p->read_only = jk_get_is_read_only(props, p->name);
5051 p->user_case_insensitive = jk_get_worker_user_case_insensitive(props, p->name);
5052 if (JK_IS_DEBUG_LEVEL(l))
5053 jk_log(l, JK_LOG_DEBUG,
5054 "Status worker '%s' is %s and has css '%s', prefix '%s', name space '%s', xml name space '%s', document type '%s'",
5056 p->read_only ? "read-only" : "read/write",
5057 p->css ? p->css : "(null)",
5058 p->prefix ? p->prefix : "(null)",
5059 p->ns ? p->ns : "(null)",
5060 p->xmlns ? p->xmlns : "(null)",
5061 p->doctype ? p->doctype : "(null)");
5062 if (jk_get_worker_user_list(props, p->name,
5064 &(p->num_of_users)) && p->num_of_users) {
5065 for (i = 0; i < p->num_of_users; i++) {
5066 if (JK_IS_DEBUG_LEVEL(l))
5067 jk_log(l, JK_LOG_DEBUG,
5068 "Status worker '%s' restricting access to user '%s' case %s",
5069 p->name, p->user_names[i],
5070 p->user_case_insensitive ? "insensitive" : "sensitive");
5073 if (jk_get_worker_good_rating(props, p->name,
5075 &num_of_good) && num_of_good) {
5077 for (i = 0; i < num_of_good; i++) {
5078 if (JK_IS_DEBUG_LEVEL(l))
5079 jk_log(l, JK_LOG_DEBUG,
5080 "Status worker '%s' rating as good: '%s'",
5081 p->name, good_rating[i]);
5082 p->good_mask |= status_get_rating(good_rating[i], l);
5086 p->good_mask = JK_STATUS_MASK_GOOD_DEF;
5088 if (jk_get_worker_bad_rating(props, p->name,
5090 &num_of_bad) && num_of_bad) {
5092 for (i = 0; i < num_of_bad; i++) {
5093 if (JK_IS_DEBUG_LEVEL(l))
5094 jk_log(l, JK_LOG_DEBUG,
5095 "Status worker '%s' rating as bad: '%s'",
5096 p->name, bad_rating[i]);
5097 p->bad_mask |= status_get_rating(bad_rating[i], l);
5101 p->bad_mask = JK_STATUS_MASK_BAD_DEF;
5103 if (JK_IS_DEBUG_LEVEL(l))
5104 jk_log(l, JK_LOG_DEBUG,
5105 "Status worker '%s' has good rating for '%08" JK_UINT32_T_HEX_FMT
5106 "' and bad rating for '%08" JK_UINT32_T_HEX_FMT "'",
5110 if (p->good_mask & p->bad_mask)
5111 jk_log(l, JK_LOG_WARNING,
5112 "Status worker '%s' has non empty intersection '%08" JK_UINT32_T_HEX_FMT
5113 "' between good rating for '%08" JK_UINT32_T_HEX_FMT
5114 "' and bad rating for '%08" JK_UINT32_T_HEX_FMT "'",
5116 p->good_mask & p->bad_mask,
5124 static int JK_METHOD get_endpoint(jk_worker_t *pThis,
5125 jk_endpoint_t **pend, jk_logger_t *l)
5129 if (pThis && pThis->worker_private && pend) {
5130 status_endpoint_t *p = (status_endpoint_t *) malloc(sizeof(status_endpoint_t));
5131 p->worker = pThis->worker_private;
5132 p->endpoint.endpoint_private = p;
5133 p->endpoint.service = service;
5134 p->endpoint.done = done;
5135 p->req_params = NULL;
5137 *pend = &p->endpoint;
5143 JK_LOG_NULL_PARAMS(l);
5150 static int JK_METHOD destroy(jk_worker_t **pThis, jk_logger_t *l)
5154 if (pThis && *pThis && (*pThis)->worker_private) {
5155 status_worker_t *private_data = (*pThis)->worker_private;
5157 jk_close_pool(&private_data->p);
5164 JK_LOG_NULL_PARAMS(l);
5169 int JK_METHOD status_worker_factory(jk_worker_t **w,
5170 const char *name, jk_logger_t *l)
5174 if (NULL != name && NULL != w) {
5175 status_worker_t *private_data =
5176 (status_worker_t *) calloc(1, sizeof(status_worker_t));
5178 jk_open_pool(&private_data->p,
5180 sizeof(jk_pool_atom_t) * TINY_POOL_SIZE);
5182 private_data->name = name;
5184 private_data->worker.worker_private = private_data;
5185 private_data->worker.validate = validate;
5186 private_data->worker.init = init;
5187 private_data->worker.get_endpoint = get_endpoint;
5188 private_data->worker.destroy = destroy;
5190 *w = &private_data->worker;
5192 return JK_STATUS_WORKER_TYPE;
5195 JK_LOG_NULL_PARAMS(l);