summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2026-07-29 22:39:21 +0800
committerruki <[email protected]>2026-07-29 22:39:21 +0800
commita6f37ee107d63df40e749f719d6ae0587ba153b8 (patch)
tree6372b8a33f819ada5aa052062bbd53c42344d5d6
parent2c6ee15e8d90a8f38778ef10be6e92a638e004cd (diff)
add fallback download support
-rw-r--r--xmake/modules/net/http/download.lua73
-rw-r--r--xmake/modules/private/action/require/impl/actions/download.lua1
-rw-r--r--xmake/modules/private/action/require/impl/actions/download_resources.lua1
-rw-r--r--xmake/modules/private/action/require/impl/actions/patch_sources.lua1
4 files changed, 64 insertions, 12 deletions
diff --git a/xmake/modules/net/http/download.lua b/xmake/modules/net/http/download.lua
index 2695be817..e171c152d 100644
--- a/xmake/modules/net/http/download.lua
+++ b/xmake/modules/net/http/download.lua
@@ -297,18 +297,8 @@ function _powershell_download(tool, url, outputfile, opt)
os.vrunv(tool.program, argv)
end
--- download url
---
--- @param url the input url
--- @param outputfile the output file
--- @param opt the option, {continue = true}
---
---
-function main(url, outputfile, opt)
-
- -- init output file
- opt = opt or {}
- outputfile = outputfile or path.filename(url):gsub("%?.+$", "")
+-- download url with the first available tool (aria2/curl/wget/powershell)
+function _download(url, outputfile, opt)
-- attempt to download url using aria2 first (multi-threaded, fastest)
local tool = find_tool("aria2", {version = true})
@@ -338,3 +328,62 @@ function main(url, outputfile, opt)
assert(tool, "aria2, curl or wget not found!")
end
+
+-- is it a ssl/tls certificate verification error?
+function _is_ssl_cert_error(errors)
+ errors = (errors or ""):lower()
+ return errors:find("ssl", 1, true)
+ or errors:find("tls", 1, true)
+ or errors:find("certificate", 1, true)
+ or errors:find("handshake", 1, true)
+end
+
+-- download url, and retry once with ssl verification disabled on a certificate error
+function _download_fallback(url, outputfile, opt)
+ local errors
+ local ok = try
+ {
+ function ()
+ _download(url, outputfile, opt)
+ return true
+ end,
+ catch
+ {
+ function (errs)
+ errors = tostring(errs)
+ end
+ }
+ }
+ if not ok then
+ if _is_ssl_cert_error(errors) then
+ wprint("download failed due to ssl certificate verification, retrying with ssl verification disabled ..")
+ return _download(url, outputfile, table.join(opt, {insecure = true}))
+ end
+ raise(errors)
+ end
+end
+
+-- download url
+--
+-- @param url the input url
+-- @param outputfile the output file
+-- @param opt the option, e.g. {continue = true, insecure = false, insecure_fallback = false}
+--
+-- @note if opt.insecure_fallback is enabled and the download fails due to a ssl certificate
+-- error, it will retry once with ssl verification disabled. this is only safe when the
+-- caller verifies the downloaded file afterwards (e.g. by its sha256 checksum).
+--
+function main(url, outputfile, opt)
+
+ -- init output file
+ opt = opt or {}
+ outputfile = outputfile or path.filename(url):gsub("%?.+$", "")
+
+ -- download it directly if we do not need the insecure fallback
+ if opt.insecure or not opt.insecure_fallback then
+ return _download(url, outputfile, opt)
+ end
+
+ -- download it with the insecure fallback
+ return _download_fallback(url, outputfile, opt)
+end
diff --git a/xmake/modules/private/action/require/impl/actions/download.lua b/xmake/modules/private/action/require/impl/actions/download.lua
index 55e43a3db..a8846f97b 100644
--- a/xmake/modules/private/action/require/impl/actions/download.lua
+++ b/xmake/modules/private/action/require/impl/actions/download.lua
@@ -216,6 +216,7 @@ function _download(package, url, sourcedir, opt)
else
http.download(url, packagefile, {
insecure = global.get("insecure-ssl"),
+ insecure_fallback = true, -- retry without ssl verification on cert error, the file is verified by sha256 below
headers = opt.url_http_headers or package:policy("package.download.http_headers")})
end
end
diff --git a/xmake/modules/private/action/require/impl/actions/download_resources.lua b/xmake/modules/private/action/require/impl/actions/download_resources.lua
index c185d25b0..dffa742b2 100644
--- a/xmake/modules/private/action/require/impl/actions/download_resources.lua
+++ b/xmake/modules/private/action/require/impl/actions/download_resources.lua
@@ -118,6 +118,7 @@ function _download(package, resource_name, resource_url, resource_hash)
elseif resource_url:find(string.ipattern("https-://")) or resource_url:find(string.ipattern("ftps-://")) then
http.download(resource_url, resource_file, {
insecure = global.get("insecure-ssl"),
+ insecure_fallback = true, -- retry without ssl verification on cert error, the file is verified by sha256 below
headers = package:policy("package.download.http_headers")})
else
raise("invalid resource url(%s)", resource_url)
diff --git a/xmake/modules/private/action/require/impl/actions/patch_sources.lua b/xmake/modules/private/action/require/impl/actions/patch_sources.lua
index 6c18b69b1..6b8e60e59 100644
--- a/xmake/modules/private/action/require/impl/actions/patch_sources.lua
+++ b/xmake/modules/private/action/require/impl/actions/patch_sources.lua
@@ -80,6 +80,7 @@ function _patch(package, patchinfo)
if patch_url:find(string.ipattern("https-://")) or patch_url:find(string.ipattern("ftps-://")) then
http.download(patch_url, patch_file, {
insecure = global.get("insecure-ssl"),
+ insecure_fallback = true, -- retry without ssl verification on cert error, the file is verified by sha256 below
headers = package:policy("package.download.http_headers")})
else
-- copy the patch file