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
This commit is contained in:
Daniel Stenberg 2025-07-31 00:02:25 +02:00
parent 3bfcfe82b9
commit 4d025fd912
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
5 changed files with 30 additions and 19 deletions

View file

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

View file

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

View file

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