diff --git a/server/static/static.go b/server/static/static.go index 1f64d871..5688fd72 100644 --- a/server/static/static.go +++ b/server/static/static.go @@ -4,12 +4,14 @@ import ( "io/fs" "net/http" "net/url" + "os" "strings" "github.com/gin-gonic/gin" "github.com/synctv-org/synctv/cmd/flags" "github.com/synctv-org/synctv/public" "github.com/synctv-org/synctv/server/middlewares" + "github.com/zijiren233/gencontainer/rwmap" ) func Init(e *gin.Engine) { @@ -22,30 +24,72 @@ func Init(e *gin.Engine) { if flags.WebPath == "" { web.Use(middlewares.NewDistCacheControl("/web/")) - err := initFSRouter(web, public.Public.(fs.ReadDirFS), ".") - if err != nil { - panic(err) - } + SiglePageAppFS(web, public.Public, true) - e.NoRoute(func(ctx *gin.Context) { - if strings.HasPrefix(ctx.Request.URL.Path, "/web/") { - ctx.FileFromFS("", http.FS(public.Public)) - return - } - }) + // err := initFSRouter(web, public.Public.(fs.ReadDirFS), ".") + // if err != nil { + // panic(err) + // } + + // e.NoRoute(func(ctx *gin.Context) { + // if strings.HasPrefix(ctx.Request.URL.Path, "/web/") { + // ctx.FileFromFS("", http.FS(public.Public)) + // return + // } + // }) } else { - web.Static("/", flags.WebPath) + SiglePageAppFS(web, os.DirFS(flags.WebPath), false) - e.NoRoute(func(ctx *gin.Context) { - if strings.HasPrefix(ctx.Request.URL.Path, "/web/") { - ctx.FileFromFS("", http.Dir(flags.WebPath)) - return - } - }) + // web.Static("/", flags.WebPath) + + // e.NoRoute(func(ctx *gin.Context) { + // if strings.HasPrefix(ctx.Request.URL.Path, "/web/") { + // ctx.FileFromFS("", http.Dir(flags.WebPath)) + // return + // } + // }) } } +func SiglePageAppFS(r *gin.RouterGroup, fileSys fs.FS, cacheStat bool) { + const param = "filepath" + var h func(ctx *gin.Context) + if cacheStat { + var cache = rwmap.RWMap[string, bool]{} + h = func(ctx *gin.Context) { + fp := strings.Trim(ctx.Param(param), "/") + if stat, ok := cache.Load(fp); ok { + if !stat { + fp = "" + } + } else { + f, err := fileSys.Open(fp) + cache.LoadOrStore(fp, err == nil) + if err != nil { + fp = "" + } else { + f.Close() + } + } + ctx.FileFromFS(fp, http.FS(fileSys)) + } + } else { + h = func(ctx *gin.Context) { + fp := strings.Trim(ctx.Param(param), "/") + f, err := fileSys.Open(fp) + if err != nil { + fp = "" + } else { + f.Close() + } + ctx.FileFromFS(fp, http.FS(fileSys)) + } + } + r.GET("/*"+param, h) + r.HEAD("/*"+param, h) +} + func initFSRouter(e *gin.RouterGroup, f fs.ReadDirFS, path string) error { dirs, err := f.ReadDir(path) if err != nil {