当服务器使用 gin-gonic 和 gin-contrib/gzip 发生恐慌时

当访问gin-gonic下面的服务器时,HTTP 客户端应该收到代码 500,但收到的代码是 200。


package main


import (

    "github.com/gin-contrib/gzip"

    "github.com/gin-gonic/gin"

)


func main() {

    gin.SetMode(gin.ReleaseMode)

    r := gin.New()

    r.Use(gin.Logger())

    r.Use(gin.Recovery())

    r.Use(gzip.Gzip(gzip.DefaultCompression))


    r.POST("/test", func(c *gin.Context) {

        panic("test")                        // Server panic and client should receive code 500.

    })


    r.Run(":8080")

}

从 HTTP 客户端访问/test时,go server 日志如下所示,看起来返回代码 500。


[GIN] 2020/09/28 - 10:23:14 | 500 |     67.2995ms |             ::1 | POST     "/test"


2020/09/28 10:23:14 [Recovery] 2020/09/28 - 10:23:14 panic recovered:

test

C:/path/to/myproject/main.go:16 (0x8f193f)

    main.func1: panic("test")

但是 HTTP 客户端收到代码 200。

http://img4.mukewang.com/62c2a4670001f62013930489.jpg

当我删除r.Use(gzip.Gzip(gzip.DefaultCompression))时,HTTP 客户端会收到代码 500。

为什么客户收到代码 200 r.Use(gzip.Gzip(gzip.DefaultCompression)),我该如何解决?


胡说叔叔
浏览 190回答 2
2回答

慕标琳琳

我已经复制了你的情况。邮递员得到代码 200,但服务器结果却是 500。服务器在收到 post 请求时会调用 c.Next() 来执行 4 个处理程序。顺序如下:gin.Loggergin.Recoverygzip.Gzip(gzip.DefaultCompression)your handler这是 gin responseWriter 写入响应头,它只会写入一次头。func (w *responseWriter) WriteHeaderNow() {    if !w.Written() {        w.size = 0        w.ResponseWriter.WriteHeader(w.status)    }}两者都gzip.Gzip(gzip.DefaultCompression)具有gin.Recovery延迟函数来写入响应标头。Golang 的延迟调用按后进先出的顺序执行。所以gzip.Gzip(gzip.DefaultCompression)会将响应头写入 200,并且gin.Recovery不会按预期将响应头写入 500。所以要解决这个问题,你应该改变处理程序的顺序,并确保gin.Recovery是最后加载的处理程序。

杨魅力

最后添加恢复中间件似乎可以解决这个问题。package mainimport (    "github.com/gin-contrib/gzip"    "github.com/gin-gonic/gin")func main() {    gin.SetMode(gin.ReleaseMode)    r := gin.New()    r.Use(gin.Logger())    r.Use(gzip.Gzip(gzip.DefaultCompression))    r.Use(gin.Recovery())    r.POST("/test", func(c *gin.Context) {        panic("test")                        // Server panic and client should receive code 500.    })    r.Run(":8080")}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go