tool_operate: make retrycheck() a separate function

Simplifies post_per_transfer()

Closes #17381
This commit is contained in:
Daniel Stenberg 2025-05-19 09:58:42 +02:00
parent c26da713e7
commit dd22442e3b
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2

View File

@ -361,102 +361,14 @@ void single_transfer_cleanup(struct OperationConfig *config)
}
}
/*
* Call this after a transfer has completed.
*/
static CURLcode post_per_transfer(struct GlobalConfig *global,
static CURLcode retrycheck(struct OperationConfig *config,
struct per_transfer *per,
CURLcode result,
bool *retryp,
long *delay) /* milliseconds! */
long *delayms)
{
struct OutStruct *outs = &per->outs;
CURL *curl = per->curl;
struct OperationConfig *config = per->config;
int rc;
*retryp = FALSE;
*delay = 0; /* for no retry, keep it zero */
if(!curl || !config)
return result;
if(per->infdopen)
close(per->infd);
if(per->skip)
goto skip;
#ifdef __VMS
if(is_vms_shell()) {
/* VMS DCL shell behavior */
if(global->silent && !global->showerror)
vms_show = VMSSTS_HIDE;
}
else
#endif
if(!config->synthetic_error && result &&
(!global->silent || global->showerror)) {
const char *msg = per->errorbuffer;
fprintf(tool_stderr, "curl: (%d) %s\n", result,
(msg && msg[0]) ? msg : curl_easy_strerror(result));
if(result == CURLE_PEER_FAILED_VERIFICATION)
fputs(CURL_CA_CERT_ERRORMSG, tool_stderr);
}
else if(config->failwithbody) {
/* if HTTP response >= 400, return error */
long code = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code);
if(code >= 400) {
if(!global->silent || global->showerror)
fprintf(tool_stderr,
"curl: (%d) The requested URL returned error: %ld\n",
CURLE_HTTP_RETURNED_ERROR, code);
result = CURLE_HTTP_RETURNED_ERROR;
}
}
/* Set file extended attributes */
if(!result && config->xattr && outs->fopened && outs->stream) {
rc = fwrite_xattr(curl, per->url, fileno(outs->stream));
if(rc)
warnf(config->global, "Error setting extended attributes on '%s': %s",
outs->filename, strerror(errno));
}
if(!result && !outs->stream && !outs->bytes) {
/* we have received no data despite the transfer was successful
==> force creation of an empty output file (if an output file
was specified) */
long cond_unmet = 0L;
/* do not create (or even overwrite) the file in case we get no
data because of unmet condition */
curl_easy_getinfo(curl, CURLINFO_CONDITION_UNMET, &cond_unmet);
if(!cond_unmet && !tool_create_output_file(outs, config))
result = CURLE_WRITE_ERROR;
}
if(!outs->s_isreg && outs->stream) {
/* Dump standard stream buffered data */
rc = fflush(outs->stream);
if(!result && rc) {
/* something went wrong in the writing process */
result = CURLE_WRITE_ERROR;
errorf(global, "Failed writing body");
}
}
#ifdef _WIN32
/* Discard incomplete UTF-8 sequence buffered from body */
if(outs->utf8seq[0])
memset(outs->utf8seq, 0, sizeof(outs->utf8seq));
#endif
/* if retry-max-time is non-zero, make sure we have not exceeded the
time */
if(per->retry_remaining &&
(!config->retry_maxtime ||
(curlx_timediff(curlx_now(), per->retrystart) <
config->retry_maxtime*1000L)) ) {
struct OutStruct *outs = &per->outs;
enum {
RETRY_NO,
RETRY_ALL_ERRORS,
@ -568,7 +480,8 @@ static CURLcode post_per_transfer(struct GlobalConfig *global,
warnf(config->global, "The Retry-After: time would "
"make this command line exceed the maximum allowed time "
"for retries.");
goto noretry;
*retryp = FALSE;
return CURLE_OK; /* no retry */
}
}
}
@ -600,6 +513,7 @@ static CURLcode post_per_transfer(struct GlobalConfig *global,
/* Windows CE's fileno() is bad so just skip the check */
#endif
{
int rc;
/* We have written data to an output file, we truncate file */
fflush(outs->stream);
notef(config->global,
@ -633,11 +547,112 @@ static CURLcode post_per_transfer(struct GlobalConfig *global,
}
*retryp = TRUE;
per->num_retries++;
*delay = sleeptime;
return CURLE_OK;
*delayms = sleeptime;
}
return CURLE_OK;
}
/*
* Call this after a transfer has completed.
*/
static CURLcode post_per_transfer(struct GlobalConfig *global,
struct per_transfer *per,
CURLcode result,
bool *retryp,
long *delay) /* milliseconds! */
{
struct OutStruct *outs = &per->outs;
CURL *curl = per->curl;
struct OperationConfig *config = per->config;
int rc;
*retryp = FALSE;
*delay = 0; /* for no retry, keep it zero */
if(!curl || !config)
return result;
if(per->infdopen)
close(per->infd);
if(per->skip)
goto skip;
#ifdef __VMS
if(is_vms_shell()) {
/* VMS DCL shell behavior */
if(global->silent && !global->showerror)
vms_show = VMSSTS_HIDE;
}
else
#endif
if(!config->synthetic_error && result &&
(!global->silent || global->showerror)) {
const char *msg = per->errorbuffer;
fprintf(tool_stderr, "curl: (%d) %s\n", result,
(msg && msg[0]) ? msg : curl_easy_strerror(result));
if(result == CURLE_PEER_FAILED_VERIFICATION)
fputs(CURL_CA_CERT_ERRORMSG, tool_stderr);
}
else if(config->failwithbody) {
/* if HTTP response >= 400, return error */
long code = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code);
if(code >= 400) {
if(!global->silent || global->showerror)
fprintf(tool_stderr,
"curl: (%d) The requested URL returned error: %ld\n",
CURLE_HTTP_RETURNED_ERROR, code);
result = CURLE_HTTP_RETURNED_ERROR;
}
}
/* Set file extended attributes */
if(!result && config->xattr && outs->fopened && outs->stream) {
rc = fwrite_xattr(curl, per->url, fileno(outs->stream));
if(rc)
warnf(config->global, "Error setting extended attributes on '%s': %s",
outs->filename, strerror(errno));
}
if(!result && !outs->stream && !outs->bytes) {
/* we have received no data despite the transfer was successful
==> force creation of an empty output file (if an output file
was specified) */
long cond_unmet = 0L;
/* do not create (or even overwrite) the file in case we get no
data because of unmet condition */
curl_easy_getinfo(curl, CURLINFO_CONDITION_UNMET, &cond_unmet);
if(!cond_unmet && !tool_create_output_file(outs, config))
result = CURLE_WRITE_ERROR;
}
if(!outs->s_isreg && outs->stream) {
/* Dump standard stream buffered data */
rc = fflush(outs->stream);
if(!result && rc) {
/* something went wrong in the writing process */
result = CURLE_WRITE_ERROR;
errorf(global, "Failed writing body");
}
}
#ifdef _WIN32
/* Discard incomplete UTF-8 sequence buffered from body */
if(outs->utf8seq[0])
memset(outs->utf8seq, 0, sizeof(outs->utf8seq));
#endif
/* if retry-max-time is non-zero, make sure we have not exceeded the
time */
if(per->retry_remaining &&
(!config->retry_maxtime ||
(curlx_timediff(curlx_now(), per->retrystart) <
config->retry_maxtime*1000L)) ) {
result = retrycheck(config, per, result, retryp, delay);
if(!result && *retryp)
return CURLE_OK; /* retry! */
}
} /* if retry_remaining */
noretry:
if((global->progressmode == CURL_PROGRESS_BAR) &&
per->progressbar.calls)