diff --git a/src/client.c b/src/client.c index 1eb2f289..2c6efd86 100644 --- a/src/client.c +++ b/src/client.c @@ -514,3 +514,103 @@ int client_body_eof(client_t *client) ICECAST_LOG_DEBUG("... result is: %i (client=%p)", ret, client); return ret; } + +client_slurp_result_t client_body_slurp(client_t *client, void *buf, size_t *len) +{ + if (!client || !buf || !len) + return CLIENT_SLURP_ERROR; + + if (client->request_body_length != -1) { + /* non-streaming mode */ + size_t left = (size_t)client->request_body_length - client->request_body_read; + size_t ret; + + if (!left) + return CLIENT_SLURP_SUCCESS; + + if (*len < client->request_body_length) + return CLIENT_SLURP_BUFFER_TO_SMALL; + + if (left > 2048) + left = 2048; + + client_body_read(client, buf + client->request_body_read, left); + + if (client->request_body_length == client->request_body_read) { + *len = client->request_body_read; + + return CLIENT_SLURP_SUCCESS; + } else { + return CLIENT_SLURP_NEEDS_MORE_DATA; + } + } else { + /* streaming mode */ + size_t left = *len - client->request_body_read; + int ret; + + if (left) { + if (left > 2048) + left = 2048; + + client_body_read(client, buf + client->request_body_read, left); + } + + ret = client_body_eof(client); + switch (ret) { + case 0: + if (*len == client->request_body_read) { + return CLIENT_SLURP_BUFFER_TO_SMALL; + } + return CLIENT_SLURP_NEEDS_MORE_DATA; + break; + case 1: + return CLIENT_SLURP_SUCCESS; + break; + default: + return CLIENT_SLURP_ERROR; + break; + } + } +} + +client_slurp_result_t client_body_skip(client_t *client) +{ + char buf[2048]; + int ret; + + if (!client) + return CLIENT_SLURP_ERROR; + + if (client->request_body_length != -1) { + size_t left = (size_t)client->request_body_length - client->request_body_read; + + if (!left) + return CLIENT_SLURP_SUCCESS; + + if (left > sizeof(buf)) + left = sizeof(buf); + + client_body_read(client, buf, left); + + if (client->request_body_length == client->request_body_read) { + return CLIENT_SLURP_SUCCESS; + } else { + return CLIENT_SLURP_NEEDS_MORE_DATA; + } + } else { + client_body_read(client, buf, sizeof(buf)); + } + + ret = client_body_eof(client); + switch (ret) { + case 0: + return CLIENT_SLURP_NEEDS_MORE_DATA; + break; + case 1: + return CLIENT_SLURP_SUCCESS; + break; + default: + return CLIENT_SLURP_ERROR; + break; + } +} diff --git a/src/client.h b/src/client.h index c9a845ea..f097fa67 100644 --- a/src/client.h +++ b/src/client.h @@ -43,6 +43,13 @@ typedef enum _reuse_tag { ICECAST_REUSE_UPGRADETLS } reuse_t; +typedef enum { + CLIENT_SLURP_ERROR, + CLIENT_SLURP_NEEDS_MORE_DATA, + CLIENT_SLURP_BUFFER_TO_SMALL, + CLIENT_SLURP_SUCCESS +} client_slurp_result_t; + struct _client_tag { /* mode of operation for this client */ operation_mode mode; @@ -132,5 +139,7 @@ int client_read_bytes (client_t *client, void *buf, unsigned len); void client_set_queue (client_t *client, refbuf_t *refbuf); ssize_t client_body_read(client_t *client, void *buf, size_t len); int client_body_eof(client_t *client); +client_slurp_result_t client_body_slurp(client_t *client, void *buf, size_t *len); +client_slurp_result_t client_body_skip(client_t *client); #endif /* __CLIENT_H__ */