feat(proxy): добавлены pclaude/pcodex для явного запуска через прокси
- Зачем: - 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.
This commit is contained in:
1 parent
84e577bc97
commit
d5559867bd
3 files changed
+249
-18
No files matched your search
@@ -75,15 +75,46 @@ function Get-PublicIp {
|
||||
catch { return $null }
|
||||
}
|
||||
|
||||
# Единый источник правды для прокси-эндпоинта.
|
||||
function Get-ProxyEndpoint {
|
||||
@{
|
||||
ProxyHost = 'hproxy.local'
|
||||
Port = 12334
|
||||
NoProxy = 'hproxy.local,localhost,127.0.0.1,.concept-software.ru'
|
||||
}
|
||||
}
|
||||
|
||||
# Внутренний: выставить proxy-env в текущей области. Единственное место,
|
||||
# где формируются значения переменных.
|
||||
function Set-ProxyEnv {
|
||||
$e = Get-ProxyEndpoint
|
||||
$env:HTTP_PROXY = "http://$($e.ProxyHost):$($e.Port)"
|
||||
$env:HTTPS_PROXY = "http://$($e.ProxyHost):$($e.Port)"
|
||||
$env:ALL_PROXY = "socks5://$($e.ProxyHost):$($e.Port)"
|
||||
$env:NO_PROXY = $e.NoProxy
|
||||
}
|
||||
|
||||
# Внутренний: fail-fast проверка доступности прокси (только reachability).
|
||||
# Таймаут — $env:PROXY_PREFLIGHT_TIMEOUT (дефолт 2 c), покрывает и медленный DNS.
|
||||
function Test-ProxyReachable {
|
||||
$e = Get-ProxyEndpoint
|
||||
$timeout = if ($env:PROXY_PREFLIGHT_TIMEOUT) { [int]$env:PROXY_PREFLIGHT_TIMEOUT } else { 2 }
|
||||
$client = [System.Net.Sockets.TcpClient]::new()
|
||||
try {
|
||||
$iar = $client.BeginConnect($e.ProxyHost, [int]$e.Port, $null, $null)
|
||||
if ($iar.AsyncWaitHandle.WaitOne([TimeSpan]::FromSeconds($timeout))) {
|
||||
$client.EndConnect($iar)
|
||||
return $true
|
||||
}
|
||||
return $false
|
||||
}
|
||||
catch { return $false }
|
||||
finally { $client.Dispose() }
|
||||
}
|
||||
|
||||
# Включить прокси для текущей сессии (hproxy.local).
|
||||
function proxy_on {
|
||||
$Host_ = 'hproxy.local'; $Port = 12334
|
||||
|
||||
$env:HTTP_PROXY = "http://${Host_}:${Port}"
|
||||
$env:HTTPS_PROXY = "http://${Host_}:${Port}"
|
||||
$env:ALL_PROXY = "socks5://${Host_}:${Port}"
|
||||
$env:NO_PROXY = "${Host_},localhost,127.0.0.1,.concept-software.ru"
|
||||
|
||||
Set-ProxyEnv
|
||||
$Ip = Get-PublicIp
|
||||
"Proxy ON. IP: $(if ($Ip) { $Ip } else { 'unavailable' })"
|
||||
}
|
||||
@@ -103,6 +134,48 @@ function myip {
|
||||
"IP: $(if ($Ip) { $Ip } else { 'unavailable' })"
|
||||
}
|
||||
|
||||
# Внутренний: запуск команды через прокси. Pre-flight, затем env только на
|
||||
# время дочернего процесса (в finally восстанавливаем прежние значения —
|
||||
# сессия не остаётся с включённым прокси).
|
||||
function Invoke-WithProxy {
|
||||
param(
|
||||
[Parameter(Mandatory)][string]$Exe,
|
||||
[Parameter(ValueFromRemainingArguments)][string[]]$CmdArgs
|
||||
)
|
||||
|
||||
if (-not (Get-Command $Exe -ErrorAction SilentlyContinue)) {
|
||||
Write-Error "Команда не найдена в PATH: $Exe"
|
||||
return
|
||||
}
|
||||
if (-not (Test-ProxyReachable)) {
|
||||
$e = Get-ProxyEndpoint
|
||||
Write-Error "Прокси $($e.ProxyHost):$($e.Port) недоступен — запуск '$Exe' отменён."
|
||||
return
|
||||
}
|
||||
|
||||
$names = 'HTTP_PROXY', 'HTTPS_PROXY', 'ALL_PROXY', 'NO_PROXY'
|
||||
$saved = @{}
|
||||
foreach ($n in $names) { $saved[$n] = [Environment]::GetEnvironmentVariable($n) }
|
||||
try {
|
||||
Set-ProxyEnv
|
||||
& $Exe @CmdArgs
|
||||
$global:LASTEXITCODE = $LASTEXITCODE
|
||||
}
|
||||
finally {
|
||||
foreach ($n in $names) {
|
||||
if ($null -eq $saved[$n]) {
|
||||
Remove-Item -Path "Env:$n" -ErrorAction SilentlyContinue
|
||||
} else {
|
||||
Set-Item -Path "Env:$n" -Value $saved[$n]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Явный запуск claude/codex гарантированно через прокси.
|
||||
function pclaude { Invoke-WithProxy claude @args }
|
||||
function pcodex { Invoke-WithProxy codex @args }
|
||||
|
||||
# ── Шорткаты Windows Terminal ────────────────────────────────────────
|
||||
|
||||
if (Get-Command wt -ErrorAction SilentlyContinue) {
|
||||
|
||||
Reference in new issue
Block a user