aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJay Satiro <raysatiro@yahoo.com>2020-04-04 16:16:18 -0400
committerJay Satiro <raysatiro@yahoo.com>2020-05-12 03:00:15 -0400
commitb995bb58cbd976280b132ee2148376fadd071063 (patch)
tree6e2c8903f3ae9e5bc515828df90f045dab186750
parent98e5904165859679cd78825bcccb52306ee3bb66 (diff)
tool: Add option --retry-all-errors to retry on any error
The "sledgehammer" of retrying. Closes https://github.com/curl/curl/pull/5185
-rw-r--r--docs/cmdline-opts/Makefile.inc1
-rw-r--r--docs/cmdline-opts/retry-all-errors.d19
-rw-r--r--src/tool_cfgable.h1
-rw-r--r--src/tool_getparam.c4
-rw-r--r--src/tool_help.c2
-rw-r--r--src/tool_operate.c5
-rw-r--r--tests/data/Makefile.inc2
-rw-r--r--tests/data/test190965
8 files changed, 98 insertions, 1 deletions
diff --git a/docs/cmdline-opts/Makefile.inc b/docs/cmdline-opts/Makefile.inc
index 5b7439e4a..6a7b953bc 100644
--- a/docs/cmdline-opts/Makefile.inc
+++ b/docs/cmdline-opts/Makefile.inc
@@ -180,6 +180,7 @@ DPAGES = \
request-target.d \
request.d \
resolve.d \
+ retry-all-errors.d \
retry-connrefused.d \
retry-delay.d \
retry-max-time.d \
diff --git a/docs/cmdline-opts/retry-all-errors.d b/docs/cmdline-opts/retry-all-errors.d
new file mode 100644
index 000000000..e0f662819
--- /dev/null
+++ b/docs/cmdline-opts/retry-all-errors.d
@@ -0,0 +1,19 @@
+Long: retry-all-errors
+Help: Retry all errors (use with --retry) (read manpage, don't use by default)
+Added: 7.71.0
+---
+Retry on any error. This option is used together with --retry.
+
+This option is the "sledgehammer" of retrying. Do not use this option by
+default (eg in curlrc), there may be unintended consequences such as sending or
+receiving duplicate data. Do not use with redirected input or output. You'd be
+much better off handling your unique problems in shell script. Please read the
+example below.
+
+Warning: For server compatibility curl attempts to retry failed flaky transfers
+as close as possible to how they were started, but this is not possible with
+redirected input or output. For example, before retrying it removes output data
+from a failed partial transfer that was written to an output file. However this
+is not true of data redirected to a | pipe or > file, which are not reset. We
+strongly suggest don't parse or record output via redirect in combination with
+this option, since you may receive duplicate data.
diff --git a/src/tool_cfgable.h b/src/tool_cfgable.h
index d7eebf598..c5b8c3071 100644
--- a/src/tool_cfgable.h
+++ b/src/tool_cfgable.h
@@ -223,6 +223,7 @@ struct OperationConfig {
bool tcp_nodelay;
bool tcp_fastopen;
long req_retry; /* number of retries */
+ bool retry_all_errors; /* retry on any error */
bool retry_connrefused; /* set connection refused as a transient error */
long retry_delay; /* delay between retries (in seconds) */
long retry_maxtime; /* maximum time to keep retrying */
diff --git a/src/tool_getparam.c b/src/tool_getparam.c
index 0252ee029..c0ab67c3f 100644
--- a/src/tool_getparam.c
+++ b/src/tool_getparam.c
@@ -197,6 +197,7 @@ static const struct LongShort aliases[]= {
{"$Y", "suppress-connect-headers", ARG_BOOL},
{"$Z", "compressed-ssh", ARG_BOOL},
{"$~", "happy-eyeballs-timeout-ms", ARG_STRING},
+ {"$!", "retry-all-errors", ARG_BOOL},
{"0", "http1.0", ARG_NONE},
{"01", "http1.1", ARG_NONE},
{"02", "http2", ARG_NONE},
@@ -927,6 +928,9 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
if(err)
return err;
break;
+ case '!': /* --retry-all-errors */
+ config->retry_all_errors = toggle;
+ break;
case 'k': /* --proxy-negotiate */
if(curlinfo->features & CURL_VERSION_SPNEGO)
diff --git a/src/tool_help.c b/src/tool_help.c
index 5afaf822e..92ccae3b9 100644
--- a/src/tool_help.c
+++ b/src/tool_help.c
@@ -399,6 +399,8 @@ static const struct helptxt helptext[] = {
"Retry on connection refused (use with --retry)"},
{" --retry-delay <seconds>",
"Wait time between retries"},
+ {" --retry-all-errors",
+ "Retry all errors (use with --retry) (read manpage, don't use by default)"},
{" --retry-max-time <seconds>",
"Retry only within this period"},
{" --sasl-authzid <identity> ",
diff --git a/src/tool_operate.c b/src/tool_operate.c
index 66c6468bc..6d489aa30 100644
--- a/src/tool_operate.c
+++ b/src/tool_operate.c
@@ -437,6 +437,7 @@ static CURLcode post_per_transfer(struct GlobalConfig *global,
config->retry_maxtime*1000L)) ) {
enum {
RETRY_NO,
+ RETRY_ALL_ERRORS,
RETRY_TIMEOUT,
RETRY_CONNREFUSED,
RETRY_HTTP,
@@ -506,11 +507,15 @@ static CURLcode post_per_transfer(struct GlobalConfig *global,
retry = RETRY_FTP;
}
+ if(result && !retry && config->retry_all_errors)
+ retry = RETRY_ALL_ERRORS;
+
if(retry) {
long sleeptime = 0;
curl_off_t retry_after = 0;
static const char * const m[]={
NULL,
+ "(retrying all errors)",
"timeout",
"connection refused",
"HTTP error",
diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc
index 26faa954f..07ab2a974 100644
--- a/tests/data/Makefile.inc
+++ b/tests/data/Makefile.inc
@@ -201,7 +201,7 @@ test1700 test1701 test1702 \
test1800 test1801 \
\
test1900 test1901 test1902 test1903 test1904 test1905 test1906 test1907 \
-test1908 \
+test1908 test1909 \
\
test2000 test2001 test2002 test2003 test2004 test2005 test2006 test2007 \
test2008 test2009 test2010 test2011 test2012 test2013 test2014 test2015 \
diff --git a/tests/data/test1909 b/tests/data/test1909
new file mode 100644
index 000000000..bde0e5e0f
--- /dev/null
+++ b/tests/data/test1909
@@ -0,0 +1,65 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+retry
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<data nocheck="yes">
+HTTP/1.1 200 OK swsclose swsbounce
+Content-Length: 5
+Connection: close
+
+bbb
+</data>
+<data1>
+HTTP/1.1 200 OK
+Content-Length: 5
+Connection: close
+
+data
+</data1>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+http
+</server>
+ <name>
+HTTP GET --retry-all-errors to overcome partial transfer
+ </name>
+ <command option="no-output,no-include">
+--retry 1 --retry-all-errors -o log/outfile1909 http://%HOSTIP:%HTTPPORT/1909
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<strip>
+^User-Agent:.*
+</strip>
+<protocol>
+GET /1909 HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+Accept: */*
+
+GET /1909 HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+Accept: */*
+
+</protocol>
+
+<file1 name="log/outfile1909">
+data
+</file1>
+
+</verify>
+</testcase>