summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2021-02-11 08:30:39 +0100
committerDaniel Stenberg <daniel@haxx.se>2021-02-11 08:35:27 +0100
commit8a964cb217b0cd84783da5ba32b18944fc43feb1 (patch)
treed6201c16d66c0b3fd1d7496ecc9d046479792f5e /src
parentc386a0df441538ee4fbcf6e4bdac77abe5cc3e5d (diff)
downloadcurl-8a964cb217b0cd84783da5ba32b18944fc43feb1.tar.gz
curl: add --fail-with-body
Prevent both --fail and --fail-with-body on the same command line. Verify with test 349, 360 and 361. Closes #6449
Diffstat (limited to 'src')
-rw-r--r--src/tool_cfgable.h1
-rw-r--r--src/tool_getparam.c10
-rw-r--r--src/tool_help.c3
-rw-r--r--src/tool_operate.c23
4 files changed, 29 insertions, 8 deletions
diff --git a/src/tool_cfgable.h b/src/tool_cfgable.h
index 243cbd11b..b5987af07 100644
--- a/src/tool_cfgable.h
+++ b/src/tool_cfgable.h
@@ -118,6 +118,7 @@ struct OperationConfig {
bool use_ascii; /* select ascii or text transfer */
bool autoreferer; /* automatically set referer */
bool failonerror; /* fail on (HTTP) errors */
+ bool failwithbody; /* fail on (HTTP) errors but still store body */
bool show_headers; /* show headers to data output */
bool no_body; /* don't get the body */
bool dirlistonly; /* only get the FTP dir list */
diff --git a/src/tool_getparam.c b/src/tool_getparam.c
index 812ce7fd9..d187643a7 100644
--- a/src/tool_getparam.c
+++ b/src/tool_getparam.c
@@ -280,6 +280,7 @@ static const struct LongShort aliases[]= {
{"fa", "fail-early", ARG_BOOL},
{"fb", "styled-output", ARG_BOOL},
{"fc", "mail-rcpt-allowfails", ARG_BOOL},
+ {"fd", "fail-with-body", ARG_BOOL},
{"F", "form", ARG_STRING},
{"Fs", "form-string", ARG_STRING},
{"g", "globoff", ARG_BOOL},
@@ -1766,8 +1767,17 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
case 'c': /* --mail-rcpt-allowfails */
config->mail_rcpt_allowfails = toggle;
break;
+ case 'd': /* --fail-with-body */
+ config->failwithbody = toggle;
+ break;
default: /* --fail (hard on errors) */
config->failonerror = toggle;
+ break;
+ }
+ if(config->failonerror && config->failwithbody) {
+ errorf(config->global, "You must select either --fail or "
+ "--fail-with-body, not both.\n");
+ return PARAM_BAD_USE;
}
break;
case 'F':
diff --git a/src/tool_help.c b/src/tool_help.c
index b90c6fd05..30a03d959 100644
--- a/src/tool_help.c
+++ b/src/tool_help.c
@@ -268,6 +268,9 @@ static const struct helptxt helptext[] = {
{" --fail-early",
"Fail on first transfer error, do not continue",
CURLHELP_CURL},
+ {" --fail-with-body",
+ "Fail on HTTP errors but save the body",
+ CURLHELP_HTTP | CURLHELP_OUTPUT},
{" --false-start",
"Enable TLS False Start",
CURLHELP_TLS},
diff --git a/src/tool_operate.c b/src/tool_operate.c
index 2b23680f2..6dd2b89d0 100644
--- a/src/tool_operate.c
+++ b/src/tool_operate.c
@@ -369,7 +369,18 @@ static CURLcode post_per_transfer(struct GlobalConfig *global,
if(result == CURLE_PEER_FAILED_VERIFICATION)
fputs(CURL_CA_CERT_ERRORMSG, global->errors);
}
-
+ 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->showerror)
+ fprintf(global->errors,
+ "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) {
int rc = fwrite_xattr(curl, fileno(outs->stream));
@@ -670,7 +681,7 @@ static CURLcode post_per_transfer(struct GlobalConfig *global,
free(per->outfile);
free(per->uploadfile);
- return CURLE_OK;
+ return result;
}
static void single_transfer_cleanup(struct OperationConfig *config)
@@ -2326,18 +2337,14 @@ static CURLcode serial_transfers(struct GlobalConfig *global,
#endif
result = curl_easy_perform(per->curl);
- /* store the result of the actual transfer */
- returncode = result;
-
- result = post_per_transfer(global, per, result, &retry, &delay);
+ returncode = post_per_transfer(global, per, result, &retry, &delay);
if(retry) {
tool_go_sleep(delay);
continue;
}
/* Bail out upon critical errors or --fail-early */
- if(result || is_fatal_error(returncode) ||
- (returncode && global->fail_early))
+ if(is_fatal_error(returncode) || (returncode && global->fail_early))
bailout = TRUE;
else {
/* setup the next one just before we delete this */