1

I'm getting empty file when I try to read the request body of my HTTP request using Go Gin. On my request I'm sending a file attached to the Request Body (Content Type: application/octet-stream).

Request Headers
Authorization: Bearer XXX
User-Agent: PostmanRuntime/7.29.0
Accept: */*
Postman-Token: XXX
Host: localhost:8080
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Content-Length: 12
Content-Type: application/octet-stream
Request Body
src: "Path to my file"

Backend Go code:

bodySize, _ = strconv.ParseInt(c.Request.Header.Get("Content-Length"), 10, 64)
buf := bytes.NewBuffer(make([]byte, 0, bodySize))
_, err = io.Copy(buf, c.Request.Body)
fmt.Println(buf.String())

The print sentence prints empty string but the file is not empty (Content Length is 12).

10
  • I don't see anything wrong with your code. can you debug the bodySize and request's body to ensure it has some value?
    – novalagung
    Commented Apr 27, 2022 at 15:44
  • What I can see debugging is that buf value is: []uint8 len: 0, cap: 12, [] when I initialize it and after the copy changes to: []uint8 len: 0, cap: 536, [] but still empty...
    – Loren
    Commented Apr 27, 2022 at 15:50
  • 1
    that's mean the request body contains no data
    – novalagung
    Commented Apr 27, 2022 at 16:08
  • 1
    is there any middleware that might potentially read the request body?
    – novalagung
    Commented Apr 27, 2022 at 16:09
  • 2
    If you already read the body, then of course there is no longer anything to read in the body.
    – JimB
    Commented Apr 27, 2022 at 16:21

1 Answer 1

1

@novalagung yes, I'm reading it in a middleware before the main function, after the middleware the execution continues with c.Next() . In the middleware the reading works fine. –

The http.Request.Body will be empty after you read its content. You will need to store the request body somewhere after being read, so you do not need to read it twice.


Or, there is another alternative workaround, you can put back the content into the req.Body after reading it.

// middleware do read the body
bodyBytes, _ := ioutil.ReadAll(req.Body)
req.Body.Close()  //  must close

// put back the bodyBytes to req.Body
req.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes))

But I do not recommend it!

Not the answer you're looking for? Browse other questions tagged or ask your own question.