Some checks failed
Windows project source guards / test (push) Failing after 43s
Требование незаметности: TLS Python (ssl) отличается от любого браузера с первого пакета, и пять одновременных TLS-соединений к публичным DoH при каждом подключении были узнаваемым узором. - Патч ядра core-patches/browser-fetch.patch (только новые файлы, общий с Android): common/browserfetch поверх Cronet — того же сетевого стека Chromium, что у naive-выхода. ClientHello, HTTP/2 SETTINGS/WINDOW_UPDATE, порядок псевдозаголовков — как у Chrome 150; User-Agent берётся из версии движка. `sing-box tools browser-fetch [--serve]` для Windows, libbox.BrowserFetch(json) для Android. Только https; без libcronet — отдельный признак «недоступно», не сетевая ошибка. - Сборщик ядра применяет патч, гоняет его Go-тесты, проверяет подкоманду в собранном sing-box.exe и пишет sha256 патча в провенанс; правка патча меняет отпечаток бандла ядер — гейт пересоберёт sing-box.exe. - network/browser_fetch.py: один долгоживущий процесс с прогретым движком, ответы по id, перезапуск после падения. - DoH имени сервера — через этот стек и к одному резолверу за раз: следующий подключается после ошибки или 0,8 с молчания. Без браузерного стека — прежний путь с предупреждением в журнале. Проверено: сборка ядра настоящим сборщиком на win10 (Go-тесты, проверка подкоманды); tls.peet.ws видит JA4 t13d1516h2_8daaf6152771_806a8c22fdea и HTTP/2 1:65536;2:0;4:6291456;6:262144|15663105|0|m,a,s,p (Chrome); DoH на win10 0,22 с первый запрос, 0,08–0,11 с прогретый. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
22 lines
942 B
Python
22 lines
942 B
Python
"""Подделка ``sing-box tools browser-fetch --serve`` для тестов клиента."""
|
|
|
|
import base64
|
|
import json
|
|
import sys
|
|
|
|
for line in sys.stdin:
|
|
request = json.loads(line)
|
|
url = request["url"]
|
|
if "crash" in url:
|
|
sys.exit(3)
|
|
if "nolib" in url:
|
|
reply = {"id": request["id"], "error": "browserfetch unavailable: cronet: library not found", "unavailable": True}
|
|
elif "fail" in url:
|
|
reply = {"id": request["id"], "error": "net::ERR_CONNECTION_RESET"}
|
|
else:
|
|
echo = json.dumps({"method": request.get("method"), "headers": request.get("headers"),
|
|
"body": request.get("body", "")}).encode()
|
|
reply = {"id": request["id"], "status": 200, "headers": [["Content-Type", "application/json"]],
|
|
"body": base64.b64encode(echo).decode(), "user_agent": "Chrome/150"}
|
|
sys.stdout.write(json.dumps(reply) + "\n")
|
|
sys.stdout.flush()
|