gin-contrib / gzip

Gin middleware to enable GZIP support.
MIT License
329 stars 86 forks source link

Gzip middleware breaks Recovery middleware setting the status code #28

Open segevfiner opened 5 years ago

segevfiner commented 5 years ago

Build:

package main

import (
    "github.com/gin-contrib/gzip"
    "github.com/gin-gonic/gin"
)

func main() {
    r := gin.Default()
    r.Use(gzip.Gzip(gzip.DefaultCompression))
    r.GET("/", func(c *gin.Context) {
        panic("panic")
    })
    r.Run()
}

Run:

$ curl -v --compressed http://localhost:8080/
*   Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8080 (#0)
> GET / HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.54.0
> Accept: */*
> Accept-Encoding: deflate, gzip
> 
< HTTP/1.1 200 OK
< Content-Encoding: gzip
< Vary: Accept-Encoding
< Date: Tue, 09 Jul 2019 10:02:44 GMT
< Content-Length: 23
< Content-Type: application/x-gzip
< 
* Connection #0 to host localhost left intact

You get the following warning from Gin:

[GIN-debug] [WARNING] Headers were already written. Wanted to override status code 200 with 500
segevfiner commented 5 years ago

I think the cause is: https://github.com/gin-contrib/gzip/blob/aef065fb847d00a98c42db4173b7cba138112c9c/gzip.go#L44-L47 which happens before the Recovery middleware handles the panic and sets the status code, but I'm unsure on how to fix this.

hmldd commented 4 years ago

@segevfiner Try to move r.Use(gin.Recovery()) next to r.Use(gzip.Gzip(gzip.DefaultCompression)).

package main

import (
    "github.com/gin-contrib/gzip"
    "github.com/gin-gonic/gin"
)

func main() {
    r := gin.New()
    r.Use(gzip.Gzip(gzip.DefaultCompression))
    r.Use(gin.Recovery())
    r.Use(gin.Logger())

    r.GET("/", func(c *gin.Context) {
        panic("panic")
    })
    r.Run()
}
pdeva commented 2 years ago

i ran into this too. a config setting or some official documentation around this would be very helpful