Files
QiuSW 6465a11074
lint / go (push) Canceled after 0s
lint / go_mod (push) Canceled after 0s
lint / conf (push) Canceled after 0s
lint / docslinks (push) Canceled after 0s
lint / docsorder (push) Canceled after 0s
lint / apidocs (push) Canceled after 0s
lint / other (push) Canceled after 0s
test / test_64 (push) Canceled after 0s
test / test_32 (push) Canceled after 0s
test / test_e2e (push) Canceled after 0s
feat: add embedded RTSP admin console (#3)
2026-08-28 11:24:47 +08:00

66 lines
1.6 KiB
Go

package api //nolint:revive
import (
"embed"
"net/http"
"path"
"strings"
"github.com/gin-gonic/gin"
)
//go:embed admin/*
var adminAssets embed.FS
var adminContentTypes = map[string]string{
".css": "text/css; charset=utf-8",
".html": "text/html; charset=utf-8",
".js": "text/javascript; charset=utf-8",
}
func setAdminSecurityHeaders(ctx *gin.Context) {
ctx.Header("Content-Security-Policy", "default-src 'self'; script-src 'self'; style-src 'self'; "+
"connect-src 'self'; frame-src http: https:; img-src 'self' data:; "+
"object-src 'none'; base-uri 'none'; form-action 'self'; frame-ancestors 'self'")
ctx.Header("Referrer-Policy", "no-referrer")
ctx.Header("X-Content-Type-Options", "nosniff")
ctx.Header("X-Frame-Options", "SAMEORIGIN")
}
func (a *API) onAdminRedirect(ctx *gin.Context) {
ctx.Redirect(http.StatusMovedPermanently, "/admin/")
}
func (a *API) onAdminAsset(ctx *gin.Context) {
assetPath := strings.TrimPrefix(ctx.Param("path"), "/")
if assetPath == "" {
assetPath = "index.html"
}
assetPath = path.Clean(assetPath)
if assetPath == "." || strings.HasPrefix(assetPath, "../") {
ctx.Status(http.StatusNotFound)
return
}
byts, err := adminAssets.ReadFile("admin/" + assetPath)
if err != nil {
ctx.Status(http.StatusNotFound)
return
}
contentType, ok := adminContentTypes[path.Ext(assetPath)]
if !ok {
ctx.Status(http.StatusNotFound)
return
}
setAdminSecurityHeaders(ctx)
if assetPath == "index.html" {
ctx.Header("Cache-Control", "no-store")
} else {
ctx.Header("Cache-Control", "no-cache")
}
ctx.Data(http.StatusOK, contentType, byts)
}