- With issues:
- Use the search tool before opening a new issue.
- Please provide source code and commit sha if you found a bug.
- Review existing issues and provide feedback or react to them.
Description
context.Copy() does not duplicate the request body source. So reading in the copied context closes the stream in the original context as well
How to reproduce
package main
import (
"github.com/gin-gonic/gin"
)
func main() {
g := gin.Default()
g.POST("/hello", func(c *gin.Context) {
go func(ccp *gin.Context) {
_, _ = ioutil.ReadAll(ccp.Request.Body)
}(c.Copy())
time.Sleep(50) // Let goroutine read the body
body, _ := ioutil.ReadAll(c.Request.Body)
c.String(200, "Hello. I got this request from you: %s", string(body))
})
g.Run(":9000")
}
Expectations
$ curl -X POST --location "http://localhost:9000/hello" \
-H "Content-Type: application/json" \
-d "{\"test\": \"value\"}"
Hello. I got this request from you: {"test": "value"}
Actual result
$ curl -X POST --location "http://localhost:9000/hello" \
-H "Content-Type: application/json" \
-d "{\"test\": \"value\"}"
Hello. I got this request from you:
Environment
- go version: 1.19
- gin version (or commit ref): v1.6.3
- operating system: Mac
Comment From: timandy
I think the author does not copy the body to save memory, and I agree with the author's design. If you want to pass the content of the body, you should read it first, and then pass the readed result in different coroutines.