| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 |
- package sub
- import (
- "strings"
- "testing"
- "github.com/mhsanaei/3x-ui/v3/internal/database/model"
- )
- // Issue #5232: a vision flow set on a VLESS+XHTTP+REALITY (vlessenc) client
- // must survive into subscription output, not just the inbound JSON.
- const testMlkemEncryption = "mlkem768x25519plus.native.0rtt.dGVzdC1rZXk"
- func TestVlessFlowAllowed(t *testing.T) {
- enc := map[string]any{"encryption": testMlkemEncryption}
- noEnc := map[string]any{"encryption": "none"}
- tests := []struct {
- name string
- network string
- security string
- settings map[string]any
- want bool
- }{
- {"tcp tls", "tcp", "tls", noEnc, true},
- {"tcp reality", "tcp", "reality", noEnc, true},
- {"tcp none", "tcp", "none", noEnc, false},
- {"tcp none vlessenc", "tcp", "none", enc, false},
- {"xhttp none vlessenc", "xhttp", "none", enc, true},
- {"xhttp reality vlessenc (#5232)", "xhttp", "reality", enc, true},
- {"xhttp tls vlessenc", "xhttp", "tls", enc, true},
- {"xhttp reality no vlessenc", "xhttp", "reality", noEnc, false},
- {"ws tls", "ws", "tls", noEnc, false},
- }
- for _, tc := range tests {
- t.Run(tc.name, func(t *testing.T) {
- if got := vlessFlowAllowed(tc.network, tc.security, tc.settings); got != tc.want {
- t.Fatalf("vlessFlowAllowed(%q, %q, %v) = %v, want %v", tc.network, tc.security, tc.settings, got, tc.want)
- }
- })
- }
- }
- func flowTestInbound(streamSettings, encryption string) *model.Inbound {
- return &model.Inbound{
- Listen: "203.0.113.1",
- Port: 443,
- Protocol: model.VLESS,
- Remark: "flowtest",
- Settings: `{"clients":[{"id":"11111111-2222-4333-8444-555555555555","email":"user","flow":"xtls-rprx-vision"}],` +
- `"decryption":"` + encryption + `","encryption":"` + encryption + `"}`,
- StreamSettings: streamSettings,
- }
- }
- const xhttpRealityStream = `{
- "network": "xhttp",
- "security": "reality",
- "xhttpSettings": {"path": "/", "mode": "auto"},
- "realitySettings": {
- "serverNames": ["example.com"],
- "shortIds": ["abcd"],
- "settings": {"publicKey": "pub", "fingerprint": "chrome"}
- }
- }`
- func TestGenVlessLink_FlowXhttpRealityVlessenc(t *testing.T) {
- s := &SubService{remarkModel: "-ieo"}
- link := s.genVlessLink(flowTestInbound(xhttpRealityStream, testMlkemEncryption), "user")
- if !strings.Contains(link, "flow=xtls-rprx-vision") {
- t.Fatalf("xhttp+reality+vlessenc link must carry the vision flow (#5232), got %q", link)
- }
- }
- func TestGenVlessLink_NoFlowXhttpRealityWithoutVlessenc(t *testing.T) {
- s := &SubService{remarkModel: "-ieo"}
- link := s.genVlessLink(flowTestInbound(xhttpRealityStream, "none"), "user")
- if strings.Contains(link, "flow=") {
- t.Fatalf("xhttp+reality without vlessenc must not carry a flow, got %q", link)
- }
- }
- func TestGenVlessLink_FlowTcpRealityStillWorks(t *testing.T) {
- stream := `{
- "network": "tcp",
- "security": "reality",
- "tcpSettings": {"header": {"type": "none"}},
- "realitySettings": {
- "serverNames": ["example.com"],
- "shortIds": ["abcd"],
- "settings": {"publicKey": "pub", "fingerprint": "chrome"}
- }
- }`
- s := &SubService{remarkModel: "-ieo"}
- link := s.genVlessLink(flowTestInbound(stream, "none"), "user")
- if !strings.Contains(link, "flow=xtls-rprx-vision") {
- t.Fatalf("tcp+reality link must keep the vision flow, got %q", link)
- }
- }
|