|
|
| version 1.1, 2013/10/14 10:32:47 | version 1.1.1.3, 2016/11/02 10:35:00 |
|---|---|
| Line 1 | Line 1 |
| #include "first.h" | |
| #include "server.h" | #include "server.h" |
| #include "connections.h" | #include "connections.h" |
| #include "response.h" | #include "response.h" |
| Line 18 | Line 20 |
| #include <time.h> | #include <time.h> |
| #include <stdio.h> | #include <stdio.h> |
| #include "version.h" | |
| typedef struct { | typedef struct { |
| buffer *config_url; | buffer *config_url; |
| buffer *status_url; | buffer *status_url; |
| Line 115 SETDEFAULTS_FUNC(mod_status_set_defaults) { | Line 115 SETDEFAULTS_FUNC(mod_status_set_defaults) { |
| if (!p) return HANDLER_ERROR; | if (!p) return HANDLER_ERROR; |
| p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *)); | p->config_storage = calloc(1, srv->config_context->used * sizeof(plugin_config *)); |
| for (i = 0; i < srv->config_context->used; i++) { | for (i = 0; i < srv->config_context->used; i++) { |
| data_config const* config = (data_config const*)srv->config_context->data[i]; | |
| plugin_config *s; | plugin_config *s; |
| s = calloc(1, sizeof(plugin_config)); | s = calloc(1, sizeof(plugin_config)); |
| Line 133 SETDEFAULTS_FUNC(mod_status_set_defaults) { | Line 134 SETDEFAULTS_FUNC(mod_status_set_defaults) { |
| p->config_storage[i] = s; | p->config_storage[i] = s; |
| if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) { | if (0 != config_insert_values_global(srv, config->value, cv, i == 0 ? T_CONFIG_SCOPE_SERVER : T_CONFIG_SCOPE_CONNECTION)) { |
| return HANDLER_ERROR; | return HANDLER_ERROR; |
| } | } |
| } | } |
| Line 199 static int mod_status_get_multiplier(double *avg, char | Line 200 static int mod_status_get_multiplier(double *avg, char |
| static handler_t mod_status_handle_server_status_html(server *srv, connection *con, void *p_d) { | static handler_t mod_status_handle_server_status_html(server *srv, connection *con, void *p_d) { |
| plugin_data *p = p_d; | plugin_data *p = p_d; |
| buffer *b; | buffer *b = buffer_init(); |
| size_t j; | size_t j; |
| double avg; | double avg; |
| char multiplier = '\0'; | char multiplier = '\0'; |
| Line 208 static handler_t mod_status_handle_server_status_html( | Line 209 static handler_t mod_status_handle_server_status_html( |
| int days, hours, mins, seconds; | int days, hours, mins, seconds; |
| b = chunkqueue_get_append_buffer(con->write_queue); | /*(CON_STATE_CLOSE must be last state in enum connection_state_t)*/ |
| int cstates[CON_STATE_CLOSE+3]; | |
| memset(cstates, 0, sizeof(cstates)); | |
| buffer_copy_string_len(b, CONST_STR_LEN( | buffer_copy_string_len(b, CONST_STR_LEN( |
| "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n" | "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n" |
| Line 228 static handler_t mod_status_handle_server_status_html( | Line 231 static handler_t mod_status_handle_server_status_html( |
| " span.sortarrow { color: white; text-decoration: none; }\n" | " span.sortarrow { color: white; text-decoration: none; }\n" |
| " </style>\n")); | " </style>\n")); |
| if (!buffer_string_is_empty(con->uri.query) && 0 == memcmp(con->uri.query->ptr, CONST_STR_LEN("refresh="))) { | |
| /* Note: Refresh is an historical, but non-standard HTTP header | |
| * References (meta http-equiv="refresh" use is deprecated): | |
| * https://www.w3.org/TR/WCAG10-HTML-TECHS/#meta-element | |
| * https://www.w3.org/TR/WCAG10-CORE-TECHS/#auto-page-refresh | |
| * https://www.w3.org/QA/Tips/reback | |
| */ | |
| const long refresh = strtol(con->uri.query->ptr+sizeof("refresh=")-1, NULL, 10); | |
| if (refresh > 0) { | |
| buffer_append_string_len(b, CONST_STR_LEN("<meta http-equiv=\"refresh\" content=\"")); | |
| buffer_append_int(b, refresh < 604800 ? refresh : 604800); | |
| buffer_append_string_len(b, CONST_STR_LEN("\">\n")); | |
| } | |
| } | |
| if (p->conf.sort) { | if (p->conf.sort) { |
| buffer_append_string_len(b, CONST_STR_LEN( | buffer_append_string_len(b, CONST_STR_LEN( |
| "<script type=\"text/javascript\">\n" | "<script type=\"text/javascript\">\n" |
| Line 299 static handler_t mod_status_handle_server_status_html( | Line 317 static handler_t mod_status_handle_server_status_html( |
| /* connection listing */ | /* connection listing */ |
| buffer_append_string_len(b, CONST_STR_LEN("<h1>Server-Status (" PACKAGE_NAME " " PACKAGE_VERSION ")</h1>")); | buffer_append_string_len(b, CONST_STR_LEN("<h1>Server-Status (")); |
| buffer_append_string_buffer(b, con->conf.server_tag); | |
| buffer_append_string_len(b, CONST_STR_LEN(")</h1>")); | |
| buffer_append_string_len(b, CONST_STR_LEN("<table summary=\"status\" class=\"status\">")); | buffer_append_string_len(b, CONST_STR_LEN("<table summary=\"status\" class=\"status\">")); |
| buffer_append_string_len(b, CONST_STR_LEN("<tr><td>Hostname</td><td class=\"string\">")); | buffer_append_string_len(b, CONST_STR_LEN("<tr><td>Hostname</td><td class=\"string\">")); |
| Line 323 static handler_t mod_status_handle_server_status_html( | Line 343 static handler_t mod_status_handle_server_status_html( |
| seconds = ts; | seconds = ts; |
| if (days) { | if (days) { |
| buffer_append_long(b, days); | buffer_append_int(b, days); |
| buffer_append_string_len(b, CONST_STR_LEN(" days ")); | buffer_append_string_len(b, CONST_STR_LEN(" days ")); |
| } | } |
| if (hours) { | if (hours) { |
| buffer_append_long(b, hours); | buffer_append_int(b, hours); |
| buffer_append_string_len(b, CONST_STR_LEN(" hours ")); | buffer_append_string_len(b, CONST_STR_LEN(" hours ")); |
| } | } |
| if (mins) { | if (mins) { |
| buffer_append_long(b, mins); | buffer_append_int(b, mins); |
| buffer_append_string_len(b, CONST_STR_LEN(" min ")); | buffer_append_string_len(b, CONST_STR_LEN(" min ")); |
| } | } |
| buffer_append_long(b, seconds); | buffer_append_int(b, seconds); |
| buffer_append_string_len(b, CONST_STR_LEN(" s")); | buffer_append_string_len(b, CONST_STR_LEN(" s")); |
| buffer_append_string_len(b, CONST_STR_LEN("</td></tr>\n")); | buffer_append_string_len(b, CONST_STR_LEN("</td></tr>\n")); |
| Line 357 static handler_t mod_status_handle_server_status_html( | Line 377 static handler_t mod_status_handle_server_status_html( |
| mod_status_get_multiplier(&avg, &multiplier, 1000); | mod_status_get_multiplier(&avg, &multiplier, 1000); |
| buffer_append_long(b, avg); | buffer_append_int(b, avg); |
| buffer_append_string_len(b, CONST_STR_LEN(" ")); | buffer_append_string_len(b, CONST_STR_LEN(" ")); |
| if (multiplier) buffer_append_string_len(b, &multiplier, 1); | if (multiplier) buffer_append_string_len(b, &multiplier, 1); |
| buffer_append_string_len(b, CONST_STR_LEN("req</td></tr>\n")); | buffer_append_string_len(b, CONST_STR_LEN("req</td></tr>\n")); |
| Line 367 static handler_t mod_status_handle_server_status_html( | Line 387 static handler_t mod_status_handle_server_status_html( |
| mod_status_get_multiplier(&avg, &multiplier, 1024); | mod_status_get_multiplier(&avg, &multiplier, 1024); |
| sprintf(buf, "%.2f", avg); | snprintf(buf, sizeof(buf), "%.2f", avg); |
| buffer_append_string(b, buf); | buffer_append_string(b, buf); |
| buffer_append_string_len(b, CONST_STR_LEN(" ")); | buffer_append_string_len(b, CONST_STR_LEN(" ")); |
| if (multiplier) buffer_append_string_len(b, &multiplier, 1); | if (multiplier) buffer_append_string_len(b, &multiplier, 1); |
| Line 382 static handler_t mod_status_handle_server_status_html( | Line 402 static handler_t mod_status_handle_server_status_html( |
| mod_status_get_multiplier(&avg, &multiplier, 1000); | mod_status_get_multiplier(&avg, &multiplier, 1000); |
| buffer_append_long(b, avg); | buffer_append_int(b, avg); |
| buffer_append_string_len(b, CONST_STR_LEN(" ")); | buffer_append_string_len(b, CONST_STR_LEN(" ")); |
| if (multiplier) buffer_append_string_len(b, &multiplier, 1); | if (multiplier) buffer_append_string_len(b, &multiplier, 1); |
| buffer_append_string_len(b, CONST_STR_LEN("req/s</td></tr>\n")); | buffer_append_string_len(b, CONST_STR_LEN("req/s</td></tr>\n")); |
| Line 392 static handler_t mod_status_handle_server_status_html( | Line 412 static handler_t mod_status_handle_server_status_html( |
| mod_status_get_multiplier(&avg, &multiplier, 1024); | mod_status_get_multiplier(&avg, &multiplier, 1024); |
| sprintf(buf, "%.2f", avg); | snprintf(buf, sizeof(buf), "%.2f", avg); |
| buffer_append_string(b, buf); | buffer_append_string(b, buf); |
| buffer_append_string_len(b, CONST_STR_LEN(" ")); | buffer_append_string_len(b, CONST_STR_LEN(" ")); |
| if (multiplier) buffer_append_string_len(b, &multiplier, 1); | if (multiplier) buffer_append_string_len(b, &multiplier, 1); |
| Line 411 static handler_t mod_status_handle_server_status_html( | Line 431 static handler_t mod_status_handle_server_status_html( |
| mod_status_get_multiplier(&avg, &multiplier, 1000); | mod_status_get_multiplier(&avg, &multiplier, 1000); |
| buffer_append_long(b, avg); | buffer_append_int(b, avg); |
| buffer_append_string_len(b, CONST_STR_LEN(" ")); | buffer_append_string_len(b, CONST_STR_LEN(" ")); |
| if (multiplier) buffer_append_string_len(b, &multiplier, 1); | if (multiplier) buffer_append_string_len(b, &multiplier, 1); |
| Line 427 static handler_t mod_status_handle_server_status_html( | Line 447 static handler_t mod_status_handle_server_status_html( |
| mod_status_get_multiplier(&avg, &multiplier, 1024); | mod_status_get_multiplier(&avg, &multiplier, 1024); |
| sprintf(buf, "%.2f", avg); | snprintf(buf, sizeof(buf), "%.2f", avg); |
| buffer_append_string(b, buf); | buffer_append_string(b, buf); |
| buffer_append_string_len(b, CONST_STR_LEN(" ")); | buffer_append_string_len(b, CONST_STR_LEN(" ")); |
| if (multiplier) buffer_append_string_len(b, &multiplier, 1); | if (multiplier) buffer_append_string_len(b, &multiplier, 1); |
| Line 435 static handler_t mod_status_handle_server_status_html( | Line 455 static handler_t mod_status_handle_server_status_html( |
| buffer_append_string_len(b, CONST_STR_LEN("</table>\n")); | buffer_append_string_len(b, CONST_STR_LEN("</table>\n")); |
| buffer_append_string_len(b, CONST_STR_LEN("<hr />\n<pre>\n")); | |
| buffer_append_string_len(b, CONST_STR_LEN( | |
| "<hr />\n<pre><b>legend</b>\n" | |
| ". = connect, C = close, E = hard error, k = keep-alive\n" | |
| "r = read, R = read-POST, W = write, h = handle-request\n" | |
| "q = request-start, Q = request-end\n" | |
| "s = response-start, S = response-end\n")); | |
| buffer_append_string_len(b, CONST_STR_LEN("<b>")); | buffer_append_string_len(b, CONST_STR_LEN("<b>")); |
| buffer_append_long(b, srv->conns->used); | buffer_append_int(b, srv->conns->used); |
| buffer_append_string_len(b, CONST_STR_LEN(" connections</b>\n")); | buffer_append_string_len(b, CONST_STR_LEN(" connections</b>\n")); |
| for (j = 0; j < srv->conns->used; j++) { | for (j = 0; j < srv->conns->used; j++) { |
| connection *c = srv->conns->ptr[j]; | connection *c = srv->conns->ptr[j]; |
| const char *state; | const char *state; |
| if (CON_STATE_READ == c->state && c->request.orig_uri->used > 0) { | if (CON_STATE_READ == c->state && !buffer_string_is_empty(c->request.orig_uri)) { |
| state = "k"; | state = "k"; |
| ++cstates[CON_STATE_CLOSE+2]; | |
| } else { | } else { |
| state = connection_get_short_state(c->state); | state = connection_get_short_state(c->state); |
| ++cstates[(c->state <= CON_STATE_CLOSE ? c->state : CON_STATE_CLOSE+1)]; | |
| } | } |
| buffer_append_string_len(b, state, 1); | buffer_append_string_len(b, state, 1); |
| Line 463 static handler_t mod_status_handle_server_status_html( | Line 479 static handler_t mod_status_handle_server_status_html( |
| buffer_append_string_len(b, CONST_STR_LEN("\n")); | buffer_append_string_len(b, CONST_STR_LEN("\n")); |
| } | } |
| } | } |
| buffer_append_string_len(b, CONST_STR_LEN("\n\n<table>\n")); | |
| buffer_append_string_len(b, CONST_STR_LEN("<tr><td style=\"text-align:right\">")); | |
| buffer_append_int(b, cstates[CON_STATE_CLOSE+2]); | |
| buffer_append_string_len(b, CONST_STR_LEN("<td> k = keep-alive</td></tr>\n")); | |
| for (j = 0; j < CON_STATE_CLOSE+2; ++j) { | |
| /*(skip "unknown" state if there are none; there should not be any unknown)*/ | |
| if (0 == cstates[j] && j == CON_STATE_CLOSE+1) continue; | |
| buffer_append_string_len(b, CONST_STR_LEN("<tr><td style=\"text-align:right\">")); | |
| buffer_append_int(b, cstates[j]); | |
| buffer_append_string_len(b, CONST_STR_LEN("</td><td> ")); | |
| buffer_append_string_len(b, connection_get_short_state(j), 1); | |
| buffer_append_string_len(b, CONST_STR_LEN(" = ")); | |
| buffer_append_string(b, connection_get_state(j)); | |
| buffer_append_string_len(b, CONST_STR_LEN("</td></tr>\n")); | |
| } | |
| buffer_append_string_len(b, CONST_STR_LEN("</table>")); | |
| buffer_append_string_len(b, CONST_STR_LEN("\n</pre><hr />\n<h2>Connections</h2>\n")); | buffer_append_string_len(b, CONST_STR_LEN("\n</pre><hr />\n<h2>Connections</h2>\n")); |
| Line 488 static handler_t mod_status_handle_server_status_html( | Line 520 static handler_t mod_status_handle_server_status_html( |
| buffer_append_string_len(b, CONST_STR_LEN("</td><td class=\"int\">")); | buffer_append_string_len(b, CONST_STR_LEN("</td><td class=\"int\">")); |
| if (c->request.content_length) { | if (c->request.content_length) { |
| buffer_append_long(b, c->request_content_queue->bytes_in); | buffer_append_int(b, c->request_content_queue->bytes_in); |
| buffer_append_string_len(b, CONST_STR_LEN("/")); | buffer_append_string_len(b, CONST_STR_LEN("/")); |
| buffer_append_long(b, c->request.content_length); | buffer_append_int(b, c->request.content_length); |
| } else { | } else { |
| buffer_append_string_len(b, CONST_STR_LEN("0/0")); | buffer_append_string_len(b, CONST_STR_LEN("0/0")); |
| } | } |
| buffer_append_string_len(b, CONST_STR_LEN("</td><td class=\"int\">")); | buffer_append_string_len(b, CONST_STR_LEN("</td><td class=\"int\">")); |
| buffer_append_off_t(b, chunkqueue_written(c->write_queue)); | buffer_append_int(b, c->write_queue->bytes_out); |
| buffer_append_string_len(b, CONST_STR_LEN("/")); | buffer_append_string_len(b, CONST_STR_LEN("/")); |
| buffer_append_off_t(b, chunkqueue_length(c->write_queue)); | buffer_append_int(b, c->write_queue->bytes_out + chunkqueue_length(c->write_queue)); |
| buffer_append_string_len(b, CONST_STR_LEN("</td><td class=\"string\">")); | buffer_append_string_len(b, CONST_STR_LEN("</td><td class=\"string\">")); |
| if (CON_STATE_READ == c->state && c->request.orig_uri->used > 0) { | if (CON_STATE_READ == c->state && !buffer_string_is_empty(c->request.orig_uri)) { |
| buffer_append_string_len(b, CONST_STR_LEN("keep-alive")); | buffer_append_string_len(b, CONST_STR_LEN("keep-alive")); |
| } else { | } else { |
| buffer_append_string(b, connection_get_state(c->state)); | buffer_append_string(b, connection_get_state(c->state)); |
| Line 511 static handler_t mod_status_handle_server_status_html( | Line 543 static handler_t mod_status_handle_server_status_html( |
| buffer_append_string_len(b, CONST_STR_LEN("</td><td class=\"int\">")); | buffer_append_string_len(b, CONST_STR_LEN("</td><td class=\"int\">")); |
| buffer_append_long(b, srv->cur_ts - c->request_start); | buffer_append_int(b, srv->cur_ts - c->request_start); |
| buffer_append_string_len(b, CONST_STR_LEN("</td><td class=\"string\">")); | buffer_append_string_len(b, CONST_STR_LEN("</td><td class=\"string\">")); |
| if (buffer_is_empty(c->server_name)) { | if (buffer_string_is_empty(c->server_name)) { |
| buffer_append_string_buffer(b, c->uri.authority); | buffer_append_string_buffer(b, c->uri.authority); |
| } | } |
| else { | else { |
| Line 524 static handler_t mod_status_handle_server_status_html( | Line 556 static handler_t mod_status_handle_server_status_html( |
| buffer_append_string_len(b, CONST_STR_LEN("</td><td class=\"string\">")); | buffer_append_string_len(b, CONST_STR_LEN("</td><td class=\"string\">")); |
| if (!buffer_is_empty(c->uri.path)) { | if (!buffer_string_is_empty(c->uri.path)) { |
| buffer_append_string_encoded(b, CONST_BUF_LEN(c->uri.path), ENCODING_HTML); | buffer_append_string_encoded(b, CONST_BUF_LEN(c->uri.path), ENCODING_HTML); |
| } | } |
| if (!buffer_is_empty(c->uri.query)) { | if (!buffer_string_is_empty(c->uri.query)) { |
| buffer_append_string_len(b, CONST_STR_LEN("?")); | buffer_append_string_len(b, CONST_STR_LEN("?")); |
| buffer_append_string_encoded(b, CONST_BUF_LEN(c->uri.query), ENCODING_HTML); | buffer_append_string_encoded(b, CONST_BUF_LEN(c->uri.query), ENCODING_HTML); |
| } | } |
| if (!buffer_is_empty(c->request.orig_uri)) { | if (!buffer_string_is_empty(c->request.orig_uri)) { |
| buffer_append_string_len(b, CONST_STR_LEN(" (")); | buffer_append_string_len(b, CONST_STR_LEN(" (")); |
| buffer_append_string_encoded(b, CONST_BUF_LEN(c->request.orig_uri), ENCODING_HTML); | buffer_append_string_encoded(b, CONST_BUF_LEN(c->request.orig_uri), ENCODING_HTML); |
| buffer_append_string_len(b, CONST_STR_LEN(")")); | buffer_append_string_len(b, CONST_STR_LEN(")")); |
| Line 555 static handler_t mod_status_handle_server_status_html( | Line 587 static handler_t mod_status_handle_server_status_html( |
| "</html>\n" | "</html>\n" |
| )); | )); |
| chunkqueue_append_buffer(con->write_queue, b); | |
| buffer_free(b); | |
| response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html")); | response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html")); |
| return 0; | return 0; |
| Line 563 static handler_t mod_status_handle_server_status_html( | Line 598 static handler_t mod_status_handle_server_status_html( |
| static handler_t mod_status_handle_server_status_text(server *srv, connection *con, void *p_d) { | static handler_t mod_status_handle_server_status_text(server *srv, connection *con, void *p_d) { |
| plugin_data *p = p_d; | plugin_data *p = p_d; |
| buffer *b; | buffer *b = buffer_init(); |
| double avg; | double avg; |
| time_t ts; | time_t ts; |
| char buf[32]; | char buf[32]; |
| unsigned int k; | unsigned int k; |
| unsigned int l; | unsigned int l; |
| b = chunkqueue_get_append_buffer(con->write_queue); | |
| /* output total number of requests */ | /* output total number of requests */ |
| buffer_append_string_len(b, CONST_STR_LEN("Total Accesses: ")); | buffer_append_string_len(b, CONST_STR_LEN("Total Accesses: ")); |
| avg = p->abs_requests; | avg = p->abs_requests; |
| Line 589 static handler_t mod_status_handle_server_status_text( | Line 622 static handler_t mod_status_handle_server_status_text( |
| /* output uptime */ | /* output uptime */ |
| buffer_append_string_len(b, CONST_STR_LEN("Uptime: ")); | buffer_append_string_len(b, CONST_STR_LEN("Uptime: ")); |
| ts = srv->cur_ts - srv->startup_ts; | ts = srv->cur_ts - srv->startup_ts; |
| buffer_append_long(b, ts); | buffer_append_int(b, ts); |
| buffer_append_string_len(b, CONST_STR_LEN("\n")); | buffer_append_string_len(b, CONST_STR_LEN("\n")); |
| /* output busy servers */ | /* output busy servers */ |
| buffer_append_string_len(b, CONST_STR_LEN("BusyServers: ")); | buffer_append_string_len(b, CONST_STR_LEN("BusyServers: ")); |
| buffer_append_long(b, srv->conns->used); | buffer_append_int(b, srv->conns->used); |
| buffer_append_string_len(b, CONST_STR_LEN("\n")); | buffer_append_string_len(b, CONST_STR_LEN("\n")); |
| buffer_append_string_len(b, CONST_STR_LEN("IdleServers: ")); | buffer_append_string_len(b, CONST_STR_LEN("IdleServers: ")); |
| buffer_append_long(b, srv->conns->size - srv->conns->used); | buffer_append_int(b, srv->conns->size - srv->conns->used); |
| buffer_append_string_len(b, CONST_STR_LEN("\n")); | buffer_append_string_len(b, CONST_STR_LEN("\n")); |
| /* output scoreboard */ | /* output scoreboard */ |
| buffer_append_string_len(b, CONST_STR_LEN("Scoreboard: ")); | buffer_append_string_len(b, CONST_STR_LEN("Scoreboard: ")); |
| for (k = 0; k < srv->conns->used; k++) { | for (k = 0; k < srv->conns->used; k++) { |
| connection *c = srv->conns->ptr[k]; | connection *c = srv->conns->ptr[k]; |
| const char *state = connection_get_short_state(c->state); | const char *state = |
| (CON_STATE_READ == c->state && !buffer_string_is_empty(c->request.orig_uri)) | |
| ? "k" | |
| : connection_get_short_state(c->state); | |
| buffer_append_string_len(b, state, 1); | buffer_append_string_len(b, state, 1); |
| } | } |
| for (l = 0; l < srv->conns->size - srv->conns->used; l++) { | for (l = 0; l < srv->conns->size - srv->conns->used; l++) { |
| Line 613 static handler_t mod_status_handle_server_status_text( | Line 649 static handler_t mod_status_handle_server_status_text( |
| } | } |
| buffer_append_string_len(b, CONST_STR_LEN("\n")); | buffer_append_string_len(b, CONST_STR_LEN("\n")); |
| /* set text/plain output */ | chunkqueue_append_buffer(con->write_queue, b); |
| buffer_free(b); | |
| /* set text/plain output */ | |
| response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/plain")); | response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/plain")); |
| return 0; | return 0; |
| } | } |
| static handler_t mod_status_handle_server_status_json(server *srv, connection *con, void *p_d) { | |
| plugin_data *p = p_d; | |
| buffer *b = buffer_init(); | |
| double avg; | |
| time_t ts; | |
| char buf[32]; | |
| size_t j; | |
| unsigned int jsonp = 0; | |
| if (buffer_string_length(con->uri.query) >= sizeof("jsonp=")-1 | |
| && 0 == memcmp(con->uri.query->ptr, CONST_STR_LEN("jsonp="))) { | |
| /* not a full parse of query string for multiple parameters, | |
| * not URL-decoding param and not XML-encoding (XSS protection), | |
| * so simply ensure that json function name isalnum() or '_' */ | |
| const char *f = con->uri.query->ptr + sizeof("jsonp=")-1; | |
| int len = 0; | |
| while (light_isalnum(f[len]) || f[len] == '_') ++len; | |
| if (0 != len && light_isalpha(f[0]) && f[len] == '\0') { | |
| buffer_append_string_len(b, f, len); | |
| buffer_append_string_len(b, CONST_STR_LEN("(")); | |
| jsonp = 1; | |
| } | |
| } | |
| /* output total number of requests */ | |
| buffer_append_string_len(b, CONST_STR_LEN("{\n\t\"RequestsTotal\": ")); | |
| avg = p->abs_requests; | |
| snprintf(buf, sizeof(buf) - 1, "%.0f", avg); | |
| buffer_append_string(b, buf); | |
| buffer_append_string_len(b, CONST_STR_LEN(",\n")); | |
| /* output total traffic out in kbytes */ | |
| buffer_append_string_len(b, CONST_STR_LEN("\t\"TrafficTotal\": ")); | |
| avg = p->abs_traffic_out / 1024; | |
| snprintf(buf, sizeof(buf) - 1, "%.0f", avg); | |
| buffer_append_string(b, buf); | |
| buffer_append_string_len(b, CONST_STR_LEN(",\n")); | |
| /* output uptime */ | |
| buffer_append_string_len(b, CONST_STR_LEN("\t\"Uptime\": ")); | |
| ts = srv->cur_ts - srv->startup_ts; | |
| buffer_append_int(b, ts); | |
| buffer_append_string_len(b, CONST_STR_LEN(",\n")); | |
| /* output busy servers */ | |
| buffer_append_string_len(b, CONST_STR_LEN("\t\"BusyServers\": ")); | |
| buffer_append_int(b, srv->conns->used); | |
| buffer_append_string_len(b, CONST_STR_LEN(",\n")); | |
| buffer_append_string_len(b, CONST_STR_LEN("\t\"IdleServers\": ")); | |
| buffer_append_int(b, srv->conns->size - srv->conns->used); | |
| buffer_append_string_len(b, CONST_STR_LEN(",\n")); | |
| for (j = 0, avg = 0; j < 5; j++) { | |
| avg += p->mod_5s_requests[j]; | |
| } | |
| avg /= 5; | |
| buffer_append_string_len(b, CONST_STR_LEN("\t\"RequestAverage5s\":")); | |
| buffer_append_int(b, avg); | |
| buffer_append_string_len(b, CONST_STR_LEN(",\n")); | |
| for (j = 0, avg = 0; j < 5; j++) { | |
| avg += p->mod_5s_traffic_out[j]; | |
| } | |
| avg /= 5; | |
| buffer_append_string_len(b, CONST_STR_LEN("\t\"TrafficAverage5s\":")); | |
| buffer_append_int(b, avg / 1024); /* kbps */ | |
| buffer_append_string_len(b, CONST_STR_LEN("\n}")); | |
| if (jsonp) buffer_append_string_len(b, CONST_STR_LEN(");")); | |
| chunkqueue_append_buffer(con->write_queue, b); | |
| buffer_free(b); | |
| /* set text/plain output */ | |
| response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("application/javascript")); | |
| return 0; | |
| } | |
| static handler_t mod_status_handle_server_statistics(server *srv, connection *con, void *p_d) { | static handler_t mod_status_handle_server_statistics(server *srv, connection *con, void *p_d) { |
| buffer *b; | buffer *b; |
| size_t i; | size_t i; |
| Line 634 static handler_t mod_status_handle_server_statistics(s | Line 758 static handler_t mod_status_handle_server_statistics(s |
| return HANDLER_FINISHED; | return HANDLER_FINISHED; |
| } | } |
| b = chunkqueue_get_append_buffer(con->write_queue); | b = buffer_init(); |
| for (i = 0; i < st->used; i++) { | for (i = 0; i < st->used; i++) { |
| size_t ndx = st->sorted[i]; | size_t ndx = st->sorted[i]; |
| buffer_append_string_buffer(b, st->data[ndx]->key); | buffer_append_string_buffer(b, st->data[ndx]->key); |
| buffer_append_string_len(b, CONST_STR_LEN(": ")); | buffer_append_string_len(b, CONST_STR_LEN(": ")); |
| buffer_append_long(b, ((data_integer *)(st->data[ndx]))->value); | buffer_append_int(b, ((data_integer *)(st->data[ndx]))->value); |
| buffer_append_string_len(b, CONST_STR_LEN("\n")); | buffer_append_string_len(b, CONST_STR_LEN("\n")); |
| } | } |
| chunkqueue_append_buffer(con->write_queue, b); | |
| buffer_free(b); | |
| response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/plain")); | response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/plain")); |
| con->http_status = 200; | con->http_status = 200; |
| Line 658 static handler_t mod_status_handle_server_status(serve | Line 784 static handler_t mod_status_handle_server_status(serve |
| if (buffer_is_equal_string(con->uri.query, CONST_STR_LEN("auto"))) { | if (buffer_is_equal_string(con->uri.query, CONST_STR_LEN("auto"))) { |
| mod_status_handle_server_status_text(srv, con, p_d); | mod_status_handle_server_status_text(srv, con, p_d); |
| } else if (buffer_string_length(con->uri.query) >= sizeof("json")-1 | |
| && 0 == memcmp(con->uri.query->ptr, CONST_STR_LEN("json"))) { | |
| mod_status_handle_server_status_json(srv, con, p_d); | |
| } else { | } else { |
| mod_status_handle_server_status_html(srv, con, p_d); | mod_status_handle_server_status_html(srv, con, p_d); |
| } | } |
| Line 671 static handler_t mod_status_handle_server_status(serve | Line 800 static handler_t mod_status_handle_server_status(serve |
| static handler_t mod_status_handle_server_config(server *srv, connection *con, void *p_d) { | static handler_t mod_status_handle_server_config(server *srv, connection *con, void *p_d) { |
| plugin_data *p = p_d; | plugin_data *p = p_d; |
| buffer *b, *m = p->module_list; | buffer *b = buffer_init(); |
| buffer *m = p->module_list; | |
| size_t i; | size_t i; |
| struct ev_map { fdevent_handler_t et; const char *name; } event_handlers[] = | struct ev_map { fdevent_handler_t et; const char *name; } event_handlers[] = |
| Line 703 static handler_t mod_status_handle_server_config(serve | Line 833 static handler_t mod_status_handle_server_config(serve |
| { FDEVENT_HANDLER_UNSET, NULL } | { FDEVENT_HANDLER_UNSET, NULL } |
| }; | }; |
| b = chunkqueue_get_append_buffer(con->write_queue); | |
| buffer_copy_string_len(b, CONST_STR_LEN( | buffer_copy_string_len(b, CONST_STR_LEN( |
| "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n" | "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n" |
| "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n" | "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n" |
| Line 714 static handler_t mod_status_handle_server_config(serve | Line 842 static handler_t mod_status_handle_server_config(serve |
| " <title>Status</title>\n" | " <title>Status</title>\n" |
| " </head>\n" | " </head>\n" |
| " <body>\n" | " <body>\n" |
| " <h1>" PACKAGE_DESC "</h1>\n" | " <h1>")); |
| buffer_append_string_buffer(b, con->conf.server_tag); | |
| buffer_append_string_len(b, CONST_STR_LEN( | |
| "</h1>\n" | |
| " <table summary=\"status\" border=\"1\">\n")); | " <table summary=\"status\" border=\"1\">\n")); |
| mod_status_header_append(b, "Server-Features"); | mod_status_header_append(b, "Server-Features"); |
| Line 740 static handler_t mod_status_handle_server_config(serve | Line 871 static handler_t mod_status_handle_server_config(serve |
| plugin *pl = ps[i]; | plugin *pl = ps[i]; |
| if (i == 0) { | if (i == 0) { |
| buffer_copy_string_buffer(m, pl->name); | buffer_copy_buffer(m, pl->name); |
| } else { | } else { |
| buffer_append_string_len(m, CONST_STR_LEN("<br />")); | buffer_append_string_len(m, CONST_STR_LEN("<br />")); |
| buffer_append_string_buffer(m, pl->name); | buffer_append_string_buffer(m, pl->name); |
| Line 756 static handler_t mod_status_handle_server_config(serve | Line 887 static handler_t mod_status_handle_server_config(serve |
| "</html>\n" | "</html>\n" |
| )); | )); |
| chunkqueue_append_buffer(con->write_queue, b); | |
| buffer_free(b); | |
| response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html")); | response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html")); |
| con->http_status = 200; | con->http_status = 200; |
| Line 809 static handler_t mod_status_handler(server *srv, conne | Line 943 static handler_t mod_status_handler(server *srv, conne |
| mod_status_patch_connection(srv, con, p); | mod_status_patch_connection(srv, con, p); |
| if (!buffer_is_empty(p->conf.status_url) && | if (!buffer_string_is_empty(p->conf.status_url) && |
| buffer_is_equal(p->conf.status_url, con->uri.path)) { | buffer_is_equal(p->conf.status_url, con->uri.path)) { |
| return mod_status_handle_server_status(srv, con, p_d); | return mod_status_handle_server_status(srv, con, p_d); |
| } else if (!buffer_is_empty(p->conf.config_url) && | } else if (!buffer_string_is_empty(p->conf.config_url) && |
| buffer_is_equal(p->conf.config_url, con->uri.path)) { | buffer_is_equal(p->conf.config_url, con->uri.path)) { |
| return mod_status_handle_server_config(srv, con, p_d); | return mod_status_handle_server_config(srv, con, p_d); |
| } else if (!buffer_is_empty(p->conf.statistics_url) && | } else if (!buffer_string_is_empty(p->conf.statistics_url) && |
| buffer_is_equal(p->conf.statistics_url, con->uri.path)) { | buffer_is_equal(p->conf.statistics_url, con->uri.path)) { |
| return mod_status_handle_server_statistics(srv, con, p_d); | return mod_status_handle_server_statistics(srv, con, p_d); |
| } | } |