/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* Cherokee * * Authors: * Alvaro Lopez Ortega * * Copyright (C) 2001-2007 Alvaro Lopez Ortega * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public * License as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA */ #include "common-internal.h" #include "handler_server_info.h" #ifdef HAVE_SYS_UTSNAME_H # include #endif #include "util.h" #include "connection.h" #include "connection-protected.h" #include "server.h" #include "server-protected.h" #include "plugin_loader.h" #define PAGE_HEADER \ "" CRLF\ "
" CRLF\ "" CRLF\ "" CRLF\ "Cherokee Web Server Info
" CRLF\ "
" CRLF\ "" CRLF\ " " CRLF\ "
" CRLF\ " " CRLF\ " \"Cherokee" CRLF\ "

%s

" CRLF\ "

" #define AUTHOR \ "Alvaro Lopez Ortega <alvaro@alobbs.com>" #define LICENSE \ "

Copyright (C) 2001, 2002, 2003, 2004, 2005 " AUTHOR "

" CRLF\ "

This program is free software; you can redistribute it and/or" CRLF\ "modify it under the terms of version 2 of the GNU General Public" CRLF\ "License as published by the Free Software Foundation.

" CRLF\ "

This program is distributed in the hope that it will be useful," CRLF\ "but WITHOUT ANY WARRANTY; without even the implied warranty of" CRLF\ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the" CRLF\ "GNU General Public License for more details.

" CRLF\ "

You should have received a copy of the GNU General Public License" CRLF\ "along with this program; if not, write to the Free Software" CRLF\ "Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

" #define PAGE_FOOT CRLF\ "

Cherokee License

" CRLF\ "" CRLF\ "" CRLF\ "
" LICENSE CRLF\ "

" CRLF\ "
" /* Plug-in initialization */ PLUGIN_INFO_HANDLER_EASIEST_INIT (server_info, http_get); /* Methods implementation */ static ret_t props_free (cherokee_handler_server_info_props_t *props) { return cherokee_module_props_free_base (MODULE_PROPS(props)); } ret_t cherokee_handler_server_info_configure (cherokee_config_node_t *conf, cherokee_server_t *srv, cherokee_module_props_t **_props) { cherokee_list_t *i; cherokee_handler_server_info_props_t *props; if (*_props == NULL) { CHEROKEE_NEW_STRUCT (n, handler_server_info_props); cherokee_module_props_init_base (MODULE_PROPS(n), MODULE_PROPS_FREE(props_free)); n->just_about = false; *_props = MODULE_PROPS(n); } props = PROP_SRV_INFO(*_props); cherokee_config_node_foreach (i, conf) { cherokee_config_node_t *subconf = CONFIG_NODE(i); if (equal_buf_str (&subconf->key, "just_about")) { props->just_about = atoi(subconf->val.buf); } else { PRINT_MSG ("ERROR: Handler file: Unknown key: '%s'\n", subconf->key.buf); return ret_error; } } return ret_ok; } static void server_info_add_table (cherokee_buffer_t *buf, char *name, char *a_name, cherokee_buffer_t *content) { cherokee_buffer_add_va (buf, "

%s

", a_name, name); cherokee_buffer_add_str (buf, ""); cherokee_buffer_add_buffer (buf, content); cherokee_buffer_add_str (buf, "

