valyala / fasthttp

Fast HTTP package for Go. Tuned for high performance. Zero memory allocations in hot paths. Up to 10x faster than net/http
MIT License
21.66k stars 1.75k forks source link

A problem caused by fasthttpadaptor when coding with gin #1501

Closed duduchristian closed 1 year ago

duduchristian commented 1 year ago

Senario:

m := map[string]struct{}{}
var lock sync.Mutex
engine := gin.Default()
engine.GET("/test/:param", func(c *gin.Context){
    p := c.Param("param")
    lock.Lock()
    m[p] = struct{}{}
    lock.Unlock()
})
if err := fasthttp.ListenAndServe(":8080", fasthttpadaptor.NewFastHTTPHandler(gin.Handler())); err != nil {
    panic(err)
}

Call /test/param1 and /test/abc respectively for several times, you can see there are entries in m like abcam1. I think the problem is caused by the b2s function in request.go which makes the params obtained by gin in different calls pointing to the same byte slice: https://github.com/valyala/fasthttp/blob/2ab79063af85601f532e85c3071c7f993b92fba5/fasthttpadaptor/request.go#L69-L72

li-jin-gou commented 1 year ago

refer to image

VERY IMPORTANT! Fasthttp disallows holding references to [RequestCtx](https://pkg.go.dev/github.com/valyala/fasthttp#RequestCtx) or to its' members after returning from [RequestHandler](https://pkg.go.dev/github.com/valyala/fasthttp#RequestHandler). Otherwise [data races](http://go.dev/blog/race-detector) are inevitable. Carefully inspect all the net/http request handlers converted to fasthttp whether they retain references to RequestCtx or to its' members after returning.

in https://github.com/valyala/fasthttp#switching-from-nethttp-to-fasthttp