fix(proxy-client): обновлён Xray и исправлен разбор VLESS

Зачем: профиль XHTTP с x_padding_bytes и пустым host не запускался.

Что: Xray обновлён до 26.10.10; добавлены параметры TLS, REALITY и XHTTP,
значения по умолчанию и преобразование старых названий сессии XHTTP.
Обновлены документация и регрессионные тесты.

Проверка: 59 тестов на Python 3.14 и 3.8, Bash-функции и установщик;
16 тестов разбора после уточнения проверки SHA-256. Настоящий Xray
проверил конфигурацию и выполнил HTTPS-запрос через профиль с HTTP 200.
Пользователь подтвердил работу proxy-client start.
This commit is contained in:
ddadmin committed 2026-10-12 16:21:16 -04:00
1 parent 16e85139b9
commit a30e2eb939
5 files changed
+266 -28

No files matched your search

+20 -2
View File
@@ -34,7 +34,7 @@ READY = "остановка: Ctrl+C или proxy-client stop"
# совпадает с разрешённым путём к xray, как у настоящего бинарника.
# «xray version» и «xray run ...» запускают одноимённые скрипты из рабочего
# каталога теста.
FAKE_VERSION = "print('Xray 26.3.27 (fake)')\n"
FAKE_VERSION = "print('Xray 26.10.10 (fake)')\n"
FAKE_RUN = r'''import json, os, socket, sys
config_path = sys.argv[-1]
@@ -219,6 +219,24 @@ class ManagedXrayTest(unittest.TestCase):
self.assertFalse(pid_alive(xray_pid))
self.assert_no_state_files()
def test_xhttp_export_with_empty_host_and_padding_starts(self):
extra = {"xPaddingBytes": "100-1000", "downloadSettings": {"address": "cdn.example"}}
profile = PROFILE.replace("&host=host.example", "&host=")
base, fragment = profile.split("#", 1)
profile = base + "&x_padding_bytes=100-1000&extra="
profile += quote(json.dumps(extra), safe="") + "#" + fragment
self.write_profile(self.profile, text=profile)
process = self.start()
config = json.loads((self.state_dir / "client.json").read_text())
stream = config["outbounds"][0]["streamSettings"]
self.assertEqual("", stream["xhttpSettings"]["host"])
self.assertEqual(extra, stream["xhttpSettings"]["extra"])
process.send_signal(signal.SIGINT)
stdout, stderr = self.finish(process)
self.assertEqual(0, process.returncode, stderr)
self.assert_no_state_files()
self.assert_no_secrets(stdout + stderr)
def test_stop_finishes_xray_left_after_killed_supervisor(self):
process = self.start()
xray_pid = self.xray_pid()
@@ -321,7 +339,7 @@ class ManagedXrayTest(unittest.TestCase):
(self.root / "version").write_text("print('Xray 26.3.26 (fake)')\n", encoding="utf-8")
result = self.run_cli("start")
self.assertEqual(1, result.returncode)
self.assertIn("не сообщил версию Xray 26.3.27", result.stderr)
self.assertIn("не сообщил версию Xray 26.10.10", result.stderr)
self.assert_no_state_files()
def test_replaced_xray_file_is_still_recognised_and_stopped(self):