mirror of
https://gitlab.xiph.org/xiph/icecast-server.git
synced 2024-12-04 14:46:30 -05:00
add a new web admin feature which allows the updating of metadata (now that we support metadata updates for most stream types). This is an new admin feature.
add cluster-password to the config to allow for future clustering of relays on the xiph stream directory. svn path=/icecast/trunk/icecast/; revision=8345
This commit is contained in:
parent
d3a9cf6a1e
commit
b3d5a657d2
@ -4,5 +4,5 @@ AUTOMAKE_OPTIONS = foreign
|
||||
|
||||
admindir = $(pkgdatadir)/admin
|
||||
dist_admin_DATA = listclients.xsl listmounts.xsl moveclients.xsl response.xsl \
|
||||
stats.xsl manageauth.xsl
|
||||
stats.xsl manageauth.xsl updatemetadata.xsl
|
||||
|
||||
|
@ -33,6 +33,7 @@
|
||||
<td align="center">
|
||||
<a class="nav2" href="listclients.xsl?mount={@mount}">Show Listeners</a> |
|
||||
<a class="nav2" href="moveclients.xsl?mount={@mount}">Move Listeners</a> |
|
||||
<a class="nav2" href="updatemetadata.xsl?mount={@mount}">Update Metadata</a> |
|
||||
<a class="nav2" href="killsource.xsl?mount={@mount}">Kill Source</a>
|
||||
</td></tr>
|
||||
</table>
|
||||
|
@ -35,6 +35,7 @@
|
||||
<td align="center">
|
||||
<a class="nav2" href="listclients.xsl?mount={@mount}">Show Listeners</a> |
|
||||
<a class="nav2" href="moveclients.xsl?mount={@mount}">Move Listeners</a> |
|
||||
<a class="nav2" href="updatemetadata.xsl?mount={@mount}">Update Metadata</a> |
|
||||
<a class="nav2" href="killsource.xsl?mount={@mount}">Kill Source</a>
|
||||
<xsl:if test="authenticator"> | <a class="nav2" href="manageauth.xsl?mount={@mount}">Manage Authentication</a></xsl:if>
|
||||
</td></tr>
|
||||
|
@ -36,6 +36,7 @@
|
||||
<td align="center">
|
||||
<a class="nav2" href="listclients.xsl?mount={@mount}">Show Listeners</a> |
|
||||
<a class="nav2" href="moveclients.xsl?mount={@mount}">Move Listeners</a> |
|
||||
<a class="nav2" href="updatemetadata.xsl?mount={@mount}">Update Metadata</a> |
|
||||
<a class="nav2" href="killsource.xsl?mount={@mount}">Kill Source</a>
|
||||
</td></tr>
|
||||
</table>
|
||||
|
@ -62,6 +62,7 @@
|
||||
<td align="center">
|
||||
<a class="nav2" href="listclients.xsl?mount={@mount}">List Clients</a> |
|
||||
<a class="nav2" href="moveclients.xsl?mount={@mount}">Move MountPoints</a> |
|
||||
<a class="nav2" href="updatemetadata.xsl?mount={@mount}">Update Metadata</a> |
|
||||
<a class="nav2" href="killsource.xsl?mount={@mount}">Kill Source</a>
|
||||
<xsl:if test="authenticator"> | <a class="nav2" href="manageauth.xsl?mount={@mount}">Manage Authentication</a></xsl:if>
|
||||
</td></tr>
|
||||
|
55
admin/updatemetadata.xsl
Normal file
55
admin/updatemetadata.xsl
Normal file
@ -0,0 +1,55 @@
|
||||
<xsl:stylesheet xmlns:xsl = "http://www.w3.org/1999/XSL/Transform" version = "1.0" >
|
||||
<xsl:output omit-xml-declaration="no" method="xml" doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" indent="yes" encoding="UTF-8" />
|
||||
<xsl:template match = "/icestats" >
|
||||
<html>
|
||||
<head>
|
||||
<title>Icecast Streaming Media Server</title>
|
||||
<link rel="stylesheet" type="text/css" href="/style.css" />
|
||||
</head>
|
||||
<body>
|
||||
<center>
|
||||
<table border="0" cellpadding="1" cellspacing="3">
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a class="nav" href="listmounts.xsl">List MountPoints</a> |
|
||||
<a class="nav" href="moveclients.xsl">Move Listeners</a> |
|
||||
<a class="nav" href="stats.xsl">Stats</a> |
|
||||
<a class="nav" href="/status.xsl">Status Page</a>
|
||||
</td></tr>
|
||||
</table>
|
||||
</center>
|
||||
<h2>Update Metadata</h2>
|
||||
<div class="roundcont">
|
||||
<div class="roundtop">
|
||||
<img src="/corner_topleft.jpg" class="corner" style="display: none" />
|
||||
</div>
|
||||
<div class="newscontent">
|
||||
<xsl:for-each select="source">
|
||||
<h3>
|
||||
<xsl:if test="server_name"><xsl:value-of select="server_name" /> </xsl:if>
|
||||
(<xsl:value-of select="@mount" />)</h3>
|
||||
|
||||
<form method="GET" action="/admin/metadata.xsl">
|
||||
<table border="0" cellpadding="4">
|
||||
<tr><td>Metadata : <input type="text" name="song"/></td></tr>
|
||||
<tr><td><input type="Submit" value="Update"/></td></tr>
|
||||
</table>
|
||||
<input type="hidden" name="mount" value="{@mount}"/>
|
||||
<input type="hidden" name="mode" value="updinfo"/>
|
||||
</form>
|
||||
|
||||
<br />
|
||||
<br />
|
||||
</xsl:for-each>
|
||||
<xsl:text disable-output-escaping="yes">&</xsl:text>nbsp;
|
||||
</div>
|
||||
<div class="roundbottom">
|
||||
<img src="/corner_bottomleft.jpg" class="corner" style="display: none" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="poster">
|
||||
<img align="left" src="/icecast.png" />Support icecast development at <a class="nav" href="http://www.icecast.org">www.icecast.org</a></div>
|
||||
</body>
|
||||
</html>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
@ -25,13 +25,11 @@
|
||||
<logdir>@localstatedir@/log/@PACKAGE@</logdir>
|
||||
<webroot>@pkgdatadir@/web</webroot>
|
||||
<adminroot>@pkgdatadir@/admin</adminroot>
|
||||
<alias source="/" dest="/status.xsl"/>
|
||||
</paths>
|
||||
<logging>
|
||||
<accesslog>access.log</accesslog>
|
||||
<errorlog>error.log</errorlog>
|
||||
<loglevel>3</loglevel> <!-- 4 Debug, 3 Info, 2 Warn, 1 Error -->
|
||||
</logging>
|
||||
<security>
|
||||
<chroot>0</chroot>
|
||||
</security>
|
||||
</icecast>
|
||||
|
89
src/admin.c
89
src/admin.c
@ -48,16 +48,19 @@
|
||||
|
||||
/* Mount-specific commands */
|
||||
#define COMMAND_RAW_FALLBACK 1
|
||||
#define COMMAND_METADATA_UPDATE 2
|
||||
#define COMMAND_RAW_METADATA_UPDATE 2
|
||||
#define COMMAND_RAW_SHOW_LISTENERS 3
|
||||
#define COMMAND_RAW_MOVE_CLIENTS 4
|
||||
#define COMMAND_RAW_MANAGEAUTH 5
|
||||
#define COMMAND_SHOUTCAST_METADATA_UPDATE 6
|
||||
#define COMMAND_RAW_UPDATEMETADATA 7
|
||||
|
||||
#define COMMAND_TRANSFORMED_FALLBACK 50
|
||||
#define COMMAND_TRANSFORMED_SHOW_LISTENERS 53
|
||||
#define COMMAND_TRANSFORMED_MOVE_CLIENTS 54
|
||||
#define COMMAND_TRANSFORMED_MANAGEAUTH 55
|
||||
#define COMMAND_TRANSFORMED_UPDATEMETADATA 56
|
||||
#define COMMAND_TRANSFORMED_METADATA_UPDATE 57
|
||||
|
||||
/* Global commands */
|
||||
#define COMMAND_RAW_LIST_MOUNTS 101
|
||||
@ -80,7 +83,8 @@
|
||||
#define FALLBACK_RAW_REQUEST "fallbacks"
|
||||
#define FALLBACK_TRANSFORMED_REQUEST "fallbacks.xsl"
|
||||
#define SHOUTCAST_METADATA_REQUEST "admin.cgi"
|
||||
#define METADATA_REQUEST "metadata"
|
||||
#define METADATA_RAW_REQUEST "metadata"
|
||||
#define METADATA_TRANSFORMED_REQUEST "metadata.xsl"
|
||||
#define LISTCLIENTS_RAW_REQUEST "listclients"
|
||||
#define LISTCLIENTS_TRANSFORMED_REQUEST "listclients.xsl"
|
||||
#define STATS_RAW_REQUEST "stats"
|
||||
@ -99,6 +103,8 @@
|
||||
#define ADMIN_XSL_RESPONSE "response.xsl"
|
||||
#define MANAGEAUTH_RAW_REQUEST "manageauth"
|
||||
#define MANAGEAUTH_TRANSFORMED_REQUEST "manageauth.xsl"
|
||||
#define UPDATEMETADATA_RAW_REQUEST "updatemetadata"
|
||||
#define UPDATEMETADATA_TRANSFORMED_REQUEST "updatemetadata.xsl"
|
||||
#define DEFAULT_RAW_REQUEST ""
|
||||
#define DEFAULT_TRANSFORMED_REQUEST ""
|
||||
#define BUILDM3U_RAW_REQUEST "buildm3u"
|
||||
@ -112,8 +118,10 @@ int admin_get_command(char *command)
|
||||
return COMMAND_RAW_FALLBACK;
|
||||
else if(!strcmp(command, FALLBACK_TRANSFORMED_REQUEST))
|
||||
return COMMAND_TRANSFORMED_FALLBACK;
|
||||
else if(!strcmp(command, METADATA_REQUEST))
|
||||
return COMMAND_METADATA_UPDATE;
|
||||
else if(!strcmp(command, METADATA_RAW_REQUEST))
|
||||
return COMMAND_RAW_METADATA_UPDATE;
|
||||
else if(!strcmp(command, METADATA_TRANSFORMED_REQUEST))
|
||||
return COMMAND_TRANSFORMED_METADATA_UPDATE;
|
||||
else if(!strcmp(command, SHOUTCAST_METADATA_REQUEST))
|
||||
return COMMAND_SHOUTCAST_METADATA_UPDATE;
|
||||
else if(!strcmp(command, LISTCLIENTS_RAW_REQUEST))
|
||||
@ -150,6 +158,10 @@ int admin_get_command(char *command)
|
||||
return COMMAND_RAW_MANAGEAUTH;
|
||||
else if(!strcmp(command, MANAGEAUTH_TRANSFORMED_REQUEST))
|
||||
return COMMAND_TRANSFORMED_MANAGEAUTH;
|
||||
else if(!strcmp(command, UPDATEMETADATA_RAW_REQUEST))
|
||||
return COMMAND_RAW_UPDATEMETADATA;
|
||||
else if(!strcmp(command, UPDATEMETADATA_TRANSFORMED_REQUEST))
|
||||
return COMMAND_TRANSFORMED_UPDATEMETADATA;
|
||||
else if(!strcmp(command, BUILDM3U_RAW_REQUEST))
|
||||
return COMMAND_BUILDM3U;
|
||||
else if(!strcmp(command, DEFAULT_TRANSFORMED_REQUEST))
|
||||
@ -161,7 +173,7 @@ int admin_get_command(char *command)
|
||||
}
|
||||
|
||||
static void command_fallback(client_t *client, source_t *source, int response);
|
||||
static void command_metadata(client_t *client, source_t *source);
|
||||
static void command_metadata(client_t *client, source_t *source, int response);
|
||||
static void command_shoutcast_metadata(client_t *client, source_t *source);
|
||||
static void command_show_listeners(client_t *client, source_t *source,
|
||||
int response);
|
||||
@ -177,6 +189,8 @@ static void command_buildm3u(client_t *client, source_t *source,
|
||||
int response);
|
||||
static void command_kill_source(client_t *client, source_t *source,
|
||||
int response);
|
||||
static void command_updatemetadata(client_t *client, source_t *source,
|
||||
int response);
|
||||
static void admin_handle_mount_request(client_t *client, source_t *source,
|
||||
int command);
|
||||
static void admin_handle_general_request(client_t *client, int command);
|
||||
@ -446,8 +460,11 @@ static void admin_handle_mount_request(client_t *client, source_t *source,
|
||||
case COMMAND_RAW_FALLBACK:
|
||||
command_fallback(client, source, RAW);
|
||||
break;
|
||||
case COMMAND_METADATA_UPDATE:
|
||||
command_metadata(client, source);
|
||||
case COMMAND_RAW_METADATA_UPDATE:
|
||||
command_metadata(client, source, RAW);
|
||||
break;
|
||||
case COMMAND_TRANSFORMED_METADATA_UPDATE:
|
||||
command_metadata(client, source, TRANSFORMED);
|
||||
break;
|
||||
case COMMAND_SHOUTCAST_METADATA_UPDATE:
|
||||
command_shoutcast_metadata(client, source);
|
||||
@ -485,6 +502,12 @@ static void admin_handle_mount_request(client_t *client, source_t *source,
|
||||
case COMMAND_RAW_MANAGEAUTH:
|
||||
command_manageauth(client, source, RAW);
|
||||
break;
|
||||
case COMMAND_TRANSFORMED_UPDATEMETADATA:
|
||||
command_updatemetadata(client, source, TRANSFORMED);
|
||||
break;
|
||||
case COMMAND_RAW_UPDATEMETADATA:
|
||||
command_updatemetadata(client, source, RAW);
|
||||
break;
|
||||
case COMMAND_BUILDM3U:
|
||||
command_buildm3u(client, source, RAW);
|
||||
break;
|
||||
@ -822,11 +845,19 @@ static void command_fallback(client_t *client, source_t *source,
|
||||
html_success(client, "Fallback configured");
|
||||
}
|
||||
|
||||
static void command_metadata(client_t *client, source_t *source)
|
||||
static void command_metadata(client_t *client, source_t *source,
|
||||
int response)
|
||||
{
|
||||
char *action;
|
||||
char *song, *title, *artist;
|
||||
format_plugin_t *plugin;
|
||||
xmlDocPtr doc;
|
||||
xmlNodePtr node;
|
||||
int ok = 1;
|
||||
|
||||
doc = xmlNewDoc("1.0");
|
||||
node = xmlNewDocNode(doc, NULL, "iceresponse", NULL);
|
||||
xmlDocSetRootElement(doc, node);
|
||||
|
||||
DEBUG0("Got metadata update request");
|
||||
|
||||
@ -837,7 +868,12 @@ static void command_metadata(client_t *client, source_t *source)
|
||||
|
||||
if (strcmp (action, "updinfo") != 0)
|
||||
{
|
||||
client_send_400 (client, "No such action");
|
||||
xmlNewChild(node, NULL, "message", "No such action");
|
||||
xmlNewChild(node, NULL, "return", "0");
|
||||
admin_send_response(doc, client, response,
|
||||
ADMIN_XSL_RESPONSE);
|
||||
xmlFreeDoc(doc);
|
||||
client_destroy(client);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -860,13 +896,25 @@ static void command_metadata(client_t *client, source_t *source)
|
||||
source->mount, artist, title);
|
||||
}
|
||||
}
|
||||
|
||||
html_success(client, "Metadata update successful");
|
||||
}
|
||||
else
|
||||
{
|
||||
client_send_400 (client, "mountpoint will not accept URL updates");
|
||||
xmlNewChild(node, NULL, "message",
|
||||
"Mountpoint will not accept URL updates");
|
||||
xmlNewChild(node, NULL, "return", "1");
|
||||
admin_send_response(doc, client, response,
|
||||
ADMIN_XSL_RESPONSE);
|
||||
xmlFreeDoc(doc);
|
||||
client_destroy(client);
|
||||
return;
|
||||
}
|
||||
|
||||
xmlNewChild(node, NULL, "message", "Metadata update successful");
|
||||
xmlNewChild(node, NULL, "return", "1");
|
||||
admin_send_response(doc, client, response,
|
||||
ADMIN_XSL_RESPONSE);
|
||||
xmlFreeDoc(doc);
|
||||
client_destroy(client);
|
||||
}
|
||||
|
||||
static void command_shoutcast_metadata(client_t *client, source_t *source)
|
||||
@ -960,3 +1008,20 @@ static void command_list_mounts(client_t *client, int response)
|
||||
return;
|
||||
}
|
||||
|
||||
static void command_updatemetadata(client_t *client, source_t *source,
|
||||
int response)
|
||||
{
|
||||
xmlDocPtr doc;
|
||||
xmlNodePtr node, srcnode;
|
||||
|
||||
doc = xmlNewDoc("1.0");
|
||||
node = xmlNewDocNode(doc, NULL, "icestats", NULL);
|
||||
srcnode = xmlNewChild(node, NULL, "source", NULL);
|
||||
xmlSetProp(srcnode, "mount", source->mount);
|
||||
xmlDocSetRootElement(doc, node);
|
||||
|
||||
admin_send_response(doc, client, response,
|
||||
UPDATEMETADATA_TRANSFORMED_REQUEST);
|
||||
xmlFreeDoc(doc);
|
||||
client_destroy(client);
|
||||
}
|
||||
|
@ -188,6 +188,9 @@ void config_clear(ice_config_t *c)
|
||||
xmlFree(mount->password);
|
||||
xmlFree(mount->dumpfile);
|
||||
xmlFree(mount->fallback_mount);
|
||||
if (mount->cluster_password) {
|
||||
xmlFree(mount->cluster_password);
|
||||
}
|
||||
|
||||
xmlFree(mount->auth_type);
|
||||
option = mount->auth_options;
|
||||
@ -610,6 +613,10 @@ static void _parse_mount(xmlDocPtr doc, xmlNodePtr node,
|
||||
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
|
||||
mount->burst_size = atoi(tmp);
|
||||
if (tmp) xmlFree(tmp);
|
||||
} else if (strcmp(node->name, "cluster-password") == 0) {
|
||||
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
|
||||
mount->cluster_password = (char *)xmlNodeListGetString(
|
||||
doc, node->xmlChildrenNode, 1);
|
||||
}
|
||||
} while ((node = node->next));
|
||||
}
|
||||
|
@ -62,6 +62,7 @@ typedef struct _mount_proxy {
|
||||
unsigned int source_timeout; /* source timeout in seconds */
|
||||
|
||||
char *auth_type; /* Authentication type */
|
||||
char *cluster_password;
|
||||
config_options_t *auth_options; /* Options for this type */
|
||||
struct _mount_proxy *next;
|
||||
} mount_proxy;
|
||||
|
22
src/yp.c
22
src/yp.c
@ -458,6 +458,7 @@ static ypdata_t *create_yp_entry (source_t *source)
|
||||
unsigned len = 512;
|
||||
int ret;
|
||||
char *url;
|
||||
mount_proxy *mountproxy = NULL;
|
||||
ice_config_t *config;
|
||||
|
||||
if (yp == NULL)
|
||||
@ -486,6 +487,18 @@ static ypdata_t *create_yp_entry (source_t *source)
|
||||
if (s) url = s;
|
||||
snprintf (url, ret, "http://%s:%d%s", config->hostname, config->port, source->mount);
|
||||
}
|
||||
|
||||
mountproxy = config->mounts;
|
||||
while (mountproxy) {
|
||||
if (strcmp (mountproxy->mountname, source->mount) == 0) {
|
||||
if (mountproxy->cluster_password) {
|
||||
add_yp_info (yp, "cluster_password",
|
||||
mountproxy->cluster_password, YP_CLUSTER_PASSWORD);
|
||||
}
|
||||
break;
|
||||
}
|
||||
mountproxy = mountproxy->next;
|
||||
}
|
||||
config_release_config();
|
||||
yp->listen_url = util_url_escape (url);
|
||||
free (url);
|
||||
@ -813,6 +826,15 @@ static void add_yp_info (ypdata_t *yp, char *stat_name, void *info, int type)
|
||||
stats_event (yp->mount, "yp_currently_playing", (char *)info);
|
||||
}
|
||||
break;
|
||||
case YP_CLUSTER_PASSWORD:
|
||||
escaped = util_url_escape(info);
|
||||
if (escaped)
|
||||
{
|
||||
if (yp->cluster_password)
|
||||
free (yp->cluster_password);
|
||||
yp->cluster_password = escaped;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user