fix(sub): emit Shadowsocks http-header links as SIP002 obfs-local plugin

v2rayN's SS parser only reads the SIP002 `plugin` query param; it ignores the
xray-native type/headerType/host/path, so an SS link with a TCP http header
imported as plain SS and failed to connect. Re-encode the http header as
`plugin=obfs-local;obfs=http;obfs-host=<host>`, which v2rayN maps to an
xray tcp/http-header outbound. Mirrored in the frontend link generator.

Note: v2rayN carries only the host and forces request path "/", so this matches
an inbound whose header path is "/" (the default); xray validates path, not host.
This commit is contained in:
MHSanaei
2026-06-17 14:11:25 +02:00
parent 5038fa1cec
commit 21e9b94bb4
3 changed files with 52 additions and 0 deletions
+12
View File
@@ -595,6 +595,18 @@ export function genShadowsocksLink(input: GenShadowsocksLinkInput): string {
applyExternalProxyTLSParams(externalProxy, params, security);
}
// SIP002 clients (v2rayN) ignore type/headerType/host/path and only read
// `plugin`. Re-encode a TCP http header as obfs-local so they build a
// matching tcp/http outbound (v2rayN forces request path "/").
if ((stream.network ?? 'tcp') === 'tcp' && params.get('headerType') === 'http') {
const host = params.get('host') ?? '';
params.delete('type');
params.delete('headerType');
params.delete('host');
params.delete('path');
params.set('plugin', `obfs-local;obfs=http;obfs-host=${host}`);
}
const isSS2022 = settings.method.substring(0, 4) === '2022';
const isSSMultiUser = settings.method !== '2022-blake3-chacha20-poly1305';
const passwords: string[] = [];