# HG changeset patch # User iabervon # Date 1169175165 28800 # Node ID cc7faecc761975519717c8b1a94d789c521c6bef # Parent cea6393eacc377e96ff688432b50f4f76702af69 [svn] Time out curl connections eventually, and don't retry them on the same VFSFile. diff -r cea6393eacc3 -r cc7faecc7619 ChangeLog --- a/ChangeLog Wed Jan 17 10:50:00 2007 -0800 +++ b/ChangeLog Thu Jan 18 18:52:45 2007 -0800 @@ -1,3 +1,10 @@ +2007-01-17 18:50:00 +0000 Jonathan Schleifer + revision [1002] + D'oh, a 2 was missing. + trunk/src/wavpack/tags.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + + 2007-01-17 18:49:17 +0000 Jonathan Schleifer revision [1000] Fixed possible buffer overflow. diff -r cea6393eacc3 -r cc7faecc7619 src/curl/curl.c --- a/src/curl/curl.c Wed Jan 17 10:50:00 2007 -0800 +++ b/src/curl/curl.c Thu Jan 18 18:52:45 2007 -0800 @@ -24,6 +24,12 @@ #include #define BUFFER_SIZE 256 * 1024 +#define REVERSE_SEEK_SIZE 2048 + +#define DEBUG_CONNECTION 0 +#define DEBUG_OPEN_CLOSE 0 +#define DEBUG_SEEK 0 +#define DEBUG_READ 0 typedef struct _CurlHandle CurlHandle; @@ -42,6 +48,7 @@ gboolean no_data; // true if we're only looking for length currently gboolean cancel; // true if the thread should be cancelled + gboolean failed; // true if we've tried and failed already GThread *thread; // the thread that's reading from the connection }; @@ -59,7 +66,7 @@ static size_t buf_space(CurlHandle *handle) { - size_t rd_edge = handle->rd_abs - 2048; + size_t rd_edge = handle->rd_abs - REVERSE_SEEK_SIZE; if (rd_edge < 0) rd_edge = 0; size_t buffer_limit = handle->buffer_length - @@ -145,13 +152,15 @@ { CurlHandle *handle = arg; CURLcode result; - //g_print("Connect %p\n", handle); + if (DEBUG_CONNECTION) + g_print("Connect %p\n", handle); if (handle->no_data) curl_easy_setopt(handle->curl, CURLOPT_NOBODY, 1); else { - //g_print("Start from %d\n", handle->wr_abs); + 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); @@ -161,24 +170,35 @@ result = curl_easy_perform(handle->curl); if (result == CURLE_OK) update_length(handle); - if (result != CURLE_OK && result != CURLE_WRITE_ERROR) + // 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. + if (result != CURLE_OK && result != CURLE_WRITE_ERROR && + result != CURLE_GOT_NOTHING) { g_print("Got curl error %d\n", result); + handle->failed = 1; } - //g_print("Done %p%s", handle, handle->cancel ? " (aborted)\n" : "\n"); + if (DEBUG_CONNECTION) + g_print("Done %p%s", handle, handle->cancel ? " (aborted)\n" : "\n"); handle->cancel = 1; return NULL; } static void curl_req_xfer(CurlHandle *handle) { + if (handle->failed) + { + handle->cancel = 1; + return; + } if (!handle->thread) { handle->cancel = 0; handle->wr_index = 0; handle->rd_index = 0; handle->wr_abs = handle->rd_abs; - //g_print("Starting connection %p at %d\n", handle, handle->wr_abs); + if (DEBUG_CONNECTION) + g_print("Starting connection %p at %d\n", handle, handle->wr_abs); handle->thread = g_thread_create(curl_manage_request, handle, TRUE, NULL); } @@ -226,14 +246,17 @@ handle->thread = NULL; handle->length = -1; handle->cancel = 0; + handle->failed = 0; handle->no_data = 0; curl_easy_setopt(handle->curl, CURLOPT_URL, url); curl_easy_setopt(handle->curl, CURLOPT_WRITEFUNCTION, curl_writecb); curl_easy_setopt(handle->curl, CURLOPT_WRITEDATA, handle); + curl_easy_setopt(handle->curl, CURLOPT_CONNECTTIMEOUT, 10); file->handle = handle; - //g_print("Open %s with curl => %p\n", url, handle); + if (DEBUG_OPEN_CLOSE) + g_print("Open %s with curl => %p\n", url, handle); return file; } @@ -244,13 +267,16 @@ gint ret = 0; if (file == NULL) return -1; - //g_print("Close %p\n", file->handle); + if (DEBUG_OPEN_CLOSE) + g_print("Close %p\n", file->handle); if (file->handle) { CurlHandle *handle = file->handle; - //g_print("Cancel transfer\n"); + if (DEBUG_CONNECTION) + g_print("Cancel transfer\n"); curl_req_no_xfer(handle); - //g_print("Okay\n"); + if (DEBUG_CONNECTION) + g_print("Okay\n"); g_free(handle->buffer); curl_easy_cleanup(handle->curl); @@ -335,16 +361,19 @@ { size_t posn; CurlHandle *handle = file->handle; - //g_print("Seek %p to %d %d\n", handle, offset, whence); + if (DEBUG_SEEK) + g_print("Seek %p to %d %d\n", handle, offset, whence); if (whence == SEEK_END && handle->length == -1) { if (!handle->thread) { // We need a HEAD to find out the length handle->no_data = 1; - //g_print("Request for head info\n"); + if (DEBUG_CONNECTION) + g_print("Request for head info\n"); curl_manage_request(handle); - //g_print("Completed\n"); + if (DEBUG_CONNECTION) + g_print("Completed\n"); handle->no_data = 0; } else @@ -378,18 +407,22 @@ if (handle->rd_abs + handle->buffer_length < handle->wr_abs || handle->rd_abs > handle->wr_abs) { - //g_print("Stop transfer\n"); + if (DEBUG_CONNECTION) + g_print("Stop transfer\n"); curl_req_no_xfer(handle); - //g_print("Okay\n"); + if (DEBUG_CONNECTION) + g_print("Okay\n"); } else { - //g_print("Continue transfer\n"); + if (DEBUG_CONNECTION) + g_print("Continue transfer\n"); curl_req_sync_xfer(handle, posn); } } - //g_print("Seeked %p from %d to %d\n", handle, posn, handle->rd_abs); + if (DEBUG_SEEK) + g_print("Seeked %p from %d to %d\n", handle, posn, handle->rd_abs); return 0; }