diff options
Diffstat (limited to 'src/mod_status.c')
-rw-r--r-- | src/mod_status.c | 893 |
1 files changed, 0 insertions, 893 deletions
diff --git a/src/mod_status.c b/src/mod_status.c deleted file mode 100644 index 459db41c..00000000 --- a/src/mod_status.c +++ /dev/null @@ -1,893 +0,0 @@ -/* - * make sure _GNU_SOURCE is defined. - */ -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif -#include <sys/types.h> - -#include <fcntl.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <time.h> -#include <stdio.h> - -#include "server.h" -#include "connections.h" -#include "response.h" -#include "connections.h" -#include "log.h" -#include "status_counter.h" -#include "network_backends.h" - -#include "plugin.h" - -#include "inet_ntop_cache.h" - -typedef struct { - buffer *config_url; - buffer *status_url; - buffer *statistics_url; - - int sort; -} plugin_config; - -typedef struct { - PLUGIN_DATA; - - double traffic_out; - double requests; - - double mod_5s_traffic_out[5]; - double mod_5s_requests[5]; - size_t mod_5s_ndx; - - double rel_traffic_out; - double rel_requests; - - double abs_traffic_out; - double abs_requests; - - double bytes_written; - - buffer *tmp_buf; - - plugin_config **config_storage; - - plugin_config conf; -} plugin_data; - -INIT_FUNC(mod_status_init) { - plugin_data *p; - size_t i; - - UNUSED(srv); - - p = calloc(1, sizeof(*p)); - - p->traffic_out = p->requests = 0; - p->rel_traffic_out = p->rel_requests = 0; - p->abs_traffic_out = p->abs_requests = 0; - p->bytes_written = 0; - p->tmp_buf = buffer_init(); - - for (i = 0; i < 5; i++) { - p->mod_5s_traffic_out[i] = p->mod_5s_requests[i] = 0; - } - - return p; -} - -FREE_FUNC(mod_status_free) { - plugin_data *p = p_d; - - UNUSED(srv); - - if (!p) return HANDLER_GO_ON; - - buffer_free(p->tmp_buf); - - if (p->config_storage) { - size_t i; - for (i = 0; i < srv->config_context->used; i++) { - plugin_config *s = p->config_storage[i]; - - buffer_free(s->status_url); - buffer_free(s->statistics_url); - buffer_free(s->config_url); - - free(s); - } - free(p->config_storage); - } - - - free(p); - - return HANDLER_GO_ON; -} - -SETDEFAULTS_FUNC(mod_status_set_defaults) { - plugin_data *p = p_d; - size_t i; - - config_values_t cv[] = { - { "status.status-url", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, - { "status.config-url", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, - { "status.enable-sort", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, - { "status.statistics-url", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, - { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } - }; - - if (!p) return HANDLER_ERROR; - - p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *)); - - for (i = 0; i < srv->config_context->used; i++) { - plugin_config *s; - - s = calloc(1, sizeof(plugin_config)); - s->config_url = buffer_init(); - s->status_url = buffer_init(); - s->sort = 1; - s->statistics_url = buffer_init(); - - cv[0].destination = s->status_url; - cv[1].destination = s->config_url; - cv[2].destination = &(s->sort); - cv[3].destination = s->statistics_url; - - p->config_storage[i] = s; - - if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) { - return HANDLER_ERROR; - } - } - - return HANDLER_GO_ON; -} - - - -static int mod_status_row_append(buffer *b, const char *key, const char *value) { - buffer_append_string_len(b, CONST_STR_LEN(" <tr>\n")); - buffer_append_string_len(b, CONST_STR_LEN(" <td><b>")); - buffer_append_string(b, key); - buffer_append_string_len(b, CONST_STR_LEN("</b></td>\n")); - buffer_append_string_len(b, CONST_STR_LEN(" <td>")); - buffer_append_string(b, value); - buffer_append_string_len(b, CONST_STR_LEN("</td>\n")); - buffer_append_string_len(b, CONST_STR_LEN(" </tr>\n")); - - return 0; -} - -static int mod_status_header_append(buffer *b, const char *key) { - buffer_append_string_len(b, CONST_STR_LEN(" <tr>\n")); - buffer_append_string_len(b, CONST_STR_LEN(" <th colspan=\"2\">")); - buffer_append_string(b, key); - buffer_append_string_len(b, CONST_STR_LEN("</th>\n")); - buffer_append_string_len(b, CONST_STR_LEN(" </tr>\n")); - - return 0; -} - -static int mod_status_header_append_sort(buffer *b, void *p_d, const char* key) { - plugin_data *p = p_d; - - if (p->conf.sort) { - buffer_append_string_len(b, CONST_STR_LEN("<th class=\"status\"><a href=\"#\" class=\"sortheader\" onclick=\"resort(this);return false;\">")); - buffer_append_string(b, key); - buffer_append_string_len(b, CONST_STR_LEN("<span class=\"sortarrow\">:</span></a></th>\n")); - } else { - buffer_append_string_len(b, CONST_STR_LEN("<th class=\"status\">")); - buffer_append_string(b, key); - buffer_append_string_len(b, CONST_STR_LEN("</th>\n")); - } - - return 0; -} - -static int mod_status_get_multiplier(double *avg, char *multiplier, int size) { - *multiplier = ' '; - - if (*avg > size) { *avg /= size; *multiplier = 'k'; } - if (*avg > size) { *avg /= size; *multiplier = 'M'; } - if (*avg > size) { *avg /= size; *multiplier = 'G'; } - if (*avg > size) { *avg /= size; *multiplier = 'T'; } - if (*avg > size) { *avg /= size; *multiplier = 'P'; } - if (*avg > size) { *avg /= size; *multiplier = 'E'; } - if (*avg > size) { *avg /= size; *multiplier = 'Z'; } - if (*avg > size) { *avg /= size; *multiplier = 'Y'; } - - return 0; -} - -static handler_t mod_status_handle_server_status_html(server *srv, connection *con, void *p_d) { - plugin_data *p = p_d; - buffer *b; - size_t j; - double avg; - char multiplier = '\0'; - char buf[128]; - time_t ts; - - int days, hours, mins, seconds; - - b = chunkqueue_get_append_buffer(con->send); - - buffer_copy_string_len(b, CONST_STR_LEN( - "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n" - "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n" - " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n" - "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n" - " <head>\n" - " <title>Status</title>\n" - - " <style type=\"text/css\">\n" - " table.status { border: black solid thin; }\n" - " td { white-space: nowrap; }\n" - " td.int { background-color: #f0f0f0; text-align: right }\n" - " td.string { background-color: #f0f0f0; text-align: left }\n" - " th.status { background-color: black; color: white; font-weight: bold; }\n" - " a.sortheader { background-color: black; color: white; font-weight: bold; text-decoration: none; display: block; }\n" - " span.sortarrow { color: white; text-decoration: none; }\n" - " </style>\n")); - - if (p->conf.sort) { - buffer_append_string_len(b, CONST_STR_LEN( - "<script type=\"text/javascript\">\n" - "// <!--\n" - "var sort_column;\n" - "var prev_span = null;\n" - - "function get_inner_text(el) {\n" - " if((typeof el == 'string')||(typeof el == 'undefined'))\n" - " return el;\n" - " if(el.innerText)\n" - " return el.innerText;\n" - " else {\n" - " var str = \"\";\n" - " var cs = el.childNodes;\n" - " var l = cs.length;\n" - " for (i=0;i<l;i++) {\n" - " if (cs[i].nodeType==1) str += get_inner_text(cs[i]);\n" - " else if (cs[i].nodeType==3) str += cs[i].nodeValue;\n" - " }\n" - " }\n" - " return str;\n" - "}\n" - - "function sortfn(a,b) {\n" - " var at = get_inner_text(a.cells[sort_column]);\n" - " var bt = get_inner_text(b.cells[sort_column]);\n" - " if (a.cells[sort_column].className == 'int') {\n" - " return parseInt(at)-parseInt(bt);\n" - " } else {\n" - " aa = at.toLowerCase();\n" - " bb = bt.toLowerCase();\n" - " if (aa==bb) return 0;\n" - " else if (aa<bb) return -1;\n" - " else return 1;\n" - " }\n" - "}\n" - - "function resort(lnk) {\n" - " var span = lnk.childNodes[1];\n" - " var table = lnk.parentNode.parentNode.parentNode.parentNode;\n" - " var rows = new Array();\n" - " for (j=1;j<table.rows.length;j++)\n" - " rows[j-1] = table.rows[j];\n" - " sort_column = lnk.parentNode.cellIndex;\n" - " rows.sort(sortfn);\n" - - " if (prev_span != null) prev_span.innerHTML = '';\n" - " if (span.getAttribute('sortdir')=='down') {\n" - " span.innerHTML = '↑';\n" - " span.setAttribute('sortdir','up');\n" - " rows.reverse();\n" - " } else {\n" - " span.innerHTML = '↓';\n" - " span.setAttribute('sortdir','down');\n" - " }\n" - " for (i=0;i<rows.length;i++)\n" - " table.tBodies[0].appendChild(rows[i]);\n" - " prev_span = span;\n" - "}\n" - "// -->\n" - "</script>\n")); - } - - buffer_append_string_len(b, CONST_STR_LEN( - " </head>\n" - " <body>\n")); - - - - /* connection listing */ - buffer_append_string_len(b, CONST_STR_LEN("<h1>Server-Status</h1>")); - - buffer_append_string_len(b, CONST_STR_LEN("<table class=\"status\" id=\"status\" summary=\"Server Status\">")); - buffer_append_string_len(b, CONST_STR_LEN("<tr><td>Hostname</td><td class=\"string\"><span id=\"host_addr\">")); - buffer_append_string_buffer(b, con->uri.authority); - buffer_append_string_len(b, CONST_STR_LEN("</span> (<span id=\"host_name\">")); - buffer_append_string_buffer(b, con->server_name); - buffer_append_string_len(b, CONST_STR_LEN("</span>)</td></tr>\n")); - buffer_append_string_len(b, CONST_STR_LEN("<tr><td>Uptime</td><td class=\"string\" id=\"uptime\">")); - - ts = srv->cur_ts - srv->startup_ts; - - days = ts / (60 * 60 * 24); - ts %= (60 * 60 * 24); - - hours = ts / (60 * 60); - ts %= (60 * 60); - - mins = ts / (60); - ts %= (60); - - seconds = ts; - - if (days) { - buffer_append_long(b, days); - buffer_append_string_len(b, CONST_STR_LEN(" days ")); - } - - if (hours) { - buffer_append_long(b, hours); - buffer_append_string_len(b, CONST_STR_LEN(" hours ")); - } - - if (mins) { - buffer_append_long(b, mins); - buffer_append_string_len(b, CONST_STR_LEN(" min ")); - } - - buffer_append_long(b, seconds); - 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("<tr><td>Started at</td><td class=\"string\">")); - - ts = srv->startup_ts; - - strftime(buf, sizeof(buf) - 1, "<span id=\"start_date\">%Y-%m-%d</span> <span id=\"start_time\">%H:%M:%S</span>", localtime(&ts)); - buffer_append_string(b, buf); - buffer_append_string_len(b, CONST_STR_LEN("</td></tr>\n")); - - - buffer_append_string_len(b, CONST_STR_LEN("<tr><th colspan=\"2\">absolute (since start)</th></tr>\n")); - - buffer_append_string_len(b, CONST_STR_LEN("<tr><td>Requests</td><td class=\"string\" ><span id=\"requests\">")); - avg = p->abs_requests; - - mod_status_get_multiplier(&avg, &multiplier, 1000); - - buffer_append_long(b, avg); - buffer_append_string_len(b, CONST_STR_LEN("</span> <span id=\"requests_mult\">")); - if (multiplier) buffer_append_string_len(b, &multiplier, 1); - buffer_append_string_len(b, CONST_STR_LEN("</span>req</td></tr>\n")); - - buffer_append_string_len(b, CONST_STR_LEN("<tr><td>Traffic</td><td class=\"string\"><span id=\"traffic\">")); - avg = p->abs_traffic_out; - - mod_status_get_multiplier(&avg, &multiplier, 1024); - - sprintf(buf, "%.2f", avg); - buffer_append_string(b, buf); - buffer_append_string_len(b, CONST_STR_LEN("</span> <span id=\"traffic_mult\">")); - if (multiplier) buffer_append_string_len(b, &multiplier, 1); - buffer_append_string_len(b, CONST_STR_LEN("</span>byte</td></tr>\n")); - - - - buffer_append_string_len(b, CONST_STR_LEN("<tr><th colspan=\"2\">average (since start)</th></tr>\n")); - - buffer_append_string_len(b, CONST_STR_LEN("<tr><td>Requests</td><td class=\"string\"><span id=\"requests_avg\">")); - avg = p->abs_requests / (srv->cur_ts - srv->startup_ts); - - mod_status_get_multiplier(&avg, &multiplier, 1000); - - buffer_append_long(b, avg); - buffer_append_string_len(b, CONST_STR_LEN("</span> <span id=\"requests_avg_mult\">")); - if (multiplier) buffer_append_string_len(b, &multiplier, 1); - buffer_append_string_len(b, CONST_STR_LEN("</span>req/s</td></tr>\n")); - - buffer_append_string_len(b, CONST_STR_LEN("<tr><td>Traffic</td><td class=\"string\"><span id=\"traffic_avg\">")); - avg = p->abs_traffic_out / (srv->cur_ts - srv->startup_ts); - - mod_status_get_multiplier(&avg, &multiplier, 1024); - - sprintf(buf, "%.2f", avg); - buffer_append_string(b, buf); - buffer_append_string_len(b, CONST_STR_LEN("</span> <span id=\"traffic_avg_mult\">")); - if (multiplier) buffer_append_string_len(b, &multiplier, 1); - buffer_append_string_len(b, CONST_STR_LEN("</span>byte/s</td></tr>\n")); - - - - buffer_append_string_len(b, CONST_STR_LEN("<tr><th colspan=\"2\">average (5s sliding average)</th></tr>\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("<tr><td>Requests</td><td class=\"string\"><span id=\"requests_sliding_avg\">")); - - mod_status_get_multiplier(&avg, &multiplier, 1000); - - buffer_append_long(b, avg); - buffer_append_string_len(b, CONST_STR_LEN("</span> <span id=\"requests_sliding_avg_mult\">")); - if (multiplier) buffer_append_string_len(b, &multiplier, 1); - - buffer_append_string_len(b, CONST_STR_LEN("</span>req/s</td></tr>\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("<tr><td>Traffic</td><td class=\"string\"><span id=\"requests_sliding_traffic\">")); - - mod_status_get_multiplier(&avg, &multiplier, 1024); - - sprintf(buf, "%.2f", avg); - buffer_append_string(b, buf); - buffer_append_string_len(b, CONST_STR_LEN("</span> <span id=\"requests_sliding_traffic_mult\">")); - if (multiplier) buffer_append_string_len(b, &multiplier, 1); - buffer_append_string_len(b, CONST_STR_LEN("</span>byte/s</td></tr>\n")); - - buffer_append_string_len(b, CONST_STR_LEN("</table>\n")); - - - buffer_append_string_len(b, CONST_STR_LEN("<hr />\n<pre><b>legend</b>\n")); - buffer_append_string_len(b, CONST_STR_LEN(". = connect, C = close, E = hard error\n")); - buffer_append_string_len(b, CONST_STR_LEN("r = read, R = read-POST, W = write, h = handle-request\n")); - buffer_append_string_len(b, CONST_STR_LEN("q = request-start, Q = request-end\n")); - buffer_append_string_len(b, CONST_STR_LEN("s = response-start, S = response-end\n")); - - buffer_append_string_len(b, CONST_STR_LEN("<strong><span id=\"connections\">")); - buffer_append_long(b, srv->conns->used); - buffer_append_string_len(b, CONST_STR_LEN("</span> connections</strong>\n")); - - for (j = 0; j < srv->conns->used; j++) { - connection *c = srv->conns->ptr[j]; - const char *state = connection_get_short_state(c->state); - - buffer_append_string_len(b, state, 1); - - if (((j + 1) % 50) == 0) { - buffer_append_string_len(b, CONST_STR_LEN("\n")); - } - } - - buffer_append_string_len(b, CONST_STR_LEN("\n</pre><hr />\n<h2>Connections</h2>\n")); - - buffer_append_string_len(b, CONST_STR_LEN("<table class=\"status\" summary=\"Current connections\" id=\"clients\">\n")); - buffer_append_string_len(b, CONST_STR_LEN("<tr>")); - mod_status_header_append_sort(b, p_d, "Client IP"); - mod_status_header_append_sort(b, p_d, "Read"); - mod_status_header_append_sort(b, p_d, "Written"); - mod_status_header_append_sort(b, p_d, "State"); - mod_status_header_append_sort(b, p_d, "Time"); - mod_status_header_append_sort(b, p_d, "Host"); - mod_status_header_append_sort(b, p_d, "URI"); - mod_status_header_append_sort(b, p_d, "File"); - buffer_append_string_len(b, CONST_STR_LEN("</tr>\n")); - - for (j = 0; j < srv->conns->used; j++) { - connection *c = srv->conns->ptr[j]; - - buffer_append_string_len(b, CONST_STR_LEN("<tr><td class=\"string ip\">")); - - buffer_append_string(b, inet_ntop_cache_get_ip(srv, &(c->dst_addr))); - - buffer_append_string_len(b, CONST_STR_LEN("</td><td class=\"int bytes_read\">")); - - if (c->request.content_length != -1) { - buffer_append_long(b, c->recv->bytes_in); - buffer_append_string_len(b, CONST_STR_LEN("/")); - buffer_append_long(b, c->request.content_length); - } else { - buffer_append_string_len(b, CONST_STR_LEN("0/0")); - } - - buffer_append_string_len(b, CONST_STR_LEN("</td><td class=\"int bytes_written\">")); - - buffer_append_off_t(b, c->send_raw->bytes_out); - buffer_append_string_len(b, CONST_STR_LEN("/")); - buffer_append_off_t(b, c->send_raw->bytes_in); - - buffer_append_string_len(b, CONST_STR_LEN("</td><td class=\"string state\">")); - - buffer_append_string(b, connection_get_state(c->state)); - - buffer_append_string_len(b, CONST_STR_LEN("</td><td class=\"int time\">")); - - buffer_append_long(b, srv->cur_ts - c->request_start); - - buffer_append_string_len(b, CONST_STR_LEN("</td><td class=\"string host\">")); - - if (buffer_is_empty(c->server_name)) { - buffer_append_string_buffer(b, c->uri.authority); - } - else { - buffer_append_string_buffer(b, c->server_name); - } - - buffer_append_string_len(b, CONST_STR_LEN("</td><td class=\"string uri\">")); - - if (!buffer_is_empty(c->uri.path)) { - buffer_append_string_encoded(b, CONST_BUF_LEN(c->uri.path), ENCODING_HTML); - } - - if (!buffer_is_empty(c->uri.query)) { - buffer_append_string_len(b, CONST_STR_LEN("?")); - buffer_append_string_encoded(b, CONST_BUF_LEN(c->uri.query), ENCODING_HTML); - } - - if (!buffer_is_empty(c->request.orig_uri)) { - 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_len(b, CONST_STR_LEN(")")); - } - buffer_append_string_len(b, CONST_STR_LEN("</td><td class=\"string file\">")); - - buffer_append_string_buffer(b, c->physical.path); - - buffer_append_string_len(b, CONST_STR_LEN("</td></tr>\n")); - } - - - buffer_append_string_len(b, CONST_STR_LEN( - "</table>\n" - - " </body>\n" - "</html>\n" - )); - - response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html")); - con->send->bytes_in += b->used-1; - - return 0; -} - - -static handler_t mod_status_handle_server_status_text(server *srv, connection *con, void *p_d) { - plugin_data *p = p_d; - buffer *b; - double avg; - time_t ts; - size_t j; - unsigned int k; - unsigned int l; - - b = chunkqueue_get_append_buffer(con->send); - - /* output total number of requests */ - buffer_append_string_len(b, CONST_STR_LEN("Total Accesses: ")); - avg = p->abs_requests; - buffer_append_long(b, avg); - buffer_append_string_len(b, CONST_STR_LEN("\n")); - - /* output total traffic out in kbytes */ - buffer_append_string_len(b, CONST_STR_LEN("Total kBytes: ")); - avg = p->abs_traffic_out / 1024; - buffer_append_long(b, avg); - buffer_append_string_len(b, CONST_STR_LEN("\n")); - - /* output uptime */ - buffer_append_string_len(b, CONST_STR_LEN("Uptime: ")); - ts = srv->cur_ts - srv->startup_ts; - buffer_append_long(b, ts); - buffer_append_string_len(b, CONST_STR_LEN("\n")); - - /* output busy servers */ - buffer_append_string_len(b, CONST_STR_LEN("BusyServers: ")); - buffer_append_long(b, srv->conns->used); - buffer_append_string_len(b, CONST_STR_LEN("\n")); - - buffer_append_string_len(b, CONST_STR_LEN("IdleServers: ")); - buffer_append_long(b, srv->conns->size - srv->conns->used); - buffer_append_string_len(b, CONST_STR_LEN("\n")); - - /* output traffic */ - buffer_append_string_len(b, CONST_STR_LEN("Traffic: ")); - avg = p->abs_traffic_out / (srv->cur_ts - srv->startup_ts); - buffer_append_long(b, avg); - buffer_append_string_len(b, CONST_STR_LEN("\n")); - - /* output traffic 5s */ - buffer_append_string_len(b, CONST_STR_LEN("Traffic5s: ")); - for (j = 0, avg = 0; j < 5; j++) { - avg += p->mod_5s_traffic_out[j]; - } - avg /= 5; - buffer_append_long(b, avg); - buffer_append_string_len(b, CONST_STR_LEN("\n")); - - /* output scoreboard */ - buffer_append_string_len(b, CONST_STR_LEN("Scoreboard: ")); - for (k = 0; k < srv->conns->used; k++) { - connection *c = srv->conns->ptr[k]; - const char *state = connection_get_short_state(c->state); - buffer_append_string_len(b, state, 1); - } - for (l = 0; l < srv->conns->size - srv->conns->used; l++) { - buffer_append_string_len(b, CONST_STR_LEN("_")); - } - buffer_append_string_len(b, CONST_STR_LEN("\n")); - - /* set text/plain output */ - - response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/plain")); - con->send->bytes_in += b->used-1; - - return 0; -} - -static handler_t mod_status_handle_server_statistics(server *srv, connection *con, void *p_d) { - buffer *b; - size_t i; - array *st = status_counter_get_array(); - - UNUSED(p_d); - - if (0 == st->used) { - /* we have nothing to send */ - con->http_status = 204; - con->send->is_closed = 1; - - return HANDLER_FINISHED; - } - - b = chunkqueue_get_append_buffer(con->send); - - for (i = 0; i < st->used; i++) { - size_t ndx = st->sorted[i]; - - buffer_append_string_buffer(b, st->data[ndx]->key); - buffer_append_string_len(b, CONST_STR_LEN(": ")); - buffer_append_long(b, ((data_integer *)(st->data[ndx]))->value); - buffer_append_string_len(b, CONST_STR_LEN("\n")); - } - - response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/plain")); - - con->http_status = 200; - con->send->bytes_in += b->used-1; - con->send->is_closed = 1; - - return HANDLER_FINISHED; -} - - -static handler_t mod_status_handle_server_status(server *srv, connection *con, void *p_d) { - - if (buffer_is_equal_string(con->uri.query, CONST_STR_LEN("auto"))) { - mod_status_handle_server_status_text(srv, con, p_d); - } else { - mod_status_handle_server_status_html(srv, con, p_d); - } - - con->http_status = 200; - con->send->is_closed = 1; - - return HANDLER_FINISHED; -} - - -static handler_t mod_status_handle_server_config(server *srv, connection *con, void *p_d) { - plugin_data *p = p_d; - buffer *b, *tmp_buf = p->tmp_buf; - size_t i; - const fdevent_handler_info_t *handler; - const network_backend_info_t *backend; - - b = chunkqueue_get_append_buffer(con->send); - - BUFFER_COPY_STRING_CONST(b, - "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n" - "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n" - " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n" - "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n" - " <head>\n" - " <title>Status</title>\n" - " </head>\n" - " <body>\n" - " <h1>" PACKAGE_NAME " " PACKAGE_VERSION "</h1>\n" - " <table summary=\"status\" border=\"1\">\n"); - - mod_status_header_append(b, "Server-Features"); -#ifdef HAVE_PCRE_H - mod_status_row_append(b, "RegEx Conditionals", "enabled"); -#else - mod_status_row_append(b, "RegEx Conditionals", "disabled - pcre missing"); -#endif - mod_status_header_append(b, "Network Engine"); - - mod_status_row_append(b, "fd-Event-Handler", fdevent_get_handler_info_by_type(srv->event_handler)->name); - buffer_reset(tmp_buf); - for (handler = fdevent_get_handlers(); handler->name; handler++) { - if (handler->init) { - buffer_append_string_len(tmp_buf, CONST_STR_LEN("+ ")); - } else { - buffer_append_string_len(tmp_buf, CONST_STR_LEN("- ")); - } - - buffer_append_string(tmp_buf, handler->name); - buffer_append_string_len(tmp_buf, CONST_STR_LEN("<br />")); - } - mod_status_row_append(b, "Supported fd-Event-Handlers", tmp_buf->ptr); - - mod_status_row_append(b, "Network-Backend", network_get_backend_info_by_type(srv->network_backend)->name); - buffer_reset(tmp_buf); - for (backend = network_get_backends(); backend->name; backend++) { - if (backend->write_handler) { - buffer_append_string_len(tmp_buf, CONST_STR_LEN("+ ")); - } else { - buffer_append_string_len(tmp_buf, CONST_STR_LEN("- ")); - } - - buffer_append_string(tmp_buf, backend->name); - buffer_append_string_len(tmp_buf, CONST_STR_LEN("<br />")); - } -#ifdef USE_MMAP - buffer_append_string_len(tmp_buf, CONST_STR_LEN("+ (mmap)<br />")); -#else - buffer_append_string_len(tmp_buf, CONST_STR_LEN("- (mmap)<br />")); -#endif - mod_status_row_append(b, "Supported Network-Backends", tmp_buf->ptr); - - mod_status_header_append(b, "Config-File-Settings"); - - buffer_reset(tmp_buf); - for (i = 0; i < srv->plugins.used; i++) { - plugin **ps = srv->plugins.ptr; - - plugin *pl = ps[i]; - - if (i == 0) { - buffer_copy_string_buffer(tmp_buf, pl->name); - } else { - buffer_append_string_len(tmp_buf, CONST_STR_LEN("<br />")); - buffer_append_string_buffer(tmp_buf, pl->name); - } - } - - mod_status_row_append(b, "Loaded Modules", tmp_buf->ptr); - - buffer_append_string_len(b, CONST_STR_LEN(" </table>\n")); - - buffer_append_string_len(b, CONST_STR_LEN( - " </body>\n" - "</html>\n" - )); - - response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html")); - - con->http_status = 200; - con->send->bytes_in += b->used-1; - con->send->is_closed = 1; - - return HANDLER_FINISHED; -} - -static int mod_status_patch_connection(server *srv, connection *con, plugin_data *p) { - size_t i, j; - plugin_config *s = p->config_storage[0]; - - PATCH_OPTION(status_url); - PATCH_OPTION(config_url); - PATCH_OPTION(sort); - PATCH_OPTION(statistics_url); - - /* skip the first, the global context */ - for (i = 1; i < srv->config_context->used; i++) { - data_config *dc = (data_config *)srv->config_context->data[i]; - s = p->config_storage[i]; - - /* condition didn't match */ - if (!config_check_cond(srv, con, dc)) continue; - - /* merge config */ - for (j = 0; j < dc->value->used; j++) { - data_unset *du = dc->value->data[j]; - - if (buffer_is_equal_string(du->key, CONST_STR_LEN("status.status-url"))) { - PATCH_OPTION(status_url); - } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("status.config-url"))) { - PATCH_OPTION(config_url); - } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("status.enable-sort"))) { - PATCH_OPTION(sort); - } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("status.statistics-url"))) { - PATCH_OPTION(statistics_url); - } - } - } - - return 0; -} - -static handler_t mod_status_handler(server *srv, connection *con, void *p_d) { - plugin_data *p = p_d; - - mod_status_patch_connection(srv, con, p); - - if (!buffer_is_empty(p->conf.status_url) && - buffer_is_equal(p->conf.status_url, con->uri.path)) { - return mod_status_handle_server_status(srv, con, p_d); - } else if (!buffer_is_empty(p->conf.config_url) && - buffer_is_equal(p->conf.config_url, con->uri.path)) { - return mod_status_handle_server_config(srv, con, p_d); - } else if (!buffer_is_empty(p->conf.statistics_url) && - buffer_is_equal(p->conf.statistics_url, con->uri.path)) { - return mod_status_handle_server_statistics(srv, con, p_d); - } - - return HANDLER_GO_ON; -} - -TRIGGER_FUNC(mod_status_trigger) { - plugin_data *p = p_d; - size_t i; - - /* check all connections */ - for (i = 0; i < srv->conns->used; i++) { - connection *c = srv->conns->ptr[i]; - - p->bytes_written += c->bytes_written_cur_second; - } - - /* a sliding average */ - p->mod_5s_traffic_out[p->mod_5s_ndx] = p->bytes_written; - p->mod_5s_requests [p->mod_5s_ndx] = p->requests; - - p->mod_5s_ndx = (p->mod_5s_ndx+1) % 5; - - p->abs_traffic_out += p->bytes_written; - p->rel_traffic_out += p->bytes_written; - - p->bytes_written = 0; - - /* reset storage - second */ - p->traffic_out = 0; - p->requests = 0; - - return HANDLER_GO_ON; -} - -REQUESTDONE_FUNC(mod_status_account) { - plugin_data *p = p_d; - - UNUSED(srv); - - p->requests++; - p->rel_requests++; - p->abs_requests++; - - p->bytes_written += con->bytes_written_cur_second; - - return HANDLER_GO_ON; -} - -LI_EXPORT int mod_status_plugin_init(plugin *p); -LI_EXPORT int mod_status_plugin_init(plugin *p) { - p->version = LIGHTTPD_VERSION_ID; - p->name = buffer_init_string("status"); - - p->init = mod_status_init; - p->cleanup = mod_status_free; - p->set_defaults= mod_status_set_defaults; - - p->handle_uri_clean = mod_status_handler; - p->handle_trigger = mod_status_trigger; - p->handle_response_done = mod_status_account; - - p->data = NULL; - - return 0; -} |