diff options
author | Daniel Stenberg <daniel@haxx.se> | 2022-02-24 10:30:10 +0100 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2022-03-10 19:57:55 +0100 |
commit | 08a96c6e4e6cf6a1917a117db1b5394713e3f01f (patch) | |
tree | 5c4692cc312e191f61e27c3f45077d92951f0d69 | |
parent | 7b0fd39db21a9291b4189d6e5b05ade40b3dce58 (diff) | |
download | curl-08a96c6e4e6cf6a1917a117db1b5394713e3f01f.tar.gz |
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
-rw-r--r-- | docs/cmdline-opts/Makefile.inc | 1 | ||||
-rw-r--r-- | docs/cmdline-opts/remove-on-error.d | 12 | ||||
-rw-r--r-- | docs/options-in-versions | 1 | ||||
-rw-r--r-- | src/tool_cfgable.h | 2 | ||||
-rw-r--r-- | src/tool_getparam.c | 6 | ||||
-rw-r--r-- | src/tool_listhelp.c | 3 | ||||
-rw-r--r-- | src/tool_operate.c | 4 | ||||
-rw-r--r-- | tests/data/Makefile.inc | 2 | ||||
-rw-r--r-- | tests/data/test376 | 64 |
9 files changed, 93 insertions, 2 deletions
diff --git a/docs/cmdline-opts/Makefile.inc b/docs/cmdline-opts/Makefile.inc index afa3d7931..3f6d00831 100644 --- a/docs/cmdline-opts/Makefile.inc +++ b/docs/cmdline-opts/Makefile.inc @@ -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 \ diff --git a/docs/cmdline-opts/remove-on-error.d b/docs/cmdline-opts/remove-on-error.d new file mode 100644 index 000000000..7c4b83a5c --- /dev/null +++ b/docs/cmdline-opts/remove-on-error.d @@ -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. diff --git a/docs/options-in-versions b/docs/options-in-versions index 5d242b8ff..559a33276 100644 --- a/docs/options-in-versions +++ b/docs/options-in-versions @@ -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 diff --git a/src/tool_cfgable.h b/src/tool_cfgable.h index a06ef6028..4a420db32 100644 --- a/src/tool_cfgable.h +++ b/src/tool_cfgable.h @@ -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 { diff --git a/src/tool_getparam.c b/src/tool_getparam.c index 56964394b..b31583299 100644 --- a/src/tool_getparam.c +++ b/src/tool_getparam.c @@ -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; } diff --git a/src/tool_listhelp.c b/src/tool_listhelp.c index 3bca52c0e..33ebda25f 100644 --- a/src/tool_listhelp.c +++ b/src/tool_listhelp.c @@ -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}, diff --git a/src/tool_operate.c b/src/tool_operate.c index 37ff44795..2e576d0d0 100644 --- a/src/tool_operate.c +++ b/src/tool_operate.c @@ -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 */ diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc index 80901c771..6a32dd678 100644 --- a/tests/data/Makefile.inc +++ b/tests/data/Makefile.inc @@ -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 \ \ diff --git a/tests/data/test376 b/tests/data/test376 new file mode 100644 index 000000000..7406d5b24 --- /dev/null +++ b/tests/data/test376 @@ -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> |