This commit is contained in:
sirpdboy 2021-04-25 17:52:03 +08:00
parent 3ec0027384
commit ad46968435
27 changed files with 2517 additions and 371 deletions

83
aria2/Config.in Normal file
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 y
config ARIA2_SFTP
bool "Enable SFTP Support"
default y
config ARIA2_ASYNC_DNS
bool "Enable Async DNS Support"
default y
config ARIA2_COOKIE
bool "Enable Firefox3/Chromium Cookie Support"
default y
config ARIA2_WEBSOCKET
bool "Enable JSON-RPC over WebSocket Support"
depends on ARIA2_OPENSSL || ARIA2_LIBGCRYPT || ARIA2_NETTLE
default y
endmenu

104
aria2/Makefile Normal file
View File

@ -0,0 +1,104 @@
#
# Copyright (C) 2012-2018 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.35.0
PKG_RELEASE:=4
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=https://github.com/aria2/aria2/releases/download/release-$(PKG_VERSION)/
PKG_HASH:=1e2b7fd08d6af228856e51c07173cfcf987528f1ac97e04c5af4a47642617dfd
PKG_INSTALL:=1
PKG_BUILD_PARALLEL:=1
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:tatsuhiro_tsujikawa: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/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:libopenssl +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
TARGET_CXXFLAGS += -ffunction-sections -fdata-sections -flto
TARGET_LDFLAGS += -Wl,--gc-sections -flto
define Package/aria2/conffiles
/etc/config/aria2
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
endef
$(eval $(call BuildPackage,aria2))

27
aria2/files/aria2.conf Normal file
View File

@ -0,0 +1,27 @@
# 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 quiet 'false'
option save_session_interval '30'
option enable_logging '0'
option rpc_auth_method 'none'
option rpc_secure 'false'
option enable_proxy '0'
option check_certificate 'true'
option enable_dht6 'false'
option enable_peer_exchange 'true'

368
aria2/files/aria2.init Normal file
View File

