Skip to content

Commit bfab0b2

Browse files
authored
Merge pull request #243 from Babylonehy/fix/proxy-sh-bugfixes
fix(proxy): harden strategy group selection
2 parents 67a5c49 + 25bdb43 commit bfab0b2

1 file changed

Lines changed: 92 additions & 16 deletions

File tree

scripts/core/proxy.sh

Lines changed: 92 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,13 @@ proxy_group_exists() {
266266

267267
[ -n "${group:-}" ] || return 1
268268

269-
[ "$(proxy_groups_json | "$(yq_bin)" -p=json eval ".proxies | has(\"$group\")" - 2>/dev/null)" = "true" ]
269+
[ "$(
270+
GROUP="$group" proxy_groups_json \
271+
| GROUP="$group" "$(yq_bin)" -p=json eval \
272+
'.proxies | to_entries | .[] | select(.key == env(GROUP)) | "true"' \
273+
- 2>/dev/null \
274+
| head -n 1
275+
)" = "true" ]
270276
}
271277

272278
proxy_group_type() {
@@ -275,7 +281,10 @@ proxy_group_type() {
275281
[ -n "${group:-}" ] || die "策略组名称不能为空"
276282
proxy_group_exists "$group" || die "策略组不存在:$group"
277283

278-
proxy_groups_json | "$(yq_bin)" -p=json eval ".proxies.\"$group\".type // \"\"" - 2>/dev/null
284+
GROUP="$group" proxy_groups_json \
285+
| GROUP="$group" "$(yq_bin)" -p=json eval \
286+
'.proxies | to_entries | .[] | select(.key == env(GROUP)) | .value.type // ""' \
287+
- 2>/dev/null
279288
}
280289

281290
proxy_group_type_key() {
@@ -378,8 +387,10 @@ proxy_group_current() {
378387
[ -n "${group:-}" ] || die "策略组名称不能为空"
379388
proxy_group_exists "$group" || die "策略组不存在:$group"
380389

381-
proxy_groups_json \
382-
| "$(yq_bin)" -p=json eval ".proxies.\"$group\".now // \"\"" - 2>/dev/null
390+
GROUP="$group" proxy_groups_json \
391+
| GROUP="$group" "$(yq_bin)" -p=json eval \
392+
'.proxies | to_entries | .[] | select(.key == env(GROUP)) | .value.now // ""' \
393+
- 2>/dev/null
383394
}
384395

385396
proxy_group_nodes() {
@@ -388,8 +399,10 @@ proxy_group_nodes() {
388399
[ -n "${group:-}" ] || die "策略组名称不能为空"
389400
proxy_group_exists "$group" || die "策略组不存在:$group"
390401

391-
proxy_groups_json \
392-
| "$(yq_bin)" -p=json eval ".proxies.\"$group\".all[] // \"\"" - 2>/dev/null
402+
GROUP="$group" proxy_groups_json \
403+
| GROUP="$group" "$(yq_bin)" -p=json eval \
404+
'.proxies | to_entries | .[] | select(.key == env(GROUP)) | .value.all[] // ""' \
405+
- 2>/dev/null
393406
}
394407

395408
proxy_node_is_descriptive_entry() {
@@ -479,8 +492,10 @@ proxy_group_supports_manual_pick() {
479492
[ "$type_key" = "selector" ] || return 1
480493

481494
has_now="$(
482-
proxy_groups_json \
483-
| "$(yq_bin)" -p=json eval ".proxies.\"$group\".now != null" - 2>/dev/null \
495+
GROUP="$group" proxy_groups_json \
496+
| GROUP="$group" "$(yq_bin)" -p=json eval \
497+
'.proxies | to_entries | .[] | select(.key == env(GROUP)) | .value.now != null' \
498+
- 2>/dev/null \
484499
| head -n 1
485500
)"
486501
[ "${has_now:-false}" = "true" ] || return 1
@@ -742,6 +757,37 @@ print_proxy_groups_summary() {
742757
done < <(proxy_group_list)
743758
}
744759

760+
proxy_node_test_delay() {
761+
local node="$1"
762+
local url="${2:-http://www.gstatic.com/generate_204}"
763+
local timeout_ms="${3:-3000}"
764+
local encoded_node
765+
766+
[ -n "${node:-}" ] || return 1
767+
encoded_node="$(proxy_node_url_encode "$node")"
768+
769+
controller_curl GET "/proxies/${encoded_node}/delay?timeout=${timeout_ms}&url=${url}" 2>/dev/null \
770+
| "$(yq_bin)" -p=json eval '.delay // 0' - 2>/dev/null \
771+
| head -n 1
772+
}
773+
774+
proxy_group_nodes_delay_map() {
775+
local group="$1"
776+
777+
[ -n "${group:-}" ] || return 1
778+
779+
GROUP="$group" proxy_groups_json 2>/dev/null \
780+
| GROUP="$group" "$(yq_bin)" -p=json eval '
781+
. as $root |
782+
(.proxies | to_entries | .[] | select(.key == env(GROUP)) | .value.all // []) | .[] |
783+
. as $n |
784+
$n + "\t" + (
785+
($root.proxies[$n].history | select(length > 0) | .[-1].delay // 0) // 0 |
786+
tostring
787+
)
788+
' - 2>/dev/null
789+
}
790+
745791
proxy_node_match_key() {
746792
local node="$1"
747793

@@ -833,13 +879,40 @@ proxy_group_current_display() {
833879
}
834880

835881
proxy_group_display_list() {
836-
local group
882+
proxy_groups_json \
883+
| "$(yq_bin)" -p=json eval '
884+
.proxies | to_entries | .[] |
885+
select(.value.all != null) |
886+
select(
887+
(.value.type // "" | downcase | sub("[-_ ]+"; "")) as $t |
888+
($t == "selector" or $t == "urltest" or $t == "fallback" or $t == "loadbalance")
889+
) |
890+
.key
891+
' - 2>/dev/null
892+
}
837893

838-
while IFS= read -r group; do
839-
[ -n "${group:-}" ] || continue
840-
proxy_group_can_show_candidates "$group" || continue
841-
echo "$group"
842-
done < <(proxy_group_list)
894+
proxy_node_url_encode() {
895+
local byte code char out=""
896+
897+
while IFS= read -r byte; do
898+
[ -n "${byte:-}" ] || continue
899+
code=$((16#$byte))
900+
if { [ "$code" -ge 48 ] && [ "$code" -le 57 ]; } \
901+
|| { [ "$code" -ge 65 ] && [ "$code" -le 90 ]; } \
902+
|| { [ "$code" -ge 97 ] && [ "$code" -le 122 ]; } \
903+
|| [ "$byte" = "2d" ] || [ "$byte" = "2e" ] || [ "$byte" = "5f" ] || [ "$byte" = "7e" ]; then
904+
printf -v char "\\x$byte"
905+
out+="$char"
906+
else
907+
out+="%${byte^^}"
908+
fi
909+
done < <(printf '%s' "$1" | od -An -tx1 -v | tr ' ' '\n')
910+
911+
printf '%s' "$out"
912+
}
913+
914+
proxy_json_string_escape() {
915+
printf '%s' "$1" | sed 's/\\/\\\\/g; s/"/\\"/g'
843916
}
844917

845918
proxy_group_select() {
@@ -848,6 +921,7 @@ proxy_group_select() {
848921
local base secret
849922
local code response_file response_body
850923
local available_node found
924+
local group_enc node_json
851925

852926
[ -n "${group:-}" ] || die "策略组名称不能为空"
853927
[ -n "${node:-}" ] || die "节点名称不能为空"
@@ -871,13 +945,15 @@ proxy_group_select() {
871945

872946
base="$(controller_api_base)"
873947
secret="$(controller_secret)"
948+
group_enc="$(proxy_node_url_encode "$group")"
949+
node_json="$(proxy_json_string_escape "$node")"
874950
response_file="$(mktemp)"
875951
code="$(
876952
curl -sS -o "$response_file" -w "%{http_code}" -X PUT \
877953
-H "Content-Type: application/json" \
878954
${secret:+-H "Authorization: Bearer $secret"} \
879-
--data "{\"name\":\"$node\"}" \
880-
"$base/proxies/$group"
955+
--data "{\"name\":\"$node_json\"}" \
956+
"$base/proxies/$group_enc"
881957
)"
882958

883959
if [ "${code:-000}" -lt 200 ] || [ "${code:-000}" -ge 300 ]; then

0 commit comments

Comments
 (0)