gzip icon indicating copy to clipboard operation
gzip copied to clipboard

Gzip middleware breaks Recovery middleware setting the status code

Open segevfiner opened this issue 6 years ago • 3 comments

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 avatar Jul 09 '19 10:07 segevfiner

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.

segevfiner avatar Jul 15 '19 23:07 segevfiner

@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()
}

hmldd avatar Mar 10 '20 02:03 hmldd

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

pdeva avatar Dec 29 '21 10:12 pdeva