[xiph-commits] r8186 - icecast/branches/kh/icecast/src
karl at motherfish-iii.xiph.org
karl at motherfish-iii.xiph.org
Wed Nov 10 06:35:19 PST 2004
Author: karl
Date: 2004-11-10 06:35:18 -0800 (Wed, 10 Nov 2004)
New Revision: 8186
Modified:
icecast/branches/kh/icecast/src/client.c
icecast/branches/kh/icecast/src/client.h
icecast/branches/kh/icecast/src/format.c
icecast/branches/kh/icecast/src/format.h
icecast/branches/kh/icecast/src/format_mp3.c
icecast/branches/kh/icecast/src/format_ogg.c
icecast/branches/kh/icecast/src/format_vorbis.c
icecast/branches/kh/icecast/src/slave.c
icecast/branches/kh/icecast/src/slave.h
icecast/branches/kh/icecast/src/source.c
Log:
drop separate predata handler for http headers, now use a per-client refbuf
instead with a specific write handler. drop ICY reply and cleanup some API
bits as well
Modified: icecast/branches/kh/icecast/src/client.c
===================================================================
--- icecast/branches/kh/icecast/src/client.c 2004-11-09 08:06:21 UTC (rev 8185)
+++ icecast/branches/kh/icecast/src/client.c 2004-11-10 14:35:18 UTC (rev 8186)
@@ -29,6 +29,7 @@
#include "connection.h"
#include "refbuf.h"
+#include "format.h"
#include "client.h"
#include "logging.h"
@@ -48,6 +49,7 @@
client->parser = parser;
client->refbuf = NULL;
client->pos = 0;
+ client->write_to_client = format_generic_write_to_client;
return client;
}
Modified: icecast/branches/kh/icecast/src/client.h
===================================================================
--- icecast/branches/kh/icecast/src/client.h 2004-11-09 08:06:21 UTC (rev 8185)
+++ icecast/branches/kh/icecast/src/client.h 2004-11-10 14:35:18 UTC (rev 8186)
@@ -25,6 +25,8 @@
#include "connection.h"
#include "refbuf.h"
+struct source_tag;
+
typedef struct _client_tag
{
/* the client's connection */
@@ -64,12 +66,8 @@
/* function to call to release format specific resources */
void (*free_client_data)(struct _client_tag *client);
+ int (*write_to_client)(struct source_tag *source, struct _client_tag *client);
- char *predata;
- unsigned predata_size;
- unsigned predata_len;
- unsigned predata_offset;
-
struct _client_tag *next;
} client_t;
Modified: icecast/branches/kh/icecast/src/format.c
===================================================================
--- icecast/branches/kh/icecast/src/format.c 2004-11-09 08:06:21 UTC (rev 8185)
+++ icecast/branches/kh/icecast/src/format.c 2004-11-10 14:35:18 UTC (rev 8186)
@@ -48,6 +48,9 @@
#define snprintf _snprintf
#endif
+static int format_prepare_headers (source_t *source, client_t *client);
+
+
format_type_t format_get_type(char *contenttype)
{
if(strcmp(contenttype, "application/x-ogg") == 0)
@@ -95,41 +98,84 @@
return ret;
}
+int format_http_write_to_client (source_t *source, client_t *client)
+{
+ refbuf_t *refbuf = client->refbuf;
+ const char *buf;
+ unsigned int len;
+ int ret;
-int format_generic_write_buf_to_client(format_plugin_t *format,
- client_t *client, unsigned char *buf, int len)
+ if (refbuf == NULL)
+ {
+ client->write_to_client = source->format->write_buf_to_client;
+ return 0;
+ }
+ if (client->respcode == 0)
+ {
+ DEBUG0("processing pending client headers");
+
+ client->respcode = 200;
+ if (format_prepare_headers (source, client) < 0)
+ {
+ ERROR0 ("internal problem, dropping client");
+ client->con->error = 1;
+ return 0;
+ }
+ }
+
+ buf = refbuf->data + client->pos;
+ len = refbuf->len - client->pos;
+
+ ret = client_send_bytes (client, buf, len);
+
+ if (ret > 0)
+ client->pos += ret;
+ if (client->pos == refbuf->len)
+ client_set_queue (client, NULL);
+
+ return ret;
+}
+
+
+int format_generic_write_to_client (source_t *source, client_t *client)
{
int ret;
+ const char *buf;
+ unsigned int len;
+ refbuf_t * refbuf = client->refbuf;
+ if (refbuf == NULL)
+ return 0;
+ buf = refbuf->data + client->pos;
+ len = refbuf->len - client->pos;
+
ret = client_send_bytes (client, buf, len);
- if (ret < 0 && client->con->error == 0)
- ret = 0;
+ if (ret == len)
+ {
+ client_set_queue (client, refbuf->next);
+ if (client->refbuf == NULL)
+ client->write_to_client = source->format->write_buf_to_client;
+ }
+
return ret;
}
-void format_prepare_headers (source_t *source, client_t *client)
+static int format_prepare_headers (source_t *source, client_t *client)
{
unsigned remaining;
char *ptr;
int bytes;
int bitrate_filtered = 0;
avl_node *node;
- char *agent;
- remaining = client->predata_size;
- ptr = client->predata;
+ remaining = client->refbuf->len;
+ ptr = client->refbuf->data;
client->respcode = 200;
- /* ugly hack, but send ICY OK header when client is realplayer */
- agent = httpp_getvar (client->parser, "user-agent");
- if (agent && strstr (agent, "RealMedia") != NULL)
- bytes = snprintf (ptr, remaining, "ICY 200 OK\r\nContent-Type: %s\r\n",
- format_get_mimetype (source->format->type));
- else
- bytes = snprintf (ptr, remaining, "HTTP/1.0 200 OK\r\nContent-Type: %s\r\n",
- format_get_mimetype (source->format->type));
+ bytes = snprintf (ptr, remaining, "HTTP/1.0 200 OK\r\n"
+ "Content-Type: %s\r\n", format_get_mimetype (source->format->type));
remaining -= bytes;
ptr += bytes;
@@ -200,7 +246,11 @@
remaining -= bytes;
ptr += bytes;
- client->predata_len = client->predata_size - remaining;
+ client->refbuf->len -= remaining;
+ if (source->format->create_client_data)
+ if (source->format->create_client_data (source, client) < 0)
+ return -1;
+ return 0;
}
Modified: icecast/branches/kh/icecast/src/format.h
===================================================================
--- icecast/branches/kh/icecast/src/format.h 2004-11-09 08:06:21 UTC (rev 8185)
+++ icecast/branches/kh/icecast/src/format.h 2004-11-10 14:35:18 UTC (rev 8186)
@@ -43,7 +43,7 @@
char *format_description;
refbuf_t *(*get_buffer)(struct source_tag *);
- int (*write_buf_to_client)(struct _format_plugin_tag *format, client_t *client);
+ int (*write_buf_to_client)(struct source_tag *format, client_t *client);
void (*write_buf_to_file)(struct source_tag *source, refbuf_t *refbuf);
int (*create_client_data)(struct source_tag *source, client_t *client);
void (*set_tag)(struct _format_plugin_tag *plugin, char *tag, char *value);
@@ -59,11 +59,10 @@
char *format_get_mimetype(format_type_t type);
int format_get_plugin(format_type_t type, struct source_tag *source);
-int format_generic_write_buf_to_client(format_plugin_t *format,
- client_t *client, unsigned char *buf, int len);
+int format_generic_write_to_client (struct source_tag *source, client_t *client);
void format_send_general_headers(format_plugin_t *format,
struct source_tag *source, client_t *client);
-void format_prepare_headers (struct source_tag *source, client_t *client);
+int format_http_write_to_client (struct source_tag *source, client_t *client);
void format_initialise();
#endif /* __FORMAT_H__ */
Modified: icecast/branches/kh/icecast/src/format_mp3.c
===================================================================
--- icecast/branches/kh/icecast/src/format_mp3.c 2004-11-09 08:06:21 UTC (rev 8185)
+++ icecast/branches/kh/icecast/src/format_mp3.c 2004-11-10 14:35:18 UTC (rev 8186)
@@ -59,7 +59,7 @@
static int format_mp3_create_client_data (source_t *source, client_t *client);
static void free_mp3_client_data (client_t *client);
-static int format_mp3_write_buf_to_client(format_plugin_t *self, client_t *client);
+static int format_mp3_write_buf_to_client(source_t *self, client_t *client);
static void write_mp3_to_file (struct source_tag *source, refbuf_t *refbuf);
static void mp3_set_tag (format_plugin_t *plugin, char *tag, char *value);
static void format_mp3_apply_settings(struct source_tag *source, struct _mount_proxy *mount);
@@ -263,15 +263,15 @@
/* If there is a change in metadata then send it else
* send a single zero value byte in its place
*/
- if (associated == client_mp3->associated)
+ if (associated && associated != client_mp3->associated)
{
- metadata = "\0";
- meta_len = 1;
+ metadata = associated->data + client_mp3->metadata_offset;
+ meta_len = associated->len - client_mp3->metadata_offset;
}
else
{
- metadata = associated->data + client_mp3->metadata_offset;
- meta_len = associated->len - client_mp3->metadata_offset;
+ metadata = "\0";
+ meta_len = 1;
}
ret = client_send_bytes (client, metadata, meta_len);
@@ -296,7 +296,7 @@
/* Handler for writing mp3 data to a client, taking into account whether
* client has requested shoutcast style metadata updates
*/
-static int format_mp3_write_buf_to_client (format_plugin_t *self, client_t *client)
+static int format_mp3_write_buf_to_client (source_t *self, client_t *client)
{
int ret, written = 0;
mp3_client_data *client_mp3 = client->format_data;
@@ -576,8 +576,9 @@
mp3_client_data *client_mp3 = calloc(1,sizeof(mp3_client_data));
mp3_state *source_mp3 = source->format->_state;
const char *metadata;
- unsigned remaining = client->predata_size - client->predata_len + 2;
- char *ptr = client->predata + client->predata_len - 2;
+ /* the +-2 is for overwriting the last set of \r\n */
+ unsigned remaining = 4096 - client->refbuf->len + 2;
+ char *ptr = client->refbuf->data + client->refbuf->len - 2;
int bytes;
if (client_mp3 == NULL)
@@ -604,12 +605,20 @@
client_mp3->interval = ICY_METADATA_INTERVAL;
else
client_mp3->interval = source_mp3->interval;
- bytes = snprintf (ptr, remaining, "icy-metaint:%u\r\n\r\n",
+ bytes = snprintf (ptr, remaining, "icy-metaint:%u\r\n",
client_mp3->interval);
if (bytes > 0)
- client->predata_len += bytes - 2;
+ {
+ remaining -= bytes;
+ ptr += bytes;
+ }
}
+ bytes = snprintf (ptr, remaining, "\r\n");
+ remaining -= bytes;
+ ptr += bytes;
+ client->refbuf->len = 4096 - remaining;
+
return 0;
}
Modified: icecast/branches/kh/icecast/src/format_ogg.c
===================================================================
--- icecast/branches/kh/icecast/src/format_ogg.c 2004-11-09 08:06:21 UTC (rev 8185)
+++ icecast/branches/kh/icecast/src/format_ogg.c 2004-11-10 14:35:18 UTC (rev 8186)
@@ -509,7 +509,7 @@
static void write_ogg_to_file (struct source_tag *source, refbuf_t *refbuf);
static refbuf_t *ogg_get_buffer (source_t *source);
-static int write_buf_to_client (format_plugin_t *self, client_t *client);
+static int write_buf_to_client (source_t *self, client_t *client);
static void free_ogg_codecs (ogg_state_t *ogg_info)
@@ -802,7 +802,7 @@
}
-static int write_buf_to_client (format_plugin_t *self, client_t *client)
+static int write_buf_to_client (source_t *self, client_t *client)
{
refbuf_t *refbuf = client->refbuf;
char *buf;
Modified: icecast/branches/kh/icecast/src/format_vorbis.c
===================================================================
--- icecast/branches/kh/icecast/src/format_vorbis.c 2004-11-09 08:06:21 UTC (rev 8185)
+++ icecast/branches/kh/icecast/src/format_vorbis.c 2004-11-10 14:35:18 UTC (rev 8186)
@@ -98,7 +98,7 @@
static void write_vorbis_to_file (struct source_tag *source, refbuf_t *refbuf);
static refbuf_t *vorbis_get_buffer (source_t *source);
-static int vorbis_write_buf_to_client (format_plugin_t *self, client_t *client);
+static int vorbis_write_buf_to_client (source_t *self, client_t *client);
static void vorbis_set_tag (format_plugin_t *plugin, char *tag, char *value);
@@ -751,7 +751,7 @@
}
-static int vorbis_write_buf_to_client (format_plugin_t *self, client_t *client)
+static int vorbis_write_buf_to_client (source_t *self, client_t *client)
{
refbuf_t *refbuf = client->refbuf;
char *buf;
Modified: icecast/branches/kh/icecast/src/slave.c
===================================================================
--- icecast/branches/kh/icecast/src/slave.c 2004-11-09 08:06:21 UTC (rev 8185)
+++ icecast/branches/kh/icecast/src/slave.c 2004-11-10 14:35:18 UTC (rev 8186)
@@ -147,7 +147,7 @@
}
-int slave_redirect (char *mountpoint, client_t *client)
+int slave_redirect (const char *mountpoint, client_t *client)
{
slave_host *slave = NULL;
Modified: icecast/branches/kh/icecast/src/slave.h
===================================================================
--- icecast/branches/kh/icecast/src/slave.h 2004-11-09 08:06:21 UTC (rev 8185)
+++ icecast/branches/kh/icecast/src/slave.h 2004-11-10 14:35:18 UTC (rev 8186)
@@ -13,9 +13,10 @@
#ifndef __SLAVE_H__
#define __SLAVE_H__
-#include <client.h>
#include <thread/thread.h>
+struct _client_tag;
+
typedef struct _relay_server {
char *server;
int port;
@@ -44,9 +45,9 @@
void slave_shutdown(void);
void slave_recheck (void);
void slave_rescan (void);
-int slave_redirect (char *mountpoint, client_t *client);
-void slave_host_add (client_t *client, const char *header);
-void slave_host_remove (client_t *client);
+int slave_redirect (const char *mountpoint, struct _client_tag *client);
+void slave_host_add (struct _client_tag *client, const char *header);
+void slave_host_remove (struct _client_tag *client);
relay_server *relay_free (relay_server *relay);
#endif /* __SLAVE_H__ */
Modified: icecast/branches/kh/icecast/src/source.c
===================================================================
--- icecast/branches/kh/icecast/src/source.c 2004-11-09 08:06:21 UTC (rev 8185)
+++ icecast/branches/kh/icecast/src/source.c 2004-11-10 14:35:18 UTC (rev 8186)
@@ -366,10 +366,19 @@
/* we need to move the client and pending trees */
while (source->active_clients)
{
- /* switch client to different queue */
client_t *client = source->active_clients;
source->active_clients = client->next;
- client_set_queue (client, dest->stream_data_tail);
+
+ /* when switching a client to a different queue, be wary of the
+ * refbuf it's referring to, if it's http headers then we need
+ * to write them so don't release it.
+ */
+ if (client->write_to_client != format_http_write_to_client)
+ {
+ client_set_queue (client, NULL);
+ client->write_to_client = NULL;
+ }
+
*dest->pending_clients_tail = client;
dest->pending_clients_tail = &client->next;
count++;
@@ -381,6 +390,8 @@
{
client_t *client = source->pending_clients;
source->pending_clients = client->next;
+ /* clients on pending have a unique refbuf containing headers
+ * so no need to change them here */
*dest->pending_clients_tail = client;
dest->pending_clients_tail = &client->next;
count++;
@@ -447,21 +458,6 @@
int total_written = 0;
int ret = 1;
- if (client->predata)
- {
- char *ptr = client->predata + client->predata_offset;
- unsigned len = client->predata_len - client->predata_offset;
- bytes = client_send_bytes (client, ptr, len);
- if (bytes > 0 && (unsigned)bytes < len)
- {
- client->predata_offset += bytes;
- return 0;
- }
- free (client->predata);
- client->predata_size = client->predata_len = client->predata_offset = 0;
- client->predata = NULL;
- }
-
/* new users need somewhere to start from */
if (client->refbuf == NULL)
{
@@ -483,7 +479,7 @@
loop--;
- bytes = source->format->write_buf_to_client (source->format, client);
+ bytes = client->write_to_client (source, client);
if (bytes <= 0)
{
ret = 0;
@@ -520,9 +516,9 @@
client_p = &source->active_clients;
while (client && client != sentinel)
{
- int move_it = send_to_listener (source, client, deletion_expected);
+ int fast_client = send_to_listener (source, client, deletion_expected);
- if (move_it)
+ if (fast_client)
{
client_t *to_go = client;
@@ -802,8 +798,9 @@
client->next = source->pending_clients;
source->pending_clients = client;
- client->predata_size = 4096;
- client->predata = calloc (1, client->predata_size);
+ client->write_to_client = format_http_write_to_client;
+ client->refbuf = refbuf_new (4096);
+
sock_set_blocking (client->con->sock, SOCK_NONBLOCK);
sock_set_nodelay (client->con->sock);
if (source->running == 0 && source->on_demand)
@@ -933,33 +930,20 @@
while (client)
{
client_t *to_go = client;
- int drop_client = 0;
client = client->next;
- to_go->next = NULL;
- /* do we need to handle http style headers */
- if (to_go->respcode == 0)
+ if (to_go->write_to_client == NULL)
{
- DEBUG0("processing pending client headers");
-
- format_prepare_headers (source, to_go);
- if (source->format->create_client_data &&
- source->format->create_client_data (source, to_go) < 0)
- drop_client = 1;
+ /* The client may of been moved here when we were an
+ * inactive on-demand relay */
+ to_go->write_to_client = source->format->write_buf_to_client;
+ client_set_queue (to_go, source->stream_data_tail);
}
- if (drop_client)
- {
- /* shouldn't happen, but don't stall */
- ERROR0 ("dropping pending client");
- to_go->respcode = 200;
- source_free_client (source, to_go);
- }
- else
- {
- to_go->next = source->active_clients;
- source->active_clients = to_go;
- count++;
- }
+
+ to_go->next = source->active_clients;
+ source->active_clients = to_go;
+
+ count++;
source->new_listeners--;
}
source->pending_clients = NULL;
More information about the commits
mailing list