"); } static void table_add_row_str (cherokee_buffer_t *buf, const char *name, const char *value) { cherokee_buffer_add_va (buf, "%s%s"CRLF, name, value); } static void table_add_row_int (cherokee_buffer_t *buf, char *name, int value) { cherokee_buffer_add_va (buf, "%s%d"CRLF, name, value); } static void add_uptime_row (cherokee_buffer_t *buf, cherokee_server_t *srv) { unsigned int elapse = srv->bogo_now - srv->start_time; unsigned int days; unsigned int hours; unsigned int mins; cherokee_buffer_t *tmp; cherokee_buffer_new (&tmp); days = elapse / (60*60*24); elapse %= (60*60*24); hours = elapse / (60*60); elapse %= (60*60); mins = elapse / 60; elapse %= 60; if (days > 0) { cherokee_buffer_add_va (tmp, "%d Day%s, %d Hour%s, %d Minute%s, %d Seconds", days, days>1?"s":"", hours, hours>1?"s":"", mins, mins>1?"s":"", elapse); } else if (hours > 0) { cherokee_buffer_add_va (tmp, "%d Hour%s, %d Minute%s, %d Seconds", hours, hours>1?"s":"", mins, mins>1?"s":"", elapse); } else if (mins > 0) { cherokee_buffer_add_va (tmp, "%d Minute%s, %d Seconds", mins, mins>1?"s":"", elapse); } else { cherokee_buffer_add_va (tmp, "%d Seconds", elapse); } table_add_row_str (buf, "Uptime", tmp->buf); cherokee_buffer_free (tmp); } static void add_data_sent_row (cherokee_buffer_t *buf, cherokee_server_t *srv) { size_t rx, tx; char tmp[5]; cherokee_server_get_total_traffic (srv, &rx, &tx); cherokee_strfsize (tx, tmp); table_add_row_str (buf, "Data sent", tmp); cherokee_strfsize (rx, tmp); table_add_row_str (buf, "Data received", tmp); } static void build_general_table_content (cherokee_buffer_t *buf, cherokee_server_t *srv) { add_uptime_row (buf, srv); add_data_sent_row (buf, srv); } static void build_server_table_content (cherokee_buffer_t *buf, cherokee_server_t *srv) { const char *on = "On"; const char *off = "Off"; table_add_row_int (buf, "Thread Number ", srv->thread_num); table_add_row_str (buf, "IPv6 ", (srv->ipv6 == 1) ? on : off); table_add_row_str (buf, "TLS support ", (SOCKET_FD(&srv->socket_tls) != -1) ? on : off); table_add_row_int (buf, "TLS port ", SOCKET_FD(&srv->port_tls)); table_add_row_str (buf, "Chroot ", (srv->chrooted) ? on : off); table_add_row_int (buf, "User ID", getuid()); table_add_row_int (buf, "Group ID", getgid()); #ifdef HAVE_SYS_UTSNAME { int rc; struct utsname buf; rc = uname ((struct utsname *)&buf); if (rc >= 0) { table_add_row_str (buf, "Operating system", buf.sysname); } } #endif } static void build_connections_table_content (cherokee_buffer_t *buf, cherokee_server_t *srv) { cuint_t conns_num = 0; cuint_t active = 0; cuint_t reusable = 0; cherokee_server_get_conns_num (srv, &conns_num); cherokee_server_get_active_conns (srv, &active); cherokee_server_get_reusable_conns (srv, &reusable); table_add_row_int (buf, "Open connections", conns_num); table_add_row_int (buf, "Active connections", active); table_add_row_int (buf, "Reusable connections", reusable); } static int build_modules_table_content_while (cherokee_buffer_t *key, void *value, void *params[]) { int *loggers = (int *) params[2]; int *handlers = (int *) params[3]; int *encoders = (int *) params[4]; int *validators = (int *) params[5]; int *generic = (int *) params[6]; int *balancer = (int *) params[7]; cherokee_plugin_loader_entry_t *entry = value; cherokee_plugin_info_t *mod = entry->info; if (mod->type & cherokee_logger) { *loggers += 1; } else if (mod->type & cherokee_handler) { *handlers += 1; } else if (mod->type & cherokee_encoder) { *encoders += 1; } else if (mod->type & cherokee_validator) { *validators += 1; } else if (mod->type & cherokee_generic) { *generic += 1; } else if (mod->type & cherokee_balancer) { *balancer += 1; } else { PRINT_ERROR("Unknown module type (%d)\n", mod->type); } return 0; } static void build_modules_table_content (cherokee_buffer_t *buf, cherokee_server_t *srv) { cuint_t loggers = 0; cuint_t handlers = 0; cuint_t encoders = 0; cuint_t validators = 0; cuint_t generic = 0; cuint_t balancers = 0; void *params[] = {buf, srv, &loggers, &handlers, &encoders, &validators, &generic, &balancers}; cherokee_avl_while (&srv->loader.table, (cherokee_avl_while_func_t) build_modules_table_content_while, params, NULL, NULL); table_add_row_int (buf, "Loggers", loggers); table_add_row_int (buf, "Handlers", handlers); table_add_row_int (buf, "Encoders", encoders); table_add_row_int (buf, "Validators", validators); table_add_row_int (buf, "Balancers", balancers); table_add_row_int (buf, "Generic", generic); } static ret_t server_info_build_logo (cherokee_handler_server_info_t *hdl) { ret_t ret; cherokee_buffer_t *buffer; buffer = &hdl->buffer; #include "logo.inc" return ret_ok; } static void build_icons_table_content (cherokee_buffer_t *buf, cherokee_server_t *srv) { table_add_row_str (buf, "Default icon", (srv->icons->default_icon.len > 0) ? srv->icons->default_icon.buf : ""); table_add_row_str (buf, "Directory icon", (srv->icons->directory_icon.len > 0) ? srv->icons->directory_icon.buf : ""); table_add_row_str (buf, "Parent directory icon", (srv->icons->parentdir_icon.len > 0) ? srv->icons->parentdir_icon.buf : ""); } static void server_info_build_page (cherokee_handler_server_info_t *hdl) { cherokee_server_t *srv; cherokee_buffer_t *buf; cherokee_buffer_t *table; cherokee_buffer_t ver = CHEROKEE_BUF_INIT; /* Init */ buf = &hdl->buffer; srv = HANDLER_SRV(hdl); /* Add the page begining */ cherokee_version_add (&ver, HANDLER_SRV(hdl)->server_token); cherokee_buffer_add_va (buf, PAGE_HEADER, ver.buf); if (! HDL_SRV_INFO_PROPS(hdl)->just_about) { /* General table */ cherokee_buffer_new (&table); build_general_table_content (table, srv); server_info_add_table (buf, "General Information", "general", table); /* Server table */ cherokee_buffer_clean (table); build_server_table_content (table, srv); server_info_add_table (buf, "Server Core", "server_core", table); /* Connections table */ cherokee_buffer_clean (table); build_connections_table_content (table, srv); server_info_add_table (buf, "Current connections", "connections", table); /* Modules table */ cherokee_buffer_clean (table); build_modules_table_content (table, srv); server_info_add_table (buf, "Modules", "modules", table); /* Icons */ cherokee_buffer_clean (table); build_icons_table_content (table, srv); server_info_add_table (buf, "Icons", "icons", table); cherokee_buffer_free (table); } /* Add the page ending */ cherokee_buffer_add_str (buf, PAGE_FOOT); cherokee_buffer_mrproper (&ver); } ret_t cherokee_handler_server_info_new (cherokee_handler_t **hdl, cherokee_connection_t *cnt, cherokee_module_props_t *props) { CHEROKEE_NEW_STRUCT (n, handler_server_info); /* Init the base class object */ cherokee_handler_init_base(HANDLER(n), cnt, HANDLER_PROPS(props), PLUGIN_INFO_HANDLER_PTR(server_info)); MODULE(n)->init = (handler_func_init_t) cherokee_handler_server_info_init; MODULE(n)->free = (module_func_free_t) cherokee_handler_server_info_free; HANDLER(n)->step = (handler_func_step_t) cherokee_handler_server_info_step; HANDLER(n)->add_headers = (handler_func_add_headers_t) cherokee_handler_server_info_add_headers; HANDLER(n)->support = hsupport_length | hsupport_range; /* Init */ cherokee_buffer_init (&n->buffer); cherokee_buffer_ensure_size (&n->buffer, 4*1024); *hdl = HANDLER(n); return ret_ok; } ret_t cherokee_handler_server_info_free (cherokee_handler_server_info_t *hdl) { cherokee_buffer_mrproper (&hdl->buffer); return ret_ok; } ret_t cherokee_handler_server_info_init (cherokee_handler_server_info_t *hdl) { ret_t ret; void *param; cint_t web_interface = 1; cherokee_connection_parse_args (HANDLER_CONN(hdl)); ret = cherokee_avl_get_ptr (HANDLER_CONN(hdl)->arguments, "logo", ¶m); if (ret == ret_ok) { /* Build the logo */ server_info_build_logo (hdl); hdl->action = send_logo; return ret_ok; } /* Build the page */ if (web_interface) { server_info_build_page (hdl); } hdl->action = send_page; return ret_ok; } ret_t cherokee_handler_server_info_step (cherokee_handler_server_info_t *hdl, cherokee_buffer_t *buffer) { cherokee_buffer_add_buffer (buffer, &hdl->buffer); return ret_eof_have_data; } ret_t cherokee_handler_server_info_add_headers (cherokee_handler_server_info_t *hdl, cherokee_buffer_t *buffer) { cherokee_buffer_add_va (buffer, "Content-length: %d"CRLF, hdl->buffer.len); switch (hdl->action) { case send_logo: cherokee_buffer_add_str (buffer, "Content-Type: image/gif"CRLF); break; case send_page: default: cherokee_buffer_add_str (buffer, "Content-Type: text/html"CRLF); break; } return ret_ok; }