240 lines
10 KiB
Diff
240 lines
10 KiB
Diff
From 8adbc01dc5975a64c55fe594d8c758c71e8183b3 Mon Sep 17 00:00:00 2001
|
|
From: myfreeer <myfreeer@users.noreply.github.com>
|
|
Date: Sun, 22 Jul 2018 19:59:02 +0800
|
|
Subject: [PATCH] option: add option to retry on http 400, 403, 406, or unknown
|
|
|
|
--retry-on-400[=true|false] Configure whether retry or not when
|
|
HTTP server returns 400 Bad Request.
|
|
Only effective if retry-wait > 0.
|
|
|
|
Possible Values: true, false
|
|
Default: false
|
|
Tags: #advanced, #http
|
|
|
|
--retry-on-403[=true|false] Configure whether retry or not when
|
|
HTTP server returns 403 Forbidden.
|
|
Only effective if retry-wait > 0.
|
|
|
|
Possible Values: true, false
|
|
Default: false
|
|
Tags: #advanced, #http
|
|
|
|
--retry-on-406[=true|false] Configure whether retry or not when
|
|
HTTP server returns 406 Not Acceptable.
|
|
Only effective if retry-wait > 0.
|
|
|
|
Possible Values: true, false
|
|
Default: false
|
|
Tags: #advanced, #http
|
|
|
|
--retry-on-unknown[=true|false] Configure whether retry or not when
|
|
HTTP server returns unknown status code.
|
|
Only effective if retry-wait > 0.
|
|
|
|
Possible Values: true, false
|
|
Default: false
|
|
Tags: #advanced, #http
|
|
---
|
|
src/HttpSkipResponseCommand.cc | 42 +++++++++++++++++++++++++++++-----
|
|
src/OptionHandlerFactory.cc | 40 ++++++++++++++++++++++++++++++++
|
|
src/prefs.cc | 8 +++++++
|
|
src/prefs.h | 8 +++++++
|
|
src/usage_text.h | 16 +++++++++++++
|
|
5 files changed, 108 insertions(+), 6 deletions(-)
|
|
|
|
diff --git a/src/HttpSkipResponseCommand.cc b/src/HttpSkipResponseCommand.cc
|
|
index a722d77..de4ad6c 100644
|
|
--- a/src/HttpSkipResponseCommand.cc
|
|
+++ b/src/HttpSkipResponseCommand.cc
|
|
@@ -204,7 +204,7 @@ bool HttpSkipResponseCommand::processResponse()
|
|
auto statusCode = httpResponse_->getStatusCode();
|
|
if (statusCode >= 400) {
|
|
switch (statusCode) {
|
|
- case 401:
|
|
+ case 401: // Unauthorized
|
|
if (getOption()->getAsBool(PREF_HTTP_AUTH_CHALLENGE) &&
|
|
!httpResponse_->getHttpRequest()->authenticationUsed() &&
|
|
getDownloadEngine()->getAuthConfigFactory()->activateBasicCred(
|
|
@@ -213,15 +213,41 @@ bool HttpSkipResponseCommand::processResponse()
|
|
return prepareForRetry(0);
|
|
}
|
|
throw DL_ABORT_EX2(EX_AUTH_FAILED, error_code::HTTP_AUTH_FAILED);
|
|
- case 404:
|
|
+ case 404: // Not Found
|
|
if (getOption()->getAsInt(PREF_MAX_FILE_NOT_FOUND) == 0) {
|
|
throw DL_ABORT_EX2(MSG_RESOURCE_NOT_FOUND,
|
|
error_code::RESOURCE_NOT_FOUND);
|
|
}
|
|
throw DL_RETRY_EX2(MSG_RESOURCE_NOT_FOUND,
|
|
error_code::RESOURCE_NOT_FOUND);
|
|
- case 502:
|
|
- case 503:
|
|
+ case 400: // Bad Request
|
|
+ if (getOption()->getAsBool(PREF_RETRY_ON_400)
|
|
+ && getOption()->getAsInt(PREF_RETRY_WAIT) > 0) {
|
|
+ throw DL_RETRY_EX2(fmt(EX_BAD_STATUS, statusCode),
|
|
+ error_code::HTTP_PROTOCOL_ERROR);
|
|
+ }
|
|
+ break;
|
|
+ case 403: // Forbidden
|
|
+ if (getOption()->getAsBool(PREF_RETRY_ON_403)
|
|
+ && getOption()->getAsInt(PREF_RETRY_WAIT) > 0) {
|
|
+ throw DL_RETRY_EX2(fmt(EX_BAD_STATUS, statusCode),
|
|
+ error_code::HTTP_PROTOCOL_ERROR);
|
|
+ }
|
|
+ break;
|
|
+ case 406: // Not Acceptable
|
|
+ if (getOption()->getAsBool(PREF_RETRY_ON_406)
|
|
+ && getOption()->getAsInt(PREF_RETRY_WAIT) > 0) {
|
|
+ throw DL_RETRY_EX2(fmt(EX_BAD_STATUS, statusCode),
|
|
+ error_code::HTTP_PROTOCOL_ERROR);
|
|
+ }
|
|
+ break;
|
|
+ case 408: // Request Timeout
|
|
+ case 429: // Too Many Requests
|
|
+ case 502: // Bad Gateway
|
|
+ case 503: // Service Unavailable
|
|
+ case 507: // Insufficient Storage
|
|
+ case 520: // https://github.com/aria2/aria2/issues/1229
|
|
+ case 521: // https://github.com/aria2/aria2/issues/1229
|
|
// Only retry if pretry-wait > 0. Hammering 'busy' server is not
|
|
// a good idea.
|
|
if (getOption()->getAsInt(PREF_RETRY_WAIT) > 0) {
|
|
@@ -230,12 +256,16 @@ bool HttpSkipResponseCommand::processResponse()
|
|
}
|
|
throw DL_ABORT_EX2(fmt(EX_BAD_STATUS, statusCode),
|
|
error_code::HTTP_SERVICE_UNAVAILABLE);
|
|
- case 504:
|
|
+ case 504: // Gateway Timeout
|
|
// This is Gateway Timeout, so try again
|
|
throw DL_RETRY_EX2(fmt(EX_BAD_STATUS, statusCode),
|
|
error_code::HTTP_SERVICE_UNAVAILABLE);
|
|
};
|
|
-
|
|
+ if (getOption()->getAsBool(PREF_RETRY_ON_UNKNOWN)
|
|
+ && getOption()->getAsInt(PREF_RETRY_WAIT) > 0) {
|
|
+ throw DL_RETRY_EX2(fmt(EX_BAD_STATUS, statusCode),
|
|
+ error_code::HTTP_PROTOCOL_ERROR);
|
|
+ }
|
|
throw DL_ABORT_EX2(fmt(EX_BAD_STATUS, statusCode),
|
|
error_code::HTTP_PROTOCOL_ERROR);
|
|
}
|
|
diff --git a/src/OptionHandlerFactory.cc b/src/OptionHandlerFactory.cc
|
|
index 5768f7b..decb03e 100644
|
|
--- a/src/OptionHandlerFactory.cc
|
|
+++ b/src/OptionHandlerFactory.cc
|
|
@@ -934,6 +934,46 @@ std::vector<OptionHandler*> OptionHandlerFactory::createOptionHandlers()
|
|
op->setChangeOptionForReserved(true);
|
|
handlers.push_back(op);
|
|
}
|
|
+ {
|
|
+ OptionHandler* op(new BooleanOptionHandler(
|
|
+ PREF_RETRY_ON_400, TEXT_RETRY_ON_400, A2_V_FALSE, OptionHandler::OPT_ARG));
|
|
+ op->addTag(TAG_ADVANCED);
|
|
+ op->addTag(TAG_HTTP);
|
|
+ op->setInitialOption(true);
|
|
+ op->setChangeGlobalOption(true);
|
|
+ op->setChangeOptionForReserved(true);
|
|
+ handlers.push_back(op);
|
|
+ }
|
|
+ {
|
|
+ OptionHandler* op(new BooleanOptionHandler(
|
|
+ PREF_RETRY_ON_403, TEXT_RETRY_ON_403, A2_V_FALSE, OptionHandler::OPT_ARG));
|
|
+ op->addTag(TAG_ADVANCED);
|
|
+ op->addTag(TAG_HTTP);
|
|
+ op->setInitialOption(true);
|
|
+ op->setChangeGlobalOption(true);
|
|
+ op->setChangeOptionForReserved(true);
|
|
+ handlers.push_back(op);
|
|
+ }
|
|
+ {
|
|
+ OptionHandler* op(new BooleanOptionHandler(
|
|
+ PREF_RETRY_ON_406, TEXT_RETRY_ON_406, A2_V_FALSE, OptionHandler::OPT_ARG));
|
|
+ op->addTag(TAG_ADVANCED);
|
|
+ op->addTag(TAG_HTTP);
|
|
+ op->setInitialOption(true);
|
|
+ op->setChangeGlobalOption(true);
|
|
+ op->setChangeOptionForReserved(true);
|
|
+ handlers.push_back(op);
|
|
+ }
|
|
+ {
|
|
+ OptionHandler* op(new BooleanOptionHandler(
|
|
+ PREF_RETRY_ON_UNKNOWN, TEXT_RETRY_ON_UNKNOWN, A2_V_FALSE, OptionHandler::OPT_ARG));
|
|
+ op->addTag(TAG_ADVANCED);
|
|
+ op->addTag(TAG_HTTP);
|
|
+ op->setInitialOption(true);
|
|
+ op->setChangeGlobalOption(true);
|
|
+ op->setChangeOptionForReserved(true);
|
|
+ handlers.push_back(op);
|
|
+ }
|
|
{
|
|
OptionHandler* op(new BooleanOptionHandler(
|
|
PREF_REUSE_URI, TEXT_REUSE_URI, A2_V_TRUE, OptionHandler::OPT_ARG));
|
|
diff --git a/src/prefs.cc b/src/prefs.cc
|
|
index 937e927..33eff91 100644
|
|
--- a/src/prefs.cc
|
|
+++ b/src/prefs.cc
|
|
@@ -327,6 +327,14 @@ PrefPtr PREF_ENABLE_ASYNC_DNS6 = makePref("enable-async-dns6");
|
|
PrefPtr PREF_MAX_DOWNLOAD_RESULT = makePref("max-download-result");
|
|
// value: 1*digit
|
|
PrefPtr PREF_RETRY_WAIT = makePref("retry-wait");
|
|
+// value: true | false
|
|
+PrefPtr PREF_RETRY_ON_400 = makePref("retry-on-400");
|
|
+// value: true | false
|
|
+PrefPtr PREF_RETRY_ON_403 = makePref("retry-on-403");
|
|
+// value: true | false
|
|
+PrefPtr PREF_RETRY_ON_406 = makePref("retry-on-406");
|
|
+// value: true | false
|
|
+PrefPtr PREF_RETRY_ON_UNKNOWN = makePref("retry-on-unknown");
|
|
// value: string
|
|
PrefPtr PREF_ASYNC_DNS_SERVER = makePref("async-dns-server");
|
|
// value: true | false
|
|
diff --git a/src/prefs.h b/src/prefs.h
|
|
index e1f8397..019e774 100644
|
|
--- a/src/prefs.h
|
|
+++ b/src/prefs.h
|
|
@@ -280,6 +280,14 @@ extern PrefPtr PREF_ENABLE_ASYNC_DNS6;
|
|
extern PrefPtr PREF_MAX_DOWNLOAD_RESULT;
|
|
// value: 1*digit
|
|
extern PrefPtr PREF_RETRY_WAIT;
|
|
+// value: true | false
|
|
+extern PrefPtr PREF_RETRY_ON_400;
|
|
+// value: true | false
|
|
+extern PrefPtr PREF_RETRY_ON_403;
|
|
+// value: true | false
|
|
+extern PrefPtr PREF_RETRY_ON_406;
|
|
+// value: true | false
|
|
+extern PrefPtr PREF_RETRY_ON_UNKNOWN;
|
|
// value: string
|
|
extern PrefPtr PREF_ASYNC_DNS_SERVER;
|
|
// value: true | false
|
|
diff --git a/src/usage_text.h b/src/usage_text.h
|
|
index d73b50d..75d34a0 100644
|
|
--- a/src/usage_text.h
|
|
+++ b/src/usage_text.h
|
|
@@ -64,6 +64,22 @@
|
|
_(" --retry-wait=SEC Set the seconds to wait between retries. \n" \
|
|
" With SEC > 0, aria2 will retry download when the\n" \
|
|
" HTTP server returns 503 response.")
|
|
+#define TEXT_RETRY_ON_400 \
|
|
+ _(" --retry-on-400[=true|false] Configure whether retry or not when\n" \
|
|
+ " HTTP server returns 400 Bad Request.\n" \
|
|
+ " Only effective if retry-wait > 0.")
|
|
+#define TEXT_RETRY_ON_403 \
|
|
+ _(" --retry-on-403[=true|false] Configure whether retry or not when\n" \
|
|
+ " HTTP server returns 403 Forbidden.\n" \
|
|
+ " Only effective if retry-wait > 0.")
|
|
+#define TEXT_RETRY_ON_406 \
|
|
+ _(" --retry-on-406[=true|false] Configure whether retry or not when\n" \
|
|
+ " HTTP server returns 406 Not Acceptable.\n" \
|
|
+ " Only effective if retry-wait > 0.")
|
|
+#define TEXT_RETRY_ON_UNKNOWN \
|
|
+ _(" --retry-on-unknown[=true|false] Configure whether retry or not when\n" \
|
|
+ " HTTP server returns unknown status code.\n" \
|
|
+ " Only effective if retry-wait > 0.")
|
|
#define TEXT_TIMEOUT \
|
|
_(" -t, --timeout=SEC Set timeout in seconds.")
|
|
#define TEXT_MAX_TRIES \
|
|
--
|
|
2.18.0
|