@ -0,0 +1,368 @@
#!/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() {
local d="$(date "+%Y-%m-%d %H:%M:%S")"
echo -e "$d: $*" >>/var/log/aria2_1.log
}
_make_dir() {
local d
for d in "$@"; do
if [ ! -d "$d" ]; then
if mkdir -p "$d" 2>/dev/null; then
_info "成功创建<code>"$d"</code>目录。"
return 0
else
_info "无法创建<code>"$d"</code>目录。"
return 1
fi
fi
done
}
_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" \
'dir:string' \
'log:string' \
'user:string' \
'split:uinteger' \
'enabled:bool:0' \
'enable_Pro:bool' \
'rpc_user:string' \
'all_proxy:string' \
'seed_time:ufloat' \
'certificate:file' \
'timeout:uinteger' \
'private_key:file' \
'seed_ratio:ufloat' \
'rpc_secret:string' \
'user_agent:string' \
'rpc_passwd:string' \
'enable_proxy:bool' \
'disk_cache:string' \
'listen_port:string' \
'max_tries:uinteger' \
'enable_logging:bool' \
'ca_certificate:file' \
'retry_wait:uinteger' \
'rpc_certificate:file' \
'rpc_private_key:file' \
'all_proxy_user:string' \
'min_split_size:string' \
'peer_id_prefix:string' \
'bt_max_peers:uinteger' \
'dht_listen_port:string' \
'all_proxy_passwd:string' \
'max_upload_limit:string' \
'bt_tracker:list(string)' \
'bt_stop_timeout:uinteger' \
'pause:or("true","false")' \
'connect_timeout:uinteger' \
'max_download_limit:string' \
'lowest_speed_limit:string' \
'bt_max_open_files:uinteger' \
'bt_prioritize_piece:string' \
'Pro:string:/usr/share/aria2' \
'force_save:or("true","false")' \
'rpc_secure:or("true","false")' \
'save_session_interval:uinteger' \
'enable_dht6:or("true","false")' \
'disable_ipv6:or("true","false")' \
'max_overall_upload_limit:string' \
'auto_save_interval:range(0,600)' \
'bt_enable_lpd:or("true","false")' \
'config_dir:string:/var/etc/aria2' \
'http_no_cache:or("true","false")' \
'max_concurrent_downloads:uinteger' \
'rpc_listen_port:range(1024,65535)' \
'pause_metadata:or("true","false")' \
'max_overall_download_limit:string' \
'enable_dht:or("true","false"):true' \
'check_integrity:or("true","false")' \
'bt_request_peer_speed_limit:string' \
'max_connection_per_server:uinteger' \
'bt_save_metadata:or("true","false")' \
'http_accept_gzip:or("true","false")' \
'bt_seed_unverified:or("true","false")' \
'bt_detach_seed_only:or("true","false")' \
'follow_torrent:or("true","false","mem")' \
'enable_peer_exchange:or("true","false")' \
'bt_load_saved_metadata:or("true","false")' \
'check_certificate:or("true","false"):true' \
'bt_remove_unselected_file:or("true","false")' \
'rpc_auth_method:or("none","user_pass","token")' \
'log_level:or("debug","info","notice","warn","error")' \
'event_poll:or("epoll","kqueue","port","poll","select")' \
'file_allocation:or("none","prealloc","trunc","falloc")'
}
aria2_start() {
local section="$1"
[ "$2" = "0" ] || { _info "验证失败。"; return 1; }
[ "$enabled" = "1" ] || { _info "实例 \"$section\" 已禁用。"; return 1; }
if [ "$enable_Pro" == 1 ]; then
a="$Pro"
_make_dir "$Pro"
else
_make_dir "$config_dir"
a="$config_dir"
[ -d "$Pro" ] && rm -rf "$Pro" && _info "扩展功能已关闭,删除原来的$Pro目录"
if [ ! -f "$a"/dht.dat ] && [ ."$enable_dht" = ."true" ]; then
dht_file="$a/dht.dat"
_create_file "$dht_file" || {
_info "无法创建DHT文件: $dht_file"
return 1; }
append_setting "enable-dht=true"
append_setting "dht-file-path=$dht_file"
fi
fi
[ -n "$dir" ] && _make_dir "$dir" || { _info "请设置下载目录。"; return 1; }
config_file="$a/$NAME.conf.$section"
config_file_tmp="$a/$NAME.conf.tmp"
session_file="$a/$NAME.session"
_create_file "$session_file" "$config_file" "$config_file_tmp" || {
_info "无法创建$session_file, $config_file, $config_file_tmp的目录。"
return 1; }
# 创建tmp文件
cat >"$config_file_tmp" <<-EOF
#===以下是系统生成,对此文件修改将无法正常运行===#
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=$a/$NAME.session"
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"
# 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 "建议设置RPC密码。"
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 "请设置RPC用户。"
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_dht6" = ."true" ] && [ ."$disable_ipv6" != ."true" ]; then
dht6_file="$a/dht6.dat"
_create_file "$dht6_file" || {
_info "无法创建DHT6文件$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" "pause" "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" "split" \
"lowest_speed_limit" "max_concurrent_downloads" "max_connection_per_server" "user_agent" \
"max_download_limit" "max_overall_download_limit" "max_overall_upload_limit" "max_tries" \
"max_upload_limit" "min_split_size" "pause_metadata" "peer_id_prefix" "private_key" \
"retry_wait" "rpc_listen_port" "save_session_interval" "seed_ratio" "seed_time" "timeout"
config_list_foreach "$section" "header" append_header
config_list_foreach "$section" "extra_settings" append_setting
# Download_Pro_conf
if [ "$enable_Pro" = "1" ]; then
cd $Pro
if for i in aria2.conf clean.sh delete.sh tracker.sh dht.dat; do
if [ ! -s $i ]; then
wget -N -t2 -T3 https://raw.githubusercontent.com/P3TERX/aria2.conf/master/$i || \
wget -N -t2 -T3 https://cdn.jsdelivr.net/gh/P3TERX/aria2.conf/$i || \
curl -fsSLO https://p3terx.github.io/aria2.conf/$i || \
curl -fsSLO https://gh.p3terx.workers.dev/aria2.conf/master/$i
[ -s $i ] && _info "附加功能脚本[ $i ]文件下载成功 !" || _info "[ $i ] 配置文件下载失败 !"
fi
done
sed -i -e 's|NLOAD_PATH=.*|NLOAD_PATH='"'$dir'"'|g' -e 's|dir=.*|dir='"$dir"'|g' \
-e 's|/root/.aria2|'"$Pro"'|g' -e 's|#!.*|#!/bin/sh|g' -e '/et=P3TERX/d' \
-e 's|${F.*X}||g' -e 's|${G.*EFIX}||g' -e 's|${R.*EFIX}||g' -e 's|${Y.*EFIX}||g' \
-e 's|${L.*EFIX}||g' "$Pro"/* 2>/dev/null; then
_info "Aria2加强配置下载完成"; fi
chmod +x *.sh && sh ./tracker.sh
cat aria2.conf > "$config_file"
sed '/^$/d' "$config_file_tmp" >> "$config_file"
else
sed '/^$/d' "$config_file_tmp" > "$config_file"
fi
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" "$a" "$log" ); then
_info "Aria2将以<code>"$user"</code>的用户身份运行。"
if [ "$user" != "root" ]; then
_info "请确保用户$user具有下载目录$dir的写入权限。"
fi
else
_info "设置$user用户运行失败使用默认用户。"
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 "$config_file"
procd_add_jail_mount_rw "$dir" "$a" "$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
}

View File

@ -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);

View File

@ -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

View File

@ -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

18
luci-app-aria2/Makefile Normal file
View File

@ -0,0 +1,18 @@
#
# Copyright (C) 2017-2019 Xingwang Liao <kuoruan@gmail.com>
#
# This is free software, licensed under the MIT License.
#
include $(TOPDIR)/rules.mk
LUCI_TITLE:=LuCI Support for Aria2
LUCI_DEPENDS:=+aria2 +ariang
LUCI_PKGARCH:=all
PKG_MAINTAINER:=Xingwang Liao <kuoruan@gmail.com>
PKG_LICENSE:=MIT
include $(TOPDIR)/feeds/luci/luci.mk
# call BuildPackage - OpenWrt buildroot signature

View File

@ -0,0 +1,39 @@
module("luci.controller.aria2",package.seeall)
local ucic = luci.model.uci.cursor()
local http = require "luci.http"
local util = require "luci.util"
function index()
if not nixio.fs.access("/etc/config/aria2")then return end
entry({"admin","nas","aria2"},firstchild(),_("Aria2")).dependent=false
entry({"admin","nas","aria2","config"},cbi("aria2/config"),_("Configuration"),1)
entry({"admin","nas","aria2","file"},form("aria2/files"),_("Files"),2)
entry({"admin","nas","aria2","log"},firstchild(),_("Log"),3)
entry({"admin","nas","aria2","log","view"},template("aria2/log_template"))
entry({"admin","nas","aria2","log","read"},call("action_log_read"))
entry({"admin", "nas", "aria2", "clear_log"}, call("clear_log")).leaf = true
entry({"admin","nas","aria2","status"},call("action_status"))
end
function action_status()
local t={
running=(luci.sys.call("pidof aria2c >/dev/null")==0)
}
http.prepare_content("application/json")
http.write_json(t)
end
function clear_log()
luci.sys.call("cat > /var/log/aria2_1.log")
end
function action_log_read()
local t={log="",syslog=""}
local o=ucic:get("aria2","main","log")or"/var/log/aria2.log"
if nixio.fs.access(o) then
t.log=util.trim(luci.sys.exec("tail -n 50 %s | sed 'x;1!H;$!d;x'"%o))
end
t.syslog=util.trim(luci.sys.exec("[ -f '/var/log/aria2_1.log' ] && cat /var/log/aria2_1.log"))
http.prepare_content("application/json")
http.write_json(t)
end

View File

@ -0,0 +1,411 @@
local a=require"luci.sys"
local i=require"luci.util"
local o,t,e
local function n()
if a.call("command -v aria2c >/dev/null")~=0 then
return nil
end
local t={}
local e
for e in i.execi("aria2c -v 2>/dev/null | grep -E '^(aria2 version|Enabled Features)'")do
if e:match("^aria2 version")then
local a,a,e=e:find("([%d%.]+)$")
t.version=e
elseif e:match("^Enabled Features")then
t.gzip=e:find("GZip")~=nil
t.https=e:find("HTTPS")~=nil
t.bt=e:find("BitTorrent")~=nil
t.sftp=e:find("SFTP")~=nil
t.adns=e:find("Async DNS")~=nil
t.cookie=e:find("Firefox3 Cookie")~=nil
end
end
return t
end
local a=n()
o=Map("aria2","%s - %s"%{translate("Aria2"),translate("Settings")},
"<p>%s</p><p>%s</p>"%{
translate("Aria2 is a lightweight multi-protocol &amp; multi-source, cross platform download utility."),
translatef("")
})
if not a then
o:section(SimpleSection,nil,"<span style=\"color: red;\">%s</span>"%
translate("Error: Can't find aria2c in PATH, please reinstall aria2."))
o.reset=false
o.submit=false
return o
end
o:append(Template("aria2/settings_header"))
t=o:section(NamedSection,"main","aria2")
t.addremove=false
t.anonymous=true
t:tab("basic",translate("Basic Options"))
e=t:taboption("basic",Flag,"enabled",translate("Enabled"))
e.rmempty=false
e=t:taboption("basic",ListValue,"user",translate("Run daemon as user"),
translate("Leave blank to use default user."))
e:value("")
local n
for t in i.execi("cat /etc/passwd | cut -d':' -f1")do
e:value(t)
end
mount=t:taboption("basic",Value,"dir",translate("Download directory"),
translate("The directory to store the downloaded file. eg. <code>/mnt/sda1</code>"))
mount.rmempty=false
for t in i.execi("mount | awk '{print $3}' | grep mnt")do
mount:value(t)
end
e=t:taboption("basic",Value,"config_dir",translate("Config file directory"),
translate("The directory to store the config file, session file and DHT file."))
e.placeholder="/var/etc/aria2"
e=t:taboption("basic",Flag,"enable_Pro",translate("Enable Aria2 Pro"),translate("When enabled, the original system configuration directory will be merged."))
e.rmempty=false
e=t:taboption("basic",Value,"Pro",translate("Aria2 Pro file"),
translate("Use the configuration scheme of p3terx to realize the enhancement and expansion of aria2 function."))
e:depends("enable_Pro","1")
e.default="/usr/share/aria2"
e=t:taboption("basic",Flag,"enable_logging",translate("Enable logging"))
e.rmempty=false
e=t:taboption("basic",Value,"log",translate("Log file"),
translate("The file name of the log file."))
e:depends("enable_logging","1")
e.placeholder="/var/log/aria2.log"
e=t:taboption("basic",ListValue,"log_level",translate("Log level"))
e:depends("enable_logging","1")
e:value("debug",translate("Debug"))
e:value("info",translate("Info"))
e:value("notice",translate("Notice"))
e:value("warn",translate("Warn"))
e:value("error",translate("Error"))
e.default="warn"
e=t:taboption("basic",Value,"max_concurrent_downloads",translate("Max concurrent downloads"))
e.placeholder="5"
t:tab("rpc",translate("RPC Options"))
e=t:taboption("rpc",Flag,"pause",translate("Pause"),translate("Pause download after added."))
e.enabled="true"
e.disabled="false"
e.default="false"
e=t:taboption("rpc",Flag,"pause_metadata",translate("Pause metadata"),
translate("Pause downloads created as a result of metadata download."))
e.enabled="true"
e.disabled="false"
e.default="false"
e=t:taboption("rpc",Value,"rpc_listen_port",translate("RPC port"),translate("The webui port defaults to 6800."))
e.datatype="range(1024,65535)"
e.placeholder="6800"
e=t:taboption("rpc",ListValue,"rpc_auth_method",translate("RPC authentication method"))
e:value("none",translate("No Authentication"))
e:value("user_pass",translate("Username & Password"))
e:value("token",translate("Token"))
e=t:taboption("rpc",Value,"rpc_user",translate("RPC username"))
e:depends("rpc_auth_method","user_pass")
e=t:taboption("rpc",Value,"rpc_passwd",translate("RPC password"))
e:depends("rpc_auth_method","user_pass")
e.password=true
e=t:taboption("rpc",Value,"rpc_secret",translate("RPC token"))
e:depends("rpc_auth_method","token")
e.template="aria2/value_with_btn"
e.btntext=translate("generate randomly")
e.btnclick="randomToken();"
if a.https then
e=t:taboption("rpc",Flag,"rpc_secure",translate("RPC secure"),
translate("RPC transport will be encrypted by SSL/TLS. The RPC clients must use https"
.." scheme to access the server. For WebSocket client, use wss scheme."))
e.enabled="true"
e.disabled="false"
e.rmempty=false
e=t:taboption("rpc",Value,"rpc_certificate",translate("RPC certificate"),
translate("Use the certificate in FILE for RPC server. The certificate must be either"
.." in PKCS12 (.p12, .pfx) or in PEM format.<br/>PKCS12 files must contain the"
.." certificate, a key and optionally a chain of additional certificates. Only PKCS12"
.." files with a blank import password can be opened!<br/>When using PEM, you have to"
.." specify the \"RPC private key\" as well."))
e:depends("rpc_secure","true")
e.datatype="file"
e=t:taboption("rpc",Value,"rpc_private_key",translate("RPC private key"),
translate("Use the private key in FILE for RPC server. The private key must be"
.." decrypted and in PEM format."))
e:depends("rpc_secure","true")
e.datatype="file"
end
e=t:taboption("rpc",Flag,"_use_ws",translate("Use WebSocket"))
e=t:taboption("rpc",Value,"_rpc_url",translate("Json-RPC URL"))
e.template="aria2/value_with_btn"
e.onmouseover="this.focus();this.select();"
e.btntext=translate("Show URL")
e.btnclick="showRPCURL();"
t:tab("http",translate("HTTP/FTP/SFTP Options"))
e=t:taboption("http",Flag,"enable_proxy",translate("Enable proxy"))
e.rmempty=false
e=t:taboption("http",Value,"all_proxy",translate("All proxy"),
translate("Use a proxy server for all protocols."))
e:depends("enable_proxy","1")
e.placeholder="[http://][USER:PASSWORD@]HOST[:PORT]"
e=t:taboption("http",Value,"all_proxy_user",translate("Proxy user"))
e:depends("enable_proxy","1")
e=t:taboption("http",Value,"all_proxy_passwd",translate("Proxy password"))
e:depends("enable_proxy","1")
e.password=true
if a.https then
e=t:taboption("http",Flag,"check_certificate",translate("Check certificate"),
translate("Verify the peer using certificates specified in \"CA certificate\" option."))
e.enabled="true"
e.disabled="false"
e.default="true"
e.rmempty=false
e=t:taboption("http",Value,"ca_certificate",translate("CA certificate"),
translate("Use the certificate authorities in FILE to verify the peers. The certificate"
.." file must be in PEM format and can contain multiple CA certificates."))
e:depends("check_certificate","true")
e.datatype="file"
e=t:taboption("http",Value,"certificate",translate("Certificate"),
translate("Use the client certificate in FILE. The certificate must be either in PKCS12"
.." (.p12, .pfx) or in PEM format.<br/>PKCS12 files must contain the certificate, a"
.." key and optionally a chain of additional certificates. Only PKCS12 files with a"
.." blank import password can be opened!<br/>When using PEM, you have to specify the"
.." \"Private key\" as well."))
e.datatype="file"
e=t:taboption("http",Value,"private_key",translate("Private key"),
translate("Use the private key in FILE. The private key must be decrypted and in PEM"
.." format. The behavior when encrypted one is given is undefined."))
e.datatype="file"
end
if a.gzip then
e=t:taboption("http",Flag,"http_accept_gzip",translate("HTTP accept gzip"),
translate("Send <code>Accept: deflate, gzip</code> request header and inflate response"
.." if remote server responds with <code>Content-Encoding: gzip</code> or"
.." <code>Content-Encoding: deflate</code>."))
e.enabled="true"
e.disabled="false"
e.default="false"
end
e=t:taboption("http",Flag,"http_no_cache",translate("HTTP no cache"),
translate("Send <code>Cache-Control: no-cache</code> and <code>Pragma: no-cache</code>"
.." header to avoid cached content. If disabled, these headers are not sent and you"
.." can add Cache-Control header with a directive you like using \"Header\" option."))
e.enabled="true"
e.disabled="false"
e.default="false"
e=t:taboption("http",DynamicList,"header",translate("Header"),
translate("Append HEADERs to HTTP request header."))
e=t:taboption("http",Value,"connect_timeout",translate("Connect timeout"),
translate("Set the connect timeout in seconds to establish connection to HTTP/FTP/proxy server."..
" After the connection is established, this option makes no effect and \"Timeout\" option is used instead."))
e.datatype="uinteger"
e.placeholder="60"
e=t:taboption("http",Value,"timeout",translate("Timeout"))
e.datatype="uinteger"
e.placeholder="60"
e=t:taboption("http",Value,"lowest_speed_limit",translate("Lowest speed limit"),
"%s %s"%{
translate("Close connection if download speed is lower than or equal to this value(bytes per sec). "..
"0 means has no lowest speed limit."),
translate("You can append K or M.")
})
e.placeholder="0"
e=t:taboption("http",Value,"max_connection_per_server",translate("Max connection per server"),
translate("The maximum number of connections to one server for each download."))
e.datatype="uinteger"
e.placeholder="1"
e=t:taboption("http",Value,"split",translate("Max number of split"),
translate("Download a file using N connections."))
e.datatype="uinteger"
e.placeholder="5"
e=t:taboption("http",Value,"min_split_size",translate("Min split size"),
translate("Don't split less than 2*SIZE byte range. Possible values: 1M-1024M."))
e.placeholder="20M"
e=t:taboption("http",Value,"max_tries",translate("Max tries"))
e.datatype="uinteger"
e.placeholder="5"
e=t:taboption("http",Value,"retry_wait",translate("Retry wait"),
translate("Set the seconds to wait between retries."))
e.datatype="uinteger"
e.placeholder="0"
e=t:taboption("http",Value,"user_agent",translate("User agent"),
translate("Set user agent for HTTP(S) downloads."))
e.placeholder="aria2/%s"%{a.version and a.version or"$VERSION"}
if a.bt then
t:tab("bt",translate("BitTorrent Options"))
e=t:taboption("bt",Flag,"enable_dht",translate("IPv4 <abbr title=\"Distributed Hash Table\">DHT</abbr> enabled"),
"%s %s"%{
translate("Enable IPv4 DHT functionality. It also enables UDP tracker support."),
translate("This option will be ignored if a private flag is set in a torrent.")
})
e.enabled="true"
e.disabled="false"
e.default="true"
e.rmempty=false
e=t:taboption("bt",Flag,"enable_dht6",translate("IPv6 <abbr title=\"Distributed Hash Table\">DHT</abbr> enabled"),
"%s %s"%{
translate("Enable IPv6 DHT functionality."),
translate("This option will be ignored if a private flag is set in a torrent.")
})
e.enabled="true"
e.disabled="false"
e=t:taboption("bt",Flag,"bt_enable_lpd",translate("<abbr title=\"Local Peer Discovery\">LPD</abbr> enabled"),
"%s %s"%{
translate("Enable Local Peer Discovery."),
translate("This option will be ignored if a private flag is set in a torrent.")
})
e.enabled="true"
e.disabled="false"
e.default="false"
e=t:taboption("bt",Flag,"enable_peer_exchange",translate("Enable peer exchange"),
"%s %s"%{
translate("Enable Peer Exchange extension."),
translate("This option will be ignored if a private flag is set in a torrent.")
})
e.enabled="true"
e.disabled="false"
e.default="true"
e.rmempty=false
e=t:taboption("bt",Flag,"bt_save_metadata",translate("Sava metadata"),
translate("Save meta data as \".torrent\" file. This option has effect only when BitTorrent"
.." Magnet URI is used. The file name is hex encoded info hash with suffix \".torrent\"."))
e.enabled="true"
e.disabled="false"
e.default="false"
e=t:taboption("bt",Flag,"bt_remove_unselected_file",translate("Remove unselected file"),
translate("Removes the unselected files when download is completed in BitTorrent. Please"
.." use this option with care because it will actually remove files from your disk."))
e.enabled="true"
e.disabled="false"
e.default="false"
e=t:taboption("bt",Flag,"bt_seed_unverified",translate("Seed unverified"),
translate("Seed previously downloaded files without verifying piece hashes."))
e.enabled="true"
e.disabled="false"
e.default="false"
e=t:taboption("bt",Value,"listen_port",translate("BitTorrent listen port"),
translate("Set TCP port number for BitTorrent downloads. Accept format: \"6881,6885\","
.." \"6881-6999\" and \"6881-6889,6999\". Make sure that the specified ports are open"
.." for incoming TCP traffic."))
e.placeholder="6881-6999"
e=t:taboption("bt",Value,"dht_listen_port",translate("DHT Listen port"),
translate("Set UDP listening port used by DHT(IPv4, IPv6) and UDP tracker. Make sure that the "
.."specified ports are open for incoming UDP traffic."))
e:depends("enable_dht","true")
e:depends("enable_dht6","true")
e.placeholder="6881-6999"
e=t:taboption("bt",ListValue,"follow_torrent",translate("Follow torrent"))
e:value("true",translate("True"))
e:value("false",translate("False"))
e:value("mem",translate("Keep in memory"))
e=t:taboption("bt",Value,"max_overall_upload_limit",translate("Max overall upload limit"),
"%s %s"%{
translate("Set max overall upload speed in bytes/sec. 0 means unrestricted."),
translate("You can append K or M.")
})
e.placeholder="0"
e=t:taboption("bt",Value,"max_upload_limit",translate("Max upload limit"),
"%s %s"%{
translate("Set max upload speed per each torrent in bytes/sec. 0 means unrestricted."),
translate("You can append K or M.")
})
e.placeholder="0"
e=t:taboption("bt",Value,"bt_max_open_files",translate("Max open files"),
translate("Specify maximum number of files to open in multi-file BitTorrent download globally."))
e.datatype="uinteger"
e.placeholder="100"
e=t:taboption("bt",Value,"bt_max_peers",translate("Max peers"),
translate("Specify the maximum number of peers per torrent, 0 means unlimited."))
e.datatype="uinteger"
e.placeholder="55"
e=t:taboption("bt",Value,"bt_request_peer_speed_limit",translate("Request peer speed limit"),
"%s %s"%{
translate("If the whole download speed of every torrent is lower than SPEED, aria2"
.." temporarily increases the number of peers to try for more download speed."
.." Configuring this option with your preferred download speed can increase your"
.." download speed in some cases."),
translate("You can append K or M.")
})
e.placeholder="50K"
e=t:taboption("bt",Value,"bt_stop_timeout",translate("Stop timeout"),
translate("Stop BitTorrent download if download speed is 0 in consecutive N seconds. If 0 is"
.." given, this feature is disabled."))
e.datatype="uinteger"
e.placeholder="0"
e=t:taboption("bt",Value,"peer_id_prefix",translate("Prefix of peer ID"),
translate("Specify the prefix of peer ID. The peer ID in BitTorrent is 20 byte length."
.." If more than 20 bytes are specified, only first 20 bytes are used. If less than 20"
.." bytes are specified, random byte data are added to make its length 20 bytes."))
e.placeholder="A2-%s-"%{
a.version and string.gsub(a.version,"%.","-")or"$MAJOR-$MINOR-$PATCH"
}
e=t:taboption("bt",Value,"seed_ratio",translate("Seed ratio"),
translate("Specify share ratio. Seed completed torrents until share ratio reaches RATIO."
.." You are strongly encouraged to specify equals or more than 1.0 here. Specify 0.0 if"
.." you intend to do seeding regardless of share ratio."))
e.datatype="ufloat"
e.placeholder="1.0"
e=t:taboption("bt",Value,"seed_time",translate("Seed time"),
translate("Specify seeding time in minutes. If \"Seed ratio\" option is"
.." specified along with this option, seeding ends when at least one of the conditions"
.." is satisfied. Specifying 0 disables seeding after download completed."))
e.datatype="ufloat"
e=t:taboption("bt",DynamicList,"bt_tracker",translate("Additional BT tracker"),
translate("List of additional BitTorrent tracker's announce URI."))
e.placeholder="http://tracker.example.com/announce"
end
t:tab("advance",translate("Advanced Options"))
e=t:taboption("advance",Flag,"disable_ipv6",translate("IPv6 disabled"),
translate("Disable IPv6. This is useful if you have to use broken DNS and want to avoid terribly"
.." slow AAAA record lookup."))
e.enabled="true"
e.disabled="false"
e.default="false"
e=t:taboption("advance",Value,"auto_save_interval",translate("Auto save interval"),
translate("Save a control file(*.aria2) every N seconds. If 0 is given, a control file is not"
.." saved during download."))
e.datatype="range(0, 600)"
e.placeholder="60"
e=t:taboption("advance",Value,"save_session_interval",translate("Save session interval"),
translate("Save error/unfinished downloads to session file every N seconds. If 0 is given, file"
.." will be saved only when aria2 exits."))
e.datatype="uinteger"
e.placeholder="0"
e=t:taboption("advance",Value,"disk_cache",translate("Disk cache"),
"%s %s"%{
translate("Enable disk cache (in bytes), set 0 to disabled."),
translate("You can append K or M.")
})
e.placeholder="16M"
e=t:taboption("advance",ListValue,"file_allocation",translate("File allocation"),
translate("Specify file allocation method. If you are using newer file systems such as ext4"
.." (with extents support), btrfs, xfs or NTFS(MinGW build only), \"falloc\" is your best choice."
.." It allocates large(few GiB) files almost instantly, but it may not be available if your system"
.." doesn't have posix_fallocate(3) function. Don't use \"falloc\" with legacy file systems such as"
.." ext3 and FAT32 because it takes almost same time as \"prealloc\" and it blocks aria2 entirely"
.." until allocation finishes."))
e:value("none",translate("None"))
e:value("prealloc",translate("prealloc"))
e:value("trunc",translate("trunc"))
e:value("falloc",translate("falloc"))
e.default="falloc"
e=t:taboption("advance",Flag,"force_save",translate("Force save"),
translate("Save download to session file even if the download is completed or removed."
.." This option also saves control file in that situations. This may be useful to save"
.." BitTorrent seeding which is recognized as completed state."))
e.enabled="true"
e.disabled="false"
e.default="false"
e=t:taboption("advance",Value,"max_overall_download_limit",translate("Max overall download limit"),
"%s %s"%{
translate("Set max overall download speed in bytes/sec. 0 means unrestricted."),
translate("You can append K or M.")
})
e.placeholder="0"
e=t:taboption("advance",Value,"max_download_limit",translate("Max download limit"),
"%s %s"%{
translate("Set max download speed per each download in bytes/sec. 0 means unrestricted."),
translate("You can append K or M.")
})
e.placeholder="0"
t=o:section(NamedSection,"main","aria2",translate("Extra Settings"),
translate("Settings in this section will be added to config file."))
t.addremove=false
t.anonymous=true
e=t:option(DynamicList,"extra_settings",translate("Settings list"),
translate("List of extra settings. Format: option=value, eg. <code>netrc-path=/tmp/.netrc</code>."))
e.placeholder="option=value"
return o

View File

@ -0,0 +1,41 @@
local t,a,e
local n=require"nixio.fs"
local o=require"luci.util"
local i=require"luci.model.uci".cursor()
if i:get("aria2","main","Pro")then
config_dir=i:get("aria2","main","Pro")or""
else
config_dir=i:get("aria2","main","config_dir")or""
end
local s="%s/aria2.conf.main"%config_dir
local h="%s/aria2.session"%config_dir
local i="/etc/config/aria2"%config_dir
t=SimpleForm("aria2","%s - %s"%{translate("Aria2"),translate("Files")},
translate("Here shows the files used by aria2."))
t.reset=false
t.submit=false
a=t:section(SimpleSection,nil,translatef("在<code>%s</code>下的config文件内容",i))
e=a:option(TextValue,"_session")
e.rows=20
e.readonly=true
e.cfgvalue=function()
local e=n.readfile(i)or translate("File does not exist.")
return o.trim(e)~=""and e or translate("Empty file.")
end
a=t:section(SimpleSection,nil,translatef("在<code>%s</code>下的config文件内容",s))
e=a:option(TextValue,"_config")
e.rows=20
e.readonly=true
e.cfgvalue=function()
local e=n.readfile(s)or translate("File does not exist.")
return o.trim(e)~=""and e or translate("Empty file.")
end
a=t:section(SimpleSection,nil,translatef("在<code>%s</code>下的session文件内容",h))
e=a:option(TextValue,"_session")
e.rows=20
e.readonly=true
e.cfgvalue=function()
local e=n.readfile(h)or translate("File does not exist.")
return o.trim(e)~=""and e or translate("Empty file.")
end
return t

View File

@ -0,0 +1,71 @@
<%#
Copyright 2017-2019 Xingwang Liao <kuoruan@gmail.com>
Licensed to the public under the MIT License.
-%>
<% css = [[
#log_text {
padding: 15px;
text-align: left;
}
#log_text pre {
word-break: break-all;
margin: 0;
font-size : 10pt;
font-family :Arial;
<!-- background-color:#F0F0F0; -->
<!-- color : #202020; -->
}
.description {
background-color: #93ccff;
font-size : 15pt;
]]
-%>
<%+header%>
<script type="text/javascript" src="<%=resource%>/cbi.js?v=git-19.300.11807-7668d3e"></script>
<script type="text/javascript">//<![CDATA[
function clearlog(btn) {
XHR.get('<%=url("admin/nas/aria2/clear_log")%>', null,
function(x, data) {
if(x && x.status == 200) {
var log_textarea = document.getElementById('log_textarea');
log_textarea.innerHTML = "";
log_textarea.scrollTop = log_textarea.scrollHeight;
}
}
);
}
XHR.poll(10, '<%=url("admin/nas/aria2/log/read")%>', null,
function(x, data) {
var logElm = document.getElementById('log_text');
if (logElm) {
logElm.innerHTML = data
? String.format(
'<pre>%s%s%s%s</pre>',
'<span class="description"><%:Last 50 lines of syslog:%></span><br/><br/>',
data.syslog || '<%:No log data.%>',
'<br/><br/><span class="description"><%:Last 50 lines of log file:%></span><br/><br/>',
data.log || '<%:No log data.%>'
)
: '<strong><%:Failed to load log data.%></strong>';
}
}
);
//]]></script>
<div class="cbi-map">
<h2 name="content"><%:Aria2%> - <%:Log Data%></h2>
<fieldset class="cbi-section">
<input class="cbi-button cbi-input-remove" type="button" onclick="clearlog()" value="<%:Clear logs%>" />
<div id="log_text">
<img src="<%=resource%>/icons/loading.gif" alt="<%:Loading%>" style="vertical-align:middle" />
<%:Collecting data...%>
</div>
<div style="text-align:right"><small><%:Refresh every 10 seconds.%></small></div>
</fieldset>
</div>
<%+footer%>

View File

@ -0,0 +1,116 @@
<%#
Copyright 2017-2019 Xingwang Liao <kuoruan@gmail.com>
Licensed to the public under the MIT License.
-%>
<%
local ipkg = require "luci.model.ipkg"
local has_ui = false
local uilist = {
supported = {
["ariang"] = "AriaNg",
["webui-aria2"] = "WebUI-Aria2",
["yaaw"] = "YAAW"
},
installed = {}
}
for k in pairs(uilist.supported) do
if ipkg.installed(k) then
uilist.installed[#uilist.installed + 1] = k
has_ui = true
end
end
%>
<fieldset class="cbi-section">
<p id="aria2_status">
<em><%:Collecting data...%></em>
</p>
<% if has_ui then %>
<p>
<%:Installed web interface: %>
<%- for _, v in pairs(uilist.installed) do %>
<input type="button" class="cbi-button cbi-button-apply" style="margin: 0 5px;" value="<%=uilist.supported[v]%>" onclick="openWebInterface('<%=v%>');" />
<%- end %>
<p>
<% end %>
</fieldset>
<script type="text/javascript">//<![CDATA[
XHR.poll(5, '<%=url("admin/nas/aria2/status")%>', null,
function(x, data) {
var tb = document.getElementById('aria2_status');
if (data && tb) {
tb.innerHTML = data.running
? '<em><b><font color=green><%:The Aria2 service is running.%>'
: '<em><b><font color=red><%:The Aria2 service is not running.%>';
}
}
);
function randomString(len) {
var randomStr = '';
var restLen = len;
while ((restLen = len - randomStr.length) > 0) {
randomStr += Math.random().toString(36).substring(2, 2 + restLen);
}
return randomStr;
}
function randomToken() {
var len = 32;
var inputLength = prompt('<%:Please input token length:%>', len);
if (inputLength === null || inputLength === '') {
return;
} else if (/^\d+$/.test(inputLength)) {
len = parseInt(inputLength);
}
var secretInput = document.getElementById('cbid.aria2.main.rpc_secret');
if (secretInput) {
secretInput.value = randomString(len);
}
};
function showRPCURL() {
var portElm = document.getElementById('cbid.aria2.main.rpc_listen_port');
var authMethodElm = document.getElementById('cbid.aria2.main.rpc_auth_method');
var useWSElm = document.getElementById('cbid.aria2.main._use_ws');
var secureElm = document.getElementById('cbid.aria2.main.rpc_secure');
var port = (portElm && /^\d+$/.test(portElm.value)) ? parseInt(portElm.value) : 6800;
var authMethod = (authMethodElm && authMethodElm.value) ? authMethodElm.value : "none";
var useWS = (useWSElm && useWSElm.checked) ? true : false;
var secure = (secureElm && secureElm.checked) ? true : false;
var protocol = useWS
? (secure ? 'wss' : 'ws')
: (secure ? 'https' : 'http');
var url = protocol + "://";
if (authMethod == 'token') {
var authToken = document.getElementById('cbid.aria2.main.rpc_secret').value;
url += 'token:' + authToken + '@';
} else if (authMethod == 'user_pass') {
var authUser = document.getElementById('cbid.aria2.main.rpc_user').value;
var authPasswd = document.getElementById('cbid.aria2.main.rpc_passwd').value;
url += authUser + ':' + authPasswd + '@';
}
url += window.location.hostname + ':' + port + '/jsonrpc';
var rpcUrlElm = document.getElementById('cbid.aria2.main._rpc_url');
if (rpcUrlElm) {
rpcUrlElm.value = url;
} else {
alert(url)
}
};
function openWebInterface(path) {
var host = window.location.host;
var protocol = window.location.protocol;
window.open(protocol + '//' + host + '/' + path);
};
//]]></script>

View File

@ -0,0 +1,22 @@
<%#
Copyright 2017-2019 Xingwang Liao <kuoruan@gmail.com>
Licensed to the public under the MIT License.
-%>
<%+cbi/valueheader%>
<input data-update="change" type="text" class="cbi-input-text"<%=
attr("id", cbid) ..
attr("name", cbid) ..
attr("value", self:cfgvalue(section) or self.default) ..
ifattr(self.size, "size") ..
ifattr(self.placeholder, "placeholder") ..
ifattr(self.maxlength, "maxlength") ..
ifattr(self.datatype, "data-type", self.datatype) ..
ifattr(self.onmouseover, "onmouseover")
%> />
<%- if self.btntext then -%>
<div class="cbi-button cbi-button-neutral" title="<%=self.btntext%>" aria-label="<%=self.btntext%>"<%=
ifattr(self.btnclick, "onclick", self.btnclick)
%>><span style="font-weight: normal;"><%=self.btntext%></span></div>
<% end %>
<%+cbi/valuefooter%>

View File

@ -0,0 +1,863 @@
msgid ""
msgstr "Content-Type: text/plain; charset=UTF-8\n"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:296
msgid "<abbr title=\"Local Peer Discovery\">LPD</abbr> enabled"
msgstr "启用<abbr title=\"Local Peer Discovery\">LPD</abbr>"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:414
msgid "Additional BT tracker"
msgstr "额外的BT Tracker"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:419
msgid "Advanced Options"
msgstr "高级选项"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:169
msgid "All proxy"
msgstr "全局代理"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:228
msgid "Append HEADERs to HTTP request header."
msgstr "追加的HTTP请求头。"
#: applications/luci-app-aria2/luasrc/controller/aria2.lua:18
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:35
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/files.lua:14
#: applications/luci-app-aria2/luasrc/view/aria2/log_template.htm:45
msgid "Aria2"
msgstr "Aria2"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:37
msgid ""
"Aria2 is a lightweight multi-protocol &amp; multi-source, cross platform "
"download utility."
msgstr "Aria2是一个轻量、多线程跨平台的下载工具。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:428
msgid "Auto save interval"
msgstr "定时保存会话间隔"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:56
msgid "Basic Options"
msgstr "基本选项"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:276
msgid "BitTorrent Options"
msgstr "BT 选项"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:335
msgid "BitTorrent listen port"
msgstr "BitTorrent监听端口"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:189
msgid "CA certificate"
msgstr "CA证书"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:195
msgid "Certificate"
msgstr "证书"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:182
msgid "Check certificate"
msgstr "检查证书"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:242
msgid ""
"Close connection if download speed is lower than or equal to this "
"value(bytes per sec). 0 means has no lowest speed limit."
msgstr ""
"如果速度小于或等于这个速度byte/s关闭下载下载连接。0表示不限制下载速"
"度。"
#: applications/luci-app-aria2/luasrc/view/aria2/log_template.htm:49
#: applications/luci-app-aria2/luasrc/view/aria2/settings_header.htm:29
msgid "Collecting data..."
msgstr "正在收集数据..."
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:73
msgid "Config file directory"
msgstr "配置文件目录"
#: applications/luci-app-aria2/luasrc/controller/aria2.lua:21
msgid "Configuration"
msgstr "配置"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:230
msgid "Connect timeout"
msgstr "连接超时时间"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/files.lua:19
msgid "Content of config file: <code>%s</code>"
msgstr "配置文件的内容:<code>%s</code>"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/files.lua:29
msgid "Content of session file: <code>%s</code>"
msgstr "Session文件的内容<code>%s</code>"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:341
msgid "DHT Listen port"
msgstr "DHT监听端口"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:87
msgid "Debug"
msgstr "调试"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:422
msgid ""
"Disable IPv6. This is useful if you have to use broken DNS and want to avoid "
"terribly slow AAAA record lookup."
msgstr ""
"禁用IPv6。如果你的DNS有问题并希望避免AAAA查询过慢可以启用此选项。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:440
msgid "Disk cache"
msgstr "磁盘缓存"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:259
msgid "Don't split less than 2*SIZE byte range. Possible values: 1M-1024M."
msgstr "当数据小于2*SIZE时不分割。可能的值1M-1024M。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:254
msgid "Download a file using N connections."
msgstr "使用N线程下载文件。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:69
msgid "Download directory"
msgstr "下载文件夹"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/files.lua:26
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/files.lua:36
msgid "Empty file."
msgstr "文件为空。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:280
msgid "Enable IPv4 DHT functionality. It also enables UDP tracker support."
msgstr "启用IPv4 DHT功能。会同时启用UDP Tracker支持。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:290
msgid "Enable IPv6 DHT functionality."
msgstr "启用IPv6 DHT功能。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:298
msgid "Enable Local Peer Discovery."
msgstr "启用本地Peer查找。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:307
msgid "Enable Peer Exchange extension."
msgstr "启用Peer交换扩展。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:442
msgid "Enable disk cache (in bytes), set 0 to disabled."
msgstr "启用硬盘缓存byte0 表示禁用。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:77
msgid "Enable logging"
msgstr "启用日志"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:305
msgid "Enable peer exchange"
msgstr "启用Peer交换"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:166
msgid "Enable proxy"
msgstr "启用代理"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:58
msgid "Enabled"
msgstr "启用"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:91
msgid "Error"
msgstr "错误"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:44
msgid "Error: Can't find aria2c in PATH, please reinstall aria2."
msgstr "错误未在PATH中找到aria2c请重新安装Aria2。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:482
msgid "Extra Settings"
msgstr "附加选项"
#: applications/luci-app-aria2/luasrc/view/aria2/log_template.htm:39
msgid "Failed to load log data."
msgstr "获取日志数据失败。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:350
msgid "False"
msgstr "否"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:447
msgid "File allocation"
msgstr "文件分配"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/files.lua:25
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/files.lua:35
msgid "File does not exist."
msgstr "文件不存在。"
#: applications/luci-app-aria2/luasrc/controller/aria2.lua:24
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/files.lua:14
msgid "Files"
msgstr "文件"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:348
msgid "Follow torrent"
msgstr "自动添加下载的种子"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:460
msgid "Force save"
msgstr "强制保存"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:129
msgid "Generate Randomly"
msgstr "随机生成"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:210
msgid "HTTP accept gzip"
msgstr "HTTP使用Gzip"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:219
msgid "HTTP no cache"
msgstr "HTTP无缓存"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:164
msgid "HTTP/FTP/SFTP Options"
msgstr "HTTP/FTP/SFTP选项"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:227
msgid "Header"
msgstr "请求头"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/files.lua:15
msgid "Here shows the files used by aria2."
msgstr "这里展示了Aria2使用的文件。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:278
msgid "IPv4 <abbr title=\"Distributed Hash Table\">DHT</abbr> enabled"
msgstr "启用IPv4<abbr title=\"Distributed Hash Table\">DHT</abbr>"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:288
msgid "IPv6 <abbr title=\"Distributed Hash Table\">DHT</abbr> enabled"
msgstr "启用IPv6<abbr title=\"Distributed Hash Table\">DHT</abbr>"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:421
msgid "IPv6 disabled"
msgstr "禁用IPv6"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:379
msgid ""
"If the whole download speed of every torrent is lower than SPEED, aria2 "
"temporarily increases the number of peers to try for more download speed. "
"Configuring this option with your preferred download speed can increase your "
"download speed in some cases."
msgstr ""
"如果某个BT任务的下载速度小于配置的速度Aria2会临时提高Peer的数量来尝试"
"获得更大的下载速度。在某些情况下,配置此选项能提高你的下载速度。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:88
msgid "Info"
msgstr "信息"
#: applications/luci-app-aria2/luasrc/view/aria2/settings_header.htm:33
msgid "Installed web interface:"
msgstr "已安装的WEB界面"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:158
msgid "Json-RPC URL"
msgstr "Json-RPC URL"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:351
msgid "Keep in memory"
msgstr "保存在内存中"
#: applications/luci-app-aria2/luasrc/view/aria2/log_template.htm:34
msgid "Last 50 lines of log file:"
msgstr "日志文件的最新50行"
#: applications/luci-app-aria2/luasrc/view/aria2/log_template.htm:36
msgid "Last 50 lines of syslog:"
msgstr "系统日志的最新50行"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:62
msgid "Leave blank to use default user."
msgstr "留空以使用默认用户。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:415
msgid "List of additional BitTorrent tracker's announce URI."
msgstr "额外的BT Tracker通告链接。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:488
msgid ""
"List of extra settings. Format: option=value, eg. <code>netrc-path=/tmp/."
"netrc</code>."
msgstr ""
"额外设置的列表。格式option=value例如<code>netrc-path=/tmp/.netrc</"
"code>。"
#: applications/luci-app-aria2/luasrc/view/aria2/log_template.htm:48
msgid "Loading"
msgstr "正在加载"
#: applications/luci-app-aria2/luasrc/controller/aria2.lua:27
msgid "Log"
msgstr "日志"
#: applications/luci-app-aria2/luasrc/view/aria2/log_template.htm:45
msgid "Log Data"
msgstr "日志数据"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:80
msgid "Log file"
msgstr "日志文件"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:85
msgid "Log level"
msgstr "日志记录等级"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:240
msgid "Lowest speed limit"
msgstr "最低限速"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:94
msgid "Max concurrent downloads"
msgstr "最大同时下载任务数"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:248
msgid "Max connection per server"
msgstr "单服务器最大连接数"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:475
msgid "Max download limit"
msgstr "最大下载限速"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:253
msgid "Max number of split"
msgstr "单文件最大线程数"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:367
msgid "Max open files"
msgstr "最大打开文件数"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:468
msgid "Max overall download limit"
msgstr "最大全局下载限速"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:353
msgid "Max overall upload limit"
msgstr "最大全局上传限速"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:372
msgid "Max peers"
msgstr "最大 Peer 数量"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:262
msgid "Max tries"
msgstr "最大重试次数"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:360
msgid "Max upload limit"
msgstr "最大上传限速"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:258
msgid "Min split size"
msgstr "最小文件分片大小"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:115
msgid "No Authentication"
msgstr "无认证"
#: applications/luci-app-aria2/luasrc/view/aria2/log_template.htm:35
#: applications/luci-app-aria2/luasrc/view/aria2/log_template.htm:37
msgid "No log data."
msgstr "无日志数据。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:454
msgid "None"
msgstr "无"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:89
msgid "Notice"
msgstr "注意"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:99
msgid "Pause"
msgstr "暂停"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:99
msgid "Pause download after added."
msgstr "在下载任务添加后不开始下载。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:105
msgid "Pause downloads created as a result of metadata download."
msgstr "暂停下载内容为元数据的下载(磁力链接和 Matalink。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:104
msgid "Pause metadata"
msgstr "暂停元数据"
#: applications/luci-app-aria2/luasrc/view/aria2/settings_header.htm:64
msgid "Please input token length:"
msgstr "请输入密钥长度:"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:393
msgid "Prefix of peer ID"
msgstr "Peer ID前缀"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:203
msgid "Private key"
msgstr "私钥"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:177
msgid "Proxy password"
msgstr "代理密码"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:174
msgid "Proxy user"
msgstr "代理用户名"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:97
msgid "RPC Options"
msgstr "RPC选项"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:114
msgid "RPC authentication method"
msgstr "RPC认证方式"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:140
msgid "RPC certificate"
msgstr "RPC证书"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:122
msgid "RPC password"
msgstr "RPC密码"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:110
msgid "RPC port"
msgstr "RPC端口"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:149
msgid "RPC private key"
msgstr "RPC私钥"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:133
msgid "RPC secure"
msgstr "RPC加密"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:126
msgid "RPC token"
msgstr "RPC令牌"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:134
msgid ""
"RPC transport will be encrypted by SSL/TLS. The RPC clients must use https "
"scheme to access the server. For WebSocket client, use wss scheme."
msgstr ""
"用SSL/TLS加密RPC连接。RPC客户端必须使用HTTPS协议来连接服务端对于 "
"WebSocket客户端则使用WSS协议。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:119
msgid "RPC username"
msgstr "RPC用户名"
#: applications/luci-app-aria2/luasrc/view/aria2/log_template.htm:51
msgid "Refresh every 10 seconds."
msgstr "每10秒刷新。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:322
msgid "Remove unselected file"
msgstr "删除未选择的文件"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:323
msgid ""
"Removes the unselected files when download is completed in BitTorrent. "
"Please use this option with care because it will actually remove files from "
"your disk."
msgstr "BT下载完成时删除未选择的文件。文件将从磁盘中被完全删除请谨慎使用。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:377
msgid "Request peer speed limit"
msgstr "单个Peer限速"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:266
msgid "Retry wait"
msgstr "重试等待"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:61
msgid "Run daemon as user"
msgstr "以此用户权限运行"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:315
msgid "Sava metadata"
msgstr "保存元数据"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:429
msgid ""
"Save a control file(*.aria2) every N seconds. If 0 is given, a control file "
"is not saved during download."
msgstr ""
"每N秒保存下载“控制文件”*.aria2。设置0表示在下载过程中不保存控制文件。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:461
msgid ""
"Save download to session file even if the download is completed or removed. "
"This option also saves control file in that situations. This may be useful "
"to save BitTorrent seeding which is recognized as completed state."
msgstr ""
"即使下载已完成或已删除,也将其保存到会话文件。开启此选项也会同时保存“控制文"
"件”。此选项可能有助于保持被识别为已完成状态的BT做种。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:435
msgid ""
"Save error/unfinished downloads to session file every N seconds. If 0 is "
"given, file will be saved only when aria2 exits."
msgstr ""
"每 N 秒将失败的/未完成的下载保存到Session文件。设置0则仅在Aria2退出时保"
"存。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:316
msgid ""
"Save meta data as \".torrent\" file. This option has effect only when "
"BitTorrent Magnet URI is used. The file name is hex encoded info hash with "
"suffix \".torrent\"."
msgstr ""
"将元数据保存到\".torrent\"文件。此选项仅在下载连接为BT磁力链接时生效。文"
"件名为Hash值后缀为\".torrent\"。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:434
msgid "Save session interval"
msgstr "Session保存间隔"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:330
msgid "Seed previously downloaded files without verifying piece hashes."
msgstr "继续之前的BT任务时, 无需再次校验分片Hash。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:401
msgid "Seed ratio"
msgstr "做种比率"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:408
msgid "Seed time"
msgstr "做种时间"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:329
msgid "Seed unverified"
msgstr "不校验种子"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:211
msgid ""
"Send <code>Accept: deflate, gzip</code> request header and inflate response "
"if remote server responds with <code>Content-Encoding: gzip</code> or "
"<code>Content-Encoding: deflate</code>."
msgstr ""
"发送<code>Accept: deflate, gzip</code>请求头,当服务器响应头包含 "
"<code>Content-Encoding: gzip</code>或者<code>Content-Encoding: deflate</"
"code>时解压响应数据。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:220
msgid ""
"Send <code>Cache-Control: no-cache</code> and <code>Pragma: no-cache</code> "
"header to avoid cached content. If disabled, these headers are not sent and "
"you can add Cache-Control header with a directive you like using \"Header\" "
"option."
msgstr ""
"发送 <code>Cache-Control: no-cache</code>和<code>Pragma: no-cache</code> 请"
"求头来防止缓存内容禁用则不发送。你也可用使用“请求头”选项来设置Cache-"
"Control请求头。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:336
msgid ""
"Set TCP port number for BitTorrent downloads. Accept format: \"6881,6885\", "
"\"6881-6999\" and \"6881-6889,6999\". Make sure that the specified ports are "
"open for incoming TCP traffic."
msgstr ""
"为BT下载设置TCP端口。支持的格式\"6881,6885\"\"6881-6999\" 和 "
"\"6881-6889,6999\"。请确保正确放行了这些端口的TCP入站通信。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:342
msgid ""
"Set UDP listening port used by DHT(IPv4, IPv6) and UDP tracker. Make sure "
"that the specified ports are open for incoming UDP traffic."
msgstr ""
"为DHTIPv4IPv6和UDP tracker设置UDP监听端口。请确保正确放行了这些端"
"口的UDP入站通信。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:477
msgid ""
"Set max download speed per each download in bytes/sec. 0 means unrestricted."
msgstr "设置每个任务的最大下载速度byte/s0表示不限制。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:470
msgid "Set max overall download speed in bytes/sec. 0 means unrestricted."
msgstr "设置全局最大下载速度byte/s0表示不限制。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:355
msgid "Set max overall upload speed in bytes/sec. 0 means unrestricted."
msgstr "设置全局最大上传速度0表示不限制。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:362
msgid ""
"Set max upload speed per each torrent in bytes/sec. 0 means unrestricted."
msgstr "设置每个任务的最大上传速度byte/s0表示不限制。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:231
msgid ""
"Set the connect timeout in seconds to establish connection to HTTP/FTP/proxy "
"server. After the connection is established, this option makes no effect and "
"\"Timeout\" option is used instead."
msgstr ""
"设置HTTP、FTP和代理服务器的连接超时时间。当连接建立后该选项失去作用"
"而“超时时间”选项会被使用。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:267
msgid "Set the seconds to wait between retries."
msgstr "设置重试的时间间隔。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:272
msgid "Set user agent for HTTP(S) downloads."
msgstr "为HTTP(S)下载设置UA。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:35
msgid "Settings"
msgstr "设置"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:483
msgid "Settings in this section will be added to config file."
msgstr "这个区域中的配置信息将被添加到配置文件中。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:487
msgid "Settings list"
msgstr "设置列表"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:161
msgid "Show URL"
msgstr "显示URL"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:448
msgid ""
"Specify file allocation method. If you are using newer file systems such as "
"ext4 (with extents support), btrfs, xfs or NTFS(MinGW build only), \"falloc"
"\" is your best choice. It allocates large(few GiB) files almost instantly, "
"but it may not be available if your system doesn't have posix_fallocate(3) "
"function. Don't use \"falloc\" with legacy file systems such as ext3 and "
"FAT32 because it takes almost same time as \"prealloc\" and it blocks aria2 "
"entirely until allocation finishes."
msgstr ""
"指定文件分配方式。如果你使用的文件系统较新例如ext4支持扩展分区"
"btrfsxfs或者NTFS仅限 MinGW 版本),强烈推荐 \"falloc\",这种方式几乎能"
"立即分配比较大的文件GB但是它要求你的系统支持posix_fallocate(3) 函数。"
"不要在ext3或者FAT32这些旧文件系统中使用 \"falloc\",因为它花费的时间和 "
"\"prealloc\" 几乎一样多而且在文件分配过程中会阻塞整个Aria2进程。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:368
msgid ""
"Specify maximum number of files to open in multi-file BitTorrent download "
"globally."
msgstr "设置BT全局最大同时下载的文件数量。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:409
msgid ""
"Specify seeding time in minutes. If \"Seed ratio\" option is specified along "
"with this option, seeding ends when at least one of the conditions is "
"satisfied. Specifying 0 disables seeding after download completed."
msgstr ""
"指定做种时间(分钟)。如果同时指定了“做种比率”选项,那么将在任一条件满足时停"
"止做种。设置0表示下载完成后停止做种。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:402
msgid ""
"Specify share ratio. Seed completed torrents until share ratio reaches "
"RATIO. You are strongly encouraged to specify equals or more than 1.0 here. "
"Specify 0.0 if you intend to do seeding regardless of share ratio."
msgstr ""
"指定做种比率。BT下载完成之后持续做种直到比率达到指定值。强烈建议将此选项设"
"置为大于或等于1.0。设置为0.0来无限做种。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:373
msgid "Specify the maximum number of peers per torrent, 0 means unlimited."
msgstr "设置每个BT任务的最大 Peer 数量0表示不限制。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:394
msgid ""
"Specify the prefix of peer ID. The peer ID in BitTorrent is 20 byte length. "
"If more than 20 bytes are specified, only first 20 bytes are used. If less "
"than 20 bytes are specified, random byte data are added to make its length "
"20 bytes."
msgstr ""
"配置Peer ID前缀。Peer ID的长度为20字节。如果配置超过了20字节将仅使用"
"前面的20字节。如果配置少于20字节将添加额外的随机字符来让长度达到20字"
"节。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:388
msgid ""
"Stop BitTorrent download if download speed is 0 in consecutive N seconds. If "
"0 is given, this feature is disabled."
msgstr ""
"当BT任务在N秒的持续时间内的下载速度一直为0则停止下载。0表示禁用。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:387
msgid "Stop timeout"
msgstr "停止超时时间"
#: applications/luci-app-aria2/luasrc/view/aria2/settings_header.htm:48
msgid "The Aria2 service is not running."
msgstr "Aria2 未运行"
#: applications/luci-app-aria2/luasrc/view/aria2/settings_header.htm:47
msgid "The Aria2 service is running."
msgstr "Aria2 运行中"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:74
msgid "The directory to store the config file, session file and DHT file."
msgstr "用于放置配置文件Session文件和DHT文件的目录。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:70
msgid "The directory to store the downloaded file. eg. <code>/mnt/sda1</code>"
msgstr "用于放置下载文件的目录。例如:<code>/mnt/sda1</code>"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:81
msgid "The file name of the log file."
msgstr "日志文件名。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:249
msgid "The maximum number of connections to one server for each download."
msgstr "单一服务器最大连接数量。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:281
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:291
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:299
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:308
msgid "This option will be ignored if a private flag is set in a torrent."
msgstr "如果种子文件具有“私有”属性,该选项将会被忽略。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:236
msgid "Timeout"
msgstr "超时"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:117
msgid "Token"
msgstr "令牌"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:349
msgid "True"
msgstr "是"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:156
msgid "Use WebSocket"
msgstr "使用WebSocket"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:170
msgid "Use a proxy server for all protocols."
msgstr "为所有协议设置代理服务器。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:190
msgid ""
"Use the certificate authorities in FILE to verify the peers. The certificate "
"file must be in PEM format and can contain multiple CA certificates."
msgstr ""
"使用文件中的证书来验证对端。证书文件必须为PEM格式并且可以包含多个证书。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:141
msgid ""
"Use the certificate in FILE for RPC server. The certificate must be either "
"in PKCS12 (.p12, .pfx) or in PEM format.<br/>PKCS12 files must contain the "
"certificate, a key and optionally a chain of additional certificates. Only "
"PKCS12 files with a blank import password can be opened!<br/>When using PEM, "
"you have to specify the \"RPC private key\" as well."
msgstr ""
"使用文件中的证书作为RPC服务器。证书必须为PKCS12 (.p12, .pfx) 或者PEM格"
"式。<br/>PKCS12 文件必须包含证书,一个密钥和可选的附加证书链。只有导入密码为"
"空白的PKCS12文件才能被打开。<br/>使用PEM 时你必须同时指定“RPC私钥”。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:196
msgid ""
"Use the client certificate in FILE. The certificate must be either in PKCS12 "
"(.p12, .pfx) or in PEM format.<br/>PKCS12 files must contain the "
"certificate, a key and optionally a chain of additional certificates. Only "
"PKCS12 files with a blank import password can be opened!<br/>When using PEM, "
"you have to specify the \"Private key\" as well."
msgstr ""
"使用文件中的客户端证书。证书必须为PKCS12 (.p12, .pfx) 或者PEM格式。<br/"
">PKCS12文件必须包含证书一个密钥和可选的附加证书链。只有导入密码为空白的 "
"PKCS12文件才能被打开。<br/>使用PEM时你必须同时指定“RPC私钥”。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:150
msgid ""
"Use the private key in FILE for RPC server. The private key must be "
"decrypted and in PEM format."
msgstr "使用文件中的私钥作为RPC服务器。私钥必须解密并且为PEM格式。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:204
msgid ""
"Use the private key in FILE. The private key must be decrypted and in PEM "
"format. The behavior when encrypted one is given is undefined."
msgstr "使用文件中的私钥。私钥必须解密并且为PEM格式不支持加密的私钥。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:271
msgid "User agent"
msgstr "User Agent"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:116
msgid "Username & Password"
msgstr "用户名与密码"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:183
msgid ""
"Verify the peer using certificates specified in \"CA certificate\" option."
msgstr "使用“CA证书”里配置的证书来验证对端。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:90
msgid "Warn"
msgstr "警告"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:244
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:356
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:363
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:383
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:443
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:471
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:478
msgid "You can append K or M."
msgstr "你可以追加K或者M。"
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:457
msgid "falloc"
msgstr ""
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:455
msgid "prealloc"
msgstr ""
#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:456
msgid "trunc"
msgstr ""
msgid "AriaNg"
msgstr "打开AriaNg的Web管理界面"
msgid "WebUI-Aria2"
msgstr "打开WebUI-Aria2的Web管理界面"
msgid "YAAW"
msgstr "打开YAAW的Web管理界面"
msgid "Enable Aria2 Pro"
msgstr "启用扩展功能"
msgid "Aria2 Pro file"
msgstr "扩展保存目录"
msgid "Use the configuration scheme of p3terx to realize the enhancement and expansion of aria2 function."
msgstr ""
"使用P3TERX的配置方案实现Aria2的增强和扩展,<br/"
">默认放置在(包括系统配置)<code>/usr/share/aria2</code>下。"
msgid "generate randomly"
msgstr "随机生成"
msgid "The webui port defaults to 6800."
msgstr "WebUI端口默认6800。"
msgid "When enabled, the original system configuration directory will be merged."
msgstr "启用后,系统配置文件的目录合并此处。"

View File

@ -0,0 +1,25 @@
#!/bin/sh
uci -q batch <<-EOF >/dev/null
delete ucitrack.@aria2[-1]
add ucitrack aria2
set ucitrack.@aria2[-1].init=aria2
commit ucitrack
EOF
if [ ."$(uci -q get aria2.main)" != ."aria2" ]; then
uci -q batch <<-EOF >/dev/null
add aria2 aria2
rename aria2.@aria2[-1]="main"
set aria2.main.enabled=0
set aria2.main.dir="/var/run/aria2"
set aria2.main.config_dir="/var/etc/aria2"
add_list aria2.main.header=""
add_list aria2.main.bt_tracker=""
add_list aria2.main.extra_setting=""
commit aria2
EOF
fi
rm -f /tmp/luci-indexcache
exit 0

View File

@ -1,16 +0,0 @@
# Copyright (C) 2018-2020 Lienol <lawlienol@gmail.com>
#
# This is free software, licensed under the Apache License, Version 2.0 .
#
include $(TOPDIR)/rules.mk
LUCI_TITLE:=LuCI support for IPSec VPN Server
LUCI_DEPENDS:=+strongswan +strongswan-minimal +strongswan-mod-xauth-generic
LUCI_PKGARCH:=all
PKG_VERSION:=1
PKG_RELEASE:=6-20200402
include ../../luci.mk
# call BuildPackage - OpenWrt buildroot signature

View File

@ -1,24 +0,0 @@
-- Copyright 2018-2019 Lienol <lawlienol@gmail.com>
module("luci.controller.ipsec-server", package.seeall)
function index()
if not nixio.fs.access("/etc/config/ipsec") then return end
entry({"admin", "vpn"}, firstchild(), "VPN", 45).dependent = false
entry({"admin", "vpn", "ipsec-server"},
alias("admin", "vpn", "ipsec-server", "settings"),
_("IPSec VPN Server"), 49).dependent = false
entry({"admin", "vpn", "ipsec-server", "settings"},
cbi("ipsec-server/settings"), _("General Settings"), 10).leaf = true
entry({"admin", "vpn", "ipsec-server", "users"}, cbi("ipsec-server/users"),
_("Users Manager"), 20).leaf = true
entry({"admin", "vpn", "ipsec-server", "status"}, call("status")).leaf =
true
end
function status()
local e = {}
e.status = luci.sys.call("/usr/bin/pgrep ipsec > /dev/null") == 0
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end

View File

@ -1,105 +0,0 @@
local s = require "luci.sys"
local net = require"luci.model.network".init()
local ifaces = s.net:devices()
local m, s, o
mp = Map("ipsec", translate("IPSec VPN Server"))
mp.description = translate(
"IPSec VPN connectivity using the native built-in VPN Client on iOS or Andriod (IKEv1 with PSK and Xauth)")
mp.template = "ipsec-server/index"
s = mp:section(TypedSection, "service")
s.anonymous = true
o = s:option(DummyValue, "ipsec-server_status", translate("Current Condition"))
o.template = "ipsec-server/status"
enabled = s:option(Flag, "enabled", translate("Enable"))
enabled.default = 0
enabled.rmempty = false
clientip = s:option(Value, "clientip", translate("VPN Client IP"))
clientip.datatype = "ip4addr"
clientip.description = translate(
"VPN Client reserved started IP addresses with the same subnet mask")
clientip.optional = false
clientip.rmempty = false
--[[
clientdns = s:option(Value, "clientdns", translate("VPN Client DNS"))
clientdns.datatype = "ip4addr"
clientdns.description = translate("DNS using in VPN tunnel.")
clientdns.optional = false
clientdns.rmempty = false
]]--
secret = s:option(Value, "secret", translate("Secret Pre-Shared Key"))
secret.password = true
function mp.on_save(self)
require "luci.model.uci"
require "luci.sys"
local have_ike_rule = false
local have_ipsec_rule = false
local have_ah_rule = false
local have_esp_rule = false
luci.model.uci.cursor():foreach('firewall', 'rule', function(section)
if section.name == 'ike' then have_ike_rule = true end
if section.name == 'ipsec' then have_ipsec_rule = true end
if section.name == 'ah' then have_ah_rule = true end
if section.name == 'esp' then have_esp_rule = true end
end)
if not have_ike_rule then
local cursor = luci.model.uci.cursor()
local ike_rulename = cursor:add('firewall', 'rule')
cursor:tset('firewall', ike_rulename, {
['name'] = 'ike',
['target'] = 'ACCEPT',
['src'] = 'wan',
['proto'] = 'udp',
['dest_port'] = 500
})
cursor:save('firewall')
cursor:commit('firewall')
end
if not have_ipsec_rule then
local cursor = luci.model.uci.cursor()
local ipsec_rulename = cursor:add('firewall', 'rule')
cursor:tset('firewall', ipsec_rulename, {
['name'] = 'ipsec',
['target'] = 'ACCEPT',
['src'] = 'wan',
['proto'] = 'udp',
['dest_port'] = 4500
})
cursor:save('firewall')
cursor:commit('firewall')
end
if not have_ah_rule then
local cursor = luci.model.uci.cursor()
local ah_rulename = cursor:add('firewall', 'rule')
cursor:tset('firewall', ah_rulename, {
['name'] = 'ah',
['target'] = 'ACCEPT',
['src'] = 'wan',
['proto'] = 'ah'
})
cursor:save('firewall')
cursor:commit('firewall')
end
if not have_esp_rule then
local cursor = luci.model.uci.cursor()
local esp_rulename = cursor:add('firewall', 'rule')
cursor:tset('firewall', esp_rulename, {
['name'] = 'esp',
['target'] = 'ACCEPT',
['src'] = 'wan',
['proto'] = 'esp'
})
cursor:save('firewall')
cursor:commit('firewall')
end
end
return mp

View File

@ -1,18 +0,0 @@
mp = Map("ipsec", translate("IPSec VPN Server"))
mp.description = translate(
"IPSec VPN connectivity using the native built-in VPN Client on iOS or Andriod (IKEv1 with PSK and Xauth)")
s = mp:section(TypedSection, "users", translate("Users Manager"))
s.addremove = true
s.anonymous = true
s.template = "cbi/tblsection"
enabled = s:option(Flag, "enabled", translate("Enabled"))
enabled.rmempty = false
username = s:option(Value, "username", translate("User name"))
username.placeholder = translate("User name")
username.rmempty = true
password = s:option(Value, "password", translate("Password"))
password.rmempty = true
return mp

View File

@ -1,13 +0,0 @@
<% include("cbi/map") %>
<script type="text/javascript">//<![CDATA[
XHR.poll(2, '<%=luci.dispatcher.build_url("admin", "vpn", "ipsec-server", "status")%>', null,
function(x, result)
{
var status = document.getElementsByClassName('ipsec-server_status')[0];
status.setAttribute("style","font-weight:bold;");
status.setAttribute("color",result.status ? "green":"red");
status.innerHTML = result.status?'<%=translate("RUNNING")%>':'<%=translate("NOT RUNNING")%>';
}
)
//]]>
</script>

View File

@ -1,3 +0,0 @@
<%+cbi/valueheader%>
<font class="ipsec-server_status"><%=pcdata(self:cfgvalue(section) or self.default or "")%></font>
<%+cbi/valuefooter%>

View File

@ -1,50 +0,0 @@
msgid "IPSec VPN Server"
msgstr "IPSec VPN 服务器"
msgid "IPSec VPN connectivity using the native built-in VPN Client on iOS or Andriod (IKEv1 with PSK and Xauth)"
msgstr "使用iOS 或者 Andriod (IKEv1 with PSK and Xauth) 原生内置 IPSec VPN 客户端进行连接"
msgid "IPSec VPN Server status"
msgstr "IPSec VPN 服务器运行状态"
msgid "Current Condition"
msgstr "当前状态"
msgid "General settings"
msgstr "基本设置"
msgid "VPN Client IP"
msgstr "VPN客户端地址段"
msgid "VPN Client reserved started IP addresses with the same subnet mask"
msgstr "VPN客户端获取IP的起始地址例如 192.168.100.10/24"
msgid "VPN Client DNS"
msgstr "VPN客户端DNS服务器"
msgid "DNS using in VPN tunnel."
msgstr "指定VPN客户端的DNS地址。"
msgid "Secret Pre-Shared Key"
msgstr "PSK密钥"
msgid "is_nat"
msgstr "NAT转发"
msgid "Interface"
msgstr "接口"
msgid "Specify interface forwarding traffic."
msgstr "指定接口转发流量。"
msgid "Disable from startup"
msgstr "禁止开机启动"
msgid "Enable on startup"
msgstr "允许开机启动"
msgid "NOT RUNNING"
msgstr "未运行"
msgid "RUNNING"
msgstr "运行中"

View File

@ -1,12 +0,0 @@
config service 'ipsec'
option enabled '0'
option secret 'ipsec'
option clientip '192.168.100.10/24'
option clientdns '223.5.5.5'
config users
option enabled '1'
option username 'guest'
option password '123456'

View File

@ -1,68 +0,0 @@
#!/bin/sh /etc/rc.common
START=99
IPSEC_SECRETS_FILE=/etc/ipsec.secrets
IPSEC_CONN_FILE=/etc/ipsec.conf
setup_login() {
config_get enabled $1 enabled
[ "$enabled" -eq 0 ] && return 0
config_get username $1 username
config_get password $1 password
[ -n "$username" ] || return 0
[ -n "$password" ] || return 0
echo "$username : XAUTH '$password'" >> $IPSEC_SECRETS_FILE
}
start() {
local vt_enabled=$(uci -q get ipsec.@service[0].enabled)
[ "$vt_enabled" = 0 ] && return 1
local vt_clientip=$(uci -q get ipsec.@service[0].clientip)
local vt_clientdns=$(uci -q get ipsec.@service[0].clientdns)
[ -z "$vt_clientdns" ] && local vt_clientdns="8.8.4.4"
local vt_secret=$(uci -q get ipsec.@service[0].secret)
cat > $IPSEC_CONN_FILE <<EOF
# ipsec.conf - strongSwan IPsec configuration file
# basic configuration
config setup
# strictcrlpolicy=yes
uniqueids=never
# Add connections here.
conn xauth_psk
keyexchange=ikev1
ike=aes128-sha1-modp2048,aes128-sha1-modp1024,3des-sha1-modp1024,3des-sha1-modp1536
esp=aes128-sha1,3des-sha1
left=%defaultroute
leftauth=psk
leftsubnet=0.0.0.0/0
right=%any
rightauth=psk
rightauth2=xauth
rightsourceip=$vt_clientip
rightdns=$vt_clientdns
auto=add
EOF
cat > /etc/ipsec.secrets <<EOF
# /etc/ipsec.secrets - strongSwan IPsec secrets file
: PSK "$vt_secret"
EOF
config_load ipsec
config_foreach setup_login users
/usr/lib/ipsec/starter --daemon charon --nofork > /dev/null 2>&1 &
fw3 -q reload 2>&1 &
}
stop() {
ps -w | grep "/usr/lib/ipsec" | grep -v "grep" | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1
fw3 -q reload 2>&1
}

View File

@ -1,23 +0,0 @@
#!/bin/sh
uci -q batch <<-EOF >/dev/null
delete firewall.ipsecvpn
set firewall.ipsecvpn=include
set firewall.ipsecvpn.type=script
set firewall.ipsecvpn.path=/usr/share/ipsecvpn/firewall.include
set firewall.ipsecvpn.reload=1
EOF
uci -q batch <<-EOF >/dev/null
delete ucitrack.@ipsec[-1]
add ucitrack ipsec
set ucitrack.@ipsec[-1].init=ipsecvpn
commit ucitrack
EOF
/etc/init.d/ipsec disable && /etc/init.d/ipsec stop
rm -f /etc/init.d/ipsec
chmod a+x /usr/share/ipsecvpn/* >/dev/null 2>&1
rm -rf /tmp/luci-*cache
exit 0

View File

@ -1,39 +0,0 @@
#!/bin/sh
iptables -D INPUT -p udp -m multiport --dports 500,4500 -m comment --comment "IPSec VPN Server" -j ACCEPT 2> /dev/null
ipsec_nums=$(iptables -t nat -n -L POSTROUTING 2>/dev/null | grep -c "IPSec VPN Server")
if [ -n "$ipsec_nums" ]; then
until [ "$ipsec_nums" = 0 ]
do
rules=$(iptables -t nat -n -L POSTROUTING --line-num 2>/dev/null | grep "IPSec VPN Server" | awk '{print $1}')
for rule in $rules
do
iptables -t nat -D POSTROUTING $rule 2> /dev/null
break
done
ipsec_nums=$(expr $ipsec_nums - 1)
done
fi
nums=$(iptables -n -L forwarding_rule 2>/dev/null | grep -c "IPSec VPN Server")
if [ -n "$nums" ]; then
until [ "$nums" = 0 ]
do
rules=$(iptables -n -L forwarding_rule --line-num 2>/dev/null | grep "IPSec VPN Server" | awk '{print $1}')
for rule in $rules
do
iptables -D forwarding_rule $rule 2> /dev/null
break
done
nums=$(expr $nums - 1)
done
fi
enable=$(uci -q get ipsec.ipsec.enabled)
if [ -n "$enable" -a "$enable" == 1 ]; then
clientip=$(uci -q get ipsec.ipsec.clientip)
iptables -t nat -I POSTROUTING -s ${clientip%.*}.0/24 -m comment --comment "IPSec VPN Server" -j MASQUERADE
iptables -I forwarding_rule -s ${clientip%.*}.0/24 -m comment --comment "IPSec VPN Server" -j ACCEPT
iptables -I forwarding_rule -m policy --dir in --pol ipsec --proto esp -m comment --comment "IPSec VPN Server" -j ACCEPT
iptables -I forwarding_rule -m policy --dir out --pol ipsec --proto esp -m comment --comment "IPSec VPN Server" -j ACCEPT
iptables -I INPUT -p udp -m multiport --dports 500,4500 -m comment --comment "IPSec VPN Server" -j ACCEPT
fi