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").
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,
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 )
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,
TrCore * core;
tr_ctor * ctor;
char * url;
+
+ tr_bool did_connect;
+ tr_bool did_timeout;
long response_code;
};
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,
{
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 );
static void
onAnnounceDone( tr_session * session,
+ tr_bool didConnect,
+ tr_bool didTimeout,
long responseCode,
const void * response,
size_t responseLen,
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;
{
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
static void
onScrapeDone( tr_session * session,
+ tr_bool didConnect,
+ tr_bool didTimeout,
long responseCode,
const void * response,
size_t responseLen,
/* %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
}
tier->lastScrapeSucceeded = success;
- tier->lastScrapeTimedOut = responseCode == 0;
+ tier->lastScrapeTimedOut = didTimeout;
}
tr_free( data );
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,
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,
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,
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;
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" );
#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 );
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 ),
{
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) );*/
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,
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,