Description
I want to write an api that will be sent gzipped json data with POST. While the below can deal with simple json in the body, it does not deal if the json is gzipped. Do we need to explicitly handle the decompression before using c.ShouldBindJSON
?
How to reproduce
package main
import (
"github.com/gin-gonic/gin"
"log"
"net/http"
)
func main() {
r := gin.Default()
r.POST("/postgzip", func(c *gin.Context) {
type PostData struct {
Data string `binding:"required" json:"data"`
}
var postdata PostData
if err := c.ShouldBindJSON(&postdata); err != nil {
log.Println("Error parsing request body", "error", err)
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
log.Printf("%s", postdata)
if !c.IsAborted() {
c.String(200, postdata.Data)
}
})
r.Run()
}
❯ echo '{"data" : "hello"}' | curl -X POST -H "Content-Type: application/json" -d @- localhost:8080/postgzip
hello
Expectations
$ echo '{"data" : "hello"}' |gzip | curl -v -i -X POST -H "Content-Type: application/json" -H "Content-Encoding: gzip" --data-binary @- localhost:8080/postgzip
hello
Actual result
$ echo '{"data" : "hello"}' | gzip | curl -v -i -X POST -H "Content-Type: application/json" -H "Content-Encoding: gzip" --data-binary @- localhost:8080/postgzip
{"error":"invalid character '\\x1f' looking for beginning of value"}
Environment
- go version:
go version go1.17.2 darwin/amd64
- gin version (or commit ref):
v1.7.4
- operating system: MacOS Monterey
Comment From: dstracab
@Moulick In case you still have this problem, take a look at https://github.com/gin-contrib/gzip.
Comment From: Moulick
Thanks @dstracab. Checking back on my code now, it looks like I wrote my own? https://github.com/Moulick/kinesis2elastic/blob/main/gzipbinding/binding.go. Been a few years so I can't remember why I did not use https://github.com/gin-contrib/gzip but there must have been some reason. I think in my case the request could come both ways, as gzip or as direct json so I also had to write some detection. ¯\_(ツ)_/¯