update 2026-10-07 18:47:42

This commit is contained in:
action committed 2026-10-07 18:47:42 +08:00
1 parent 617f7ca2a6
commit bd061545ed
4832 files changed
+1693456

No files matched your search

+83
View File
@@ -0,0 +1,83 @@
menu "Aria2 Configuration"
depends on PACKAGE_aria2
choice
prompt "SSL Library"
default ARIA2_OPENSSL
config ARIA2_OPENSSL
bool "OpenSSL"
config ARIA2_GNUTLS
bool "GnuTLS"
config ARIA2_NOSSL
bool "No SSL Support"
endchoice
choice
prompt "Crypto Library"
depends on !ARIA2_OPENSSL
default ARIA2_NOCRYPTO
config ARIA2_NETTLE
bool "Nettle"
config ARIA2_LIBGCRYPT
bool "Libgcrypt"
config ARIA2_NOCRYPTO
bool "No Crypto Library"
endchoice
choice
prompt "XML Library"
default ARIA2_NOXML
config ARIA2_LIBXML2
bool "Libxml2"
config ARIA2_EXPAT
bool "Expat"
config ARIA2_NOXML
bool "No XML Library"
endchoice
config ARIA2_GMP
bool "GNU Multiple Precision Arithmetic Library"
depends on ARIA2_NETTLE
default n
config ARIA2_BITTORRENT
bool "Enable Bittorrent Support"
depends on ARIA2_OPENSSL || ARIA2_LIBGCRYPT || \
(ARIA2_NETTLE && ARIA2_GMP)
default y
config ARIA2_METALINK
bool "Enable Metalink Support"
depends on !ARIA2_NOXML
default n
config ARIA2_SFTP
bool "Enable SFTP Support"
default n
config ARIA2_ASYNC_DNS
bool "Enable Async DNS Support"
default n
config ARIA2_COOKIE
bool "Enable Firefox3/Chromium Cookie Support"
default n
config ARIA2_WEBSOCKET
bool "Enable JSON-RPC over WebSocket Support"
depends on ARIA2_OPENSSL || ARIA2_LIBGCRYPT || ARIA2_NETTLE
default y
endmenu
+134
View File
@@ -0,0 +1,134 @@
#
# Copyright (C) 2012-2023 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=aria2
PKG_VERSION:=1.37.0
PKG_RELEASE:=9
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=https://github.com/aria2/aria2/releases/download/release-$(PKG_VERSION)/
PKG_HASH:=skip
PKG_INSTALL:=1
PKG_BUILD_PARALLEL:=1
PKG_BUILD_FLAGS:=gc-sections lto
PKG_MAINTAINER:=Imre Kaloz <kaloz@openwrt.org>, \
Hsing-Wang Liao <kuoruan@gmail.com>
PKG_LICENSE:=GPLv2
PKG_LICENSE_FILES:=COPYING
PKG_CPE_ID:=cpe:/a:aria2_project:aria2
PKG_CONFIG_DEPENDS := \
CONFIG_ARIA2_NOSSL \
CONFIG_ARIA2_OPENSSL \
CONFIG_ARIA2_GNUTLS \
CONFIG_ARIA2_NOCRYPTO \
CONFIG_ARIA2_NETTLE \
CONFIG_ARIA2_LIBGCRYPT \
CONFIG_ARIA2_LIBXML2 \
CONFIG_ARIA2_EXPAT \
CONFIG_ARIA2_GMP \
CONFIG_ARIA2_BITTORRENT \
CONFIG_ARIA2_METALINK \
CONFIG_ARIA2_SFTP \
CONFIG_ARIA2_ASYNC_DNS \
CONFIG_ARIA2_COOKIE \
CONFIG_ARIA2_WEBSOCKET
include $(INCLUDE_DIR)/package.mk
include $(INCLUDE_DIR)/nls.mk
define Package/aria2-openssl
SECTION:=net
CATEGORY:=Network
SUBMENU:=File Transfer
TITLE:=lightweight download utility (OpenSSL dependencies)
DEPENDS:=+libopenssl +libopenssl-legacy
HIDDEN:=1
endef
define Package/aria2/config
source "$(SOURCE)/Config.in"
endef
define Package/aria2
SECTION:=net
CATEGORY:=Network
SUBMENU:=File Transfer
TITLE:=lightweight download utility
URL:=https://aria2.github.io/
DEPENDS:=+zlib +libstdcpp +ARIA2_OPENSSL:aria2-openssl +ARIA2_GNUTLS:libgnutls \
+ARIA2_NETTLE:libnettle +ARIA2_LIBGCRYPT:libgcrypt +ARIA2_GMP:libgmp \
+ARIA2_LIBXML2:libxml2 +ARIA2_EXPAT:libexpat +ARIA2_SFTP:libssh2 \
+ARIA2_ASYNC_DNS:libcares +ARIA2_COOKIE:libsqlite3
USERID:=aria2=6800:aria2=6800
endef
define Package/aria2/description
aria2 is a lightweight multi-protocol & multi-source command-line download
utility
endef
CONFIGURE_ARGS += \
--disable-nls \
$(if $(CONFIG_ARIA2_NOSSL),--disable,--enable)-ssl \
$(if $(CONFIG_ARIA2_BITTORRENT),--enable,--disable)-bittorrent \
$(if $(CONFIG_ARIA2_METALINK),--enable,--disable)-metalink \
$(if $(CONFIG_ARIA2_WEBSOCKET),--enable,--disable)-websocket \
$(if $(CONFIG_ARIA2_OPENSSL),--with,--without)-openssl \
$(if $(CONFIG_ARIA2_GNUTLS),--with,--without)-gnutls \
$(if $(CONFIG_ARIA2_NETTLE),--with,--without)-libnettle \
$(if $(CONFIG_ARIA2_LIBGCRYPT),--with,--without)-libgcrypt \
$(if $(CONFIG_ARIA2_GMP),--with,--without)-libgmp \
$(if $(CONFIG_ARIA2_LIBXML2),--with,--without)-libxml2 \
$(if $(CONFIG_ARIA2_EXPAT),--with,--without)-libexpat \
$(if $(CONFIG_ARIA2_SFTP),--with,--without)-libssh2 \
$(if $(CONFIG_ARIA2_ASYNC_DNS),--with,--without)-libcares \
$(if $(CONFIG_ARIA2_COOKIE),--with,--without)-sqlite3 \
--without-libuv \
--with-libz
define Package/aria2/conffiles
/etc/config/aria2
endef
define Download/aria2.conf
URL:=https://github.com/P3TERX/aria2.conf/archive
URL_FILE:=master.zip
FILE:=aria2.conf
HASH:=skip
endef
define Build/Prepare
$(call Build/Prepare/Default)
unzip $(DL_DIR)/aria2.conf -d $(PKG_BUILD_DIR)/
sed -i '/rpc-secret/d' $(PKG_BUILD_DIR)/aria2.conf-master/*
[ -x $(PKG_BUILD_DIR)/aria2.conf-master/tracker.sh ] && { cd $(PKG_BUILD_DIR)/aria2.conf-master && sh ./tracker.sh >/dev/null 2>&1; }
endef
define Package/aria2/install
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/aria2c $(1)/usr/bin
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_BIN) ./files/aria2.init $(1)/etc/init.d/aria2
$(INSTALL_DIR) $(1)/etc/config
$(INSTALL_CONF) ./files/aria2.conf $(1)/etc/config/aria2
$(INSTALL_DIR) $(1)/usr/share/aria2
$(INSTALL_BIN) $(PKG_BUILD_DIR)/aria2.conf-master/* $(1)/usr/share/aria2/
endef
define Package/aria2-openssl/install
true
endef
$(eval $(call Download,aria2.conf))
$(eval $(call BuildPackage,aria2))
$(eval $(call BuildPackage,aria2-openssl))
+23
View File
@@ -0,0 +1,23 @@
# You can use most aria2 command-line options, replace '-' with '_'.
# eg. 'rpc-secret' ==> 'rpc_secret'
#
# We do not support all options at this time. But you can add any option
# with 'list extra_settings'.
#
# You can also add new config sections to define multi instance.
#
config aria2 'main'
option enabled '0'
option user 'aria2'
option dir '/mnt/sda1/aria2'
option config_dir '/var/etc/aria2'
option bt_enable_lpd 'true'
option enable_dht 'true'
option follow_torrent 'true'
option file_allocation 'none'
option save_session_interval '30'
option split '128'
option min_split_size '100K'
option max_connection_per_server '128'
list extra_settings 'dht-file-path=/usr/share/aria2/dht.dat'
+364
View File
@@ -0,0 +1,364 @@
#!/bin/sh /etc/rc.common
# Copyright (C) 2016-2017 Hsing-wang Liao <kuoruan@gmail.com>
# Licensed to the public under the Apache License 2.0.
START=99
USE_PROCD=1
NAME=aria2
PROG=/usr/bin/aria2c
_info() {
logger -p daemon.info -t "$NAME" "$*"
}
_err() {
logger -p daemon.err -t "$NAME" "$*"
}
_make_dir() {
local d
for d in "$@"; do
if [ ! -d "$d" ]; then
mkdir -p "$d" 2>/dev/null || return 1
fi
done
return 0
}
_create_file() {
touch "$@" 2>/dev/null
}
_change_owner() {
local u="$1"; shift
local d
for d in "$@"; do
if [ -f "$d" ]; then
chown "$u" "$d" 2>/dev/null || return 1
elif [ -d "$d" ]; then
chown -R "$u" "$d" 2>/dev/null || return 1
fi
done
return 0
}
_change_file_mode() {
local mod="$1"; shift
chmod "$mod" "$@" 2>/dev/null
}
_reset_dir_mode() {
local d
for d in "$@"; do
if [ -d "$d" ]; then
find "$d" -type d -exec chmod 755 {} \; 2>/dev/null
find "$d" -type f -exec chmod 644 {} \; 2>/dev/null
fi
done
}
append_options() {
local o; local v
for o in "$@"; do
v="$(eval echo "\$$o")"
[ -n "$v" ] && \
echo "${o//_/-}=$v" >>"$config_file_tmp"
done
}
append_setting() {
local s="$1"
[ -n "$s" ] && \
echo "$s" >>"$config_file_tmp"
}
append_header() {
local h="$1"
[ -n "$h" ] && \
echo "header=\"$h\"" >>"$config_file_tmp"
}
aria2_validate() {
uci_load_validate "$NAME" aria2 "$1" "$2" \
'enabled:bool:0' \
'enable_logging:bool' \
'enable_proxy:bool' \
'config_dir:string:/var/etc/aria2' \
'user:string' \
'all_proxy:string' \
'all_proxy_passwd:string' \
'all_proxy_user:string' \
'auto_save_interval:range(0,600)' \
'bt_enable_lpd:or("true","false")' \
'bt_detach_seed_only:or("true","false")' \
'bt_load_saved_metadata:or("true","false")' \
'bt_prioritize_piece:string' \
'bt_max_open_files:uinteger' \
'bt_max_peers:uinteger' \
'bt_remove_unselected_file:or("true","false")' \
'bt_request_peer_speed_limit:string' \
'bt_save_metadata:or("true","false")' \
'bt_seed_unverified:or("true","false")' \
'bt_stop_timeout:uinteger' \
'bt_tracker:list(string)' \
'ca_certificate:file' \
'certificate:file' \
'check_certificate:or("true","false"):true' \
'check_integrity:or("true","false")' \
'connect_timeout:uinteger' \
'dht_listen_port:string' \
'dir:string' \
'disable_ipv6:or("true","false")' \
'disk_cache:string' \
'enable_dht:or("true","false"):true' \
'enable_dht6:or("true","false")' \
'enable_peer_exchange:or("true","false")' \
'event_poll:or("epoll","kqueue","port","poll","select")' \
'file_allocation:or("none","prealloc","trunc","falloc")' \
'follow_torrent:or("true","false","mem")' \
'force_save:or("true","false")' \
'http_accept_gzip:or("true","false")' \
'http_no_cache:or("true","false")' \
'listen_port:string' \
'log:string' \
'log_level:or("debug","info","notice","warn","error")' \
'lowest_speed_limit:string' \
'max_concurrent_downloads:uinteger' \
'max_connection_per_server:uinteger' \
'max_download_limit:string' \
'max_overall_download_limit:string' \
'max_overall_upload_limit:string' \
'max_tries:uinteger' \
'max_upload_limit:string' \
'min_split_size:string' \
'pause:or("true","false")' \
'pause_metadata:or("true","false")' \
'peer_id_prefix:string' \
'private_key:file' \
'retry_wait:uinteger' \
'rpc_auth_method:or("none","user_pass","token")' \
'rpc_certificate:file' \
'rpc_listen_port:range(1024,65535)' \
'rpc_passwd:string' \
'rpc_private_key:file' \
'rpc_secret:string' \
'rpc_secure:or("true","false")' \
'rpc_user:string' \
'save_session_interval:uinteger' \
'seed_ratio:ufloat' \
'seed_time:ufloat' \
'split:uinteger' \
'timeout:uinteger' \
'user_agent:string'
}
aria2_start() {
local section="$1"
[ "$2" = "0" ] || { _err "Validation failed."; return 1; }
[ "$enabled" = "1" ] || { _info "Instance \"$section\" disabled."; return 1; }
[ -n "$dir" ] || { _err "Please set download dir."; return 1; }
[ -d "$dir" ] || _make_dir "$dir" || {
_err "Can't create download dir: $dir"
return 1
}
config_file="$config_dir/$NAME.conf.$section"
config_file_tmp="$config_dir/$NAME.conf.tmp"
session_file="$config_dir/$NAME.session.$section"
_make_dir "$config_dir" || {
_err "Can't create config dir: $config_dir"
return 1
}
_create_file "$session_file" "$config_file" "$config_file_tmp" || {
_err "Can't create files: $session_file, $config_file, $config_file_tmp"
return 1
}
# create tmp file
cat >"$config_file_tmp" <<-EOF
# Auto generated file, changes to this file will be lost.
EOF
append_setting "dir=$dir"
append_setting "enable-rpc=true"
append_setting "rpc-allow-origin-all=true"
append_setting "rpc-listen-all=true"
append_setting "quiet=true"
append_setting "continue=true"
append_setting "input-file=$session_file"
append_setting "save-session=$session_file"
if [ -z "$enable_logging" ]; then
append_options "log" "log_level"
elif [ "$enable_logging" = "1" ]; then
log=${log:-"/var/log/aria2.log"}
local log_dir
log_dir="$(dirname "$log")"
_make_dir "$log_dir" || {
_err "Can't create log dir: $log_dir"
return 1
}
# create or clear log file
echo >"$log"
append_setting "log=$log"
append_options "log_level"
fi
if [ -z "$enable_proxy" ] || [ "$enable_proxy" = "1" ]; then
append_options "all_proxy" "all_proxy_user" "all_proxy_passwd"
fi
unset_auth_method() {
uci -q batch <<-EOF
set $NAME.$section.rpc_auth_method=""
commit $NAME
EOF
}
if [ -z "$rpc_auth_method" ]; then
if [ -n "$rpc_secret" ]; then
append_setting "rpc-secret=$rpc_secret"
elif [ -n "$rpc_user" ]; then
append_setting "rpc-user=$rpc_user"
append_setting "rpc-passwd=$rpc_passwd"
else
_info "It is recommended to set RPC secret."
fi
elif [ "$rpc_auth_method" = "token" ]; then
if [ -n "$rpc_secret" ]; then
append_setting "rpc-secret=$rpc_secret"
else
unset_auth_method
fi
elif [ "$rpc_auth_method" = "user_pass" ]; then
if [ -n "$rpc_user" ]; then
append_setting "rpc-user=$rpc_user"
append_setting "rpc-passwd=$rpc_passwd"
else
_info "Please set RPC user."
unset_auth_method
fi
fi
if [ ."$rpc_secure" = ."true" ] && [ -n "$rpc_certificate" ]; then
append_setting "rpc-secure=true"
append_options "rpc_certificate" "rpc_private_key"
fi
if [ ."$check_certificate" = ."true" ]; then
append_setting "check-certificate=true"
append_options "ca_certificate"
elif [ ."$check_certificate" = ."false" ]; then
append_setting "check-certificate=false"
fi
if [ ."$enable_dht" = ."true" ]; then
dht_file="$config_dir/dht.dat.$section"
_create_file "$dht_file" || {
_err "Can't create DHT file: $dht_file"
return 1
}
append_setting "enable-dht=true"
append_setting "dht-file-path=$dht_file"
fi
if [ ."$enable_dht6" = ."true" ] && [ ."$disable_ipv6" != ."true" ]; then
dht6_file="$config_dir/dht6.dat.$section"
_create_file "$dht6_file" || {
_err "Can't create DHT6 file: $dht6_file"
return 1
}
append_setting "enable-dht6=true"
append_setting "dht-file-path6=$dht6_file"
fi
if [ -n "$bt_tracker" ]; then
local bt_tracker_list; local t
for t in $bt_tracker; do
if [ -z "$bt_tracker_list" ]; then
bt_tracker_list="$t"
else
bt_tracker_list="$bt_tracker_list,$t"
fi
done
append_setting "bt-tracker=$bt_tracker_list"
fi
append_options "auto_save_interval" "bt_enable_lpd" "bt_max_open_files" "bt_max_peers" \
"bt_remove_unselected_file" "bt_request_peer_speed_limit" "bt_prioritize_piece" \
"bt_stop_timeout" "bt_detach_seed_only" "bt_save_metadata" "bt_load_saved_metadata" \
"bt_seed_unverified" "certificate" "check_integrity" "connect_timeout" "dht_listen_port" \
"disable_ipv6" "disk_cache" "enable_peer_exchange" "event_poll" "file_allocation" \
"follow_torrent" "force_save" "http_accept_gzip" "http_no_cache" "listen_port" \
"lowest_speed_limit" "max_concurrent_downloads" "max_connection_per_server" \
"max_download_limit" "max_overall_download_limit" "max_overall_upload_limit" "max_tries" \
"max_upload_limit" "min_split_size" "pause" "pause_metadata" "peer_id_prefix" "private_key" \
"retry_wait" "rpc_listen_port" "save_session_interval" "seed_ratio" "seed_time" "split" "timeout" \
"user_agent"
config_list_foreach "$section" "header" append_header
config_list_foreach "$section" "extra_settings" append_setting
cd /usr/share/aria2 && sh ./tracker.sh >/dev/null 2>&1 &
cat /usr/share/aria2/aria2.conf > "$config_file"
echo '' >> "$config_file"
sed '/^$/d' "$config_file_tmp" >> "$config_file"
rm -f "$config_file_tmp"
_reset_dir_mode "$config_dir"
_change_file_mode 600 "$config_file"
if [ -n "$user" ]; then
if ( user_exists "$user" && _change_owner "$user" "$config_dir" "$log" ); then
_info "Aria2 will run with user '$user'."
if [ "$user" != "root" ]; then
_info "Please make sure user '$user' has write access to download dir: $dir"
fi
else
_info "Setting run user to '$user' failed, default user will be used."
user=
fi
fi
procd_open_instance "$NAME.$section"
procd_set_param command "$PROG"
procd_append_param command --conf-path="$config_file"
procd_set_param respawn
procd_set_param stdout 1
procd_set_param stderr 1
procd_set_param file "$config_file"
[ -n "$user" ] && \
procd_set_param user "$user"
procd_add_jail "$NAME.$section" log
procd_add_jail_mount "/usr/lib/ossl-modules"
procd_add_jail_mount "$ca_certificate" "$certificate" "$rpc_certificate" "$rpc_private_key"
procd_add_jail_mount_rw "$dir" "$config_dir" "$log"
procd_close_instance
}
service_triggers() {
procd_add_reload_trigger "$NAME"
procd_add_validation aria2_validate
}
start_service() {
config_load "$NAME"
config_foreach aria2_validate "aria2" aria2_start
}
@@ -0,0 +1,29 @@
--- /src/OptionHandlerFactory.cc 2018-05-15 20:33:25.000000000 +0800
+++ /src/OptionHandlerFactory.cc 2018-07-05 10:40:25.000000000 +0800
@@ -440,7 +440,7 @@
{
OptionHandler* op(new NumberOptionHandler(PREF_MAX_CONNECTION_PER_SERVER,
TEXT_MAX_CONNECTION_PER_SERVER,
- "1", 1, 16, 'x'));
+ "64", 1, -1, 'x'));
op->addTag(TAG_BASIC);
op->addTag(TAG_FTP);
op->addTag(TAG_HTTP);
@@ -501,7 +501,7 @@
}
{
OptionHandler* op(new UnitNumberOptionHandler(
- PREF_MIN_SPLIT_SIZE, TEXT_MIN_SPLIT_SIZE, "20M", 1_m, 1_g, 'k'));
+ PREF_MIN_SPLIT_SIZE, TEXT_MIN_SPLIT_SIZE, "1M", 1_k, 1_g, 'k'));
op->addTag(TAG_BASIC);
op->addTag(TAG_FTP);
op->addTag(TAG_HTTP);
@@ -905,7 +905,7 @@ std::vector<OptionHandler*> OptionHandlerFactory::createOptionHandlers()
}
{
OptionHandler* op(new UnitNumberOptionHandler(
- PREF_PIECE_LENGTH, TEXT_PIECE_LENGTH, "1M", 1_m, 1_g));
+ PREF_PIECE_LENGTH, TEXT_PIECE_LENGTH, "1M", 1_k, 1_g));
op->addTag(TAG_ADVANCED);
op->addTag(TAG_FTP);
op->addTag(TAG_HTTP);
@@ -0,0 +1,61 @@
From 66524bee738e98742c908d93c993d0a78a2d9891 Mon Sep 17 00:00:00 2001
From: myfreeer <myfreeer@users.noreply.github.com>
Date: Sat, 18 Nov 2017 11:55:04 +0800
Subject: [PATCH 3/4] download: retry on slow speed and conection close
This would provide better speed on bad network conditions
---
src/DownloadCommand.cc | 2 +-
src/SocketBuffer.cc | 3 ++-
src/SocketCore.cc | 2 +-
3 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/src/DownloadCommand.cc b/src/DownloadCommand.cc
index 2db41e4..f49eb80 100644
--- a/src/DownloadCommand.cc
+++ b/src/DownloadCommand.cc
@@ -306,7 +306,7 @@ void DownloadCommand::checkLowestDownloadSpeed() const
startupIdleTime_) {
int nowSpeed = peerStat_->calculateDownloadSpeed();
if (nowSpeed <= lowestDownloadSpeedLimit_) {
- throw DL_ABORT_EX2(fmt(EX_TOO_SLOW_DOWNLOAD_SPEED, nowSpeed,
+ throw DL_RETRY_EX2(fmt(EX_TOO_SLOW_DOWNLOAD_SPEED, nowSpeed,
lowestDownloadSpeedLimit_,
getRequest()->getHost().c_str()),
error_code::TOO_SLOW_DOWNLOAD_SPEED);
diff --git a/src/SocketBuffer.cc b/src/SocketBuffer.cc
index 62862ff..1906173 100644
--- a/src/SocketBuffer.cc
+++ b/src/SocketBuffer.cc
@@ -39,6 +39,7 @@
#include "SocketCore.h"
#include "DlAbortEx.h"
+#include "DlRetryEx.h"
#include "message.h"
#include "fmt.h"
#include "LogFactory.h"
@@ -158,7 +159,7 @@ ssize_t SocketBuffer::send()
}
ssize_t slen = socket_->writeVector(iov, num);
if (slen == 0 && !socket_->wantRead() && !socket_->wantWrite()) {
- throw DL_ABORT_EX(fmt(EX_SOCKET_SEND, "Connection closed."));
+ throw DL_RETRY_EX(fmt(EX_SOCKET_SEND, "Connection closed."));
}
// A2_LOG_NOTICE(fmt("num=%zu, amount=%d, bufq.size()=%zu, SEND=%d",
// num, amount, bufq_.size(), slen));
diff --git a/src/SocketCore.cc b/src/SocketCore.cc
index 77dc30c..537375a 100644
--- a/src/SocketCore.cc
+++ b/src/SocketCore.cc
@@ -1009,7 +1009,7 @@ bool SocketCore::tlsHandshake(TLSContext* tlsctx, const std::string& hostname)
if (rv == TLS_ERR_ERROR) {
// Damn those error.
- throw DL_ABORT_EX(fmt("SSL/TLS handshake failure: %s",
+ throw DL_RETRY_EX(fmt("SSL/TLS handshake failure: %s",
handshakeError.empty()
? tlsSession_->getLastErrorString().c_str()
: handshakeError.c_str()));
--
2.17.1
@@ -0,0 +1,239 @@
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