Description
While writing to response header in goroutines we get fatal error: concurrent map writes.
How to reproduce
package main
import (
"sync"
"github.com/gin-gonic/gin"
)
func setHeader(c *gin.Context) {
c.Header("key", "value")
}
func main() {
g := gin.Default()
g.GET("/hello", func(c *gin.Context) {
wg := sync.WaitGroup{}
go func() {
wg.Add(1)
defer wg.Done()
for i := 0; i < 100000; i++ {
setHeader(c)
}
}()
go func() {
wg.Add(1)
defer wg.Done()
for i := 0; i < 100000; i++ {
setHeader(c)
}
}()
wg.Wait()
})
g.Run(":9000")
}
Expectations
$ curl http://localhost:9000/hello
Should not crash
Actual result
fatal error: concurrent map writes
goroutine 25 [running]:
net/textproto.MIMEHeader.Set(...)
/opt/homebrew/Cellar/go/1.22.5/libexec/src/net/textproto/header.go:22
net/http.Header.Set(...)
/opt/homebrew/Cellar/go/1.22.5/libexec/src/net/http/header.go:40
github.com/gin-gonic/gin.(*Context).Header(0x0?, {0x1002fe555, 0x3}, {0x1002fedc8, 0x5})
/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.0/context.go:897 +0xb0
main.setHeader(...)
/Users/admin/repos/scripts/main.go:12
main.main.func1.1()
/Users/admin/repos/scripts/main.go:23 +0x94
created by main.main.func1 in goroutine 23
/Users/admin/repos/scripts/main.go:19 +0x7c
Environment
- go version: 1.22.0
- gin version (or commit ref): 1.10.0
- operating system: Linux amd64
Comment From: flc1125
For this reason, I suggest that the application side solve it.
https://github.com/gin-gonic/gin/pull/4101#issuecomment-2492897986