getparam: make --rate accept "number of units"

Do no more than 5 transfers per 15 seconds with "5/15s" or limit it to 3
transfers per 4 hours with "3/4h" etc.

Previously it would always only work with a single time unit.

Ref: #14242
Closes #14245
This commit is contained in:
Daniel Stenberg 2024-07-20 17:54:44 +02:00
parent 2d8464c4cb
commit b80798c24d
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
2 changed files with 26 additions and 0 deletions

View File

@ -40,3 +40,7 @@ more than 1000 per second, it instead runs unrestricted.
When retrying transfers, enabled with --retry, the separate retry delay logic
is used and not this setting.
Starting in version 8.10.0, you can specify number of time units in the rate
expression. Make curl do no more than 5 transfers per 15 seconds with "5/15s"
or limit it to 3 transfers per 4 hours with "3/4h". No spaces allowed.

View File

@ -1244,6 +1244,20 @@ static ParameterError set_rate(struct GlobalConfig *global,
if(div) {
char unit = div[1];
curl_off_t numunits;
char *endp;
if(curlx_strtoofft(&div[1], &endp, 10, &numunits)) {
/* if it fails, there is no legit number specified */
if(endp == &div[1])
/* if endp did not move, accept it as a 1 */
numunits = 1;
else
return PARAM_BAD_USE;
}
else
unit = *endp;
switch(unit) {
case 's': /* per second */
numerator = 1000;
@ -1261,6 +1275,14 @@ static ParameterError set_rate(struct GlobalConfig *global,
err = PARAM_BAD_USE;
break;
}
if((LONG_MAX / numerator) < numunits) {
/* overflow, too large number */
errorf(global, "too large --rate unit");
err = PARAM_NUMBER_TOO_LARGE;
}
/* this typecast is okay based on the check above */
numerator *= (long)numunits;
}
if(err)