I am trying to use context#BindJSON but it returns EOF. If I replace it with a JSON Decoder it works fine.
A sample of the code: http://hastebin.com/torosarosi.go
Anyone know as to why it may be returning EOF?
Comment From: erizocosmico
Can you provide an example of the JSON you're using?
Comment From: renannprado
Using the latest version of Gin I sometimes Get EOF error too while doing ctx.Bind(&myStruct)
and it's intermittent.
Struct that I am using:
type LocationRequest struct {
RestaurantId uint `json:"restaurantId"`
Latitude float64 `json:"latitude"`
Longitude float64 `json:"longitude"`
Reference string `json:"reference"`
}
Comment From: nscarlson
Same problem here!
Comment From: tboerger
Without further details it's hard to reproduce such an issue, for my cases it works totally fine.
Comment From: vjeantet
Hello, i had this issue too, the problem occurs when i read from the Request Body twice.
Comment From: pkix
Hi all, it's just need to comment the code in BindWith method of context.go file, then it will not show two or more errors json structs , you can handle the error response on your side.
//c.AbortWithError(400, err).SetType(ErrorTypeBind)
Comment From: ramabmtr
Hi all, I just realized that when I validate JSON using c.BindJSON
and that JSON is not a valid JSON, EOF
will returned.
This happen because Gin will try to decode that JSON first using json.NewDecoder(req.Body).Decode(obj)
before validating.
Can you try validate your JSON first are they valid or not?
for @vjeantet issue, read request body (c.Request.Body
) before validating will trigger EOF
too because after you read request body, it will closed automatically by system. This will affect BindJSON
to return EOF
because request body is not present anymore.
Please CMIIW, I'm quite new at Golang 😄 and sorry for my english
Comment From: dlb233
Same problem. it will happened when I use Decoder.Decode after ctx.Bind. Guess it's because of the former function will mark a terminated sign to the Context or something like that, so the second function returns EOF.
How can I receive the other parameter that do not exist at the parameter struct if I can only read context once?
I'm a green hand of golang, this question confused me a lot.
Comment From: rmrf
same issue, then find the reason,
I have a ioutils read c.Request.Body
before the BindJson, after delete the ioutil read, issue gone.
Comment From: lucabelluccini
The BindJSON is reading the body, so we are at EOF if the context Body get read multiple times.
What would be the best approach? Storing it somewhere?
Comment From: yunfengsay
same to me
Comment From: delphinus
@yunfengsay Your example seems to load JSON from body, but body is none because it is GET request. GET request should have no body.
https://stackoverflow.com/questions/978061/http-get-with-request-body
Yes, you can send a request body with GET but it should not have any meaning.
Comment From: chunbaise
I had this issue too, the problem occurs when i read from the Request Body twice. What would be the best approach? Thanks
Comment From: rksh1997
I have this issue too when I read from the request body more than once.
Comment From: ruanyanghui
You can try Copy()
Comment From: thinkerou
Hi, all, please use ShouldBindBodyWith
and see #1341 details which have fixed the issue, thanks!
Comment From: yw4c
Cloning the context is work for me
return func(context *gin.Context) {
c := *context
context.Next()
databyte, err := c.GetRawData()
var req string
if err != nil && len(databyte) == 0 {
req = ""
}
req = string(databyte)
log.Info().
Str("path", c.Request.URL.Path).
Str("method", c.Request.Method).
Str("request-id", c.Request.Header.Get("x-request-id")).
Str("request-data", req).
Interface("header", c.Request.Header).
Int("response-status",context.Writer.Status()).
Msg("Access Log")
}
Comment From: lzhpo
I guess you requestBody maybe not JSON, so you get EOF error.
You can use ShouldBind
instead of BindJSON
.
userReq := &user.PageUserReq{}
err := c.ShouldBind(userReq)
Comment From: ZhangDongling
unexpected EOF
may be caused by that:
In your request header, the value of Content-Length
is smaller than the actual length of request body.
Just remove the Content-Length
in the request header and it will work well.
Comment From: krystalics
Hello, i had this issue too, the problem occurs when i read from the Request Body twice. yes 、I just have the same issue, I think the data stream has been read out , and the second time it will read the EOF directly. When I remove the first bind , the other one works well! maybe it can reset the cursor in the body stream? very common operation
json := make(map[string]interface{})
c.BindJSON(&json)
bodyStr, _ := jsoniter.MarshalToString(json)
Comment From: JulioCRFilho
Hello, i had this issue too, the problem occurs when i read from the Request Body twice.
This is the right answer, my middleware that prints the request body was causing the problem, seems foolish but it's true lol
Comment From: axoxymous-coder
I encountered a similar situation of EOF
while doing something as below:
1. Read the request body into a []byte (using io.ReadAll)
2. Validate the request body against a JSON Schema (using gojsonschema library)
3. If Validation passes, bind the request body to a struct (using Gin's c.ShouldBindJSON)
Gin's context copy()
method did not work as intended. So, all I had to do was to refill c.Request.Body with the original content as below:
jsonData, err := io.ReadAll(c.Request.Body)
if err != nil {
// handle error
}
if err = validateSchema(string(jsonData)); err != nil {
// handle error
}
c.Request.Body = io.NopCloser(bytes.NewBuffer(jsonData))
if err = c.ShouldBindJSON(&p); err != nil {
// handle error
}
Is there a better alternative (if any) than what I am doing?
Comment From: aminNazarii
this issue occurs when you read body data twice.
with ShouldBindBodyWith
method you can copy of body and solve EOF error.
like this
var req NewRequest
if err := ctx.ShouldBindBodyWith(&req, binding.JSON); err != nil {
// do something
}