package ws import ( "net/http" "testing" ) // TestCheckOrigin 驗證 WebSocket upgrade 的 origin 白名單(M8-8 / TDD §5)。 func TestCheckOrigin(t *testing.T) { cases := []struct { name string origin string want bool }{ {"empty same-origin", "", true}, {"loopback 127.0.0.1", "http://127.0.0.1:3721", true}, {"loopback localhost", "http://localhost:3000", true}, {"loopback ipv6", "http://[::1]:3721", true}, {"https 不允許", "https://127.0.0.1:3721", false}, {"非 loopback hostname", "http://192.168.1.5:3721", false}, {"惡意網站", "http://evil.com", false}, {"null origin", "null", false}, {"suffix 攻擊", "http://127.0.0.1.evil.com", false}, } for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { req, _ := http.NewRequest(http.MethodGet, "http://127.0.0.1:3721/ws/devices/events", nil) if tc.origin != "" { req.Header.Set("Origin", tc.origin) } got := CheckOrigin(req) if got != tc.want { t.Errorf("CheckOrigin(%q) = %v, want %v", tc.origin, got, tc.want) } }) } }