mirror of
https://gitlab.xiph.org/xiph/icecast-server.git
synced 2024-12-04 14:46:30 -05:00
status.xsl updates, better now.
Automatically create .m3u responses for any existing streams. If /stream.ogg exists, you can now request /stream.ogg.m3u in your browser. svn path=/trunk/icecast/; revision=3797
This commit is contained in:
parent
e97e404904
commit
84a76ac3ee
@ -344,6 +344,7 @@ static void *_handle_connection(void *arg)
|
||||
int bytes;
|
||||
struct stat statbuf;
|
||||
char fullPath[4096];
|
||||
char *uri;
|
||||
|
||||
while (global.running == ICE_RUNNING) {
|
||||
memset(header, 0, 4096);
|
||||
@ -376,13 +377,14 @@ static void *_handle_connection(void *arg)
|
||||
continue;
|
||||
}
|
||||
|
||||
uri = httpp_getvar(parser, HTTPP_VAR_URI);
|
||||
|
||||
if (parser->req_type == httpp_req_source) {
|
||||
INFO1("Source logging in at mountpoint \"%s\"",
|
||||
httpp_getvar(parser, HTTPP_VAR_URI));
|
||||
INFO1("Source logging in at mountpoint \"%s\"", uri);
|
||||
stats_event_inc(NULL, "source_connections");
|
||||
|
||||
if (strcmp((httpp_getvar(parser, "ice-password") != NULL) ? httpp_getvar(parser, "ice-password") : "", (config_get_config()->source_password != NULL) ? config_get_config()->source_password : "") != 0) {
|
||||
INFO1("Source (%s) attempted to login with bad password", httpp_getvar(parser, HTTPP_VAR_URI));
|
||||
INFO1("Source (%s) attempted to login with bad password", uri);
|
||||
connection_close(con);
|
||||
httpp_destroy(parser);
|
||||
continue;
|
||||
@ -393,8 +395,8 @@ static void *_handle_connection(void *arg)
|
||||
*/
|
||||
|
||||
avl_tree_rlock(global.source_tree);
|
||||
if (source_find_mount(httpp_getvar(parser, HTTPP_VAR_URI)) != NULL) {
|
||||
INFO1("Source tried to log in as %s, but is already used", httpp_getvar(parser, HTTPP_VAR_URI));
|
||||
if (source_find_mount(uri) != NULL) {
|
||||
INFO1("Source tried to log in as %s, but is already used", uri);
|
||||
connection_close(con);
|
||||
httpp_destroy(parser);
|
||||
avl_tree_unlock(global.source_tree);
|
||||
@ -402,7 +404,7 @@ static void *_handle_connection(void *arg)
|
||||
}
|
||||
avl_tree_unlock(global.source_tree);
|
||||
|
||||
if (!connection_create_source(con, parser, httpp_getvar(parser, HTTPP_VAR_URI))) {
|
||||
if (!connection_create_source(con, parser, uri)) {
|
||||
connection_close(con);
|
||||
httpp_destroy(parser);
|
||||
}
|
||||
@ -443,7 +445,7 @@ static void *_handle_connection(void *arg)
|
||||
** aren't subject to the limits.
|
||||
*/
|
||||
// TODO: add GUID-xxxxxx
|
||||
if (strcmp(httpp_getvar(parser, HTTPP_VAR_URI), "/stats.xml") == 0) {
|
||||
if (strcmp(uri, "/stats.xml") == 0) {
|
||||
DEBUG0("Stats request, sending xml stats");
|
||||
stats_sendxml(client);
|
||||
client_destroy(client);
|
||||
@ -454,8 +456,8 @@ static void *_handle_connection(void *arg)
|
||||
** if the extension is .xsl, if so, then process
|
||||
** this request as an XSLT request
|
||||
*/
|
||||
if (util_check_valid_extension(httpp_getvar(parser, HTTPP_VAR_URI)) == XSLT_CONTENT) {
|
||||
util_get_full_path(httpp_getvar(parser, HTTPP_VAR_URI), fullPath, sizeof(fullPath));
|
||||
if (util_check_valid_extension(uri) == XSLT_CONTENT) {
|
||||
util_get_full_path(uri, fullPath, sizeof(fullPath));
|
||||
|
||||
/* If the file exists, then transform it, otherwise, write a 404 error */
|
||||
if (stat(fullPath, &statbuf) == 0) {
|
||||
@ -473,7 +475,33 @@ static void *_handle_connection(void *arg)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmp(httpp_getvar(parser, HTTPP_VAR_URI), "/allstreams.txt") == 0) {
|
||||
if(strcmp(util_get_extension(uri), "m3u") == 0) {
|
||||
char *sourceuri = strdup(uri);
|
||||
char *dot = strrchr(sourceuri, '.');
|
||||
*dot = 0;
|
||||
avl_tree_rlock(global.source_tree);
|
||||
source = source_find_mount(sourceuri);
|
||||
if (source) {
|
||||
client->respcode = 200;
|
||||
bytes = sock_write(client->con->sock,
|
||||
"HTTP/1.0 200 OK\r\nContent-Type: audio/x-mpegurl\r\n\r\nhttp://%s:%d%s",
|
||||
config_get_config()->hostname,
|
||||
config_get_config()->port,
|
||||
sourceuri
|
||||
);
|
||||
}
|
||||
else {
|
||||
client->respcode = 404;
|
||||
bytes = sock_write(client->con->sock,
|
||||
"HTTP/1.0 404 Not Found\r\nContent-Type: text/html\r\n<b>The file you requested could not be found</b>\r\n");
|
||||
}
|
||||
avl_tree_unlock(global.source_tree);
|
||||
if(bytes > 0) client->con->sent_bytes = bytes;
|
||||
client_destroy(client);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmp(uri, "/allstreams.txt") == 0) {
|
||||
if (strcmp((httpp_getvar(parser, "ice-password") != NULL) ? httpp_getvar(parser, "ice-password") : "", (config_get_config()->source_password != NULL) ? config_get_config()->source_password : "") != 0) {
|
||||
INFO0("Client attempted to fetch allstreams.txt with bad password");
|
||||
if (parser->req_type == httpp_req_get) {
|
||||
@ -518,7 +546,7 @@ static void *_handle_connection(void *arg)
|
||||
global_unlock();
|
||||
|
||||
avl_tree_rlock(global.source_tree);
|
||||
source = source_find_mount(httpp_getvar(parser, HTTPP_VAR_URI));
|
||||
source = source_find_mount(uri);
|
||||
if (source) {
|
||||
DEBUG0("Source found for client");
|
||||
|
||||
|
@ -19,6 +19,8 @@ typedef struct _format_plugin_tag
|
||||
/* we need to know the mount to report statistics */
|
||||
char *mount;
|
||||
|
||||
char *format_description;
|
||||
|
||||
/* set this is the data format has a header that
|
||||
** we must send before regular data
|
||||
*/
|
||||
|
@ -28,6 +28,7 @@ format_plugin_t *format_mp3_get_plugin(void)
|
||||
plugin->get_buffer = format_mp3_get_buffer;
|
||||
plugin->get_predata = format_mp3_get_predata;
|
||||
plugin->free_plugin = format_mp3_free_plugin;
|
||||
plugin->format_description = "MP3 audio";
|
||||
|
||||
plugin->_state = NULL;
|
||||
|
||||
|
@ -52,6 +52,7 @@ format_plugin_t *format_vorbis_get_plugin(void)
|
||||
plugin->get_buffer = format_vorbis_get_buffer;
|
||||
plugin->get_predata = format_vorbis_get_predata;
|
||||
plugin->free_plugin = format_vorbis_free_plugin;
|
||||
plugin->format_description = "Ogg Vorbis";
|
||||
|
||||
state = (vstate_t *)calloc(1, sizeof(vstate_t));
|
||||
ogg_sync_init(&state->oy);
|
||||
|
@ -139,10 +139,13 @@ void *source_main(void *arg)
|
||||
stats_event(source->mount, "name", s);
|
||||
if ((s = httpp_getvar(source->parser, "ice-url")))
|
||||
stats_event(source->mount, "url", s);
|
||||
if ((s = httpp_getvar(source->parser, "ice-genre")))
|
||||
stats_event(source->mount, "genre", s);
|
||||
if ((s = httpp_getvar(source->parser, "ice-bitrate")))
|
||||
stats_event(source->mount, "bitrate", s);
|
||||
if ((s = httpp_getvar(source->parser, "ice-description")))
|
||||
stats_event(source->mount, "description", s);
|
||||
stats_event(source->mount, "type", source->format->format_description);
|
||||
|
||||
while (global.running == ICE_RUNNING) {
|
||||
ret = source->format->get_buffer(source->format, NULL, 0, &refbuf);
|
||||
|
11
src/util.c
11
src/util.c
@ -96,12 +96,21 @@ int util_get_full_path(char *uri, char *fullPath, int fullPathLen) {
|
||||
int ret = 0;
|
||||
if (uri) {
|
||||
memset(fullPath, '\000', fullPathLen);
|
||||
snprintf(fullPath, fullPathLen-1, "%s%s%s", config_get_config()->webroot_dir, PATH_SEPARATOR, uri);
|
||||
snprintf(fullPath, fullPathLen-1, "%s%s", config_get_config()->webroot_dir, uri);
|
||||
ret = 1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *util_get_extension(char *path) {
|
||||
char *ext = strrchr(path, '.');
|
||||
|
||||
if(ext == NULL)
|
||||
return "";
|
||||
else
|
||||
return ext+1;
|
||||
}
|
||||
|
||||
int util_check_valid_extension(char *uri) {
|
||||
int ret = 0;
|
||||
char *p2;
|
||||
|
@ -8,5 +8,6 @@ int util_timed_wait_for_fd(int fd, int timeout);
|
||||
int util_read_header(int sock, char *buff, unsigned long len);
|
||||
int util_get_full_path(char *uri, char *fullPath, int fullPathLen);
|
||||
int util_check_valid_extension(char *uri);
|
||||
char *util_get_extension(char *path);
|
||||
|
||||
#endif /* __UTIL_H__ */
|
||||
|
@ -55,9 +55,16 @@ a:hover {color: black; font-family:Verdana}
|
||||
<tr>
|
||||
<td bgcolor="#5BB2EB" colspan="2" align="center">
|
||||
<center>
|
||||
<xsl:choose>
|
||||
<xsl:when test="listeners">
|
||||
<font class="mount">Current Stream Information<br></br>
|
||||
<xsl:value-of select="@mount" />
|
||||
</font>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<font class="mount">Stream Information (stream not currently available)</font>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</center>
|
||||
</td>
|
||||
</tr>
|
||||
@ -80,14 +87,27 @@ a:hover {color: black; font-family:Verdana}
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="100" >
|
||||
<font class="default1">Stream Status: </font>
|
||||
<font class="default1">Stream Type: </font>
|
||||
</td>
|
||||
<td>
|
||||
<font class="default2">
|
||||
<b><xsl:value-of select="listeners" /> listeners</b>
|
||||
<b><xsl:value-of select="type" /></b>
|
||||
</font>
|
||||
</td>
|
||||
</tr>
|
||||
<xsl:if test="listeners">
|
||||
<tr>
|
||||
<td width="100" >
|
||||
<font class="default1">Stream Listeners: </font>
|
||||
</td>
|
||||
<td>
|
||||
<font class="default2">
|
||||
<b><xsl:value-of select="listeners" /></b>
|
||||
</font>
|
||||
</td>
|
||||
</tr>
|
||||
</xsl:if>
|
||||
<xsl:if test="name">
|
||||
<tr>
|
||||
<td width="100" >
|
||||
<font class="default1">Stream Title: </font>
|
||||
@ -98,6 +118,8 @@ a:hover {color: black; font-family:Verdana}
|
||||
</font>
|
||||
</td>
|
||||
</tr>
|
||||
</xsl:if>
|
||||
<xsl:if test="genre">
|
||||
<tr>
|
||||
<td width="100" >
|
||||
<font class="default1">Stream Genre: </font>
|
||||
@ -108,6 +130,8 @@ a:hover {color: black; font-family:Verdana}
|
||||
</font>
|
||||
</td>
|
||||
</tr>
|
||||
</xsl:if>
|
||||
<xsl:if test="description">
|
||||
<tr>
|
||||
<td width="100" >
|
||||
<font class="default1">Stream Description: </font>
|
||||
@ -118,6 +142,8 @@ a:hover {color: black; font-family:Verdana}
|
||||
</font>
|
||||
</td>
|
||||
</tr>
|
||||
</xsl:if>
|
||||
<xsl:if test="url">
|
||||
<tr>
|
||||
<td width="100" >
|
||||
<font class="default1">Stream URL: </font>
|
||||
@ -130,6 +156,7 @@ a:hover {color: black; font-family:Verdana}
|
||||
</font>
|
||||
</td>
|
||||
</tr>
|
||||
</xsl:if>
|
||||
<tr>
|
||||
<td width="100" >
|
||||
<font class="default1">Current Song: </font>
|
||||
@ -140,16 +167,18 @@ a:hover {color: black; font-family:Verdana}
|
||||
</font>
|
||||
</td>
|
||||
</tr>
|
||||
<xsl:if test="listeners">
|
||||
<tr>
|
||||
<td width="100" >
|
||||
<font class="default1">Listen: </font>
|
||||
</td>
|
||||
<td>
|
||||
<font class="default2">
|
||||
<a href="{@mount}">Here</a>
|
||||
<a href="{@mount}.m3u">Here</a>
|
||||
</font>
|
||||
</td>
|
||||
</tr>
|
||||
</xsl:if>
|
||||
</table>
|
||||
<table cellpadding="0" cellspacing="0" border="0" width="100%">
|
||||
<tr>
|
||||
|
Loading…
Reference in New Issue
Block a user