Commit cb398ff4 authored by Michael Smith's avatar Michael Smith

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
parent 4cc07051
......@@ -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);
......
......@@ -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
......
#ifndef __STATS_H__
#define __STATS_H__
#include "connection.h"
#include "httpp.h"
#include "client.h"
typedef struct _stats_connection_tag
{
connection_t *con;
......
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