Mercurial > audlegacy-plugins
changeset 763:58dcfb61cf76 trunk
[svn] Add support for resuming lost connections.
author | iabervon |
---|---|
date | Wed, 28 Feb 2007 23:01:41 -0800 |
parents | 59b4bce10c3b |
children | 5810f14fc8e6 |
files | ChangeLog src/curl/curl.c |
diffstat | 2 files changed, 104 insertions(+), 39 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Wed Feb 28 21:16:10 2007 -0800 +++ b/ChangeLog Wed Feb 28 23:01:41 2007 -0800 @@ -1,3 +1,12 @@ +2007-03-01 05:16:10 +0000 William Pitcock <nenolod@sacredspiral.co.uk> + revision [1622] + - enable seeking on HTTP streams. + + trunk/src/madplug/decoder.c | 2 +- + trunk/src/madplug/plugin.c | 1 - + 2 files changed, 1 insertion(+), 2 deletions(-) + + 2007-03-01 05:02:06 +0000 William Pitcock <nenolod@sacredspiral.co.uk> revision [1620] - support id3 reading of static files
--- a/src/curl/curl.c Wed Feb 28 21:16:10 2007 -0800 +++ b/src/curl/curl.c Wed Feb 28 23:01:41 2007 -0800 @@ -32,7 +32,7 @@ #define REVERSE_SEEK_SIZE 2048 #define DEBUG_CONNECTION 0 -#define DEBUG_OPEN_CLOSE 1 +#define DEBUG_OPEN_CLOSE 0 #define DEBUG_SEEK 0 #define DEBUG_READ 0 #define DEBUG_HEADERS 0 @@ -61,6 +61,7 @@ gsize rd_index; gsize wr_index; + gsize hdrs_start; gsize hdr_index; GSList *stream_stack; // stack for stream functions (getc, ungetc) @@ -399,11 +400,12 @@ // Empty header means the end of the headers handle->header = 0; handle->hdr_index = (i + 2) % handle->buffer_length; - // We read from the start of the data in the request - handle->rd_index = handle->hdr_index; - // We've already written the amount that's after - // the header. - leftover = (handle->wr_index - handle->hdr_index + handle->buffer_length) % handle->buffer_length; + // There's some after the header; we have to put + // it in the buffer where we started the headers + // and account for it in wr_abs. + leftover = (handle->wr_index - handle->hdr_index + + handle->buffer_length) % + handle->buffer_length; handle->wr_abs += leftover; if (handle->download) { @@ -413,6 +415,24 @@ vfs_fwrite(ptr + ret - leftover, leftover, 1, handle->download); } + handle->wr_index = handle->hdrs_start; + if (handle->wr_index + leftover > handle->buffer_length) + { + g_print("Wrapped rewrite\n"); + memcpy(handle->buffer + handle->wr_index, ptr + ret, + handle->buffer_length - handle->wr_index); + memcpy(handle->buffer, ptr + ret + + handle->buffer_length - handle->wr_index, + leftover - handle->buffer_length + + handle->wr_index); + } + else + { + memcpy(handle->buffer + handle->wr_index, ptr + ret, + leftover); + } + handle->wr_index = (handle->wr_index + leftover) % + handle->buffer_length; handle->icy_left = handle->icy_interval; if (handle->icy_interval) { @@ -438,40 +458,60 @@ { CurlHandle *handle = arg; CURLcode result; - if (DEBUG_CONNECTION) - g_print("Connect %p\n", handle); - - if (handle->no_data) - curl_easy_setopt(handle->curl, CURLOPT_NOBODY, 1); - else + do { if (DEBUG_CONNECTION) - g_print("Start from %d\n", handle->wr_abs); - curl_easy_setopt(handle->curl, CURLOPT_RESUME_FROM, handle->wr_abs); + g_print("Connect %p\n", handle); - curl_easy_setopt(handle->curl, CURLOPT_NOBODY, 0); - curl_easy_setopt(handle->curl, CURLOPT_HTTPGET, 1); - } - - handle->header = 1; - handle->hdr_index = 0; - handle->icy_interval = 0; + if (handle->no_data) + curl_easy_setopt(handle->curl, CURLOPT_NOBODY, 1); + else + { + if (DEBUG_CONNECTION) + g_print("Start from %d\n", handle->wr_abs); + curl_easy_setopt(handle->curl, CURLOPT_RESUME_FROM, handle->wr_abs); + + curl_easy_setopt(handle->curl, CURLOPT_NOBODY, 0); + curl_easy_setopt(handle->curl, CURLOPT_HTTPGET, 1); + } + + handle->header = 1; + handle->hdr_index = handle->wr_index; + handle->hdrs_start = handle->wr_index; + handle->icy_interval = 0; - result = curl_easy_perform(handle->curl); - if (result == CURLE_OK) - update_length(handle); - // We expect to get CURLE_WRITE_ERROR if we cancel. - // We get CURLE_GOT_NOTHING if we send a HEAD request to a shoutcast server. - // We get CURLE_HTTP_RANGE_ERROR if we try to use range with shoutcast. - if (result != CURLE_OK && result != CURLE_WRITE_ERROR && - result != CURLE_GOT_NOTHING && result != CURLE_HTTP_RANGE_ERROR && - result != CURLE_PARTIAL_FILE) - { - g_print("Got curl error %d\n", result); - handle->failed = 1; + if (DEBUG_CONNECTION) + g_print("About to perform %p\n", handle); + result = curl_easy_perform(handle->curl); + if (result == CURLE_OK) + { + update_length(handle); + //g_print("Length: %d\n", handle->length); + } + // We expect to get CURLE_WRITE_ERROR if we cancel. + // We get CURLE_GOT_NOTHING if we send a HEAD request to a shoutcast server. + // We get CURLE_HTTP_RANGE_ERROR if we try to use range with shoutcast. + // Why do we get CURLE_PARTIAL_FILE? + if (result != CURLE_OK && result != CURLE_WRITE_ERROR && + result != CURLE_GOT_NOTHING && result != CURLE_HTTP_RANGE_ERROR && + result != CURLE_PARTIAL_FILE) + { + g_print("Got curl error %d\n", result); + handle->failed = 1; + } + if (DEBUG_CONNECTION) + g_print("Got curl error %d\n", result); + if (result == CURLE_PARTIAL_FILE) + { + if (DEBUG_CONNECTION) + g_print("Lost connection %p; restarting\n", handle); + continue; + } + if (DEBUG_CONNECTION) + g_print("Done %p%s", handle, handle->cancel ? " (aborted)\n" : "\n"); + break; } - if (DEBUG_CONNECTION) - g_print("Done %p%s", handle, handle->cancel ? " (aborted)\n" : "\n"); + while (1); handle->cancel = 1; return NULL; } @@ -486,8 +526,8 @@ if (!handle->thread) { handle->cancel = 0; - handle->wr_index = 0; - handle->rd_index = 0; + handle->rd_index = 0; //BUFFER_SIZE - 100; + handle->wr_index = handle->rd_index; handle->wr_abs = handle->rd_abs; if (DEBUG_CONNECTION) g_print("Starting connection %p at %d\n", handle, handle->wr_abs); @@ -827,9 +867,25 @@ if (whence == SEEK_SET) handle->rd_abs = offset; else if (whence == SEEK_END) - handle->rd_abs = handle->length + offset; + { + if (-offset > handle->length) + handle->rd_abs = 0; + else + handle->rd_abs = handle->length + offset; + } else - handle->rd_abs = handle->rd_abs + offset; + { + if (-offset > handle->rd_abs) + handle->rd_abs = 0; + else + handle->rd_abs = handle->rd_abs + offset; + } + + if (handle->rd_abs > handle->length) + { + g_print("Seek before start of file: %d %d = %d\n", posn, offset, + handle->rd_abs); + } // XXXX // There's a race here between finding available space and