(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").
This commit is contained in:
Jordan Lee 2011-02-17 02:26:24 +00:00
parent e4fb51a778
commit 716a3c90c2
8 changed files with 51 additions and 8 deletions

View File

@ -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,

View File

@ -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,

View File

@ -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 );

View File

@ -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 );

View File

@ -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,

View File

@ -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) );*/

View File

@ -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,

View File

@ -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,