package gateway import ( _ "embed" "net/http" "github.com/gin-gonic/gin" ) // 会议纪要分享落地页。 // // 为什么嵌进二进制而不是当静态文件下发: // 这个页面必须跟着 echomeet_getsharedrecord 的协议走,两者版本对不上就是白页。 // 嵌进来意味着「部署了新镜像 = 页面也是新的」,服务器上不需要维护任何文件, // prod-deploy.sh 也不用多下发一份(confs/*.yaml 那套人工维护的坑已经够多了)。 // // 上线只剩一步:NPM 上把 share.ymaikj.com 反代到 ym-a11:7100(即本 gateway),申请证书。 // //go:embed share_page.html var sharePageHTML []byte // sharePage 把落地页返回给任意 /share/... 路径。 // // ⚠️ 必须是 catch-all:真实链接形如 /share/ym.ymaikj.com/ymaikj.com/42/, // 路径里的段是**数据**不是文件路径。用 gin.Static 会去磁盘上找同名文件,一律 404。 // 解析工作全在页面里的 JS 做(它要按 location.pathname 取 serverHost/id/ticket)。 func (this *WSServiceComp) sharePage(c *gin.Context) { // 不缓存:页面里写死了接口协议,缓存住旧版会在协议变更后变成白页,而用户 // 完全没有手段让它刷新(分享链接是别人发来的,不会有人去硬刷)。 c.Header("Cache-Control", "no-cache, must-revalidate") // 落地页不该被别的站点嵌进 iframe 里套壳。 c.Header("X-Frame-Options", "SAMEORIGIN") c.Header("X-Content-Type-Options", "nosniff") // 别把带票据的完整 URL 经 Referer 泄漏给第三方(音频在 OSS 上,是跨站请求)。 c.Header("Referrer-Policy", "no-referrer") c.Data(http.StatusOK, "text/html; charset=utf-8", sharePageHTML) }