viper-app/internal/server/ext/ext_web.go

102 lines
2.1 KiB
Go
Raw Permalink Normal View History

//go:build web
package ext
import (
"crypto/md5"
"demo-server/pkg/str"
"embed"
"fmt"
"github.com/gin-gonic/gin"
"github.com/vearutop/statigz"
"go.uber.org/zap"
"io"
"io/fs"
"net/http"
"strings"
)
/*
embed static web learn insp opensource license MIT
see "github.com/v2rayA/v2rayA/server/router/index.go"
*/
func init() {
initEngQueue = append(initEngQueue, initGUI)
}
// webRootFS 嵌入静态文件
//
//go:embed web
var webRootFS embed.FS
func initGUI(r *gin.Engine) {
webFS, err := fs.Sub(webRootFS, "web")
if err != nil {
zap.S().Panic("init gui err, cause: ", err)
}
guiStaticResource(r, webFS)
guiIndexHTML(r, webFS)
}
// html 缓存 HTML 页面
func html(html []byte) func(ctx *gin.Context) {
etag := fmt.Sprintf("W/%x", md5.Sum(html))
h := str.B2S(html)
return func(ctx *gin.Context) {
if ctx.IsAborted() {
return
}
ctx.Header("Content-Type", "text/html; charset=utf-8")
ctx.Header("Cache-Control", "public, must-revalidate")
ctx.Header("ETag", etag)
if match := ctx.GetHeader("If-None-Match"); match != "" {
if strings.Contains(match, etag) {
ctx.Status(http.StatusNotModified)
return
}
}
ctx.String(http.StatusOK, h)
}
}
func guiStaticResource(r *gin.Engine, sfs fs.FS) {
const (
assetsPrefix = "/assets"
staticPrefix = "/static"
stripPrefix = ""
)
staticResource := http.StripPrefix(stripPrefix, statigz.FileServer(sfs.(fs.ReadDirFS)))
r.GET(assetsPrefix+"/*w", func(c *gin.Context) {
staticResource.ServeHTTP(c.Writer, c.Request)
})
r.GET(staticPrefix+"/*w", func(c *gin.Context) {
staticResource.ServeHTTP(c.Writer, c.Request)
})
r.GET("/favicon.ico", func(c *gin.Context) {
staticResource.ServeHTTP(c.Writer, c.Request)
})
}
func guiIndexHTML(r *gin.Engine, sfs fs.FS) {
var indexHTML []byte
{
const indexFileName = "index.html"
index, err := sfs.Open(indexFileName)
if err != nil {
zap.S().Panicf("open [%s] err! cause: %e", indexFileName, err)
}
indexHTML, err = io.ReadAll(index)
if err != nil {
zap.S().Panicf("read [%s] err! cause: %e", indexFileName, err)
}
}
r.GET("/", html(indexHTML))
r.NoRoute(html(indexHTML))
}