package ws import ( "net/http" "net/url" "strings" ) // CheckOrigin 決定 WebSocket upgrade 是否允許。 // // M8-8 / TDD v2/cors-security.md §5: // 與 HTTP CORS 白名單一致,只允許本機 loopback 來源: // - http://127.0.0.1:* / http://localhost:* / http://[::1]:* // - same-origin(Origin header 為空,gorilla 預設行為) // // 注意:這個 helper 故意與 api package 的 isAllowedOrigin 重複實作(不直接 import), // 避免 ws → api 反向 import(會造成 cycle)。兩邊邏輯保持一致。 func CheckOrigin(r *http.Request) bool { origin := r.Header.Get("Origin") if origin == "" { // same-origin 或非瀏覽器 client(websocat、Postman 等) return true } if origin == "null" { return false } u, err := url.Parse(origin) if err != nil { return false } if u.Scheme != "http" { return false } host := strings.ToLower(u.Hostname()) switch host { case "127.0.0.1", "localhost", "::1", "[::1]": return true } return false }