Commit 94d24f40 authored by Karl Heyes's avatar Karl Heyes

cleanup patch, push per client write error trap lower down

svn path=/icecast/trunk/icecast/; revision=7165
parent b8304fc7
......@@ -33,6 +33,9 @@
#include "client.h"
#include "logging.h"
#undef CATMODULE
#define CATMODULE "client"
client_t *client_create(connection_t *con, http_parser_t *parser)
{
client_t *client = (client_t *)calloc(1, sizeof(client_t));
......@@ -125,3 +128,19 @@ void client_send_403(client_t *client) {
client->respcode = 403;
client_destroy(client);
}
/* helper function for sending the data to a client */
int client_send_bytes (client_t *client, const void *buf, unsigned len)
{
int ret = sock_write_bytes (client->con->sock, buf, len);
if (ret < 0 && !sock_recoverable (sock_error()))
{
DEBUG0 ("Client connection died");
client->con->error = 1;
}
if (ret > 0)
client->con->sent_bytes += ret;
return ret;
}
......@@ -55,5 +55,6 @@ void client_send_404(client_t *client, char *message);
void client_send_401(client_t *client);
void client_send_403(client_t *client);
void client_send_400(client_t *client, char *message);
int client_send_bytes (client_t *client, const void *buf, unsigned len);
#endif /* __CLIENT_H__ */
......@@ -100,20 +100,7 @@ format_plugin_t *format_get_plugin(format_type_t type, char *mount,
int format_generic_write_buf_to_client(format_plugin_t *format,
client_t *client, unsigned char *buf, int len)
{
int ret;
ret = sock_write_bytes(client->con->sock, buf, len);
if(ret < 0) {
if(sock_recoverable(sock_error())) {
DEBUG1("Client had recoverable error %ld", ret);
ret = 0;
}
}
else
client->con->sent_bytes += ret;
return ret;
return client_send_bytes (client, buf, len);
}
void format_send_general_headers(format_plugin_t *format,
......
......@@ -164,7 +164,8 @@ static int send_metadata(client_t *client, mp3_client_data *client_state,
thread_mutex_unlock (&(source_state->lock));
/* only write what hasn't been written already */
ret = sock_write_bytes (client->con->sock, buf+client_state->metadata_offset, len-client_state->metadata_offset);
ret = client_send_bytes (client, buf + client_state->metadata_offset,
len - client_state->metadata_offset);
if (ret > 0 && ret < len) {
client_state->metadata_offset += ret;
......@@ -188,7 +189,7 @@ static int send_metadata(client_t *client, mp3_client_data *client_state,
static int format_mp3_write_buf_to_client(format_plugin_t *self,
client_t *client, unsigned char *buf, int len)
{
int ret;
int ret = 0;
mp3_client_data *mp3data = client->format_data;
if(((mp3_state *)self->_state)->metadata && mp3data->use_metadata)
......@@ -203,30 +204,18 @@ static int format_mp3_write_buf_to_client(format_plugin_t *self,
max = len;
if(max > 0) {
ret = sock_write_bytes(client->con->sock, buf, max);
ret = client_send_bytes (client, buf, max);
if(ret > 0)
state->offset += ret;
}
else {
ret = send_metadata(client, state, self->_state);
if(ret > 0)
client->con->sent_bytes += ret;
ret = 0;
send_metadata (client, state, self->_state);
}
}
else {
ret = sock_write_bytes(client->con->sock, buf, len);
}
if(ret < 0) {
if(sock_recoverable(sock_error())) {
DEBUG1("Client had recoverable error %ld", ret);
ret = 0;
}
ret = client_send_bytes (client, buf, len);
}
else
client->con->sent_bytes += ret;
return ret;
}
......
......@@ -247,24 +247,14 @@ static void *fserv_thread_function(void *arg)
}
/* Now try and send current chunk. */
sbytes = sock_write_bytes(client->client->con->sock,
sbytes = client_send_bytes (client->client,
&client->buf[client->offset],
client->datasize - client->offset);
/* TODO: remove clients if they take too long. */
if(sbytes >= 0) {
client->offset += sbytes;
client->client->con->sent_bytes += sbytes;
}
else if(!sock_recoverable(sock_error())) {
DEBUG0("Fileserving client had fatal error, disconnecting");
client->client->con->error = 1;
}
/*
else
DEBUG0("Fileserving client had recoverable error");
*/
avl_node_unlock(client_node);
client_node = avl_get_next(client_node);
}
......
......@@ -584,33 +584,24 @@ void source_main (source_t *source)
/* do we have any old buffers? */
abuf = refbuf_queue_remove(&client->queue);
while (abuf) {
if (client->pos > 0)
bytes = abuf->len - client->pos;
else
bytes = abuf->len;
bytes = abuf->len - client->pos;
sbytes = source->format->write_buf_to_client(source->format,
client, &abuf->data[client->pos], bytes);
if (sbytes >= 0) {
if(sbytes != bytes) {
if (sbytes < bytes) {
if (client->con->error) {
refbuf_release (abuf);
}
else {
/* We didn't send the entire buffer. Leave it for
* the moment, handle it in the next iteration.
*/
client->pos += sbytes;
refbuf_queue_insert(&client->queue, abuf);
data_done = 1;
break;
client->pos += sbytes<0?0:sbytes;
refbuf_queue_insert (&client->queue, abuf);
}
}
else {
DEBUG0("Client has unrecoverable error catching up. "
"Client has probably disconnected");
client->con->error = 1;
data_done = 1;
refbuf_release(abuf);
break;
}
/* we're done with that refbuf, release it and reset the pos */
refbuf_release(abuf);
client->pos = 0;
......@@ -625,18 +616,11 @@ void source_main (source_t *source)
} else {
sbytes = source->format->write_buf_to_client(source->format,
client, refbuf->data, refbuf->len);
if (sbytes >= 0) {
if(sbytes != refbuf->len) {
/* Didn't send the entire buffer, queue it */
client->pos = sbytes;
refbuf_addref(refbuf);
refbuf_queue_insert(&client->queue, refbuf);
}
}
else {
DEBUG0("Client had unrecoverable error with new data, "
"probably due to client disconnection");
client->con->error = 1;
if (client->con->error == 0 && sbytes < refbuf->len) {
/* Didn't send the entire buffer, queue it */
client->pos = sbytes<0?0:sbytes;
refbuf_addref(refbuf);
refbuf_queue_insert(&client->queue, refbuf);
}
}
......
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