summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZmmfly <[email protected]>2026-04-30 00:01:00 +0800
committerZmmfly <[email protected]>2026-04-30 00:51:36 +0800
commitb6b122b6fa489f51916f9e305ff82c963a6dd9fa (patch)
tree13e1bb6fb3ab39a38550b1483a21f21c808e0546
parent6a10bec8cf45841e3ddb4dfa82a28538c7136a39 (diff)
add aria2 download backend with multi-threaded support
-rw-r--r--xmake/modules/detect/tools/find_aria2.lua54
-rw-r--r--xmake/modules/net/http/download.lua88
2 files changed, 139 insertions, 3 deletions
diff --git a/xmake/modules/detect/tools/find_aria2.lua b/xmake/modules/detect/tools/find_aria2.lua
new file mode 100644
index 000000000..b60059d97
--- /dev/null
+++ b/xmake/modules/detect/tools/find_aria2.lua
@@ -0,0 +1,54 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, Xmake Open Source Community.
+--
+-- @author Zmmfly
+-- @file find_aria2.lua
+--
+
+-- imports
+import("lib.detect.find_program")
+import("lib.detect.find_programver")
+
+-- find aria2
+--
+-- @param opt the argument options, e.g. {version = true}
+--
+-- @return program, version
+--
+-- @code
+--
+-- local aria2 = find_aria2()
+-- local aria2, version = find_aria2({version = true})
+--
+-- @endcode
+--
+function main(opt)
+
+ -- init options
+ opt = opt or {}
+
+ -- find program
+ local program = find_program(opt.program or "aria2c", opt)
+
+ -- find program version
+ local version = nil
+ if program and opt and opt.version then
+ version = find_programver(program, opt)
+ end
+
+ -- ok?
+ return program, version
+end
diff --git a/xmake/modules/net/http/download.lua b/xmake/modules/net/http/download.lua
index 87ce42d6d..2695be817 100644
--- a/xmake/modules/net/http/download.lua
+++ b/xmake/modules/net/http/download.lua
@@ -52,6 +52,82 @@ function _get_user_agent()
return _g._USER_AGENT
end
+-- download url using aria2
+function _aria2_download(tool, url, outputfile, opt)
+
+ -- ensure output directory
+ local outputdir = path.directory(outputfile)
+ if not os.isdir(outputdir) then
+ os.mkdir(outputdir)
+ end
+
+ -- set basic arguments
+ local argv = {"--no-conf=true"}
+ if option.get("verbose") then
+ table.insert(argv, "--console-log-level=notice")
+ else
+ table.insert(argv, "--console-log-level=error")
+ end
+
+ -- user-agent
+ local user_agent = _get_user_agent()
+ if user_agent then
+ if tool.version then
+ user_agent = user_agent .. " aria2/" .. tool.version
+ end
+ table.insert(argv, "--user-agent=" .. user_agent)
+ end
+
+ -- use proxy?
+ local proxy_conf = proxy.config(url)
+ if proxy_conf then
+ table.insert(argv, "--all-proxy=" .. proxy_conf)
+ end
+
+ -- ignore to check ssl certificates
+ if opt.insecure then
+ table.insert(argv, "--check-certificate=false")
+ end
+
+ -- add custom headers
+ if opt.headers then
+ for _, header in ipairs(opt.headers) do
+ table.insert(argv, "--header=" .. header)
+ end
+ end
+
+ -- continue to download?
+ if opt.continue then
+ table.insert(argv, "--continue=true")
+ end
+
+ -- set connect timeout
+ if opt.timeout then
+ table.insert(argv, "--connect-timeout=" .. tostring(opt.timeout))
+ end
+
+ -- set read timeout (inactivity timeout in aria2)
+ if opt.read_timeout then
+ table.insert(argv, "--timeout=" .. tostring(opt.read_timeout))
+ end
+
+ -- enable parallel download (multi-threaded)
+ table.insert(argv, "--split=8")
+ table.insert(argv, "--max-connection-per-server=8")
+ table.insert(argv, "--min-split-size=1M")
+ table.insert(argv, "--allow-overwrite=true")
+
+ -- set output directory and filename
+ table.insert(argv, "--dir=" .. outputdir)
+ table.insert(argv, "--out=" .. path.filename(outputfile))
+
+ -- set url
+ table.insert(argv, url)
+
+ -- download it
+ os.vrunv(tool.program, argv)
+end
+
-- download url using curl
function _curl_download(tool, url, outputfile, opt)
@@ -234,8 +310,14 @@ function main(url, outputfile, opt)
opt = opt or {}
outputfile = outputfile or path.filename(url):gsub("%?.+$", "")
- -- attempt to download url using curl first
- local tool = find_tool("curl", {version = true})
+ -- attempt to download url using aria2 first (multi-threaded, fastest)
+ local tool = find_tool("aria2", {version = true})
+ if tool then
+ return _aria2_download(tool, url, outputfile, opt)
+ end
+
+ -- attempt to download url using curl
+ tool = find_tool("curl", {version = true})
if tool then
return _curl_download(tool, url, outputfile, opt)
end
@@ -254,5 +336,5 @@ function main(url, outputfile, opt)
end
end
- assert(tool, "curl or wget not found!")
+ assert(tool, "aria2, curl or wget not found!")
end