]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
curl: support -w '%{num_retries}
authorDaniel Stenberg <daniel@haxx.se>
Fri, 7 Jun 2024 22:18:44 +0000 (00:18 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Tue, 11 Jun 2024 07:07:43 +0000 (09:07 +0200)
Suggested-by: Jay Guerette
Ref: https://github.com/curl/curl/discussions/13901
Closes #13910

docs/cmdline-opts/write-out.md
src/tool_operate.c
src/tool_operate.h
src/tool_writeout.c
src/tool_writeout.h
tests/data/test196
tests/data/test970
tests/data/test972

index bb1422c99e3689f8768ab4b66659be8a7238be5b..97cb1fe37b94b27fa0264a6242f3453f8c711100 100644 (file)
@@ -130,6 +130,10 @@ redirect). Note that the status line IS NOT a header. (Added in 7.73.0)
 ## `num_redirects`
 Number of redirects that were followed in the request. (Added in 7.12.3)
 
+## `num_retries`
+Number of retries actually performed when `--retry` has been used.
+(Added in 8.9.0)
+
 ## `onerror`
 The rest of the output is only shown if the transfer returned a non-zero error.
 (Added in 7.75.0)
index 0f36a08ce86aacdfbae37dd658daede051c1c7e5..1caf8f0e8e0c60b6db5da5128c5d8dab380a3081 100644 (file)
@@ -510,7 +510,7 @@ static CURLcode post_per_transfer(struct GlobalConfig *global,
 
   /* if retry-max-time is non-zero, make sure we haven't exceeded the
      time */
-  if(per->retry_numretries &&
+  if(per->retry_remaining &&
      (!config->retry_maxtime ||
       (tvdiff(tvnow(), per->retrystart) <
        config->retry_maxtime*1000L)) ) {
@@ -632,9 +632,9 @@ static CURLcode post_per_transfer(struct GlobalConfig *global,
       warnf(config->global, "Problem %s. "
             "Will retry in %ld seconds. "
             "%ld retries left.",
-            m[retry], sleeptime/1000L, per->retry_numretries);
+            m[retry], sleeptime/1000L, per->retry_remaining);
 
-      per->retry_numretries--;
+      per->retry_remaining--;
       if(!config->retry_delay) {
         per->retry_sleep *= 2;
         if(per->retry_sleep > RETRY_SLEEP_MAX)
@@ -672,10 +672,11 @@ static CURLcode post_per_transfer(struct GlobalConfig *global,
         outs->bytes = 0; /* clear for next round */
       }
       *retryp = TRUE;
+      per->num_retries++;
       *delay = sleeptime;
       return CURLE_OK;
     }
-  } /* if retry_numretries */
+  } /* if retry_remaining */
 noretry:
 
   if((global->progressmode == CURL_PROGRESS_BAR) &&
@@ -2265,7 +2266,7 @@ static CURLcode single_transfer(struct GlobalConfig *global,
         /* initialize retry vars for loop below */
         per->retry_sleep_default = (config->retry_delay) ?
           config->retry_delay*1000L : RETRY_SLEEP_DEFAULT; /* ms */
-        per->retry_numretries = config->req_retry;
+        per->retry_remaining = config->req_retry;
         per->retry_sleep = per->retry_sleep_default; /* ms */
         per->retrystart = tvnow();
 
index 4993b1c961f711d0dfd8b3a2b32604221fbc4709..820ac1395d91a3a529f6827dd6ee10cc8f4eabfe 100644 (file)
@@ -35,9 +35,10 @@ struct per_transfer {
   struct OperationConfig *config; /* for this transfer */
   struct curl_certinfo *certinfo;
   CURL *curl;
-  long retry_numretries;
+  long retry_remaining;
   long retry_sleep_default;
   long retry_sleep;
+  long num_retries; /* counts the performed retries */
   struct timeval start; /* start of this transfer */
   struct timeval retrystart;
   char *this_url;
index d30a2b8412b7f762ee9016cd8d2aa5359a021699..a52e5f7d6dd236acf1ae31c7c88124f05d31c6cb 100644 (file)
@@ -92,6 +92,7 @@ static const struct writeoutvar variables[] = {
   {"num_connects", VAR_NUM_CONNECTS, CURLINFO_NUM_CONNECTS, writeLong},
   {"num_headers", VAR_NUM_HEADERS, CURLINFO_NONE, writeLong},
   {"num_redirects", VAR_REDIRECT_COUNT, CURLINFO_REDIRECT_COUNT, writeLong},
+  {"num_retries", VAR_NUM_RETRY, CURLINFO_NONE, writeLong},
   {"onerror", VAR_ONERROR, CURLINFO_NONE, NULL},
   {"proxy_ssl_verify_result", VAR_PROXY_SSL_VERIFY_RESULT,
    CURLINFO_PROXY_SSL_VERIFYRESULT, writeLong},
@@ -443,6 +444,10 @@ static int writeLong(FILE *stream, const struct writeoutvar *wovar,
   }
   else {
     switch(wovar->id) {
+    case VAR_NUM_RETRY:
+      longinfo = per->num_retries;
+      valid = true;
+      break;
     case VAR_NUM_CERTS:
       certinfo(per);
       longinfo = per->certinfo ? per->certinfo->num_of_certs : 0;
index 0b9e3cbb1c51d628916aff33bdb7ef574bbe2120..36b218cc447ab37d2e9ddd32cf09f92905824ef1 100644 (file)
@@ -74,6 +74,7 @@ typedef enum {
   VAR_NUM_CERTS,
   VAR_NUM_CONNECTS,
   VAR_NUM_HEADERS,
+  VAR_NUM_RETRY,
   VAR_ONERROR,
   VAR_PRETRANSFER_TIME,
   VAR_PRIMARY_IP,
index b1a684f10808a3f58ecc864fa582c137ef104d76..c72cbebf49ec6dd66617c686da1ffc5502e92f82 100644 (file)
@@ -22,7 +22,7 @@ ftp
 FTP transient error, retry request once
 </name>
 <command>
-ftp://%HOSTIP:%FTPPORT/%TESTNUMBER --retry 1
+ftp://%HOSTIP:%FTPPORT/%TESTNUMBER --retry 1 -w '%{num_retries}\n'
 </command>
 </client>
 
@@ -38,5 +38,8 @@ PASS ftp@example.com
 USER anonymous\r
 PASS ftp@example.com\r
 </protocol>
+<stdout>
+1
+</stdout>
 </verify>
 </testcase>
index 2f336e9f1064d5e4f8a7c10c53de0eedd0d3da02..4b77ad6b7f3a45cddf4d317e1ae1af7b002e0a3a 100644 (file)
@@ -59,7 +59,7 @@ Accept: */*
 \r
 </protocol>
 <stdout nonewline="yes">
-{"certs":"","conn_id":0,"content_type":"text/html","errormsg":null,"exitcode":0,"filename_effective":"%LOGDIR/out%TESTNUMBER","ftp_entry_path":null,"http_code":200,"http_connect":0,"http_version":"1.1","local_ip":"127.0.0.1","local_port":13,"method":"GET","num_certs":0,"num_connects":1,"num_headers":9,"num_redirects":0,"proxy_ssl_verify_result":0,"proxy_used":0,"redirect_url":null,"referer":null,"remote_ip":"%HOSTIP","remote_port":%HTTPPORT,"response_code":200,"scheme":"http","size_download":445,"size_header":4019,"size_request":4019,"size_upload":0,"speed_download":13,"speed_upload":13,"ssl_verify_result":0,"time_appconnect":0.000013,"time_connect":0.000013,"time_namelookup":0.000013,"time_pretransfer":0.000013,"time_redirect":0.000013,"time_starttransfer":0.000013,"time_total":0.000013,"url":"http://%HOSTIP:%HTTPPORT/%TESTNUMBER","url.fragment":null,"url.host":"127.0.0.1","url.options":null,"url.password":null,"url.path":"/%TESTNUMBER","url.port":"%HTTPPORT","url.query":null,"url.scheme":"http","url.user":null,"url.zoneid":null,"url_effective":"http://%HOSTIP:%HTTPPORT/%TESTNUMBER","urle.fragment":null,"urle.host":"127.0.0.1","urle.options":null,"urle.password":null,"urle.path":"/%TESTNUMBER","urle.port":"%HTTPPORT","urle.query":null,"urle.scheme":"http","urle.user":null,"urle.zoneid":null,"urlnum":0,"xfer_id":0,"curl_version":"curl-unit-test-fake-version"}
+{"certs":"","conn_id":0,"content_type":"text/html","errormsg":null,"exitcode":0,"filename_effective":"%LOGDIR/out%TESTNUMBER","ftp_entry_path":null,"http_code":200,"http_connect":0,"http_version":"1.1","local_ip":"127.0.0.1","local_port":13,"method":"GET","num_certs":0,"num_connects":1,"num_headers":9,"num_redirects":0,"num_retries":0,"proxy_ssl_verify_result":0,"proxy_used":0,"redirect_url":null,"referer":null,"remote_ip":"%HOSTIP","remote_port":%HTTPPORT,"response_code":200,"scheme":"http","size_download":445,"size_header":4019,"size_request":4019,"size_upload":0,"speed_download":13,"speed_upload":13,"ssl_verify_result":0,"time_appconnect":0.000013,"time_connect":0.000013,"time_namelookup":0.000013,"time_pretransfer":0.000013,"time_redirect":0.000013,"time_starttransfer":0.000013,"time_total":0.000013,"url":"http://%HOSTIP:%HTTPPORT/%TESTNUMBER","url.fragment":null,"url.host":"127.0.0.1","url.options":null,"url.password":null,"url.path":"/%TESTNUMBER","url.port":"%HTTPPORT","url.query":null,"url.scheme":"http","url.user":null,"url.zoneid":null,"url_effective":"http://%HOSTIP:%HTTPPORT/%TESTNUMBER","urle.fragment":null,"urle.host":"127.0.0.1","urle.options":null,"urle.password":null,"urle.path":"/%TESTNUMBER","urle.port":"%HTTPPORT","urle.query":null,"urle.scheme":"http","urle.user":null,"urle.zoneid":null,"urlnum":0,"xfer_id":0,"curl_version":"curl-unit-test-fake-version"}
 </stdout>
 </verify>
 </testcase>
index 367eb39d86347994c96dd6f36cfcb91c30a68e60..3ac080dc53f69a26ddcbe9dd02772be7e41549a9 100644 (file)
@@ -60,7 +60,7 @@ Accept: */*
 \r
 </protocol>
 <stdout mode="text">
-{"certs":"","conn_id":0,"content_type":"text/html","errormsg":null,"exitcode":0,"filename_effective":"%LOGDIR/out%TESTNUMBER","ftp_entry_path":null,"http_code":200,"http_connect":0,"http_version":"1.1","local_ip":"127.0.0.1","local_port":13,"method":"GET","num_certs":0,"num_connects":1,"num_headers":9,"num_redirects":0,"proxy_ssl_verify_result":0,"proxy_used":0,"redirect_url":null,"referer":null,"remote_ip":"%HOSTIP","remote_port":%HTTPPORT,"response_code":200,"scheme":"http","size_download":445,"size_header":4019,"size_request":4019,"size_upload":0,"speed_download":13,"speed_upload":13,"ssl_verify_result":0,"time_appconnect":0.000013,"time_connect":0.000013,"time_namelookup":0.000013,"time_pretransfer":0.000013,"time_redirect":0.000013,"time_starttransfer":0.000013,"time_total":0.000013,"url":"http://%HOSTIP:%HTTPPORT/%TESTNUMBER","url.fragment":null,"url.host":"127.0.0.1","url.options":null,"url.password":null,"url.path":"/%TESTNUMBER","url.port":"%HTTPPORT","url.query":null,"url.scheme":"http","url.user":null,"url.zoneid":null,"url_effective":"http://%HOSTIP:%HTTPPORT/%TESTNUMBER","urle.fragment":null,"urle.host":"127.0.0.1","urle.options":null,"urle.password":null,"urle.path":"/%TESTNUMBER","urle.port":"%HTTPPORT","urle.query":null,"urle.scheme":"http","urle.user":null,"urle.zoneid":null,"urlnum":0,"xfer_id":0,"curl_version":"curl-unit-test-fake-version"}
+{"certs":"","conn_id":0,"content_type":"text/html","errormsg":null,"exitcode":0,"filename_effective":"%LOGDIR/out%TESTNUMBER","ftp_entry_path":null,"http_code":200,"http_connect":0,"http_version":"1.1","local_ip":"127.0.0.1","local_port":13,"method":"GET","num_certs":0,"num_connects":1,"num_headers":9,"num_redirects":0,"num_retries":0,"proxy_ssl_verify_result":0,"proxy_used":0,"redirect_url":null,"referer":null,"remote_ip":"%HOSTIP","remote_port":%HTTPPORT,"response_code":200,"scheme":"http","size_download":445,"size_header":4019,"size_request":4019,"size_upload":0,"speed_download":13,"speed_upload":13,"ssl_verify_result":0,"time_appconnect":0.000013,"time_connect":0.000013,"time_namelookup":0.000013,"time_pretransfer":0.000013,"time_redirect":0.000013,"time_starttransfer":0.000013,"time_total":0.000013,"url":"http://%HOSTIP:%HTTPPORT/%TESTNUMBER","url.fragment":null,"url.host":"127.0.0.1","url.options":null,"url.password":null,"url.path":"/%TESTNUMBER","url.port":"%HTTPPORT","url.query":null,"url.scheme":"http","url.user":null,"url.zoneid":null,"url_effective":"http://%HOSTIP:%HTTPPORT/%TESTNUMBER","urle.fragment":null,"urle.host":"127.0.0.1","urle.options":null,"urle.password":null,"urle.path":"/%TESTNUMBER","urle.port":"%HTTPPORT","urle.query":null,"urle.scheme":"http","urle.user":null,"urle.zoneid":null,"urlnum":0,"xfer_id":0,"curl_version":"curl-unit-test-fake-version"}
 </stdout>
 </verify>
 </testcase>