mirror of
https://gitlab.xiph.org/xiph/icecast-server.git
synced 2024-12-04 14:46:30 -05:00
cleanup patch, push per client write error trap lower down
svn path=/icecast/trunk/icecast/; revision=7165
This commit is contained in:
parent
b8304fc73e
commit
94d24f406e
19
src/client.c
19
src/client.c
@ -33,6 +33,9 @@
|
|||||||
#include "client.h"
|
#include "client.h"
|
||||||
#include "logging.h"
|
#include "logging.h"
|
||||||
|
|
||||||
|
#undef CATMODULE
|
||||||
|
#define CATMODULE "client"
|
||||||
|
|
||||||
client_t *client_create(connection_t *con, http_parser_t *parser)
|
client_t *client_create(connection_t *con, http_parser_t *parser)
|
||||||
{
|
{
|
||||||
client_t *client = (client_t *)calloc(1, sizeof(client_t));
|
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->respcode = 403;
|
||||||
client_destroy(client);
|
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_401(client_t *client);
|
||||||
void client_send_403(client_t *client);
|
void client_send_403(client_t *client);
|
||||||
void client_send_400(client_t *client, char *message);
|
void client_send_400(client_t *client, char *message);
|
||||||
|
int client_send_bytes (client_t *client, const void *buf, unsigned len);
|
||||||
|
|
||||||
#endif /* __CLIENT_H__ */
|
#endif /* __CLIENT_H__ */
|
||||||
|
15
src/format.c
15
src/format.c
@ -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,
|
int format_generic_write_buf_to_client(format_plugin_t *format,
|
||||||
client_t *client, unsigned char *buf, int len)
|
client_t *client, unsigned char *buf, int len)
|
||||||
{
|
{
|
||||||
int ret;
|
return client_send_bytes (client, buf, len);
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void format_send_general_headers(format_plugin_t *format,
|
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));
|
thread_mutex_unlock (&(source_state->lock));
|
||||||
|
|
||||||
/* only write what hasn't been written already */
|
/* 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) {
|
if (ret > 0 && ret < len) {
|
||||||
client_state->metadata_offset += ret;
|
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,
|
static int format_mp3_write_buf_to_client(format_plugin_t *self,
|
||||||
client_t *client, unsigned char *buf, int len)
|
client_t *client, unsigned char *buf, int len)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret = 0;
|
||||||
mp3_client_data *mp3data = client->format_data;
|
mp3_client_data *mp3data = client->format_data;
|
||||||
|
|
||||||
if(((mp3_state *)self->_state)->metadata && mp3data->use_metadata)
|
if(((mp3_state *)self->_state)->metadata && mp3data->use_metadata)
|
||||||
@ -203,31 +204,19 @@ static int format_mp3_write_buf_to_client(format_plugin_t *self,
|
|||||||
max = len;
|
max = len;
|
||||||
|
|
||||||
if(max > 0) {
|
if(max > 0) {
|
||||||
ret = sock_write_bytes(client->con->sock, buf, max);
|
ret = client_send_bytes (client, buf, max);
|
||||||
if(ret > 0)
|
if(ret > 0)
|
||||||
state->offset += ret;
|
state->offset += ret;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ret = send_metadata(client, state, self->_state);
|
send_metadata (client, state, self->_state);
|
||||||
if(ret > 0)
|
|
||||||
client->con->sent_bytes += ret;
|
|
||||||
ret = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ret = sock_write_bytes(client->con->sock, buf, len);
|
ret = client_send_bytes (client, 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 ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
12
src/fserve.c
12
src/fserve.c
@ -247,24 +247,14 @@ static void *fserv_thread_function(void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Now try and send current chunk. */
|
/* 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->buf[client->offset],
|
||||||
client->datasize - client->offset);
|
client->datasize - client->offset);
|
||||||
|
|
||||||
/* TODO: remove clients if they take too long. */
|
/* TODO: remove clients if they take too long. */
|
||||||
if(sbytes >= 0) {
|
if(sbytes >= 0) {
|
||||||
client->offset += sbytes;
|
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);
|
avl_node_unlock(client_node);
|
||||||
client_node = avl_get_next(client_node);
|
client_node = avl_get_next(client_node);
|
||||||
}
|
}
|
||||||
|
42
src/source.c
42
src/source.c
@ -584,33 +584,24 @@ void source_main (source_t *source)
|
|||||||
/* do we have any old buffers? */
|
/* do we have any old buffers? */
|
||||||
abuf = refbuf_queue_remove(&client->queue);
|
abuf = refbuf_queue_remove(&client->queue);
|
||||||
while (abuf) {
|
while (abuf) {
|
||||||
if (client->pos > 0)
|
bytes = abuf->len - client->pos;
|
||||||
bytes = abuf->len - client->pos;
|
|
||||||
else
|
|
||||||
bytes = abuf->len;
|
|
||||||
|
|
||||||
sbytes = source->format->write_buf_to_client(source->format,
|
sbytes = source->format->write_buf_to_client(source->format,
|
||||||
client, &abuf->data[client->pos], bytes);
|
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
|
/* We didn't send the entire buffer. Leave it for
|
||||||
* the moment, handle it in the next iteration.
|
* the moment, handle it in the next iteration.
|
||||||
*/
|
*/
|
||||||
client->pos += sbytes;
|
client->pos += sbytes<0?0:sbytes;
|
||||||
refbuf_queue_insert(&client->queue, abuf);
|
refbuf_queue_insert (&client->queue, abuf);
|
||||||
data_done = 1;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else {
|
|
||||||
DEBUG0("Client has unrecoverable error catching up. "
|
|
||||||
"Client has probably disconnected");
|
|
||||||
client->con->error = 1;
|
|
||||||
data_done = 1;
|
data_done = 1;
|
||||||
refbuf_release(abuf);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we're done with that refbuf, release it and reset the pos */
|
/* we're done with that refbuf, release it and reset the pos */
|
||||||
refbuf_release(abuf);
|
refbuf_release(abuf);
|
||||||
client->pos = 0;
|
client->pos = 0;
|
||||||
@ -625,18 +616,11 @@ void source_main (source_t *source)
|
|||||||
} else {
|
} else {
|
||||||
sbytes = source->format->write_buf_to_client(source->format,
|
sbytes = source->format->write_buf_to_client(source->format,
|
||||||
client, refbuf->data, refbuf->len);
|
client, refbuf->data, refbuf->len);
|
||||||
if (sbytes >= 0) {
|
if (client->con->error == 0 && sbytes < refbuf->len) {
|
||||||
if(sbytes != refbuf->len) {
|
/* Didn't send the entire buffer, queue it */
|
||||||
/* Didn't send the entire buffer, queue it */
|
client->pos = sbytes<0?0:sbytes;
|
||||||
client->pos = sbytes;
|
refbuf_addref(refbuf);
|
||||||
refbuf_addref(refbuf);
|
refbuf_queue_insert(&client->queue, 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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user