Commit ea6dd695 authored by Philipp Schafft's avatar Philipp Schafft 🦁

Feature: Added new admin command publicstats with a public view of the stats

parent 7a3eb6f5
......@@ -108,7 +108,7 @@ acl_t *acl_new(void)
acl_set_method_str(ret, ACL_POLICY_ALLOW, "get,options");
acl_set_admin_str(ret, ACL_POLICY_DENY, "*");
acl_set_admin_str(ret, ACL_POLICY_ALLOW, "buildm3u");
acl_set_admin_str(ret, ACL_POLICY_ALLOW, "buildm3u,publicstats,publicstats.json");
acl_set_web_policy(ret, ACL_POLICY_ALLOW);
......
......@@ -78,6 +78,8 @@
#define STATS_RAW_REQUEST "stats"
#define STATS_HTML_REQUEST "stats.xsl"
#define STATS_JSON_REQUEST "stats.json"
#define PUBLICSTATS_RAW_REQUEST "publicstats"
#define PUBLICSTATS_JSON_REQUEST "publicstats.json"
#define QUEUE_RELOAD_RAW_REQUEST "reloadconfig"
#define QUEUE_RELOAD_HTML_REQUEST "reloadconfig.xsl"
#define QUEUE_RELOAD_JSON_REQUEST "reloadconfig.json"
......@@ -129,6 +131,7 @@ static void command_metadata (client_t *client, source_t *source, adm
static void command_shoutcast_metadata (client_t *client, source_t *source, admin_format_t response);
static void command_show_listeners (client_t *client, source_t *source, admin_format_t response);
static void command_stats (client_t *client, source_t *source, admin_format_t response);
static void command_public_stats (client_t *client, source_t *source, admin_format_t response);
static void command_queue_reload (client_t *client, source_t *source, admin_format_t response);
static void command_list_mounts (client_t *client, source_t *source, admin_format_t response);
static void command_move_clients (client_t *client, source_t *source, admin_format_t response);
......@@ -157,6 +160,8 @@ static const admin_command_handler_t handlers[] = {
{ STATS_HTML_REQUEST, ADMINTYPE_HYBRID, ADMIN_FORMAT_HTML, command_stats, NULL},
{ STATS_JSON_REQUEST, ADMINTYPE_HYBRID, ADMIN_FORMAT_JSON, command_stats, NULL},
{ "stats.xml", ADMINTYPE_HYBRID, ADMIN_FORMAT_RAW, command_stats, NULL},
{ PUBLICSTATS_RAW_REQUEST, ADMINTYPE_HYBRID, ADMIN_FORMAT_RAW, command_public_stats, NULL},
{ PUBLICSTATS_JSON_REQUEST, ADMINTYPE_HYBRID, ADMIN_FORMAT_JSON, command_public_stats, NULL},
{ QUEUE_RELOAD_RAW_REQUEST, ADMINTYPE_GENERAL, ADMIN_FORMAT_RAW, command_queue_reload, NULL},
{ QUEUE_RELOAD_HTML_REQUEST, ADMINTYPE_GENERAL, ADMIN_FORMAT_HTML, command_queue_reload, NULL},
{ QUEUE_RELOAD_JSON_REQUEST, ADMINTYPE_GENERAL, ADMIN_FORMAT_JSON, command_queue_reload, NULL},
......@@ -1260,6 +1265,15 @@ static void command_stats(client_t *client, source_t *source, admin_format_t res
return;
}
static void command_public_stats (client_t *client, source_t *source, admin_format_t response)
{
const char *mount = (source) ? source->mount : NULL;
xmlDocPtr doc = stats_get_xml(STATS_XML_FLAG_PUBLIC_VIEW, mount, client);
admin_send_response(doc, client, response, STATS_HTML_REQUEST);
xmlFreeDoc(doc);
return;
}
static void command_queue_reload(client_t *client, source_t *source, admin_format_t response)
{
global_lock();
......
......@@ -838,15 +838,37 @@ static inline void __add_authstack (auth_stack_t *stack, xmlNodePtr parent) {
auth_stack_next(&stack);
}
}
static inline int __is_in_list(const char *key, const char *list[])
{
size_t i;
for (i = 0; list[i]; i++)
if (strcmp(key, list[i]) == 0)
return 1;
return 0;
}
static inline int __include_node(unsigned int flags, const char *key, const char *list[])
{
return !(flags & STATS_XML_FLAG_PUBLIC_VIEW) || __is_in_list(key, list);
}
static xmlNodePtr _dump_stats_to_doc (xmlNodePtr root, unsigned int flags, const char *show_mount, client_t *client) {
static const char *public_keys_global[] = {"admin", "location", "host", "server_id", "server_start_iso8601", NULL};
static const char *public_keys_source[] = {"listeners", "server_name", "server_description", "stream_start_iso8601", "subtype", "content-type", "listenurl", "genre", NULL};
int hidden = flags & STATS_XML_FLAG_SHOW_HIDDEN ? 1 : 0;
avl_node *avlnode;
xmlNodePtr ret = NULL;
ice_config_t *config;
config = config_get_config();
__add_authstack(config->authstack, root);
config_release_config();
if (flags & STATS_XML_FLAG_PUBLIC_VIEW) {
/* Ensure those flags are clear when rendering a public view */
flags &= ~(STATS_XML_FLAG_SHOW_LISTENERS|STATS_XML_FLAG_SHOW_HIDDEN);
} else {
config = config_get_config();
__add_authstack(config->authstack, root);
config_release_config();
}
thread_mutex_lock(&_stats_mutex);
/* general stats first */
......@@ -854,7 +876,7 @@ static xmlNodePtr _dump_stats_to_doc (xmlNodePtr root, unsigned int flags, const
while (avlnode) {
stats_node_t *stat = avlnode->key;
if (stat->hidden <= hidden)
if (stat->hidden <= hidden && __include_node(flags, stat->name, public_keys_global))
xmlNewTextChild (root, NULL, XMLSTR(stat->name), XMLSTR(stat->value));
avlnode = avl_get_next (avlnode);
}
......@@ -881,12 +903,14 @@ static xmlNodePtr _dump_stats_to_doc (xmlNodePtr root, unsigned int flags, const
while (avlnode2)
{
stats_node_t *stat = avlnode2->key;
if (client && strcmp(stat->name, "listenurl") == 0) {
char buf[512];
client_get_baseurl(client, NULL, buf, sizeof(buf), NULL, NULL, NULL, source->source, NULL);
xmlNewTextChild (xmlnode, NULL, XMLSTR(stat->name), XMLSTR(buf));
} else {
xmlNewTextChild (xmlnode, NULL, XMLSTR(stat->name), XMLSTR(stat->value));
if (__include_node(flags, stat->name, public_keys_source)) {
if (client && strcmp(stat->name, "listenurl") == 0) {
char buf[512];
client_get_baseurl(client, NULL, buf, sizeof(buf), NULL, NULL, NULL, source->source, NULL);
xmlNewTextChild (xmlnode, NULL, XMLSTR(stat->name), XMLSTR(buf));
} else {
xmlNewTextChild (xmlnode, NULL, XMLSTR(stat->name), XMLSTR(stat->value));
}
}
avlnode2 = avl_get_next (avlnode2);
}
......@@ -913,10 +937,12 @@ static xmlNodePtr _dump_stats_to_doc (xmlNodePtr root, unsigned int flags, const
}
avl_tree_unlock(global.source_tree);
config = config_get_config();
mountproxy = config_find_mount(config, source->source, MOUNT_TYPE_NORMAL);
__add_authstack(mountproxy->authstack, xmlnode);
config_release_config();
if (!(flags & STATS_XML_FLAG_PUBLIC_VIEW)) {
config = config_get_config();
mountproxy = config_find_mount(config, source->source, MOUNT_TYPE_NORMAL);
__add_authstack(mountproxy->authstack, xmlnode);
config_release_config();
}
}
avlnode = avl_get_next (avlnode);
}
......
......@@ -24,6 +24,7 @@
#define STATS_XML_FLAG_NONE 0x0000U
#define STATS_XML_FLAG_SHOW_HIDDEN 0x0001U
#define STATS_XML_FLAG_SHOW_LISTENERS 0x0002U
#define STATS_XML_FLAG_PUBLIC_VIEW 0x0004U
typedef struct _stats_node_tag
{
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment