mirror of
https://github.com/moparisthebest/curl
synced 2024-12-22 16:18:48 -05:00
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
This commit is contained in:
parent
c386a0df44
commit
8a964cb217
@ -5,7 +5,7 @@
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
# Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
@ -61,10 +61,11 @@ DPAGES = \
|
||||
dump-header.d \
|
||||
egd-file.d \
|
||||
engine.d \
|
||||
etag-compare.d \
|
||||
etag-save.d \
|
||||
etag-compare.d \
|
||||
etag-save.d \
|
||||
expect100-timeout.d \
|
||||
fail-early.d \
|
||||
fail-with-body.d \
|
||||
fail.d \
|
||||
false-start.d \
|
||||
form-string.d \
|
||||
|
16
docs/cmdline-opts/fail-with-body.d
Normal file
16
docs/cmdline-opts/fail-with-body.d
Normal file
@ -0,0 +1,16 @@
|
||||
Long: fail-with-body
|
||||
Protocols: HTTP
|
||||
Help: Fail on HTTP errors but save the body
|
||||
Category: http output
|
||||
Added: 7.76.0
|
||||
See-also: fail
|
||||
---
|
||||
|
||||
Return an error on server errors where the HTTP response code is 400 or
|
||||
greater). In normal cases when an HTTP server fails to deliver a document, it
|
||||
returns an HTML document stating so (which often also describes why and
|
||||
more). This flag will still allow curl to outputting and save that content but
|
||||
also to return error 22.
|
||||
|
||||
This is an alternative option to --fail which makes curl fail for the same
|
||||
circumstances but without saving the content.
|
@ -2,6 +2,7 @@ Long: fail
|
||||
Short: f
|
||||
Protocols: HTTP
|
||||
Help: Fail silently (no output at all) on HTTP errors
|
||||
See-also: fail-with-body
|
||||
Category: important http
|
||||
---
|
||||
Fail silently (no output at all) on server errors. This is mostly done to
|
||||
|
@ -59,6 +59,7 @@
|
||||
--expect100-timeout 7.47.0
|
||||
--fail (-f) 4.0
|
||||
--fail-early 7.52.0
|
||||
--fail-with-body 7.76.0
|
||||
--false-start 7.42.0
|
||||
--form (-F) 5.0
|
||||
--form-string 7.13.2
|
||||
|
@ -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 */
|
||||
|
@ -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':
|
||||
|
@ -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},
|
||||
|
@ -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 */
|
||||
|
@ -58,9 +58,10 @@ test307 test308 test309 test310 test311 test312 test313 test314 test315 \
|
||||
test316 test317 test318 test319 test320 test321 test322 test323 test324 \
|
||||
test325 test326 test327 test328 test329 test330 test331 test332 test333 \
|
||||
test334 test335 test336 test337 test338 test339 test340 test341 test342 \
|
||||
test343 test344 test345 test346 test347 test348 \
|
||||
test350 test351 test352 test353 test354 test355 test356 test357 test358 \
|
||||
test359 \
|
||||
test343 test344 test345 test346 test347 test348 test349 test350 test351 \
|
||||
test352 test353 test354 test355 test356 test357 test358 test359 test360 \
|
||||
test361 \
|
||||
\
|
||||
test393 test394 test395 test396 test397 \
|
||||
\
|
||||
test400 test401 test402 test403 test404 test405 test406 test407 test408 \
|
||||
|
@ -3,6 +3,7 @@
|
||||
<keywords>
|
||||
HTTP
|
||||
HTTP GET
|
||||
--fail
|
||||
</keywords>
|
||||
</info>
|
||||
# Server-side
|
||||
|
45
tests/data/test349
Normal file
45
tests/data/test349
Normal file
@ -0,0 +1,45 @@
|
||||
<testcase>
|
||||
<info>
|
||||
<keywords>
|
||||
HTTP
|
||||
HTTP GET
|
||||
--fail-with-body
|
||||
</keywords>
|
||||
</info>
|
||||
# Server-side
|
||||
<reply>
|
||||
<data>
|
||||
HTTP/1.0 404 BAD BOY swsclose
|
||||
Content-Type: text/html
|
||||
|
||||
This silly page doesn't reaaaaaly exist so you should not get it.
|
||||
</data>
|
||||
</reply>
|
||||
|
||||
# Client-side
|
||||
<client>
|
||||
<server>
|
||||
http
|
||||
</server>
|
||||
<name>
|
||||
HTTP GET --fail-with-body on HTTP error return
|
||||
</name>
|
||||
<command>
|
||||
http://%HOSTIP:%HTTPPORT/349 --fail-with-body
|
||||
</command>
|
||||
</client>
|
||||
|
||||
# Verify data after the test has been "shot"
|
||||
<verify>
|
||||
<protocol>
|
||||
GET /349 HTTP/1.1
|
||||
Host: %HOSTIP:%HTTPPORT
|
||||
User-Agent: curl/%VERSION
|
||||
Accept: */*
|
||||
|
||||
</protocol>
|
||||
<errorcode>
|
||||
22
|
||||
</errorcode>
|
||||
</verify>
|
||||
</testcase>
|
28
tests/data/test360
Normal file
28
tests/data/test360
Normal file
@ -0,0 +1,28 @@
|
||||
<testcase>
|
||||
<info>
|
||||
<keywords>
|
||||
--fail
|
||||
--fail-with-body
|
||||
</keywords>
|
||||
</info>
|
||||
|
||||
# Client-side
|
||||
<client>
|
||||
<server>
|
||||
http
|
||||
</server>
|
||||
<name>
|
||||
Error on both --fail-with-body and --fail
|
||||
</name>
|
||||
<command>
|
||||
http://%HOSTIP:%HTTPPORT/360 --fail-with-body --fail
|
||||
</command>
|
||||
</client>
|
||||
|
||||
# Verify data after the test has been "shot"
|
||||
<verify>
|
||||
<errorcode>
|
||||
2
|
||||
</errorcode>
|
||||
</verify>
|
||||
</testcase>
|
50
tests/data/test361
Normal file
50
tests/data/test361
Normal file
@ -0,0 +1,50 @@
|
||||
<testcase>
|
||||
<info>
|
||||
<keywords>
|
||||
HTTP
|
||||
HTTP GET
|
||||
--fail-with-body
|
||||
</keywords>
|
||||
</info>
|
||||
# Server-side
|
||||
<reply>
|
||||
<data>
|
||||
HTTP/1.0 404 BAD BOY swsclose
|
||||
Content-Type: text/html
|
||||
|
||||
This silly page doesn't reaaaaaly exist so you should not get it.
|
||||
</data>
|
||||
</reply>
|
||||
|
||||
# Client-side
|
||||
<client>
|
||||
<server>
|
||||
http
|
||||
</server>
|
||||
<name>
|
||||
HTTP GET --fail-with-body on HTTP error return - twice
|
||||
</name>
|
||||
<command>
|
||||
http://%HOSTIP:%HTTPPORT/361 http://%HOSTIP:%HTTPPORT/361 --fail-with-body
|
||||
</command>
|
||||
</client>
|
||||
|
||||
# Verify data after the test has been "shot"
|
||||
<verify>
|
||||
<protocol>
|
||||
GET /361 HTTP/1.1
|
||||
Host: %HOSTIP:%HTTPPORT
|
||||
User-Agent: curl/%VERSION
|
||||
Accept: */*
|
||||
|
||||
GET /361 HTTP/1.1
|
||||
Host: %HOSTIP:%HTTPPORT
|
||||
User-Agent: curl/%VERSION
|
||||
Accept: */*
|
||||
|
||||
</protocol>
|
||||
<errorcode>
|
||||
22
|
||||
</errorcode>
|
||||
</verify>
|
||||
</testcase>
|
Loading…
Reference in New Issue
Block a user