Release v1.2.6
Downloads
macOS (Universal) - Supports both Apple Silicon and Intel
Option 1: Installation Script (Recommended)
Install with a single command (version v1.2.6):
curl -fsSL https://raw.githubusercontent.com/Leadaxe/singbox-launcher/develop/scripts/install-macos.sh | bash -s -- v1.2.6The script will:
- Download the release archive
- Extract and install to
/Applications/ - Fix macOS quarantine attributes and permissions
- Launch the application automatically
Option 2: Manual Installation
- Download:
singbox-launcher-v1.2.6-macos.zip - Extract the ZIP file
- Remove quarantine attribute (required):
xattr -cr "singbox-launcher.app" && chmod +x "singbox-launcher.app/Contents/MacOS/singbox-launcher"
- Double-click
singbox-launcher.appto run- If macOS blocks the app, go to System Settings → Privacy & Security and click "Open Anyway"
- Alternatively, right-click the app and select "Open" (first time only)
Windows (amd64)
- Download:
singbox-launcher-v1.2.6-win64.zip - Extract the ZIP file to a folder, for example:
C:\Program Files\singbox-launcher\ - Run
singbox-launcher.exefrom that folder- You may need administrator rights to install to Program Files
- The launcher will automatically download
sing-boxandwintun.dllon first launch
Windows 7 (x86, legacy)
- Download:
singbox-launcher-v1.2.6-win7-32.zip - Extract the ZIP file to a folder and run
singbox-launcher-win7-32.exe- For Windows 7 / 32-bit or legacy compatibility only
Linux Support
Checksums
See checksums.txt for SHA256 checksums of all files.
v1.2.6 — подписки с WebSocket Early Data (?ed=) наконец подключаются
Core pinned: sing-box-lx 1.14.0-lx.5 (unchanged from v1.2.5). No config migration needed.
A one-bug release. If your provider ships WebSocket nodes whose path carries Xray's ?ed=N tail, those nodes imported fine, looked correct in the UI, and then failed to connect with unexpected HTTP response status: 404. They work now.
EN
Highlights
-
WebSocket nodes with an
?ed=Npath now connect (issue #96). Xray encodes WebSocket Early Data into the path itself —"path": "/api/v2/channel?ed=2560"— rather than using a dedicated field. The launcher copied that string straight through, and sing-box has no?ed=convention: it treated the whole thing as a literal WebSocket path, so the server matched no route and answered404. The tail is now split off into the two fields sing-box actually expects:"transport": { "type": "ws", "path": "/api/v2/channel", "max_early_data": 2560, "early_data_header_name": "Sec-WebSocket-Protocol" }
early_data_header_namehas to be exactlySec-WebSocket-Protocol: left empty, sing-box appends early data to the path instead (the V2Ray convention), which an Xray server does not understand. Reported with a full diagnosis — including the working manual fix — by @Septdir.
Technical / Internal
- The
?ed=tail arrived through four layers, and all four needed the fix. A single helper (splitWSEarlyData/applyWSEarlyDatainnode_parser_transport.go) is now applied at every one:uriTransportFromQuery— share-URItype=ws, which covers both VLESS and Trojan;buildOutbound— the VMessnet=wsbranch;xrayTransportFromStreamSettings— Xray JSONwsSettings.path, the path the issue was filed against;appendOutboundTransportParts— the emitter.
- The emitter was the non-obvious one.
appendOutboundTransportPartsis an allow-list of transport keys, not a passthrough copy. Without an explicit branch there,max_early_dataandearly_data_header_namewould have been silently dropped every timeconfig.jsonwas rebuilt fromstate.json— the fix would have survived the initial subscription import and then quietly disappeared on the next rebuild.max_early_datais read type-tolerantly, because it is anintcoming out of the parser and afloat64coming back through a state round-trip. - Share-URI exporters re-encode
?ed=N.transportToQuery(VLESS/Trojan) andshareURIFromVMessput the tail back, so a node → share-link → node round-trip no longer loses early data. - Malformed
eddegrades instead of failing. A non-numeric, empty, or zeroeddrops the early-data fields but still strips the?-tail from the path — the node runs as plain WebSocket rather than poisoning the wholeconfig.json. This follows the same policy as the REALITYpbkvalidation added in v1.1.7. - Tests: 12 new cases across two files — the helper's edge cases, all three parser layers, the emitter, the
float64state round-trip, and the share-URI round-trip.
Notes
sing-box checknever caught this. The broken config was syntactically valid —/api/v2/channel?ed=2560is a perfectly legal string for a path field. The failure only ever showed up at runtime, as a 404 during the WebSocket handshake. Worth remembering when a node validates but will not connect.- Nothing else changed. If none of your nodes use
?ed=WebSocket paths, this release is a no-op for you.
RU
Основное
-
WebSocket-ноды с
?ed=Nв пути наконец подключаются (issue #96). Xray кодирует WebSocket Early Data прямо в путь —"path": "/api/v2/channel?ed=2560"— вместо отдельного поля. Лаунчер копировал эту строку как есть, а в sing-box никакого соглашения?ed=нет: он считал её буквальным путём WebSocket, сервер не находил такого маршрута и отвечал404. Теперь хвост отделяется в те два поля, которых sing-box и ждёт:"transport": { "type": "ws", "path": "/api/v2/channel", "max_early_data": 2560, "early_data_header_name": "Sec-WebSocket-Protocol" }
early_data_header_nameобязан быть именноSec-WebSocket-Protocol: с пустым значением sing-box отправляет early data в путь (соглашение V2Ray), и Xray-сервер этого не понимает. Issue с полным разбором — включая рабочий обходной путь — прислал @Septdir.
Техническое / Внутреннее
- Хвост
?ed=приходил через четыре слоя, и чинить пришлось все четыре. Общий хелпер (splitWSEarlyData/applyWSEarlyDataвnode_parser_transport.go) теперь применяется в каждом:uriTransportFromQuery— share-URItype=ws, покрывает и VLESS, и Trojan;buildOutbound— ветка VMessnet=ws;xrayTransportFromStreamSettings— Xray JSONwsSettings.path, то самое место из issue;appendOutboundTransportParts— эмиттер.
- Эмиттер — неочевидная часть.
appendOutboundTransportPartsэто allowlist ключей транспорта, а не сквозное копирование. Без явной ветки тамmax_early_dataиearly_data_header_nameмолча вырезались бы при каждой пересборкеconfig.jsonизstate.json— фикс пережил бы первый импорт подписки и тихо исчез на следующей пересборке.max_early_dataчитается устойчиво к типу: из парсера этоint, а после round-trip через state — ужеfloat64. - Share-экспортёры восстанавливают
?ed=N.transportToQuery(VLESS/Trojan) иshareURIFromVMessдописывают хвост обратно, поэтому round-trip «нода → ссылка → нода» больше не теряет early data. - Битый
edдеградирует, а не роняет конфиг. Нечисловой, пустой или нулевойedубирает поля early data, но?-хвост из пути всё равно срезается — нода работает как обычный WebSocket вместо того, чтобы испортить весьconfig.json. Та же политика, что и при валидации REALITYpbkв v1.1.7. - Тесты: 12 новых кейсов в двух файлах — краевые случаи хелпера, все три слоя парсинга, эмиттер, round-trip через state с
float64и round-trip через share-URI.
Примечания
sing-box checkэту проблему не ловил. Сломанный конфиг синтаксически валиден —/api/v2/channel?ed=2560совершенно законная строка для поля пути. Отказ проявлялся только в рантайме, как 404 при WebSocket-хендшейке. Стоит помнить, когда нода проходит проверку, но не подключается.- Больше ничего не изменилось. Если у вас нет нод с
?ed=в пути WebSocket, этот релиз для вас пустой.