]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
curl: add --remove-on-error
authorDaniel Stenberg <daniel@haxx.se>
Thu, 24 Feb 2022 09:30:10 +0000 (10:30 +0100)
committerDaniel Stenberg <daniel@haxx.se>
Thu, 10 Mar 2022 18:57:55 +0000 (19:57 +0100)
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

docs/cmdline-opts/Makefile.inc
docs/cmdline-opts/remove-on-error.d [new file with mode: 0644]
docs/options-in-versions
src/tool_cfgable.h
src/tool_getparam.c
src/tool_listhelp.c
src/tool_operate.c
tests/data/Makefile.inc
tests/data/test376 [new file with mode: 0644]

index afa3d7931f4263beefa43213b0a80d0ca619e66c..3f6d00831ac9919cebc51adf3bf190fd1a8a3e4c 100644 (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 \
diff --git a/docs/cmdline-opts/remove-on-error.d b/docs/cmdline-opts/remove-on-error.d
new file mode 100644 (file)
index 0000000..7c4b83a
--- /dev/null
@@ -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.
index 5d242b8ffc5c7a62620b454ce0e9c7af40bdcebd..559a3327603740684a0a5aaf49dff1017d2ad940 100644 (file)
 --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
index a06ef602819b5f26ae0cc82f8bf993aee0fdfaae..4a420db32d5a674667cf6a26a89f0dfc972dc134 100644 (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 {
index 56964394b76c7b1e9f4269fad1221628ddee984d..b31583299cf1683fb5e4f3928615e7589c244f23 100644 (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;
       }
index 3bca52c0e69737cb97f05cf61ebeca1a1b231c72..33ebda25fdaf1bbc0b5022f451e23000872c0e2f 100644 (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},
index 37ff44795f03e471cb6b4473ee736d427be37353..2e576d0d0e5cce910eddc6fcabb226f325bec767 100644 (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 */
index 80901c7719f19f77d5c40ce97b6c340ccfe4a3ea..6a32dd67827b8912bb017bd62599213a0e753071 100644 (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 \
 \
diff --git a/tests/data/test376 b/tests/data/test376
new file mode 100644 (file)
index 0000000..7406d5b
--- /dev/null
@@ -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\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+
+# the file should be empty now
+<file name="log/save-%TESTNUMBER">
+</file>
+</verify>
+</testcase>