1
0
mirror of https://gitlab.xiph.org/xiph/icecast-common.git synced 2024-11-03 04:17:20 -05:00

Feature: Allow checking for transfer encoding EOF

This commit is contained in:
Philipp Schafft 2018-04-17 08:59:42 +00:00
parent 829cd5f3b6
commit 308e73134c
2 changed files with 56 additions and 1 deletions

View File

@ -56,6 +56,7 @@ struct httpp_encoding_tag {
size_t buf_write_encoded_offset, buf_write_encoded_len; size_t buf_write_encoded_offset, buf_write_encoded_len;
/* backend specific stuff */ /* backend specific stuff */
ssize_t bytes_till_eof;
size_t read_bytes_till_header; size_t read_bytes_till_header;
}; };
@ -182,6 +183,7 @@ httpp_encoding_t *httpp_encoding_new(const char *encoding) {
return NULL; return NULL;
ret->refc = 1; ret->refc = 1;
ret->bytes_till_eof = -1;
if (strcasecmp(encoding, HTTPP_ENCODING_IDENTITY) == 0) { if (strcasecmp(encoding, HTTPP_ENCODING_IDENTITY) == 0) {
ret->process_read = __enc_identity_read; ret->process_read = __enc_identity_read;
@ -279,6 +281,23 @@ ssize_t httpp_encoding_read(httpp_encoding_t *self, void *buf, size_t
return done; return done;
} }
int httpp_encoding_eof(httpp_encoding_t *self, int (*cb)(void*), void *userdata)
{
if (!self)
return -1;
if (self->buf_read_decoded_len - self->buf_read_decoded_offset)
return 0;
if (self->bytes_till_eof == 0)
return 1;
if (cb)
return cb(userdata);
return 0;
}
/* Read any meta data that is in buffer. /* Read any meta data that is in buffer.
* After a call to this function the meta data is released from the * After a call to this function the meta data is released from the
* encoding object and the caller is responsible to free it. * encoding object and the caller is responsible to free it.
@ -493,7 +512,11 @@ static ssize_t __enc_chunked_read(httpp_encoding_t *self, void *buf, size_t len,
/* ok. now we should have 2 or less bytes till next header. /* ok. now we should have 2 or less bytes till next header.
* We just read a few bytes into our decoding buffer and see what we got. * We just read a few bytes into our decoding buffer and see what we got.
*/ */
if (self->bytes_till_eof != -1) {
buflen = self->bytes_till_eof;
} else {
buflen = 1024; buflen = 1024;
}
if (self->buf_read_raw) { if (self->buf_read_raw) {
bufptr = realloc(self->buf_read_raw, self->buf_read_raw_len + buflen); bufptr = realloc(self->buf_read_raw, self->buf_read_raw_len + buflen);
@ -540,6 +563,15 @@ static ssize_t __enc_chunked_read(httpp_encoding_t *self, void *buf, size_t len,
self->read_bytes_till_header = 0; self->read_bytes_till_header = 0;
} }
/* Check if we reached EOF */
if (self->bytes_till_eof != -1) {
if (self->read_bytes_till_header == 0)
self->bytes_till_eof = 0;
if (self->bytes_till_eof == 0)
return 0;
}
/* ok. next we have at least a little bit if a header. /* ok. next we have at least a little bit if a header.
* Now we need to find out if the header is complet. * Now we need to find out if the header is complet.
* If it is we will process it. If it isn't we will * If it is we will process it. If it isn't we will
@ -608,6 +640,10 @@ static ssize_t __enc_chunked_read(httpp_encoding_t *self, void *buf, size_t len,
/* ok, Now we move the offset forward to the body. */ /* ok, Now we move the offset forward to the body. */
self->buf_read_raw_offset = offset_LF + 1; self->buf_read_raw_offset = offset_LF + 1;
if (!bodylen) {
self->bytes_till_eof = 2; /* 2 = tailing "\r\n" */
}
/* Do we still have some data in buffer? /* Do we still have some data in buffer?
* If not free the buffer and set the counters * If not free the buffer and set the counters
* to point to the next header. * to point to the next header.
@ -649,6 +685,20 @@ static ssize_t __enc_chunked_read(httpp_encoding_t *self, void *buf, size_t len,
self->buf_read_raw_offset += bodylen; self->buf_read_raw_offset += bodylen;
self->read_bytes_till_header = 2; /* tailing "\r\n" */ self->read_bytes_till_header = 2; /* tailing "\r\n" */
if ((self->buf_read_raw_len - self->buf_read_raw_offset) >= 2) {
self->buf_read_raw_offset += 2;
self->read_bytes_till_header = 0;
if (self->bytes_till_eof != -1)
self->bytes_till_eof = 0;
if ((self->buf_read_raw_len - self->buf_read_raw_offset) == 0) {
free(self->buf_read_raw);
self->buf_read_raw = NULL;
self->buf_read_raw_len = 0;
self->buf_read_raw_offset = 0;
}
}
return 0; return 0;
} }

View File

@ -60,6 +60,11 @@ int httpp_encoding_release(httpp_encoding_t *self);
*/ */
ssize_t httpp_encoding_read(httpp_encoding_t *self, void *buf, size_t len, ssize_t (*cb)(void*, void*, size_t), void *userdata); ssize_t httpp_encoding_read(httpp_encoding_t *self, void *buf, size_t len, ssize_t (*cb)(void*, void*, size_t), void *userdata);
/* Check if EOF is reached.
* If cb is not NULL this also considers backend state.
*/
int httpp_encoding_eof(httpp_encoding_t *self, int (*cb)(void*), void *userdata);
/* Read any meta data that is in buffer. /* Read any meta data that is in buffer.
* After a call to this function the meta data is released from the * After a call to this function the meta data is released from the
* encoding object and the caller is responsible to free it. * encoding object and the caller is responsible to free it.