]> granicus.if.org Git - transmission/commitdiff
(trunk) #4032 "Better error detection / reporting in http announces" -- added to...
authorJordan Lee <jordan@transmissionbt.com>
Thu, 17 Feb 2011 02:26:24 +0000 (02:26 +0000)
committerJordan Lee <jordan@transmissionbt.com>
Thu, 17 Feb 2011 02:26:24 +0000 (02:26 +0000)
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").

cli/cli.c
gtk/favicon.c
gtk/tr-core.c
libtransmission/announcer.c
libtransmission/rpcimpl.c
libtransmission/web.c
libtransmission/web.h
libtransmission/webseed.c

index a9a2cfc1fec39683ab0e5aadc4d60cfec3fd3ce3..2b93fe1e5825f3aea8703807424e4b9ae9dba389 100644 (file)
--- 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,
index a9eab69777a9e869845c10c4a22d1362659654b4..470c6d7840bce5f6033e8a85703f9050e1de79a1 100644 (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,
index 4e5015a2b2eaa3ad814023abac235cc43c5ba4d9..132eabb68e042aac502da54cb1be7e0e7301c86e 100644 (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 );
index ef4afe8da7a6db284f998e43aab022f1ca597fc4..abc0b024a23bc35d8bd468d58a831d407d55998a 100644 (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 );
index f09ee4cd50e106dc64dfe98b14ae42f34e7b10cb..ed462c7d5f922b25c11422c4c74aa8333bf2f137 100644 (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,
index a160ec842407df15a69c02f4f331b63b1e9c6393..2515c02a3df6d2521a70d8a9a12d55f8d44f5818 100644 (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) );*/
index 896444425fe651bf06636d5e55fa3613a258ec82..7c9b49ed327408463dcfaec5ccecaeb3fbc67aac 100644 (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,
index 88b6dcd1b31bba56f65f4b8a2f87a14ba937bd64..8a3c5164d29c8e07b624a90e27f6ecfc87149ace 100644 (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,