diff --git a/docs/curl.1 b/docs/curl.1 index bc0612f0c..8434d6b7a 100644 --- a/docs/curl.1 +++ b/docs/curl.1 @@ -1620,6 +1620,10 @@ also \fI--retry-max-time\fP to limit the total time allowed for retries. (Added in 7.12.3) If this option is used several times, the last one will be used. +.IP "--retry-connrefused" +In addition to the other conditions, consider ECONNREFUSED as a transient +error too for \fI--retry\fP. This option is used together with +\fI--retry\fP. (Added in 7.52.0) .IP "--retry-delay " Make curl sleep this amount of time before each retry when a transfer has failed with a transient error (it changes the default backoff time algorithm diff --git a/src/tool_cfgable.h b/src/tool_cfgable.h index aa98fced5..9f4dbba8c 100644 --- a/src/tool_cfgable.h +++ b/src/tool_cfgable.h @@ -176,6 +176,7 @@ struct OperationConfig { bool tcp_nodelay; bool tcp_fastopen; long req_retry; /* number of retries */ + 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 2d16e066d..d1888a2ab 100644 --- a/src/tool_getparam.c +++ b/src/tool_getparam.c @@ -125,6 +125,7 @@ static const struct LongShort aliases[]= { {"$e", "proxy-digest", FALSE}, {"$f", "proxy-basic", FALSE}, {"$g", "retry", TRUE}, + {"$V", "retry-connrefused", FALSE}, {"$h", "retry-delay", TRUE}, {"$i", "retry-max-time", TRUE}, {"$k", "proxy-negotiate", FALSE}, @@ -793,6 +794,9 @@ ParameterError getparameter(char *flag, /* f or -long-flag */ if(err) return err; break; + case 'V': /* --retry-connrefused */ + config->retry_connrefused = toggle; + break; case 'h': /* --retry-delay */ err = str2unum(&config->retry_delay, nextarg); if(err) diff --git a/src/tool_help.c b/src/tool_help.c index 9890cc83b..f4d648c01 100644 --- a/src/tool_help.c +++ b/src/tool_help.c @@ -198,6 +198,8 @@ static const char *const helptext[] = { " --resolve HOST:PORT:ADDRESS Force resolve of HOST:PORT to ADDRESS", " --retry NUM " "Retry request NUM times if transient problems occur", + " --retry-connrefused " + "Consider \"connection refused\" a transient error", " --retry-delay SECONDS Wait SECONDS between retries", " --retry-max-time SECONDS Retry only within this period", " --sasl-ir Enable initial response in SASL authentication", diff --git a/src/tool_operate.c b/src/tool_operate.c index deae87753..d467b0df5 100644 --- a/src/tool_operate.c +++ b/src/tool_operate.c @@ -1441,6 +1441,7 @@ static CURLcode operate_do(struct GlobalConfig *global, enum { RETRY_NO, RETRY_TIMEOUT, + RETRY_CONNREFUSED, RETRY_HTTP, RETRY_FTP, RETRY_LAST /* not used */ @@ -1452,6 +1453,13 @@ static CURLcode operate_do(struct GlobalConfig *global, (CURLE_FTP_ACCEPT_TIMEOUT == result)) /* retry timeout always */ retry = RETRY_TIMEOUT; + else if(config->retry_connrefused && + (CURLE_COULDNT_CONNECT == result)) { + long oserrno; + curl_easy_getinfo(curl, CURLINFO_OS_ERRNO, &oserrno); + if(ECONNREFUSED == oserrno) + retry = RETRY_CONNREFUSED; + } else if((CURLE_OK == result) || (config->failonerror && (CURLE_HTTP_RETURNED_ERROR == result))) { @@ -1499,7 +1507,11 @@ static CURLcode operate_do(struct GlobalConfig *global, if(retry) { static const char * const m[]={ - NULL, "timeout", "HTTP error", "FTP error" + NULL, + "timeout", + "connection refused", + "HTTP error", + "FTP error" }; warnf(config->global, "Transient problem: %s "