2026-09-19 18:20:56 +03:00
|
|
|
|
package server
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
|
"net/http"
|
|
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
|
|
|
|
"glchat/internal/httpx"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
// reservedPrefixes are handled by the API, the gateway or the file CDN; an
|
|
|
|
|
|
// unknown path under them is a real 404 and must not receive the SPA shell.
|
2026-09-22 23:17:22 +03:00
|
|
|
|
// `/updates/` — статика автообновления: обёртка ждёт JSON или 404, а не HTML.
|
|
|
|
|
|
var reservedPrefixes = []string{"/api/", "/gateway", "/files/", "/rtc", "/updates/"}
|
2026-09-19 18:20:56 +03:00
|
|
|
|
|
|
|
|
|
|
func isReservedPath(path string) bool {
|
|
|
|
|
|
for _, prefix := range reservedPrefixes {
|
|
|
|
|
|
if path == strings.TrimSuffix(prefix, "/") || strings.HasPrefix(path, prefix) {
|
|
|
|
|
|
return true
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return false
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (s *Server) handleFallback(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
|
if isReservedPath(r.URL.Path) {
|
|
|
|
|
|
httpx.WriteError(w, httpx.NewError(httpx.CodeNotFound, "resource not found"))
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
if r.Method == http.MethodGet || r.Method == http.MethodHead {
|
|
|
|
|
|
s.static.serve(w, r)
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
httpx.WriteError(w, httpx.NewError(httpx.CodeNotFound, "resource not found"))
|
|
|
|
|
|
}
|