|
| 1 | +#!/usr/bin/env bash |
| 2 | +# GitHub 族下载 URL 改写(供其它脚本 source)。默认不改写;由环境变量显式启用。 |
| 3 | +# 参见 scripts/tools/download/README.md |
| 4 | + |
| 5 | +[[ -n "${_NLT_GITHUB_DOWNLOAD_LIB_LOADED:-}" ]] && return 0 |
| 6 | +_NLT_GITHUB_DOWNLOAD_LIB_LOADED=1 |
| 7 | + |
| 8 | +_nlt_gh_dl_lc() { |
| 9 | + printf '%s' "$1" | tr '[:upper:]' '[:lower:]' |
| 10 | +} |
| 11 | + |
| 12 | +# 参数:主机名(小写) |
| 13 | +_nlt_is_github_download_host() { |
| 14 | + case "$1" in |
| 15 | + github.com | www.github.com) return 0 ;; |
| 16 | + raw.githubusercontent.com) return 0 ;; |
| 17 | + api.github.com) return 0 ;; |
| 18 | + *) return 1 ;; |
| 19 | + esac |
| 20 | +} |
| 21 | + |
| 22 | +# 将 https URL 解析为 host(小写)与路径部分(以 / 开头,无路径则为 /) |
| 23 | +_nlt_gh_dl_parse_https() { |
| 24 | + local url="$1" rest host_raw host path |
| 25 | + if [[ "$url" != https://* ]]; then |
| 26 | + return 1 |
| 27 | + fi |
| 28 | + rest="${url#https://}" |
| 29 | + host_raw="${rest%%/*}" |
| 30 | + host="$(_nlt_gh_dl_lc "$host_raw")" |
| 31 | + path="${rest#"${host_raw}"}" |
| 32 | + [[ -z "$path" ]] && path="/" |
| 33 | + [[ "$path" != /* ]] && path="/${path}" |
| 34 | + printf '%s\t%s\n' "$host" "$path" |
| 35 | +} |
| 36 | + |
| 37 | +# 输出一行:改写后的 URL(stdout)。发生改写时 stderr 打一行诊断。 |
| 38 | +_nlt_github_download_resolve_url() { |
| 39 | + local url="$1" |
| 40 | + local mode hub_pre raw_base |
| 41 | + mode="${NLTDEPLOY_GITHUB_DOWNLOAD_MODE:-off}" |
| 42 | + hub_pre="${NLTDEPLOY_GITHUB_HUB_PROXY_PREFIX:-}" |
| 43 | + raw_base="${NLTDEPLOY_GITHUB_RAW_MIRROR_BASE:-}" |
| 44 | + |
| 45 | + if [[ -z "$url" ]]; then |
| 46 | + printf '%s\n' "$url" |
| 47 | + return 0 |
| 48 | + fi |
| 49 | + |
| 50 | + if [[ "$url" != https://* ]]; then |
| 51 | + printf '%s\n' "$url" |
| 52 | + return 0 |
| 53 | + fi |
| 54 | + |
| 55 | + local host path parsed |
| 56 | + if ! parsed="$(_nlt_gh_dl_parse_https "$url")"; then |
| 57 | + printf '%s\n' "$url" |
| 58 | + return 0 |
| 59 | + fi |
| 60 | + host="${parsed%%$'\t'*}" |
| 61 | + path="${parsed#*$'\t'}" |
| 62 | + |
| 63 | + if ! _nlt_is_github_download_host "$host"; then |
| 64 | + printf '%s\n' "$url" |
| 65 | + return 0 |
| 66 | + fi |
| 67 | + |
| 68 | + # 优先级:hub 前缀 > mirror_raw > off(与设计文档一致) |
| 69 | + if [[ -n "$hub_pre" ]]; then |
| 70 | + if [[ "$url" == "${hub_pre}"* ]]; then |
| 71 | + printf '%s\n' "$url" |
| 72 | + return 0 |
| 73 | + fi |
| 74 | + local out="${hub_pre}${url}" |
| 75 | + printf '%s\n' "[nlt-download] URL rewrite (hub proxy): ${url} -> ${out}" >&2 |
| 76 | + printf '%s\n' "$out" |
| 77 | + return 0 |
| 78 | + fi |
| 79 | + |
| 80 | + if [[ "$mode" == "mirror_raw" ]] && [[ -n "$raw_base" ]]; then |
| 81 | + if [[ "$host" != "raw.githubusercontent.com" ]]; then |
| 82 | + printf '%s\n' "$url" |
| 83 | + return 0 |
| 84 | + fi |
| 85 | + local new_url="${raw_base%/}${path}" |
| 86 | + if [[ "$new_url" != "$url" ]]; then |
| 87 | + printf '%s\n' "[nlt-download] URL rewrite (mirror_raw): ${url} -> ${new_url}" >&2 |
| 88 | + fi |
| 89 | + printf '%s\n' "$new_url" |
| 90 | + return 0 |
| 91 | + fi |
| 92 | + |
| 93 | + if [[ "$mode" == "hub_proxy" ]] && [[ -z "$hub_pre" ]]; then |
| 94 | + printf '%s\n' "[nlt-download] NLTDEPLOY_GITHUB_DOWNLOAD_MODE=hub_proxy 但未设置 NLTDEPLOY_GITHUB_HUB_PROXY_PREFIX,跳过改写。" >&2 |
| 95 | + fi |
| 96 | + |
| 97 | + printf '%s\n' "$url" |
| 98 | + return 0 |
| 99 | +} |
| 100 | + |
| 101 | +# 与 nlt-download curl 子命令相同:扫描参数中 https:// 开头的 token 并改写后调用 curl(非 exec)。 |
| 102 | +_nlt_github_download_curl() { |
| 103 | + command -v curl >/dev/null 2>&1 || { |
| 104 | + echo "错误: 需要 curl。" >&2 |
| 105 | + return 127 |
| 106 | + } |
| 107 | + local args=() a new |
| 108 | + for a in "$@"; do |
| 109 | + if [[ "$a" == https://* ]]; then |
| 110 | + new="$(_nlt_github_download_resolve_url "$a")" |
| 111 | + args+=("$new") |
| 112 | + else |
| 113 | + args+=("$a") |
| 114 | + fi |
| 115 | + done |
| 116 | + curl "${args[@]}" |
| 117 | +} |
0 commit comments