fix(protocol): strip ws-headers from VLESS/VMess listeners

Mihomo inbound only supports ws-path for WebSocket; headers are
client-side. Keep ws-headers in panel config for share/export.
This commit is contained in:
kazeyukiro committed 2026-09-30 08:01:44 +00:00
1 parent 0d894a7415
commit d2a80f5f80
2 files changed
+39 -1

No files matched your search

+4 -1
View File
@@ -155,7 +155,10 @@ func clientOnlyListenerKey(k string) bool {
"grpc-user-agent", "ping-interval", "max-connections", "min-streams", "max-streams",
// Client-only TUIC/Hy2 hints sometimes stored in panel JSON.
"udp-relay-mode", "reduce-rtt", "request-timeout", "heartbeat-interval",
"fast-open", "max-open-streams", "disable-sni", "ip":
"fast-open", "max-open-streams", "disable-sni", "ip",
// Listener WS is only ws-path (wiki inbound VLESS/VMess). Headers belong on
// the client as ws-opts.headers / share URI — not on the serving listener.
"ws-headers", "ws-opts", "headers", "network":
return true
default:
return false
@@ -0,0 +1,35 @@
package protocol
import "testing"
// Official VLESS/VMess listeners only accept ws-path for WebSocket, not
// ws-headers (client-side Host goes in share URI / ws-opts.headers).
func TestCompileVLESSStripsWSHeaders(t *testing.T) {
cfg := map[string]interface{}{
"ws-path": "/ws",
"ws-headers": map[string]interface{}{"Host": "cdn.example.com"},
"allow-insecure": true,
}
reg := DefaultCompileRegistry()
m, err := reg.Compile(CompileInput{
Name: "VLESS-WS",
Protocol: "vless",
Listen: "0.0.0.0",
Port: 10000,
Config: cfg,
Users: []UserCred{{UUID: "9d0cb9d0-964f-4ef6-897d-6c6b3ccf9e68", Username: "u1"}},
})
if err != nil {
t.Fatal(err)
}
if _, ok := m["ws-headers"]; ok {
t.Fatalf("ws-headers must not appear on listener: %#v", m)
}
if m["ws-path"] != "/ws" {
t.Fatalf("ws-path should remain: %#v", m["ws-path"])
}
// Panel config keeps headers for share/export.
if cfg["ws-headers"] == nil {
t.Fatal("input ws-headers must stay for client export")
}
}