mirror of
https://gitlab.xiph.org/xiph/icecast-server.git
synced 2025-02-02 15:07:36 -05:00
Bunch of fixes:
- connections are now matched to format plugins based on content-type headers, and are rejected if there isn't a format handler for that content-type, or there is no content-type at all. - format_vorbis now handles pages with granulepos of -1 in the headers correctly (this happens if the headers are fairly large, because of many comments, for example). - various #include fixes. - buffer overflow in httpp.c fixed. svn path=/trunk/avl/; revision=3042
This commit is contained in:
parent
4cc0705134
commit
cb398ff41c
@ -2,7 +2,7 @@
|
||||
* Copyright (C) 1995 by Sam Rushing <rushing@nightmare.com>
|
||||
*/
|
||||
|
||||
/* $Id: avl.h,v 1.1 2001/09/10 02:28:03 jack Exp $ */
|
||||
/* $Id: avl.h,v 1.2 2002/02/11 09:11:18 msmith Exp $ */
|
||||
|
||||
#ifndef __AVL_H
|
||||
#define __AVL_H
|
||||
@ -11,6 +11,8 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "thread.h"
|
||||
|
||||
typedef struct avl_node_tag {
|
||||
void * key;
|
||||
struct avl_node_tag * left;
|
||||
|
@ -336,6 +336,8 @@ static void *_handle_connection(void *arg)
|
||||
}
|
||||
|
||||
if (parser->req_type == httpp_req_source) {
|
||||
char *contenttype;
|
||||
|
||||
printf("DEBUG: source logging in\n");
|
||||
stats_event_inc(NULL, "source_connections");
|
||||
|
||||
@ -379,7 +381,22 @@ static void *_handle_connection(void *arg)
|
||||
|
||||
stats_event_inc(NULL, "sources");
|
||||
|
||||
source = source_create(con, parser, httpp_getvar(parser, HTTPP_VAR_URI), FORMAT_TYPE_VORBIS);
|
||||
contenttype = httpp_getvar(parser, "content-type");
|
||||
|
||||
if (contenttype != NULL) {
|
||||
format_type_t format = format_get_type(contenttype);
|
||||
if(format < 0) {
|
||||
WARN1("Content-type \"%s\" not supported, dropping source", contenttype);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
source = source_create(con, parser, httpp_getvar(parser, HTTPP_VAR_URI), format);
|
||||
}
|
||||
else {
|
||||
WARN0("No content-type header, cannot handle source");
|
||||
continue;
|
||||
}
|
||||
|
||||
source->shutdown_rwlock = &_source_shutdown_rwlock;
|
||||
|
||||
sock_set_blocking(con->sock, SOCK_NONBLOCK);
|
||||
|
10
src/format.c
10
src/format.c
@ -15,6 +15,16 @@
|
||||
|
||||
#include "format_vorbis.h"
|
||||
|
||||
format_type_t format_get_type(char *contenttype)
|
||||
{
|
||||
if(strcmp(contenttype, "application/x-ogg") == 0)
|
||||
return FORMAT_TYPE_VORBIS;
|
||||
else if(strcmp(contenttype, "audio/mpeg") == 0)
|
||||
return FORMAT_TYPE_MP3;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
format_plugin_t *format_get_plugin(format_type_t type, char *mount)
|
||||
{
|
||||
format_plugin_t *plugin;
|
||||
|
@ -32,6 +32,7 @@ typedef struct _format_plugin_tag
|
||||
void *_state;
|
||||
} format_plugin_t;
|
||||
|
||||
format_type_t format_get_type(char *contenttype);
|
||||
format_plugin_t *format_get_plugin(format_type_t type, char *mount);
|
||||
|
||||
#endif /* __FORMAT_H__ */
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
#include "refbuf.h"
|
||||
|
||||
#include "stats.h"
|
||||
#include "format.h"
|
||||
|
||||
typedef struct _vstate_tag
|
||||
@ -122,7 +123,11 @@ refbuf_t *format_vorbis_get_buffer(format_plugin_t *self, char *data, unsigned l
|
||||
}
|
||||
|
||||
if (state->header >= 0) {
|
||||
if (ogg_page_granulepos(&state->og) == 0) {
|
||||
/* FIXME: In some streams (non-vorbis ogg streams), this could get
|
||||
* extras pages beyond the header. We need to collect the pages
|
||||
* here anyway, but they may have to be discarded later.
|
||||
*/
|
||||
if (ogg_page_granulepos(&state->og) <= 0) {
|
||||
state->header++;
|
||||
} else {
|
||||
/* we're done caching headers */
|
||||
|
@ -62,10 +62,11 @@ int httpp_parse(http_parser_t *parser, char *http_data, unsigned long len)
|
||||
if (http_data == NULL)
|
||||
return 0;
|
||||
|
||||
/* make a local copy of the data */
|
||||
data = (char *)malloc(len);
|
||||
/* make a local copy of the data, including 0 terminator */
|
||||
data = (char *)malloc(len+1);
|
||||
if (data == NULL) return 0;
|
||||
memcpy(data, http_data, len);
|
||||
data[len] = 0;
|
||||
|
||||
/* first we count how many lines there are
|
||||
** and set up the line[] array
|
||||
@ -77,14 +78,12 @@ int httpp_parse(http_parser_t *parser, char *http_data, unsigned long len)
|
||||
data[i] = '\0';
|
||||
if (data[i] == '\n') {
|
||||
lines++;
|
||||
if (i + 1 < len)
|
||||
if (data[i + 1] == '\n' || data[i + 1] == '\r') {
|
||||
data[i] = '\0';
|
||||
break;
|
||||
}
|
||||
data[i] = '\0';
|
||||
if (i < len - 1)
|
||||
if (i + 1 < len) {
|
||||
if (data[i + 1] == '\n' || data[i + 1] == '\r')
|
||||
break;
|
||||
line[lines] = &data[i + 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -178,11 +178,11 @@ void *source_main(void *arg)
|
||||
|
||||
/* we have a refbuf buffer, which a data block to be sent to
|
||||
** all clients. if a client is not able to send the buffer
|
||||
** immediately, it should store it on it's queue for the next
|
||||
** immediately, it should store it on its queue for the next
|
||||
** go around.
|
||||
**
|
||||
** instead of sending the current block, a client should send
|
||||
** all data in the cue, plus the current block, until either
|
||||
** all data in the queue, plus the current block, until either
|
||||
** it runs out of data, or it hits a recoverable error like
|
||||
** EAGAIN. this will allow a client that got slightly lagged
|
||||
** to catch back up if it can
|
||||
|
@ -1,6 +1,10 @@
|
||||
#ifndef __STATS_H__
|
||||
#define __STATS_H__
|
||||
|
||||
#include "connection.h"
|
||||
#include "httpp.h"
|
||||
#include "client.h"
|
||||
|
||||
typedef struct _stats_connection_tag
|
||||
{
|
||||
connection_t *con;
|
||||
|
Loading…
Reference in New Issue
Block a user