pet-house/core/server/web/web_gin/index.go

152 lines
3.3 KiB
Go

package web_gin
import (
"errors"
"fmt"
"github.com/mattn/go-colorable"
"net/http"
"path/filepath"
"regexp"
"strings"
"time"
"github.com/gin-gonic/gin"
"pet-house.com/core/helper/arr"
"pet-house.com/core/helper/dir"
"pet-house.com/core/helper/str"
"pet-house.com/core/server/web"
"pet-house.com/core/server/web/web_gin/middleware"
)
var ErrAuthDriverEmpty = errors.New("auth driver initialize fail")
// WebServer
// - app gin.Engine
// - idleConnsClosed
// - addr
// - timeFormat
// - staticPrefix
type WebServer struct {
app *gin.Engine
server
addr string
timeFormat string
webStatics []WebStatic
}
type WebStatic struct {
Prefix string
IndexFile []byte
}
// Init
func Init() *WebServer {
gin.SetMode(web.CONFIG.System.Level)
app := gin.Default()
if web.CONFIG.System.Tls {
app.Use(middleware.LoadTls())
}
app.Use(middleware.Cors())
registerValidation()
gin.DefaultWriter = colorable.NewColorableStdout()
web.SetDefaultAddrAndTimeFormat()
return &WebServer{
app: app,
addr: web.CONFIG.System.Addr,
timeFormat: web.CONFIG.System.TimeFormat,
}
}
// NoRoute for 404 http status
func (ws *WebServer) NoRoute() {
if len(ws.webStatics) == 0 {
return
}
ws.app.NoRoute(func(ctx *gin.Context) {
// excepte for /v0 /v1 and so on
reg := `^/v[0-9]+$|^(/v[0-9]+)/`
ok, _ := regexp.MatchString(reg, ctx.Request.RequestURI)
if ok {
ctx.Writer.WriteHeader(http.StatusNotFound)
ctx.Writer.Flush()
return
}
var indexFile []byte
for _, wp := range ws.webStatics {
// match /admin or /admin/***
reg := str.Join("^", wp.Prefix, "$|^(", wp.Prefix, ")/")
ok, err := regexp.MatchString(reg, ctx.Request.RequestURI)
if err != nil || !ok {
continue
}
indexFile = wp.IndexFile
}
ctx.Writer.WriteHeader(http.StatusOK)
ctx.Writer.Write(indexFile)
ctx.Writer.Header().Add("Accept", "text/html")
ctx.Writer.Flush()
})
}
// GetEngine return *gin.Engine
func (ws *WebServer) GetEngine() *gin.Engine {
return ws.app
}
// AddWebStatic
func (ws *WebServer) AddWebStatic(staticAbsPath, webPrefix string, paths ...string) {
webPrefixs := strings.Split(web.CONFIG.System.WebPrefix, ",")
wp := arr.NewCheckArrayType(2)
for _, webPrefix := range webPrefixs {
wp.Add(webPrefix)
}
if wp.Check(webPrefix) {
return
}
favicon := filepath.Join(staticAbsPath, "favicon.ico")
index := filepath.Join(staticAbsPath, "index.html")
ws.app.Static(str.Join(webPrefix, "/favicon.ico"), favicon)
ws.app.StaticFile(webPrefix, index)
if len(paths) > 0 {
for _, path := range paths {
static := filepath.Join(staticAbsPath, path)
ws.app.Static(path, static)
}
}
web.CONFIG.System.WebPrefix = str.Join(web.CONFIG.System.WebPrefix, ",", webPrefix)
file, _ := dir.ReadBytes(index)
webStatic := WebStatic{
Prefix: webPrefix,
IndexFile: file,
}
ws.webStatics = append(ws.webStatics, webStatic)
}
// AddUploadStatic
func (ws *WebServer) AddUploadStatic(webPrefix, staticAbsPath string) {
ws.app.StaticFS(webPrefix, http.Dir(staticAbsPath))
web.CONFIG.System.StaticPrefix = webPrefix
}
// Run
func (ws *WebServer) Run() {
ws.NoRoute()
s := initServer(web.CONFIG.System.Addr, ws.app)
time.Sleep(10 * time.Microsecond)
fmt.Printf("默认监听地址: http://%s\n", web.CONFIG.System.Addr)
s.ListenAndServe()
}