From: Jordan Lee Date: Thu, 17 Feb 2011 02:26:24 +0000 (+0000) Subject: (trunk) #4032 "Better error detection / reporting in http announces" -- added to... X-Git-Tag: 2.30b1~358 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=716a3c90c2cc761f9fa4851852a7da03d014dd42;p=transmission (trunk) #4032 "Better error detection / reporting in http announces" -- added to trunk. This patch adds two new flags to the callback function -- did_connect and did_timeout -- that are calculated inside of web.c using information from libcurl. This allows the announcer to detect timeouts more accurately and also to distinguish between unresponsive peers (which get the preexisting "Tracker did not respond" error message) and unconnectable peers (which get a new error message, "Could not connect to tracker"). --- diff --git a/cli/cli.c b/cli/cli.c index a9a2cfc1f..2b93fe1e5 100644 --- a/cli/cli.c +++ b/cli/cli.c @@ -131,6 +131,8 @@ static tr_bool waitingOnWeb; static void onTorrentFileDownloaded( tr_session * session UNUSED, + tr_bool did_connect UNUSED, + tr_bool did_timeout UNUSED, long response_code UNUSED, const void * response, size_t response_byte_count, diff --git a/gtk/favicon.c b/gtk/favicon.c index a9eab6977..470c6d784 100644 --- a/gtk/favicon.c +++ b/gtk/favicon.c @@ -81,7 +81,7 @@ favicon_load_from_cache( const char * host ) return pixbuf; } -static void favicon_web_done_cb( tr_session*, long, const void*, size_t, void* ); +static void favicon_web_done_cb( tr_session*, tr_bool, tr_bool, long, const void*, size_t, void* ); static gboolean favicon_web_done_idle_cb( gpointer vfav ) @@ -129,6 +129,8 @@ favicon_web_done_idle_cb( gpointer vfav ) static void favicon_web_done_cb( tr_session * session UNUSED, + tr_bool did_connect UNUSED, + tr_bool did_timeout UNUSED, long code UNUSED, const void * data, size_t len, diff --git a/gtk/tr-core.c b/gtk/tr-core.c index 4e5015a2b..132eabb68 100644 --- a/gtk/tr-core.c +++ b/gtk/tr-core.c @@ -1055,6 +1055,9 @@ struct url_dialog_data TrCore * core; tr_ctor * ctor; char * url; + + tr_bool did_connect; + tr_bool did_timeout; long response_code; }; @@ -1088,6 +1091,8 @@ onURLDoneIdle( gpointer vdata ) static void onURLDone( tr_session * session, + tr_bool did_connect, + tr_bool did_timeout, long response_code, const void * response, size_t response_byte_count, @@ -1095,6 +1100,8 @@ onURLDone( tr_session * session, { struct url_dialog_data * data = vdata; + data->did_connect = did_connect; + data->did_timeout = did_timeout; data->response_code = response_code; data->ctor = tr_ctorNew( session ); tr_core_apply_defaults( data->ctor ); diff --git a/libtransmission/announcer.c b/libtransmission/announcer.c index ef4afe8da..abc0b024a 100644 --- a/libtransmission/announcer.c +++ b/libtransmission/announcer.c @@ -1036,6 +1036,8 @@ struct announce_data static void onAnnounceDone( tr_session * session, + tr_bool didConnect, + tr_bool didTimeout, long responseCode, const void * response, size_t responseLen, @@ -1052,7 +1054,7 @@ onAnnounceDone( tr_session * session, tr_tracker_item * tracker; tier->lastAnnounceTime = now; - tier->lastAnnounceTimedOut = responseCode == 0; + tier->lastAnnounceTimedOut = didTimeout; tier->lastAnnounceSucceeded = FALSE; tier->isAnnouncing = FALSE; tier->manualAnnounceAllowedAt = now + tier->announceMinIntervalSec; @@ -1105,9 +1107,11 @@ onAnnounceDone( tr_session * session, { int interval; - if( !responseCode ) - tr_strlcpy( tier->lastAnnounceStr, - _( "Tracker did not respond" ), + if( !didConnect ) + tr_strlcpy( tier->lastAnnounceStr, _( "Could not connect to tracker" ), + sizeof( tier->lastAnnounceStr ) ); + else if( !responseCode ) + tr_strlcpy( tier->lastAnnounceStr, _( "Tracker did not respond" ), sizeof( tier->lastAnnounceStr ) ); else { /* %1$ld - http status code, such as 404 @@ -1308,6 +1312,8 @@ parseScrapeResponse( tr_tier * tier, static void onScrapeDone( tr_session * session, + tr_bool didConnect, + tr_bool didTimeout, long responseCode, const void * response, size_t responseLen, @@ -1363,7 +1369,10 @@ onScrapeDone( tr_session * session, /* %1$ld - http status code, such as 404 * %2$s - human-readable explanation of the http status code */ - if( !responseCode ) + if( !didConnect ) + tr_strlcpy( tier->lastScrapeStr, _( "Could not connect to tracker" ), + sizeof( tier->lastScrapeStr ) ); + else if( !responseCode ) tr_strlcpy( tier->lastScrapeStr, _( "tracker did not respond" ), sizeof( tier->lastScrapeStr ) ); else @@ -1373,7 +1382,7 @@ onScrapeDone( tr_session * session, } tier->lastScrapeSucceeded = success; - tier->lastScrapeTimedOut = responseCode == 0; + tier->lastScrapeTimedOut = didTimeout; } tr_free( data ); diff --git a/libtransmission/rpcimpl.c b/libtransmission/rpcimpl.c index f09ee4cd5..ed462c7d5 100644 --- a/libtransmission/rpcimpl.c +++ b/libtransmission/rpcimpl.c @@ -1066,6 +1066,8 @@ torrentSetLocation( tr_session * session, static void portTested( tr_session * session UNUSED, + tr_bool did_connect UNUSED, + tr_bool did_timeout UNUSED, long response_code, const void * response, size_t response_byte_count, @@ -1108,6 +1110,8 @@ portTest( tr_session * session, static void gotNewBlocklist( tr_session * session, + tr_bool did_connect UNUSED, + tr_bool did_timeout UNUSED, long response_code, const void * response, size_t response_byte_count, @@ -1252,6 +1256,8 @@ struct add_torrent_idle_data static void gotMetadataFromURL( tr_session * session UNUSED, + tr_bool did_connect UNUSED, + tr_bool did_timeout UNUSED, long response_code, const void * response, size_t response_byte_count, diff --git a/libtransmission/web.c b/libtransmission/web.c index a160ec842..2515c02a3 100644 --- a/libtransmission/web.c +++ b/libtransmission/web.c @@ -72,6 +72,9 @@ struct tr_web struct tr_web_task { long code; + long timeout_secs; + tr_bool did_connect; + tr_bool did_timeout; struct evbuffer * response; struct evbuffer * freebuf; char * url; @@ -150,6 +153,8 @@ createEasy( tr_session * s, struct tr_web_task * task ) const long verbose = getenv( "TR_CURL_VERBOSE" ) != NULL; char * cookie_filename = tr_buildPath( s->configDir, "cookies.txt", NULL ); + task->timeout_secs = getTimeoutFromURL( task ); + curl_easy_setopt( e, CURLOPT_AUTOREFERER, 1L ); curl_easy_setopt( e, CURLOPT_COOKIEFILE, cookie_filename ); curl_easy_setopt( e, CURLOPT_ENCODING, "gzip;q=1.0, deflate, identity" ); @@ -163,7 +168,7 @@ createEasy( tr_session * s, struct tr_web_task * task ) #endif curl_easy_setopt( e, CURLOPT_SSL_VERIFYHOST, 0L ); curl_easy_setopt( e, CURLOPT_SSL_VERIFYPEER, 0L ); - curl_easy_setopt( e, CURLOPT_TIMEOUT, getTimeoutFromURL( task ) ); + curl_easy_setopt( e, CURLOPT_TIMEOUT, task->timeout_secs ); curl_easy_setopt( e, CURLOPT_URL, task->url ); curl_easy_setopt( e, CURLOPT_USERAGENT, TR_NAME "/" SHORT_VERSION_STRING ); curl_easy_setopt( e, CURLOPT_VERBOSE, verbose ); @@ -197,6 +202,8 @@ task_finish_func( void * vtask ) if( task->done_func != NULL ) task->done_func( task->session, + task->did_connect, + task->did_timeout, task->code, evbuffer_pullup( task->response, -1 ), evbuffer_get_length( task->response ), @@ -364,10 +371,16 @@ tr_webThreadFunc( void * vsession ) { if(( msg->msg == CURLMSG_DONE ) && ( msg->easy_handle != NULL )) { + double total_time; struct tr_web_task * task; + long req_bytes_sent; CURL * e = msg->easy_handle; curl_easy_getinfo( e, CURLINFO_PRIVATE, (void*)&task ); curl_easy_getinfo( e, CURLINFO_RESPONSE_CODE, &task->code ); + curl_easy_getinfo( e, CURLINFO_REQUEST_SIZE, &req_bytes_sent ); + curl_easy_getinfo( e, CURLINFO_TOTAL_TIME, &total_time ); + task->did_connect = task->code>0 || req_bytes_sent>0; + task->did_timeout = !task->code && ( total_time >= task->timeout_secs ); curl_multi_remove_handle( multi, e ); curl_easy_cleanup( e ); /*fprintf( stderr, "removing a completed task.. taskCount is now %d (response code: %d, response len: %d)\n", taskCount, (int)task->code, (int)evbuffer_get_length(task->response) );*/ diff --git a/libtransmission/web.h b/libtransmission/web.h index 896444425..7c9b49ed3 100644 --- a/libtransmission/web.h +++ b/libtransmission/web.h @@ -43,6 +43,8 @@ void tr_sessionSetWebConfigFunc( tr_session * session, void (*config)(tr_session void tr_webClose( tr_session * session, tr_web_close_mode close_mode ); typedef void ( tr_web_done_func )( tr_session * session, + tr_bool timeout_flag, + tr_bool did_connect_flag, long response_code, const void * response, size_t response_byte_count, diff --git a/libtransmission/webseed.c b/libtransmission/webseed.c index 88b6dcd1b..8a3c5164d 100644 --- a/libtransmission/webseed.c +++ b/libtransmission/webseed.c @@ -196,6 +196,8 @@ on_idle( tr_webseed * w ) static void web_response_func( tr_session * session, + tr_bool did_connect UNUSED, + tr_bool did_timeout UNUSED, long response_code, const void * response UNUSED, size_t response_byte_count UNUSED,