gin-gonic / gin

Gin is a HTTP web framework written in Go (Golang). It features a Martini-like API with much better performance -- up to 40 times faster. If you need smashing performance, get yourself some Gin.
https://gin-gonic.com/
MIT License
78.83k stars 8.02k forks source link

Explicit handle gzipped json #2931

Closed Moulick closed 2 months ago

Moulick commented 3 years ago

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

dstracab commented 2 months ago

@Moulick In case you still have this problem, take a look at https://github.com/gin-contrib/gzip.

Moulick commented 2 months ago

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. ¯\_(ツ)_/¯