diff --git a/luci-app-podkop/Makefile b/luci-app-podkop/Makefile index f6ae3a0..14c86fe 100644 --- a/luci-app-podkop/Makefile +++ b/luci-app-podkop/Makefile @@ -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))) \ No newline at end of file +$(eval $(call BuildPackage,$(PKG_NAME))) diff --git a/podkop/Makefile b/podkop/Makefile index 5cef0c1..12aa332 100644 --- a/podkop/Makefile +++ b/podkop/Makefile @@ -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 diff --git a/podkop/files/usr/bin/podkop b/podkop/files/usr/bin/podkop index 8abf252..c7627c7 100755 --- a/podkop/files/usr/bin/podkop +++ b/podkop/files/usr/bin/podkop @@ -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" diff --git a/podkop/files/usr/lib/helpers.sh b/podkop/files/usr/lib/helpers.sh index c16b938..2fa9c16 100644 --- a/podkop/files/usr/lib/helpers.sh +++ b/podkop/files/usr/lib/helpers.sh @@ -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 diff --git a/podkop/files/usr/lib/sing_box_config_facade.sh b/podkop/files/usr/lib/sing_box_config_facade.sh index c27f97f..a4aa819 100644 --- a/podkop/files/usr/lib/sing_box_config_facade.sh +++ b/podkop/files/usr/lib/sing_box_config_facade.sh @@ -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).