diff options
author | Daniel Stenberg <daniel@haxx.se> | 2021-02-11 08:30:39 +0100 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2021-02-11 08:35:27 +0100 |
commit | 8a964cb217b0cd84783da5ba32b18944fc43feb1 (patch) | |
tree | d6201c16d66c0b3fd1d7496ecc9d046479792f5e /src | |
parent | c386a0df441538ee4fbcf6e4bdac77abe5cc3e5d (diff) | |
download | curl-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.h | 1 | ||||
-rw-r--r-- | src/tool_getparam.c | 10 | ||||
-rw-r--r-- | src/tool_help.c | 3 | ||||
-rw-r--r-- | src/tool_operate.c | 23 |
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 */ |