Add base64 subscription support
Some checks failed
Differential ShellCheck / Differential ShellCheck (push) Has been cancelled

This commit is contained in:
Денисов Александр Андреевич
2026-05-14 13:21:20 +03:00
parent bec1f4c10e
commit 3eea1810e3
5 changed files with 94 additions and 4 deletions

View File

@@ -2,7 +2,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-podkop
PKG_VERSION := $(if $(PODKOP_VERSION),$(PODKOP_VERSION),0.$(shell date +%d%m%Y))
PKG_VERSION := $(if $(PODKOP_VERSION),$(PODKOP_VERSION),0.7.28)
PKG_RELEASE:=1
@@ -27,4 +27,4 @@ define Package/$(PKG_NAME)/install
sed -i -e 's/__COMPILED_VERSION_VARIABLE__/$(PKG_VERSION)/g' $(1)$(HTDOCS)/luci-static/resources/view/podkop/main.js || true
endef
$(eval $(call BuildPackage,$(PKG_NAME)))
$(eval $(call BuildPackage,$(PKG_NAME)))

View File

@@ -2,7 +2,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=podkop
PKG_VERSION := $(if $(PODKOP_VERSION),$(PODKOP_VERSION),0.$(shell date +%d%m%Y))
PKG_VERSION := $(if $(PODKOP_VERSION),$(PODKOP_VERSION),0.7.28)
PKG_RELEASE:=1

View File

@@ -206,6 +206,12 @@ download_subscription_into_cache() {
return 1
fi
if ! sing_box_cf_subscription_file_to_json "$tmpfile" "$tmpfile"; then
log "Downloaded subscription for section '$section' cannot be converted to sing-box JSON" "error"
rm -f "$tmpfile"
return 1
fi
if ! validate_subscription_file "$tmpfile"; then
log "Downloaded subscription for section '$section' is invalid" "error"
rm -f "$tmpfile"

View File

@@ -404,7 +404,7 @@ generate_hwid() {
"$(echo "$raw_hash" | cut -c13-16)"
}
# Downloads a subscription JSON from the given URL with custom headers
# Downloads a subscription from the given URL with custom headers
# Arguments:
# $1 - subscription URL
# $2 - output file path

View File

@@ -329,6 +329,90 @@ sing_box_cf_add_single_key_reject_rule() {
echo "$config"
}
sing_box_cf_subscription_file_to_json() {
local input_path="$1"
local output_path="$2"
[ -s "$input_path" ] || return 1
if jq -e '
type == "object" and
(.outbounds | type == "array") and
((.outbounds | length) > 0)
' "$input_path" > /dev/null 2>&1; then
[ "$input_path" = "$output_path" ] || cp "$input_path" "$output_path"
return 0
fi
local raw_content decoded_content content
raw_content="$(cat "$input_path" 2>/dev/null)"
if is_base64 "$raw_content"; then
decoded_content="$(base64_decode "$raw_content")"
content="$decoded_content"
else
content="$raw_content"
fi
if printf '%s' "$content" | jq -e '
type == "object" and
(.outbounds | type == "array") and
((.outbounds | length) > 0)
' > /dev/null 2>&1; then
printf '%s' "$content" > "$output_path"
return 0
fi
local config link scheme i outbound_tag fragment display_name links_tmp
config='{"outbounds":[]}'
i=1
links_tmp="$(mktemp)" || return 1
printf '%s\n' "$content" > "$links_tmp"
while IFS= read -r link || [ -n "$link" ]; do
link="$(printf '%s' "$link" | tr -d '\r')"
[ -n "$link" ] || continue
scheme="$(url_get_scheme "$link")"
case "$scheme" in
socks4 | socks4a | socks5 | vless | ss | trojan | hysteria2 | hy2) ;;
*)
log "Skip unsupported subscription link scheme: $scheme" "warn"
continue
;;
esac
if ! config="$(sing_box_cf_add_proxy_outbound "$config" "subscription-$i" "$link" "")"; then
rm -f "$links_tmp"
return 1
fi
outbound_tag="$(get_outbound_tag_by_section "subscription-$i")"
case "$link" in
*#*)
fragment="${link#*#}"
display_name="$(url_decode "$fragment")"
if [ -n "$display_name" ]; then
if ! config="$(printf '%s' "$config" | jq -c --arg tag "$outbound_tag" --arg display_name "$display_name" \
'(.outbounds[] | select(.tag == $tag) | .tag) = $display_name')"; then
rm -f "$links_tmp"
return 1
fi
fi
;;
esac
i=$((i + 1))
done < "$links_tmp"
rm -f "$links_tmp"
if ! printf '%s' "$config" | jq -e '(.outbounds | length) > 0' > /dev/null 2>&1; then
return 1
fi
printf '%s' "$config" | jq -c '{outbounds: .outbounds}' > "$output_path"
}
#######################################
# Parse a sing-box subscription JSON and add all proxy outbounds to the configuration.
# Filters out non-proxy types (selector, urltest, direct, dns, block).