编号:L-05 严重级:medium 工作线:监听与 HTTP(internal/listener、internal/httpx、serve 的 HTTP 装配) 来源:审查 A-03、P-10 依赖:无 被依赖:无
两份审查结论一致(管理后台审查判 high、传输区判 medium;有"从根路径进入"的绕过办法,取 medium)。统一方案:在 internal/httpx 新增 SPA(fsys fs.FS) http.Handler:
internal/httpx
SPA(fsys fs.FS) http.Handler
fs.Stat
Cache-Control: no-cache
/assets/x.js
cmd/nixmsg/serve.go 的 staticFileHandler 改为调用它。
cmd/nixmsg/serve.go
staticFileHandler
internal/httpx/spa.go(新)、cmd/nixmsg/serve.go(staticFileHandler)。
internal/httpx/spa.go
/api/、/mqtt、/metrics 由外层 mux 先匹配,不受影响。
/api/
/mqtt
/metrics
/endpoints
/assets/nope.js
/assets/
-tags embeddist
page.reload()
以下是本次复审各区审查报告的原文段落。A、M、I、P、S 开头的是原始发现编号(A 管理后台与网页、M 消息核心、I 身份认证群在线、P 传输平台部署、S SDK)。解决方案以本 issue 上方的"结论与统一方案"为准;原文里的方案与之不一致时,按上方执行。
createWebHistory()
web/src/router/index.ts:4-5
/messages
http.FileServer
func staticFileHandler() http.Handler { root := web.Dist() for _, prefix := range []string{"dist", "stub"} { sub, err := fs.Sub(root, prefix) if err != nil { continue } if f, err := sub.Open("index.html"); err == nil { _ = f.Close() return http.FileServer(http.FS(sub)) } } return http.FileServer(http.FS(root)) }
internal/listener/routes.go:80-84,96-101
/
playwright.config.ts:17-24
start-stack.mjs:100-103
embeddist
index.html
serve.go
serve.go:350-363
web/src/router/index.ts:5
web/playwright.config.ts:18-23
/api/...
复审基线:main 4059a15(2026-09-30)。编号说明、各工作线的合并顺序、共享文件归属见总览 #7。
4059a15
已合入 origin/main 0c9b459。落地提交 7c926a0 fix: 修复 TLS ConnectionState、SPA 回退、健康检查与监听小问题 (#24)。
0c9b459
7c926a0
No dependencies set.
The note is not visible to the blocked user.
编号:L-05 严重级:medium 工作线:监听与 HTTP(internal/listener、internal/httpx、serve 的 HTTP 装配) 来源:审查 A-03、P-10
依赖:无 被依赖:无
结论与统一方案
两份审查结论一致(管理后台审查判 high、传输区判 medium;有"从根路径进入"的绕过办法,取 medium)。统一方案:在
internal/httpx新增SPA(fsys fs.FS) http.Handler:fs.Stat,是文件就交给 FileServer。Cache-Control: no-cache。/assets/x.js)返回 404。cmd/nixmsg/serve.go的staticFileHandler改为调用它。改动文件
internal/httpx/spa.go(新)、cmd/nixmsg/serve.go(staticFileHandler)。与其他问题的交互 / 冲突说明
/api/、/mqtt、/metrics由外层 mux 先匹配,不受影响。验收与测试
/endpoints返回 200 text/html;GET/assets/nope.js返回 404;GET/assets/不列目录。-tags embeddist构建、由 Go 直出页面的 e2e 冒烟(含page.reload())。现有 e2e 走 Vite 开发服务器,测不出这个问题。问题明细(各区审查原文,证据含文件与行号)
[A-03] 生产静态页不回退 index.html,刷新或深链接即 404
createWebHistory()(web/src/router/index.ts:4-5)。在/endpoints、/messages等页面按 F5、打开书签或新标签页,http.FileServer找不到对应文件,直接返回纯文本 "404 page not found"。真实工作流不可用。internal/listener/routes.go:80-84,96-101把它挂在/。playwright.config.ts:17-24;start-stack.mjs:100-103编译时不带embeddist),Vite 自带回退,所以测不出来。internal/httpx新增SPA(fsys fs.FS) http.Handler:index.html,加Cache-Control: no-cache。/assets/x.js)仍返回 404,并关闭目录列表。serve.go改成一行调用它。internal/httpx/spa.go(新)、cmd/nixmsg/serve.go(总控)。/api/、/mqtt、/metrics由外层 mux 先匹配,不受影响。/endpoints返回 200 text/html;/assets/nope.js返回 404。加一个用-tags embeddist构建、由 Go 直出页面的冒烟测试,包含page.reload()。[P-10] 后台静态页没有前端路由回退:刷新或直接打开 /overview、/endpoints 返回 404
createWebHistory(),服务端staticFileHandler是裸的http.FileServer,找不到文件就返回 404。/进入后,前端路由才能用;刷新任何二级页面、打开收藏的链接,都得到 404。/assets/)还会列出文件清单。serve.go:350-363;web/src/router/index.ts:5;web/playwright.config.ts:18-23。fs.Stat查嵌入的文件系统,是文件就交给 FileServer;Cache-Control: no-cache;cmd/nixmsg/serve.go/api/...由各自的路由处理,不受影响。/endpoints返回 200 且内容是 index.html;GET/assets/nope.js返回 404。复审基线:main
4059a15(2026-09-30)。编号说明、各工作线的合并顺序、共享文件归属见总览 #7。已合入 origin/main
0c9b459。落地提交7c926a0fix: 修复 TLS ConnectionState、SPA 回退、健康检查与监听小问题 (#24)。