diff options
Diffstat (limited to 'src/input/curl_input_plugin.c')
-rw-r--r-- | src/input/curl_input_plugin.c | 203 |
1 files changed, 22 insertions, 181 deletions
diff --git a/src/input/curl_input_plugin.c b/src/input/curl_input_plugin.c index c6e5a30af..5cfc28fc8 100644 --- a/src/input/curl_input_plugin.c +++ b/src/input/curl_input_plugin.c @@ -42,9 +42,6 @@ #undef G_LOG_DOMAIN #define G_LOG_DOMAIN "input_curl" -/** rewinding is possible after up to 64 kB */ -static const goffset max_rewind_size = 64 * 1024; - /** * Buffers created by input_curl_writefunction(). */ @@ -79,9 +76,6 @@ struct input_curl { /** did libcurl tell us the we're at the end of the response body? */ bool eof; - /** limited list of old buffers, for rewinding */ - GQueue *rewind; - /** error message provided by libcurl */ char error[CURL_ERROR_SIZE]; @@ -179,11 +173,6 @@ input_curl_easy_free(struct input_curl *c) g_queue_foreach(c->buffers, buffer_free_callback, NULL); g_queue_clear(c->buffers); - - if (c->rewind != NULL) { - g_queue_foreach(c->rewind, buffer_free_callback, NULL); - g_queue_clear(c->rewind); - } } /** @@ -204,8 +193,6 @@ input_curl_free(struct input_stream *is) curl_multi_cleanup(c->multi); g_queue_free(c->buffers); - if (c->rewind != NULL) - g_queue_free(c->rewind); g_free(c->url); g_free(c); @@ -330,7 +317,7 @@ fill_buffer(struct input_stream *is, GError **error_r) * Mark a part of the buffer object as consumed. */ static struct buffer * -consume_buffer(struct buffer *buffer, size_t length, GQueue *rewind_buffers) +consume_buffer(struct buffer *buffer, size_t length) { assert(buffer != NULL); assert(buffer->consumed < buffer->size); @@ -341,19 +328,14 @@ consume_buffer(struct buffer *buffer, size_t length, GQueue *rewind_buffers) assert(buffer->consumed == buffer->size); - if (rewind_buffers != NULL) - /* append this buffer to the rewind buffer list */ - g_queue_push_tail(rewind_buffers, buffer); - else - g_free(buffer); + g_free(buffer); return NULL; } static size_t read_from_buffer(struct icy_metadata *icy_metadata, GQueue *buffers, - void *dest0, size_t length, - GQueue *rewind_buffers) + void *dest0, size_t length) { struct buffer *buffer = g_queue_pop_head(buffers); uint8_t *dest = dest0; @@ -372,7 +354,7 @@ read_from_buffer(struct icy_metadata *icy_metadata, GQueue *buffers, if (chunk > 0) { memcpy(dest, buffer->data + buffer->consumed, chunk); - buffer = consume_buffer(buffer, chunk, rewind_buffers); + buffer = consume_buffer(buffer, chunk); nbytes += chunk; dest += chunk; @@ -387,7 +369,7 @@ read_from_buffer(struct icy_metadata *icy_metadata, GQueue *buffers, chunk = icy_meta(icy_metadata, buffer->data + buffer->consumed, length); if (chunk > 0) { - buffer = consume_buffer(buffer, chunk, rewind_buffers); + buffer = consume_buffer(buffer, chunk); length -= chunk; @@ -427,31 +409,9 @@ input_curl_read(struct input_stream *is, void *ptr, size_t size, { struct input_curl *c = is->data; bool success; - GQueue *rewind_buffers; size_t nbytes = 0; char *dest = ptr; -#ifndef NDEBUG - if (c->rewind != NULL && - (!g_queue_is_empty(c->rewind) || is->offset == 0)) { - goffset offset = 0; - struct buffer *buffer; - - for (GList *list = g_queue_peek_head_link(c->rewind); - list != NULL; list = g_list_next(list)) { - buffer = list->data; - offset += buffer->consumed; - assert(offset <= is->offset); - } - - buffer = g_queue_peek_head(c->buffers); - if (buffer != NULL) - offset += buffer->consumed; - - assert(offset == is->offset); - } -#endif - do { /* fill the buffer */ @@ -461,19 +421,9 @@ input_curl_read(struct input_stream *is, void *ptr, size_t size, /* send buffer contents */ - if (c->rewind != NULL && - (!g_queue_is_empty(c->rewind) || is->offset == 0)) - /* at the beginning or already writing the rewind - buffer list */ - rewind_buffers = c->rewind; - else - /* we don't need the rewind buffers anymore */ - rewind_buffers = NULL; - while (size > 0 && !g_queue_is_empty(c->buffers)) { size_t copy = read_from_buffer(&c->icy_metadata, c->buffers, - dest + nbytes, size, - rewind_buffers); + dest + nbytes, size); nbytes += copy; size -= copy; @@ -485,33 +435,6 @@ input_curl_read(struct input_stream *is, void *ptr, size_t size, is->offset += (goffset)nbytes; -#ifndef NDEBUG - if (rewind_buffers != NULL) { - goffset offset = 0; - struct buffer *buffer; - - for (GList *list = g_queue_peek_head_link(c->rewind); - list != NULL; list = g_list_next(list)) { - buffer = list->data; - offset += buffer->consumed; - assert(offset <= is->offset); - } - - buffer = g_queue_peek_head(c->buffers); - if (buffer != NULL) - offset += buffer->consumed; - - assert(offset == is->offset); - } -#endif - - if (rewind_buffers != NULL && is->offset > max_rewind_size) { - /* drop the rewind buffer, it has grown too large */ - - g_queue_foreach(c->rewind, buffer_free_callback, NULL); - g_queue_clear(c->rewind); - } - return nbytes; } @@ -646,15 +569,6 @@ input_curl_headerfunction(void *ptr, size_t size, size_t nmemb, void *stream) /* a stream with icy-metadata is not seekable */ is->seekable = false; - - if (c->rewind != NULL) { - /* rewinding with icy-metadata is too - hairy for me .. */ - assert(g_queue_is_empty(c->rewind)); - - g_queue_free(c->rewind); - c->rewind = NULL; - } } } @@ -752,6 +666,18 @@ input_curl_easy_init(struct input_stream *is, GError **error_r) return true; } +void +input_curl_reinit(struct input_stream *is) +{ + struct input_curl *c = is->data; + + assert(is->plugin == &input_plugin_curl); + assert(c->easy != NULL); + + curl_easy_setopt(c->easy, CURLOPT_WRITEHEADER, is); + curl_easy_setopt(c->easy, CURLOPT_WRITEDATA, is); +} + static bool input_curl_send_request(struct input_curl *c, GError **error_r) { @@ -773,72 +699,6 @@ input_curl_send_request(struct input_curl *c, GError **error_r) } static bool -input_curl_can_rewind(struct input_stream *is) -{ - struct input_curl *c = is->data; - struct buffer *buffer; - - if (c->rewind == NULL) - return false; - - if (!g_queue_is_empty(c->rewind)) - /* the rewind buffer hasn't been wiped yet */ - return true; - - if (g_queue_is_empty(c->buffers)) - /* there are no buffers at all - cheap rewind not - possible */ - return false; - - /* rewind is possible if this is the very first buffer of the - resource */ - buffer = (struct buffer*)g_queue_peek_head(c->buffers); - return (goffset)buffer->consumed == is->offset; -} - -static void -input_curl_rewind(struct input_stream *is) -{ - struct input_curl *c = is->data; -#ifndef NDEBUG - goffset offset = 0; -#endif - - assert(c->rewind != NULL); - - /* rewind the current buffer */ - - if (!g_queue_is_empty(c->buffers)) { - struct buffer *buffer = - (struct buffer*)g_queue_peek_head(c->buffers); -#ifndef NDEBUG - offset += buffer->consumed; -#endif - buffer->consumed = 0; - } - - /* reset and move all rewind buffers back to the regular buffer list */ - - while (!g_queue_is_empty(c->rewind)) { - struct buffer *buffer = - (struct buffer*)g_queue_pop_tail(c->rewind); -#ifndef NDEBUG - offset += buffer->consumed; -#endif - buffer->consumed = 0; - g_queue_push_head(c->buffers, buffer); - } - - assert(offset == is->offset); - - is->offset = 0; - - /* rewind the icy_metadata object */ - - icy_reset(&c->icy_metadata); -} - -static bool input_curl_seek(struct input_stream *is, goffset offset, int whence, GError **error_r) { @@ -847,17 +707,9 @@ input_curl_seek(struct input_stream *is, goffset offset, int whence, assert(is->ready); - if (whence == SEEK_SET && offset == 0) { - if (is->offset == 0) - /* no-op */ - return true; - - if (input_curl_can_rewind(is)) { - /* we have enough rewind buffers left */ - input_curl_rewind(is); - return true; - } - } + if (whence == SEEK_SET && offset == is->offset) + /* no-op */ + return true; if (!is->seekable) return false; @@ -890,26 +742,16 @@ input_curl_seek(struct input_stream *is, goffset offset, int whence, /* check if we can fast-forward the buffer */ while (offset > is->offset && !g_queue_is_empty(c->buffers)) { - GQueue *rewind_buffers; struct buffer *buffer; size_t length; - if (c->rewind != NULL && - (!g_queue_is_empty(c->rewind) || is->offset == 0)) - /* at the beginning or already writing the rewind - buffer list */ - rewind_buffers = c->rewind; - else - /* we don't need the rewind buffers anymore */ - rewind_buffers = NULL; - buffer = (struct buffer *)g_queue_pop_head(c->buffers); length = buffer->size - buffer->consumed; if (offset - is->offset < (goffset)length) length = offset - is->offset; - buffer = consume_buffer(buffer, length, rewind_buffers); + buffer = consume_buffer(buffer, length); if (buffer != NULL) g_queue_push_head(c->buffers, buffer); @@ -962,7 +804,6 @@ input_curl_open(struct input_stream *is, const char *url, GError **error_r) c = g_new0(struct input_curl, 1); c->url = g_strdup(url); c->buffers = g_queue_new(); - c->rewind = g_queue_new(); is->plugin = &input_plugin_curl; is->data = c; |