update new route middlewares

This commit is contained in:
Jay
2020-08-16 17:39:13 +08:00
parent 77cc488d89
commit b3a93abfb9
29 changed files with 643 additions and 5 deletions
+14
View File
@@ -0,0 +1,14 @@
package middleware
import (
"github.com/gin-contrib/cors"
"github.com/gin-gonic/gin"
)
func Cors() gin.HandlerFunc {
corsOpts := cors.DefaultConfig()
corsOpts.AllowCredentials = true
corsOpts.AllowOriginFunc = func(origin string) bool { return origin != "" }
return cors.New(corsOpts)
}
+53
View File
@@ -0,0 +1,53 @@
package middleware
import (
"fmt"
"go-api/pkg/context"
apierr "go-api/pkg/errors"
"go-api/pkg/response"
"runtime"
"strings"
)
func ServerPanicCatch() context.CustomHandler {
return func(c *context.C) {
defer func() {
if err := recover(); err != nil {
// show error Stack
// *****
builder := &strings.Builder{}
fmt.Printf("[Server Error Catch]\n")
pc := make([]uintptr, 10)
n := runtime.Callers(1, pc)
frames := runtime.CallersFrames(pc[:n])
for {
frame, more := frames.Next()
builder.WriteString(fmt.Sprintf("%s:%d %s\n", frame.File, frame.Line, frame.Function))
if !more {
break
}
}
// *****
var e *apierr.APIError
if convertedErr, ok := err.(*apierr.APIError); ok {
e = convertedErr
} else {
e = apierr.ErrInternalError
}
code := make([]response.MessageCode, 0)
if c := e.Code(); c != nil {
code = append(code, *c)
}
resp := response.Get(e.Status(), code...)
c.AbortWithStatusJSON(resp.Status, resp.Body)
}
}()
c.Next()
}
}
+85
View File
@@ -0,0 +1,85 @@
package middleware
import (
"encoding/json"
"fmt"
"go-api/static"
"net/http"
"net/textproto"
"regexp"
"strings"
"github.com/gin-gonic/gin"
)
type SwaggerOptions struct {
Root string
}
var regex = regexp.MustCompile(`(src|href)="./`)
var specRegex = regexp.MustCompile(`url:.+`)
func SwaggerSpecServe() gin.HandlerFunc {
return func(c *gin.Context) {
b, err := static.GetSpec()
if err != nil {
c.String(http.StatusNotFound, "not found")
return
}
var j map[string]interface{}
if err := json.Unmarshal(b, &j); err != nil {
c.String(http.StatusInternalServerError, "internal error")
return
}
if _, ok := j["host"]; ok {
j["host"] = c.Request.Host
}
if xfp := c.Request.Header.Get(textproto.CanonicalMIMEHeaderKey("X-Forwarded-Proto")); xfp != "" && xfp == "https" {
j["schemes"] = []string{xfp}
}
c.JSON(http.StatusOK, j)
}
}
func SwaggerServe(prefix string, opts *SwaggerOptions) gin.HandlerFunc {
return func(c *gin.Context) {
fp := c.Request.URL.Path
if prefix != "" {
if !strings.HasPrefix(fp, prefix) {
c.Next()
return
}
if fp = strings.Replace(fp, prefix, "", 1); fp == "" {
fp = "/"
}
}
// end of slash replace to index.html file
if strings.HasSuffix(fp, "/") {
fp += "index.html"
}
if b, mime, err := static.GetWebFile(fp); err == nil {
// 如果是 index.html 要更新內部的連結 轉換成絕對路徑
if fp == "/index.html" {
replPrefix := prefix
if !strings.HasSuffix(replPrefix, "/") {
replPrefix += "/"
}
b = regex.ReplaceAll(b, []byte(fmt.Sprintf(`$1="%s`, replPrefix)))
b = specRegex.ReplaceAll(b, []byte(fmt.Sprintf(`url: '%s.json',`, prefix)))
}
c.Writer.Header().Set(textproto.CanonicalMIMEHeaderKey("Content-Type"), mime)
c.Status(http.StatusOK)
c.Writer.Write(b)
c.Abort()
}
}
}