Files
ARTEX/server/webui_embed.go
BaaRai e233c02314 Translate all Chinese text to English
Comments, doc comments, UI labels, log and error messages, LLM prompt
strings, markdown docs, test data and assertions. Identifiers, enum
keys, routes, placeholders and code structure are unchanged.

Notes:
- docs/漏洞流量证据.md renamed to docs/vulnerability-traffic-evidence.md
- tests that exercised CJK specific handling (GBK zip names, Chinese
  full text search) now use ASCII equivalents; go build passes and the
  test suite matches the pre translation baseline (remaining failures
  need a PostgreSQL DSN and fail identically on the original)
- frontend mention syntax now uses English kinds (finding, asset, ...)
  matching the backend, chat mentions tests pass
2026-10-08 23:14:34 +02:00

61 lines
1.7 KiB
Go

//go:build embedui
package server
import (
"embed"
"io/fs"
"net/http"
"path"
"strings"
)
// webuiDist holds the statically-exported frontend (built with
// `cd web && npm run build:static`, then copied into server/webui/dist). Compiled
// into the binary only when building with `-tags embedui`. The `all:` prefix is
// required so Next's `_next/` asset dir (leading underscore) is included.
//
//go:embed all:webui/dist
var webuiDist embed.FS
// webuiHandler serves the embedded SPA. Public (no JWT) — auth is enforced
// client-side and on /api. Serves the exported per-route index.html files and
// falls back to index.html so client-side routing still resolves unknown paths.
func (s *Server) webuiHandler() http.Handler {
root, err := fs.Sub(webuiDist, "webui/dist")
if err != nil {
panic(err)
}
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
p := strings.TrimPrefix(path.Clean(r.URL.Path), "/")
if p == "" {
p = "index.html"
}
// 1) exact file (assets: _next/*, favicon.ico, ...)
// 2) route dir → <p>/index.html (trailingSlash export)
// 3) <p>.html
// 4) SPA fallback → index.html (hand it to client-side routing)
for _, cand := range []string{p, p + "/index.html", p + ".html"} {
if serveFileIfExists(w, r, root, cand) {
return
}
}
http.ServeFileFS(w, r, root, "index.html")
})
}
// serveFileIfExists serves name from fsys when it exists as a regular file.
func serveFileIfExists(w http.ResponseWriter, r *http.Request, fsys fs.FS, name string) bool {
f, err := fsys.Open(name)
if err != nil {
return false
}
st, statErr := f.Stat()
_ = f.Close()
if statErr != nil || st.IsDir() {
return false
}
http.ServeFileFS(w, r, fsys, name)
return true
}