mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-10-06 06:02:09 +03:00
fix(sub): append host serverDescription to hysteria links (#6740)
* fix(sub): append host serverDescription to hysteria links A host's Description reached vless/trojan/ss through buildEndpointLinks, but genHysteriaLink renders the fragment in its own externalProxy loop and never added the suffix, so Happ fell back to its "Hysteria | hysteria | TLS" caption for every Hysteria server on a host that also serves VLESS (#6738). Reuse appendHappServerDescription with the description the endpoint map already carries, so no key lookup is duplicated and a host with no description emits the same bytes as before. genTuicLink (service.go:912) has the same gap; left alone to keep this diff to the reported protocol. Regression test is red without the fix for both hysteria:// and hysteria2://. * chore(sub): trim the hysteria serverDescription regression test The no-description test passed with and without the #6738 fix: the empty description branch is already pinned by TestAppendHappServerDescription, so it certified nothing about this change. Also cut the remaining test's comment block to the two-line limit CLAUDE.md sets. --------- Co-authored-by: MHSanaei <ho3ein.sanaei@gmail.com>
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
package sub
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/mhsanaei/3x-ui/v3/internal/database/model"
|
||||
)
|
||||
|
||||
// #6738: without the host's Description on hysteria(2):// links, Happ falls back
|
||||
// to its own "Hysteria | hysteria | TLS" caption on a host that also serves VLESS.
|
||||
func TestGenHysteriaLinkAppendsHostServerDescription(t *testing.T) {
|
||||
tests := map[string]struct {
|
||||
version int
|
||||
scheme string
|
||||
}{
|
||||
"hysteria v1": {version: 1, scheme: "hysteria://"},
|
||||
"hysteria v2": {version: 2, scheme: "hysteria2://"},
|
||||
}
|
||||
for name, tc := range tests {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
host := &model.Host{
|
||||
Address: "hy.example.com", Port: 443,
|
||||
Remark: "Poland", ServerDescription: "Wi-Fi",
|
||||
}
|
||||
stream := map[string]any{
|
||||
"security": "tls",
|
||||
"externalProxy": []any{hostToExternalProxyMap(host, "hy.example.com", 443)},
|
||||
}
|
||||
rawStream, err := json.Marshal(stream)
|
||||
if err != nil {
|
||||
t.Fatalf("marshal stream settings: %v", err)
|
||||
}
|
||||
// The inbound's own `version` picks the hysteria vs hysteria2 scheme.
|
||||
rawSettings, err := json.Marshal(map[string]any{
|
||||
"version": tc.version,
|
||||
"clients": []any{map[string]any{"auth": "secret", "email": "user"}},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("marshal inbound settings: %v", err)
|
||||
}
|
||||
in := &model.Inbound{
|
||||
Id: 920010, Listen: "203.0.113.1", Port: 443, Protocol: model.Hysteria,
|
||||
Remark: "hy", StreamSettings: string(rawStream), Settings: string(rawSettings),
|
||||
}
|
||||
got := (&SubService{}).genHysteriaLink(in, "user")
|
||||
if !strings.HasPrefix(got, tc.scheme) {
|
||||
t.Fatalf("link scheme changed.\n got: %s\nwant prefix: %s", got, tc.scheme)
|
||||
}
|
||||
// base64("Wi-Fi"), matching the reporter's subscription output.
|
||||
if !strings.HasSuffix(got, "?serverDescription=V2ktRmk=") {
|
||||
t.Fatalf("host serverDescription missing from fragment.\n got: %s\nwant suffix: ?serverDescription=V2ktRmk=", got)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1535,7 +1535,11 @@ func (s *SubService) genHysteriaLink(inbound *model.Inbound, email string) strin
|
||||
applyExternalProxyHysteriaParams(ep, epParams)
|
||||
|
||||
link := fmt.Sprintf("%s://%s@%s", protocol, auth, joinHostPort(dest, int(portF)))
|
||||
links = append(links, buildLinkWithParams(link, epParams, s.endpointRemark(inbound, email, ep, "quic")))
|
||||
// VLESS/Trojan/SS get the host's description through buildEndpointLinks;
|
||||
// this loop renders the fragment itself, so add it here too (#6738).
|
||||
remark := s.endpointRemark(inbound, email, ep, "quic")
|
||||
remark = appendHappServerDescription(remark, externalProxyToEndpoint(ep).ServerDescription)
|
||||
links = append(links, buildLinkWithParams(link, epParams, remark))
|
||||
}
|
||||
return strings.Join(links, "\n")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user