Edited at

Ginのリクエストボディはストリーム

Ginで受け取れるリクエストボディはストリームなので、一度Readメソッドなどで読み出してしまうと空っぽになってしまう。従って、BindJSONなどのメソッドを読み出した後に使用するとEOFエラーが発生することがある。たとえば以下。

package main

import (
"fmt"
"github.com/gin-gonic/gin"
)

func main() {
router := gin.New()

router.POST("hoge", func(c *gin.Context) {
buf := make([]byte, 2048)
n, _ := c.Request.Body.Read(buf) // ここでRequest.Bodyを読み切ってしまっている
b := string(buf[0:n])
fmt.Println(b)

var params RequestParams

// BindJSONは内部でRequest.Bodyを再び読み出そうとするが
// Request.Bodyはすでに読み出されて空になっているため、ここでEOFエラーになる
if err := c.BindJSON(&params); err != nil {
uc.Warningf("Failed binding request parameters: %s", err.Error())
c.Status(http.StatusBadRequest)
return
}

c.JSON(200, params)
})

router.Run()
}

対策としては、ioutil.NopCloserメソッドを使って読み出してしまったリクエストボディを書き戻すなど。

 buf := make([]byte, 2048)

n, _ := c.Request.Body.Read(buf)
b := string(buf[0:n])
c.Request.Body = ioutil.NopCloser(bytes.NewBuffer([]byte(s)))
fmt.Println(b)

https://stackoverflow.com/questions/47990026/gin-if-request-body-bound-in-middleware-c-request-body-become-0