tool_getparam: make --fail and --fail-with-body override each other

This allows users to put one of them in their .curlrc and still easily
use the other one at will in command lines.

The --no-* versions disable both of them.

Reported-by: Mitchell Blank Jr
Fixes #19029
Closes #19034
This commit is contained in:
Daniel Stenberg 2025-10-12 15:58:43 +02:00
parent 56450ce26f
commit 27375ca364
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
5 changed files with 38 additions and 26 deletions

View File

@ -851,7 +851,7 @@ CURLcode config2setopts(struct OperationConfig *config,
if(result)
return result;
my_setopt_long(curl, CURLOPT_FAILONERROR, config->failonerror);
my_setopt_long(curl, CURLOPT_FAILONERROR, config->fail == FAIL_WO_BODY);
my_setopt_str(curl, CURLOPT_REQUEST_TARGET, config->request_target);
my_setopt_long(curl, CURLOPT_UPLOAD, !!per->uploadfile);
my_setopt_long(curl, CURLOPT_DIRLISTONLY, config->dirlistonly);

View File

@ -58,6 +58,10 @@ struct State {
curl_off_t urlidx; /* index for globbed URLs */
};
#define FAIL_NONE 0
#define FAIL_WITH_BODY 1
#define FAIL_WO_BODY 2
struct OperationConfig {
struct dynbuf postdata;
char *useragent;
@ -223,6 +227,7 @@ struct OperationConfig {
unsigned short porttouse;
unsigned char ssl_version; /* 0 - 4, 0 being default */
unsigned char ssl_version_max; /* 0 - 4, 0 being default */
unsigned char fail; /* NONE, with body, without body */
BIT(remote_name_all); /* --remote-name-all */
BIT(remote_time);
BIT(cookiesession); /* new session? */
@ -241,8 +246,6 @@ struct OperationConfig {
BIT(ftp_append); /* APPE on ftp */
BIT(use_ascii); /* select ASCII or text transfer */
BIT(autoreferer); /* automatically set referer */
BIT(failonerror); /* fail on (HTTP) errors */
BIT(failwithbody); /* fail on (HTTP) errors but still store body */
BIT(show_headers); /* show headers to data output */
BIT(no_body); /* do not get the body */
BIT(dirlistonly); /* only get the FTP dir list */

View File

@ -2037,14 +2037,6 @@ static ParameterError opt_bool(struct OperationConfig *config,
case C_MAIL_RCPT_ALLOWFAILS: /* --mail-rcpt-allowfails */
config->mail_rcpt_allowfails = toggle;
break;
case C_FAIL_WITH_BODY: /* --fail-with-body */
config->failwithbody = toggle;
if(config->failonerror && config->failwithbody) {
errorf("You must select either --fail or "
"--fail-with-body, not both.");
return PARAM_BAD_USE;
}
break;
case C_REMOVE_ON_ERROR: /* --remove-on-error */
if(config->use_resume && toggle) {
errorf("--continue-at is mutually exclusive with --remove-on-error");
@ -2052,13 +2044,15 @@ static ParameterError opt_bool(struct OperationConfig *config,
}
config->rm_partial = toggle;
break;
case C_FAIL: /* --fail */
config->failonerror = toggle;
if(config->failonerror && config->failwithbody) {
errorf("You must select either --fail or "
"--fail-with-body, not both.");
return PARAM_BAD_USE;
}
case C_FAIL: /* --fail without body */
if(toggle && (config->fail == FAIL_WITH_BODY))
warnf("--fail deselects --fail-with-body here");
config->fail = toggle ? FAIL_WO_BODY : FAIL_NONE;
break;
case C_FAIL_WITH_BODY: /* --fail-with-body */
if(toggle && (config->fail == FAIL_WO_BODY))
warnf("--fail-with-body deselects --fail here");
config->fail = toggle ? FAIL_WITH_BODY : FAIL_NONE;
break;
case C_GLOBOFF: /* --globoff */
config->globoff = toggle;

View File

@ -393,8 +393,7 @@ static CURLcode retrycheck(struct OperationConfig *config,
retry = RETRY_CONNREFUSED;
}
else if((CURLE_OK == result) ||
((config->failonerror || config->failwithbody) &&
(CURLE_HTTP_RETURNED_ERROR == result))) {
(config->fail && (CURLE_HTTP_RETURNED_ERROR == result))) {
/* If it returned OK. _or_ failonerror was enabled and it
returned due to such an error, check for HTTP transient
errors to retry on. */
@ -659,7 +658,7 @@ static CURLcode post_per_transfer(struct per_transfer *per,
if(result == CURLE_PEER_FAILED_VERIFICATION)
fputs(CURL_CA_CERT_ERRORMSG, tool_stderr);
}
else if(config->failwithbody) {
else if(config->fail == FAIL_WITH_BODY) {
/* if HTTP response >= 400, return error */
long code = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code);

View File

@ -6,7 +6,23 @@
</keywords>
</info>
# Client-side
<reply>
<data crlf="yes">
HTTP/1.1 200 OK
Date: Tue, 09 Nov 2010 14:49:00 GMT
Server: test-server/fake
Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
ETag: "21025-dc7-39462498"
Accept-Ranges: bytes
Content-Length: 6
Connection: close
Content-Type: text/html
Funny-head: yesyes
-foo-
</data>
</reply>
<client>
<server>
http
@ -15,14 +31,14 @@ http
Error on both --fail-with-body and --fail
</name>
<command>
http://%HOSTIP:%HTTPPORT/%TESTNUMBER --fail-with-body --fail
http://%HOSTIP:%HTTPPORT/%TESTNUMBER --fail-with-body --fail --no-progress-meter
</command>
</client>
# Verify data after the test has been "shot"
<verify>
<errorcode>
2
</errorcode>
<stderr mode="text">
Warning: --fail deselects --fail-with-body here
</stderr>
</verify>
</testcase>