mirror of
https://github.com/curl/curl.git
synced 2025-09-09 21:52:40 +03:00
tool_operate: make retrycheck() a separate function
Simplifies post_per_transfer() Closes #17381
This commit is contained in:
parent
c26da713e7
commit
dd22442e3b
|
@ -361,102 +361,14 @@ void single_transfer_cleanup(struct OperationConfig *config)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static CURLcode retrycheck(struct OperationConfig *config,
|
||||||
* Call this after a transfer has completed.
|
|
||||||
*/
|
|
||||||
static CURLcode post_per_transfer(struct GlobalConfig *global,
|
|
||||||
struct per_transfer *per,
|
struct per_transfer *per,
|
||||||
CURLcode result,
|
CURLcode result,
|
||||||
bool *retryp,
|
bool *retryp,
|
||||||
long *delay) /* milliseconds! */
|
long *delayms)
|
||||||
{
|
{
|
||||||
struct OutStruct *outs = &per->outs;
|
|
||||||
CURL *curl = per->curl;
|
CURL *curl = per->curl;
|
||||||
struct OperationConfig *config = per->config;
|
struct OutStruct *outs = &per->outs;
|
||||||
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)) ) {
|
|
||||||
enum {
|
enum {
|
||||||
RETRY_NO,
|
RETRY_NO,
|
||||||
RETRY_ALL_ERRORS,
|
RETRY_ALL_ERRORS,
|
||||||
|
@ -568,7 +480,8 @@ static CURLcode post_per_transfer(struct GlobalConfig *global,
|
||||||
warnf(config->global, "The Retry-After: time would "
|
warnf(config->global, "The Retry-After: time would "
|
||||||
"make this command line exceed the maximum allowed time "
|
"make this command line exceed the maximum allowed time "
|
||||||
"for retries.");
|
"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 */
|
/* Windows CE's fileno() is bad so just skip the check */
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
int rc;
|
||||||
/* We have written data to an output file, we truncate file */
|
/* We have written data to an output file, we truncate file */
|
||||||
fflush(outs->stream);
|
fflush(outs->stream);
|
||||||
notef(config->global,
|
notef(config->global,
|
||||||
|
@ -633,11 +547,112 @@ static CURLcode post_per_transfer(struct GlobalConfig *global,
|
||||||
}
|
}
|
||||||
*retryp = TRUE;
|
*retryp = TRUE;
|
||||||
per->num_retries++;
|
per->num_retries++;
|
||||||
*delay = sleeptime;
|
*delayms = sleeptime;
|
||||||
return CURLE_OK;
|
}
|
||||||
|
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) &&
|
if((global->progressmode == CURL_PROGRESS_BAR) &&
|
||||||
per->progressbar.calls)
|
per->progressbar.calls)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user