- Зачем: - claude/codex должны ходить через hproxy.local, а ручной proxy_on легко забыть; нужны явные команды, которые не стартуют молча при недоступном прокси. - Что: - bash: добавлены _proxy_export/_proxy_reachable/_proxy_run и pclaude/pcodex; proxy_on рефакторен на единый источник правды без смены поведения. - powershell: добавлены Get-ProxyEndpoint/Set-ProxyEnv/Test-ProxyReachable/Invoke-WithProxy и pclaude/pcodex; proxy_on рефакторен аналогично. - таймаут pre-flight вынесен в PROXY_PREFLIGHT_TIMEOUT (дефолт 2 c). - добавлен tests/test_proxy_launchers.sh (fail-fast, изоляция env, проброс кода, аргументы, регресс proxy_on). - Проверка: - bash tests/test_proxy_launchers.sh.
93 lines
4.4 KiB
Bash
93 lines
4.4 KiB
Bash
# --- Proxy Settings ---
|
||
# Переменные для прокси по умолчанию (если нужно, чтобы он был включен всегда)
|
||
# export HTTP_PROXY="http://127.0.0.1:10809"
|
||
# export HTTPS_PROXY="http://127.0.0.1:10809"
|
||
|
||
# --- WSL Host Update (только WSL NAT) ---
|
||
update_hproxy() {
|
||
local script
|
||
script="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")/../scripts/setup-hproxy.sh"
|
||
if [ ! -f "$script" ]; then
|
||
echo "❌ Скрипт не найден: $script"
|
||
return 1
|
||
fi
|
||
if ! awk '/^\[boot\]$/{b=1;next} /^\[/{b=0} b && /^[[:space:]]*command[[:space:]]*=/ && /setup-hproxy\.sh/' \
|
||
"${WSL_CONF_PATH:-/etc/wsl.conf}" 2>/dev/null | grep -q .; then
|
||
echo "⚠️ Boot command не настроен — update_hproxy работает только для WSL NAT"
|
||
return 1
|
||
fi
|
||
if ! sudo "$script"; then
|
||
echo "❌ Ошибка обновления hproxy.local"
|
||
return 1
|
||
fi
|
||
echo "✅ hproxy.local -> $(getent hosts hproxy.local 2>/dev/null | awk '{print $1}')"
|
||
}
|
||
|
||
# Единый источник правды для прокси-эндпоинта (не экспортируется; идемпотентно
|
||
# при повторном source). NO_PROXY: ::1 и [::1] нужны, т.к. localhost в dual-stack
|
||
# Linux резолвится в IPv6, и без них локальные MCP/loopback-соединения
|
||
# (chroma-mcp, claude-mem worker и т.п.) уходят в SOCKS5 через hproxy.local.
|
||
: "${_PROXY_HOST:=hproxy.local}"
|
||
: "${_PROXY_PORT:=12334}"
|
||
: "${_PROXY_NO_PROXY:=hproxy.local,localhost,127.0.0.1,::1,[::1],.concept-software.ru}"
|
||
|
||
# Внутренний: экспортирует proxy-env (+ lower-case дубли для Python-стека).
|
||
# Единственное место, где формируются значения переменных.
|
||
_proxy_export() {
|
||
export HTTP_PROXY="http://${_PROXY_HOST}:${_PROXY_PORT}"
|
||
export HTTPS_PROXY="http://${_PROXY_HOST}:${_PROXY_PORT}"
|
||
export ALL_PROXY="socks5://${_PROXY_HOST}:${_PROXY_PORT}"
|
||
export NO_PROXY="$_PROXY_NO_PROXY"
|
||
export http_proxy="$HTTP_PROXY"
|
||
export https_proxy="$HTTPS_PROXY"
|
||
export all_proxy="$ALL_PROXY"
|
||
export no_proxy="$_PROXY_NO_PROXY"
|
||
}
|
||
|
||
# Внутренний: fail-fast проверка доступности прокси (только reachability —
|
||
# не доказательство, что трафик реально проксируется). Таймаут покрывает и
|
||
# медленный DNS-резолв; при зависании — отказ запуска (безопасный отказ).
|
||
_proxy_reachable() {
|
||
timeout "${PROXY_PREFLIGHT_TIMEOUT:-2}" \
|
||
bash -c "exec 3<>/dev/tcp/${_PROXY_HOST}/${_PROXY_PORT}" 2>/dev/null
|
||
}
|
||
|
||
# Внутренний: запуск команды с proxy-env. Pre-flight, затем subshell+exec —
|
||
# env виден только дочернему процессу, не протекает в родительский shell,
|
||
# код возврата пробрасывается.
|
||
_proxy_run() {
|
||
local cmd="$1"; shift
|
||
if ! command -v "$cmd" >/dev/null 2>&1; then
|
||
echo "❌ Команда не найдена в PATH: $cmd" >&2
|
||
return 127
|
||
fi
|
||
if ! _proxy_reachable; then
|
||
echo "❌ Прокси ${_PROXY_HOST}:${_PROXY_PORT} недоступен — запуск '$cmd' отменён." >&2
|
||
return 1
|
||
fi
|
||
# exec и так резолвит через PATH в обход функций/алиасов.
|
||
( _proxy_export; exec "$cmd" "$@" )
|
||
}
|
||
|
||
pclaude() { _proxy_run claude "$@"; }
|
||
pcodex() { _proxy_run codex "$@"; }
|
||
|
||
# Удобные функции-переключатели для терминала.
|
||
proxy_on() {
|
||
_proxy_export
|
||
echo "✅ Proxy enabled. Checking route..."
|
||
# Подставляем результат выполнения curl прямо в строку
|
||
echo "🌍 Current IP: $(curl -s --max-time 3 https://ifconfig.me)"
|
||
}
|
||
|
||
proxy_off() {
|
||
unset HTTP_PROXY HTTPS_PROXY ALL_PROXY NO_PROXY
|
||
unset http_proxy https_proxy all_proxy no_proxy
|
||
echo "❌ Proxy disabled. Checking route..."
|
||
echo "🏠 Current IP: $(curl -s --max-time 3 https://ifconfig.me)"
|
||
}
|
||
|
||
# Заодно можно добавить алиас, чтобы быстро чекать IP в любой момент без переключения
|
||
alias myip='echo "IP: $(curl -s --max-time 3 https://ifconfig.me)"'
|
||
|