From 4d025fd9120603dfbb3a9bd40747d954de9e9147 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 31 Jul 2025 00:02:25 +0200 Subject: [PATCH] curl: make --retry-delay and --retry-max-time accept decimal seconds Like other time options already do. Reported-by: Alice Lee Poetics Fixes #18109 Closes #18111 --- docs/cmdline-opts/retry-delay.md | 7 +++++++ docs/cmdline-opts/retry-max-time.md | 15 ++++++++++----- src/tool_cfgable.h | 4 ++-- src/tool_getparam.c | 4 ++-- src/tool_operate.c | 19 +++++++++---------- 5 files changed, 30 insertions(+), 19 deletions(-) diff --git a/docs/cmdline-opts/retry-delay.md b/docs/cmdline-opts/retry-delay.md index fcee1767a4..25ab1a660b 100644 --- a/docs/cmdline-opts/retry-delay.md +++ b/docs/cmdline-opts/retry-delay.md @@ -9,6 +9,7 @@ Category: curl timeout Multi: single See-also: - retry + - retry-max-time Example: - --retry-delay 5 --retry 7 $URL --- @@ -19,3 +20,9 @@ Make curl sleep this amount of time before each retry when a transfer has failed with a transient error (it changes the default backoff time algorithm between retries). This option is only interesting if --retry is also used. Setting this delay to zero makes curl use the default backoff time. + +By default, curl uses an exponentially increasing timeout between retries. + +Staring in curl 8.16.0, this option accepts a time as decimal number for parts +of seconds. The decimal value needs to be provided using a dot (.) as decimal +separator - not the local version even if it might be using another separator. diff --git a/docs/cmdline-opts/retry-max-time.md b/docs/cmdline-opts/retry-max-time.md index e95a381a45..654b00f393 100644 --- a/docs/cmdline-opts/retry-max-time.md +++ b/docs/cmdline-opts/retry-max-time.md @@ -9,6 +9,7 @@ Category: curl timeout Multi: single See-also: - retry + - retry-delay Example: - --retry-max-time 30 --retry 10 $URL --- @@ -16,8 +17,12 @@ Example: # `--retry-max-time` The retry timer is reset before the first transfer attempt. Retries are done -as usual (see --retry) as long as the timer has not reached this given -limit. Notice that if the timer has not reached the limit, the request is -made and while performing, it may take longer than this given time period. To -limit a single request's maximum time, use --max-time. Set this option to zero -to not timeout retries. +as usual (see --retry) as long as the timer has not reached this given limit. +Notice that if the timer has not reached the limit, the request is made and +while performing, it may take longer than this given time period. To limit a +single request's maximum time, use --max-time. Set this option to zero to not +timeout retries. + +Staring in curl 8.16.0, this option accepts a time as decimal number for parts +of seconds. The decimal value needs to be provided using a dot (.) as decimal +separator - not the local version even if it might be using another separator. diff --git a/src/tool_cfgable.h b/src/tool_cfgable.h index 80411f2cd8..d23902885e 100644 --- a/src/tool_cfgable.h +++ b/src/tool_cfgable.h @@ -212,8 +212,8 @@ struct OperationConfig { long httpversion; unsigned long socks5_auth;/* auth bitmask for socks5 proxies */ long req_retry; /* number of retries */ - long retry_delay; /* delay between retries (in seconds) */ - long retry_maxtime; /* maximum time to keep retrying */ + long retry_delay_ms; /* delay between retries (in milliseconds) */ + long retry_maxtime_ms; /* maximum time to keep retrying */ unsigned long mime_options; /* Mime option flags. */ long tftp_blksize; /* TFTP BLKSIZE option */ diff --git a/src/tool_getparam.c b/src/tool_getparam.c index ad76c8d280..4540a59136 100644 --- a/src/tool_getparam.c +++ b/src/tool_getparam.c @@ -2344,10 +2344,10 @@ static ParameterError opt_filestring(struct OperationConfig *config, err = str2unum(&config->req_retry, nextarg); break; case C_RETRY_DELAY: /* --retry-delay */ - err = str2unummax(&config->retry_delay, nextarg, LONG_MAX/1000); + err = secs2ms(&config->retry_delay_ms, nextarg); break; case C_RETRY_MAX_TIME: /* --retry-max-time */ - err = str2unummax(&config->retry_maxtime, nextarg, LONG_MAX/1000); + err = secs2ms(&config->retry_maxtime_ms, nextarg); break; case C_FTP_ACCOUNT: /* --ftp-account */ err = getstr(&config->ftp_account, nextarg, DENY_BLANK); diff --git a/src/tool_operate.c b/src/tool_operate.c index 17e1c1cf96..7e09528844 100644 --- a/src/tool_operate.c +++ b/src/tool_operate.c @@ -469,12 +469,11 @@ static CURLcode retrycheck(struct OperationConfig *config, /* if adding retry_after seconds to the process would exceed the maximum time allowed for retrying, then exit the retries right away */ - if(config->retry_maxtime) { - curl_off_t seconds = curlx_timediff(curlx_now(), - per->retrystart)/1000; + if(config->retry_maxtime_ms) { + timediff_t ms = curlx_timediff(curlx_now(), per->retrystart); - if((CURL_OFF_T_MAX - retry_after < seconds) || - (seconds + retry_after > config->retry_maxtime)) { + if((CURL_OFF_T_MAX - sleeptime < ms) || + (ms + sleeptime > config->retry_maxtime_ms)) { warnf(config->global, "The Retry-After: time would " "make this command line exceed the maximum allowed time " "for retries."); @@ -493,7 +492,7 @@ static CURLcode retrycheck(struct OperationConfig *config, (per->retry_remaining > 1 ? "ies" : "y")); per->retry_remaining--; - if(!config->retry_delay) { + if(!config->retry_delay_ms) { per->retry_sleep *= 2; if(per->retry_sleep > RETRY_SLEEP_MAX) per->retry_sleep = RETRY_SLEEP_MAX; @@ -659,9 +658,9 @@ static CURLcode post_per_transfer(struct GlobalConfig *global, /* if retry-max-time is non-zero, make sure we have not exceeded the time */ if(per->retry_remaining && - (!config->retry_maxtime || + (!config->retry_maxtime_ms || (curlx_timediff(curlx_now(), per->retrystart) < - config->retry_maxtime*1000L)) ) { + config->retry_maxtime_ms)) ) { result = retrycheck(config, per, result, retryp, delay); if(!result && *retryp) return CURLE_OK; /* retry! */ @@ -1366,8 +1365,8 @@ static CURLcode single_transfer(struct OperationConfig *config, return result; /* initialize retry vars for loop below */ - per->retry_sleep_default = (config->retry_delay) ? - config->retry_delay*1000L : RETRY_SLEEP_DEFAULT; /* ms */ + per->retry_sleep_default = config->retry_delay_ms ? + config->retry_delay_ms : RETRY_SLEEP_DEFAULT; /* ms */ per->retry_remaining = config->req_retry; per->retry_sleep = per->retry_sleep_default; /* ms */ per->retrystart = curlx_now(); -- 2.47.2