curl: add --remove-on-error

If a transfer returns an error, using this option makes curl remove the
leftover downloded (partial) local file before exiting.

Added test 376 to verify

Closes #8503
This commit is contained in:
Daniel Stenberg 2022-02-24 10:30:10 +01:00
parent 7b0fd39db2
commit 08a96c6e4e
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
9 changed files with 93 additions and 2 deletions

View File

@ -203,6 +203,7 @@ DPAGES = \
remote-name-all.d \
remote-name.d \
remote-time.d \
remove-on-error.d \
request-target.d \
request.d \
resolve.d \

View File

@ -0,0 +1,12 @@
Long: remove-on-error
Help: Remove output file on errors
See-also: fail
Category: curl
Example: --remove-on-error -o output $URL
Added: 7.83.0
---
When curl returns an error when told to save output in a local file, this
option removes that saved file before exiting. This prevevents curl from
leaving a partial file in the case of an error during transfer.
If the output is not a file, this option has no effect.

View File

@ -191,6 +191,7 @@
--remote-name (-O) 4.0
--remote-name-all 7.19.0
--remote-time (-R) 7.9
--remove-on-error 7.83.0
--request (-X) 6.0
--request-target 7.55.0
--resolve 7.21.3

View File

@ -294,6 +294,8 @@ struct OperationConfig {
struct OperationConfig *prev;
struct OperationConfig *next; /* Always last in the struct */
struct State state; /* for create_transfer() */
bool rm_partial; /* on error, remove partially written output
files */
};
struct GlobalConfig {

View File

@ -284,6 +284,7 @@ static const struct LongShort aliases[]= {
{"fb", "styled-output", ARG_BOOL},
{"fc", "mail-rcpt-allowfails", ARG_BOOL},
{"fd", "fail-with-body", ARG_BOOL},
{"fe", "remove-on-error", ARG_BOOL},
{"F", "form", ARG_STRING},
{"Fs", "form-string", ARG_STRING},
{"g", "globoff", ARG_BOOL},
@ -1830,7 +1831,10 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
case 'd': /* --fail-with-body */
config->failwithbody = toggle;
break;
default: /* --fail (hard on errors) */
case 'e': /* --remove-on-error */
config->rm_partial = toggle;
break;
default: /* --fail (hard on errors) */
config->failonerror = toggle;
break;
}

View File

@ -574,6 +574,9 @@ const struct helptxt helptext[] = {
{"-R, --remote-time",
"Set the remote file's time on the local output",
CURLHELP_OUTPUT},
{" --remove-on-error",
"Remove output file on errors",
CURLHELP_CURL},
{"-X, --request <method>",
"Specify request method to use",
CURLHELP_CONNECTION},

View File

@ -595,6 +595,10 @@ static CURLcode post_per_transfer(struct GlobalConfig *global,
if(global->showerror)
fprintf(global->errors, "curl: (%d) Failed writing body\n", result);
}
if(result && config->rm_partial) {
notef(global, "Removing output file: %s", per->outfile);
unlink(per->outfile);
}
}
/* File time can only be set _after_ the file has been closed */

View File

@ -61,7 +61,7 @@ test334 test335 test336 test337 test338 test339 test340 test341 test342 \
test343 test344 test345 test346 test347 test348 test349 test350 test351 \
test352 test353 test354 test355 test356 test357 test358 test359 test360 \
test361 test362 test363 test364 test365 test366 test367 test368 test369 \
test370 test371 test372 test373 test374 test375 \
test370 test371 test372 test373 test374 test375 test376 \
\
test380 test381 test383 test384 test385 test386 \
\

64
tests/data/test376 Normal file
View File

@ -0,0 +1,64 @@
<testcase>
<info>
<keywords>
HTTP
HTTP GET
</keywords>
</info>
#
# Crafted to cause error 18
<reply>
<data nocheck="yes">
HTTP/1.1 200 OK swsclose
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: 75
Connection: close
Content-Type: text/html
Funny-head: yesyes
-foo-
</data>
</reply>
#
# Client-side
<client>
<server>
http
</server>
<name>
HTTP GET
</name>
<command option="no-output">
http://%HOSTIP:%HTTPPORT/%TESTNUMBER -o log/save-%TESTNUMBER --remove-on-error
</command>
</client>
#
# Verify data after the test has been "shot". hyper doesn't do error 18
<verify>
<errorcode>
%if hyper
56
%else
18
%endif
</errorcode>
<protocol>
GET /%TESTNUMBER HTTP/1.1
Host: %HOSTIP:%HTTPPORT
User-Agent: curl/%VERSION
Accept: */*
</protocol>
# the file should be empty now
<file name="log/save-%TESTNUMBER">
</file>
</verify>
</testcase>