Sfoglia il codice sorgente

Add frontend util for websubsvc.

ZRY 9 mesi fa
parent
commit
f0f1bd6bce
3 ha cambiato i file con 91 aggiunte e 1 eliminazioni
  1. 11 0
      websubsvc/frontend_fs.go
  2. 68 0
      websubsvc/frontend_util.go
  3. 12 1
      websubsvc/webctx.go

+ 11 - 0
websubsvc/frontend_fs.go

@@ -0,0 +1,11 @@
+package websubsvc
+
+import (
+	"io/fs"
+	"os"
+)
+
+type IFilesystem interface {
+	fs.FS
+	Stat(path string) (os.FileInfo, error)
+}

+ 68 - 0
websubsvc/frontend_util.go

@@ -0,0 +1,68 @@
+package websubsvc
+
+import (
+	"github.com/gin-gonic/gin"
+	"net/http"
+	"path"
+)
+
+type FrontendUtil struct {
+	filesystem     IFilesystem
+	vueHistoryMode bool
+	notFoundHdl    gin.HandlerFunc
+	forbiddenHdl   gin.HandlerFunc
+	fileServer     http.Handler
+}
+
+func NewFrontendUtil(fs IFilesystem, vueHistoryMode bool) *FrontendUtil {
+	s := &FrontendUtil{
+		filesystem:     fs,
+		vueHistoryMode: vueHistoryMode,
+		fileServer:     http.FileServer(http.FS(fs)),
+	}
+	s.forbiddenHdl = s.DefaultForbiddenHandler
+	s.notFoundHdl = s.DefaultNotFoundHandler
+	return s
+}
+
+func (s *FrontendUtil) StaticFilesHandler(ctx *gin.Context) {
+	url := ctx.Request.URL.Path
+	fin, err := s.filesystem.Stat(path.Clean(url))
+	if err != nil {
+		if s.vueHistoryMode {
+			s.VueHistoryModeHandler(ctx)
+			return
+		} else {
+			s.notFoundHdl(ctx)
+			return
+		}
+	}
+	if fin.IsDir() {
+		_, xerr := s.filesystem.Stat(path.Join(path.Clean(url), "index.html"))
+		if xerr != nil {
+			if s.vueHistoryMode {
+				s.VueHistoryModeHandler(ctx)
+				return
+			} else {
+				s.forbiddenHdl(ctx)
+				return
+			}
+		}
+	}
+	ctx.Request.URL.Path = url
+	s.fileServer.ServeHTTP(ctx.Writer, ctx.Request)
+}
+
+func (s *FrontendUtil) DefaultNotFoundHandler(ctx *gin.Context) {
+	ctx.Writer.WriteString("404 not found")
+	ctx.Status(404)
+}
+
+func (s *FrontendUtil) DefaultForbiddenHandler(ctx *gin.Context) {
+	ctx.Writer.WriteString("403 forbidden")
+	ctx.Status(403)
+}
+
+func (s *FrontendUtil) VueHistoryModeHandler(ctx *gin.Context) {
+	ctx.HTML(200, "index.html", &gin.H{})
+}

+ 12 - 1
websubsvc/webctx.go

@@ -5,6 +5,7 @@ import (
 	"fmt"
 	"git.swzry.com/zry/zry-go-program-framework/core"
 	"github.com/gin-gonic/gin"
+	"html/template"
 	"net"
 	"net/http"
 	"net/http/httputil"
@@ -17,7 +18,8 @@ import (
 type WebSubServiceContext struct {
 	subSvcCtx *core.SubServiceContext
 	core.IModuleLogger
-	s *WebSubService
+	s            *WebSubService
+	frontendUtil *FrontendUtil
 }
 
 // GetSubSvcCtx get the SubServiceContext of this sub service
@@ -172,3 +174,12 @@ func (c *WebSubServiceContext) EnableRecovery(recoveryLogPrefix string) {
 	}
 	c.s.ginEngine.Use(fn)
 }
+
+func (c *WebSubServiceContext) EnableFrontend(fs IFilesystem, useVueHistoryMode bool) *FrontendUtil {
+	fu := NewFrontendUtil(fs, useVueHistoryMode)
+	tmpl := template.New("")
+	tmpl = template.Must(tmpl.ParseFS(fu.filesystem, "index.html"))
+	c.s.ginEngine.SetHTMLTemplate(tmpl)
+	c.s.ginEngine.NoRoute(fu.StaticFilesHandler)
+	return fu
+}