mirror of
https://gitlab.xiph.org/xiph/icecast-server.git
synced 2024-12-04 14:46:30 -05:00
Feature: Added new admin command publicstats with a public view of the stats
This commit is contained in:
parent
7a3eb6f530
commit
ea6dd6954a
@ -108,7 +108,7 @@ acl_t *acl_new(void)
|
|||||||
acl_set_method_str(ret, ACL_POLICY_ALLOW, "get,options");
|
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_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);
|
acl_set_web_policy(ret, ACL_POLICY_ALLOW);
|
||||||
|
|
||||||
|
14
src/admin.c
14
src/admin.c
@ -78,6 +78,8 @@
|
|||||||
#define STATS_RAW_REQUEST "stats"
|
#define STATS_RAW_REQUEST "stats"
|
||||||
#define STATS_HTML_REQUEST "stats.xsl"
|
#define STATS_HTML_REQUEST "stats.xsl"
|
||||||
#define STATS_JSON_REQUEST "stats.json"
|
#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_RAW_REQUEST "reloadconfig"
|
||||||
#define QUEUE_RELOAD_HTML_REQUEST "reloadconfig.xsl"
|
#define QUEUE_RELOAD_HTML_REQUEST "reloadconfig.xsl"
|
||||||
#define QUEUE_RELOAD_JSON_REQUEST "reloadconfig.json"
|
#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_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_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_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_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_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);
|
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_HTML_REQUEST, ADMINTYPE_HYBRID, ADMIN_FORMAT_HTML, command_stats, NULL},
|
||||||
{ STATS_JSON_REQUEST, ADMINTYPE_HYBRID, ADMIN_FORMAT_JSON, command_stats, NULL},
|
{ STATS_JSON_REQUEST, ADMINTYPE_HYBRID, ADMIN_FORMAT_JSON, command_stats, NULL},
|
||||||
{ "stats.xml", ADMINTYPE_HYBRID, ADMIN_FORMAT_RAW, 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_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_HTML_REQUEST, ADMINTYPE_GENERAL, ADMIN_FORMAT_HTML, command_queue_reload, NULL},
|
||||||
{ QUEUE_RELOAD_JSON_REQUEST, ADMINTYPE_GENERAL, ADMIN_FORMAT_JSON, 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;
|
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)
|
static void command_queue_reload(client_t *client, source_t *source, admin_format_t response)
|
||||||
{
|
{
|
||||||
global_lock();
|
global_lock();
|
||||||
|
28
src/stats.c
28
src/stats.c
@ -838,15 +838,37 @@ static inline void __add_authstack (auth_stack_t *stack, xmlNodePtr parent) {
|
|||||||
auth_stack_next(&stack);
|
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 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;
|
int hidden = flags & STATS_XML_FLAG_SHOW_HIDDEN ? 1 : 0;
|
||||||
avl_node *avlnode;
|
avl_node *avlnode;
|
||||||
xmlNodePtr ret = NULL;
|
xmlNodePtr ret = NULL;
|
||||||
ice_config_t *config;
|
ice_config_t *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();
|
config = config_get_config();
|
||||||
__add_authstack(config->authstack, root);
|
__add_authstack(config->authstack, root);
|
||||||
config_release_config();
|
config_release_config();
|
||||||
|
}
|
||||||
|
|
||||||
thread_mutex_lock(&_stats_mutex);
|
thread_mutex_lock(&_stats_mutex);
|
||||||
/* general stats first */
|
/* general stats first */
|
||||||
@ -854,7 +876,7 @@ static xmlNodePtr _dump_stats_to_doc (xmlNodePtr root, unsigned int flags, const
|
|||||||
|
|
||||||
while (avlnode) {
|
while (avlnode) {
|
||||||
stats_node_t *stat = avlnode->key;
|
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));
|
xmlNewTextChild (root, NULL, XMLSTR(stat->name), XMLSTR(stat->value));
|
||||||
avlnode = avl_get_next (avlnode);
|
avlnode = avl_get_next (avlnode);
|
||||||
}
|
}
|
||||||
@ -881,6 +903,7 @@ static xmlNodePtr _dump_stats_to_doc (xmlNodePtr root, unsigned int flags, const
|
|||||||
while (avlnode2)
|
while (avlnode2)
|
||||||
{
|
{
|
||||||
stats_node_t *stat = avlnode2->key;
|
stats_node_t *stat = avlnode2->key;
|
||||||
|
if (__include_node(flags, stat->name, public_keys_source)) {
|
||||||
if (client && strcmp(stat->name, "listenurl") == 0) {
|
if (client && strcmp(stat->name, "listenurl") == 0) {
|
||||||
char buf[512];
|
char buf[512];
|
||||||
client_get_baseurl(client, NULL, buf, sizeof(buf), NULL, NULL, NULL, source->source, NULL);
|
client_get_baseurl(client, NULL, buf, sizeof(buf), NULL, NULL, NULL, source->source, NULL);
|
||||||
@ -888,6 +911,7 @@ static xmlNodePtr _dump_stats_to_doc (xmlNodePtr root, unsigned int flags, const
|
|||||||
} else {
|
} else {
|
||||||
xmlNewTextChild (xmlnode, NULL, XMLSTR(stat->name), XMLSTR(stat->value));
|
xmlNewTextChild (xmlnode, NULL, XMLSTR(stat->name), XMLSTR(stat->value));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
avlnode2 = avl_get_next (avlnode2);
|
avlnode2 = avl_get_next (avlnode2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -913,11 +937,13 @@ static xmlNodePtr _dump_stats_to_doc (xmlNodePtr root, unsigned int flags, const
|
|||||||
}
|
}
|
||||||
avl_tree_unlock(global.source_tree);
|
avl_tree_unlock(global.source_tree);
|
||||||
|
|
||||||
|
if (!(flags & STATS_XML_FLAG_PUBLIC_VIEW)) {
|
||||||
config = config_get_config();
|
config = config_get_config();
|
||||||
mountproxy = config_find_mount(config, source->source, MOUNT_TYPE_NORMAL);
|
mountproxy = config_find_mount(config, source->source, MOUNT_TYPE_NORMAL);
|
||||||
__add_authstack(mountproxy->authstack, xmlnode);
|
__add_authstack(mountproxy->authstack, xmlnode);
|
||||||
config_release_config();
|
config_release_config();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
avlnode = avl_get_next (avlnode);
|
avlnode = avl_get_next (avlnode);
|
||||||
}
|
}
|
||||||
thread_mutex_unlock(&_stats_mutex);
|
thread_mutex_unlock(&_stats_mutex);
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#define STATS_XML_FLAG_NONE 0x0000U
|
#define STATS_XML_FLAG_NONE 0x0000U
|
||||||
#define STATS_XML_FLAG_SHOW_HIDDEN 0x0001U
|
#define STATS_XML_FLAG_SHOW_HIDDEN 0x0001U
|
||||||
#define STATS_XML_FLAG_SHOW_LISTENERS 0x0002U
|
#define STATS_XML_FLAG_SHOW_LISTENERS 0x0002U
|
||||||
|
#define STATS_XML_FLAG_PUBLIC_VIEW 0x0004U
|
||||||
|
|
||||||
typedef struct _stats_node_tag
|
typedef struct _stats_node_tag
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user