diff options
| author | ruki <[email protected]> | 2026-07-29 22:39:21 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2026-07-29 22:39:21 +0800 |
| commit | a6f37ee107d63df40e749f719d6ae0587ba153b8 (patch) | |
| tree | 6372b8a33f819ada5aa052062bbd53c42344d5d6 | |
| parent | 2c6ee15e8d90a8f38778ef10be6e92a638e004cd (diff) | |
add fallback download support
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 |
