Browse Source

cors: edit

Yi 1 year ago
parent
commit
3cb3f01ba9
3 changed files with 109 additions and 2 deletions
  1. 1 1
      http/middleware/cors.go
  2. 107 0
      http/middleware/log.go
  3. 1 1
      http/route/root.go

+ 1 - 1
http/middleware/cors.go

@@ -27,7 +27,7 @@ func CORS(configs ...cors.Config) gin.HandlerFunc {
 			//允许跨域设置可以返回其他子段,可以自定义字段
 			c.Header("Access-Control-Allow-Headers", "Authorization, Content-Length, Content-Type,X-CSRF-Token,Accept,Referer,User-Agent")
 			// 允许浏览器(客户端)可以解析的头部 (重要)
-			c.Header("Access-Control-Expose-Headers", "Content-Length,Content-Type, Page,Access-Control-Allow-Origin, Access-Control-Allow-Headers")
+			c.Header("Access-Control-Expose-Headers", "Content-Length,Content-Type, Page,Access-Control-Allow-Origin, Access-Control-Allow-Headers,Accept,Referer,User-Agent")
 
 			//设置缓存时间
 			c.Header("Access-Control-Max-Age", "172800")

+ 107 - 0
http/middleware/log.go

@@ -0,0 +1,107 @@
+package middleware
+
+import (
+	"bytes"
+	"io/ioutil"
+
+	"net"
+	"net/http"
+	"net/http/httputil"
+	"os"
+	"runtime/debug"
+	"strings"
+	"time"
+
+	"gitee.com/xuyiping_admin/pkg/logger/zaplog"
+	"github.com/gin-gonic/gin"
+	"go.uber.org/zap"
+)
+
+type responseBodyWriter struct {
+	gin.ResponseWriter
+	body *bytes.Buffer
+}
+
+func (r responseBodyWriter) Write(b []byte) (int, error) {
+	r.body.Write(b)
+	return r.ResponseWriter.Write(b)
+}
+
+// GinLogger 接管gin框架默认的日志
+func GinLogger() gin.HandlerFunc {
+	return func(c *gin.Context) {
+		// 获取 response 内容
+		w := &responseBodyWriter{body: &bytes.Buffer{}, ResponseWriter: c.Writer}
+		c.Writer = w
+
+		var requestBody []byte
+		if c.Request.Body != nil {
+			requestBody, _ = ioutil.ReadAll(c.Request.Body)
+			c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(requestBody))
+		}
+		start := time.Now()
+		c.Next()
+		cost := time.Since(start)
+
+		logFields := []zap.Field{
+			zap.Int("status", c.Writer.Status()),
+			zap.String("request", c.Request.Method+" "+c.Request.URL.String()),
+			zap.String("query", c.Request.URL.RawQuery),
+			zap.String("ip", c.ClientIP()),
+			zap.String("user-agent", c.Request.UserAgent()),
+			zap.String("errors", c.Errors.ByType(gin.ErrorTypePrivate).String()),
+			zap.String("time", cost.String()),
+			zap.String("x-request-id", c.Request.Header.Get("X-Request-Id")),
+		}
+		logFields = append(logFields, zap.String("Request body", string(requestBody)))
+		logFields = append(logFields, zap.String("Response body", w.body.String()))
+		zaplog.Info("Http-Access-Log", logFields...)
+	}
+}
+
+// GinRecovery recover掉我的项目可能呈现的panic
+func GinRecovery(stack bool) gin.HandlerFunc {
+	return func(c *gin.Context) {
+		defer func() {
+			if err := recover(); err != nil {
+				// Check for a broken connection, as it is not really a
+				// condition that warrants a panic stack trace.
+				var brokenPipe bool
+				if ne, ok := err.(*net.OpError); ok {
+					if se, ok := ne.Err.(*os.SyscallError); ok {
+						if strings.Contains(strings.ToLower(se.Error()), "broken pipe") || strings.Contains(strings.ToLower(se.Error()), "connection reset by peer") {
+							brokenPipe = true
+						}
+					}
+				}
+
+				httpRequest, _ := httputil.DumpRequest(c.Request, false)
+				if brokenPipe {
+					zaplog.Error(c.Request.URL.Path,
+						zap.Any("error", err),
+						zap.String("request", string(httpRequest)),
+					)
+					// If the connection is dead, we can't write a status to it.
+					c.Error(err.(error)) // nolint: errcheck
+					c.Abort()
+					return
+				}
+
+				if stack {
+					zaplog.Error("[Recovery from panic]",
+						zap.Any("error", err),
+						zap.String("request", string(httpRequest)),
+						zap.String("stack", string(debug.Stack())),
+					)
+				} else {
+					zaplog.Error("[Recovery from panic]",
+						zap.Any("error", err),
+						zap.String("request", string(httpRequest)),
+					)
+				}
+				c.AbortWithStatus(http.StatusInternalServerError)
+			}
+		}()
+		c.Next()
+	}
+}

+ 1 - 1
http/route/root.go

@@ -20,7 +20,7 @@ func Root(opts ...func(engine *gin.Engine)) func(s *gin.Engine) {
 			middleware.Pagination(),
 			requestid.New(),
 			gzip.Gzip(gzip.DefaultCompression),
-			gin.Recovery(),
+			middleware.GinRecovery(true),
 		)
 	}
 }