template: Race Condition in GoFiber HTML/Template render

Hello Gofiber team,

First of all, thank you all for making a great product.

I have encountered a problem that I believe is very serious with gofiber’s html package.

I use the sample of the package at https://github.com/gofiber/template, no problem happens. But when I added the layout path to the first router handle, race conditions occurred.

app.Get("/", func(c *fiber.Ctx) error {
		// Render index
		return c.Render("index", fiber.Map{
			"Title": "Hello, World!",
		}, "layouts/main")
})

I use the package https://github.com/tsliwowicz/go-wrk to test. The result is as follows:

==================
WARNING: DATA RACE
Read at 0x00c0003ae000 by goroutine 16:
  github.com/gofiber/fiber/v2/internal/bytebufferpool.(*ByteBuffer).Write()
      C:/Users/TungDT/go/pkg/mod/github.com/gofiber/fiber/v2@v2.9.0/internal/bytebufferpool/bytebuffer.go:73 +0x45
  text/template.(*state).walk()
      C:/Program Files/Go/src/text/template/exec.go:271 +0x763
  text/template.(*state).walk()
      C:/Program Files/Go/src/text/template/exec.go:264 +0x1ad
  text/template.(*Template).execute()
      C:/Program Files/Go/src/text/template/exec.go:220 +0x2fe
  text/template.(*Template).Execute()
      C:/Program Files/Go/src/text/template/exec.go:203 +0xda
  html/template.(*Template).Execute()
      C:/Program Files/Go/src/html/template/template.go:124 +0x8a
  github.com/gofiber/template/html.(*Engine).Render.func1()
      C:/Users/TungDT/go/pkg/mod/github.com/gofiber/template@v1.6.9/html/html.go:208 +0x70
  runtime.call16()
      C:/Program Files/Go/src/runtime/asm_amd64.s:550 +0x44
  reflect.Value.Call()
      C:/Program Files/Go/src/reflect/value.go:337 +0xe4
  text/template.safeCall()
      C:/Program Files/Go/src/text/template/funcs.go:365 +0xf9
  text/template.(*state).evalCall()
      C:/Program Files/Go/src/text/template/exec.go:725 +0x6ee
  text/template.(*state).evalFunction()
      C:/Program Files/Go/src/text/template/exec.go:580 +0x1de
  text/template.(*state).evalCommand()
      C:/Program Files/Go/src/text/template/exec.go:467 +0x1ac
  text/template.(*state).evalPipeline()
      C:/Program Files/Go/src/text/template/exec.go:436 +0x224
  text/template.(*state).walk()
      C:/Program Files/Go/src/text/template/exec.go:255 +0x571
  text/template.(*state).walk()
      C:/Program Files/Go/src/text/template/exec.go:264 +0x1ad
  text/template.(*Template).execute()
      C:/Program Files/Go/src/text/template/exec.go:220 +0x2fe
  text/template.(*Template).Execute()
      C:/Program Files/Go/src/text/template/exec.go:203 +0xda
  html/template.(*Template).Execute()
      C:/Program Files/Go/src/html/template/template.go:124 +0x8a
  github.com/gofiber/template/html.(*Engine).Render()
      C:/Users/TungDT/go/pkg/mod/github.com/gofiber/template@v1.6.9/html/html.go:211 +0x3a6
  github.com/gofiber/fiber/v2.(*Ctx).Render()
      C:/Users/TungDT/go/pkg/mod/github.com/gofiber/fiber/v2@v2.9.0/ctx.go:875 +0x1cf
  main.main.func1()
      D:/WORK/SelfServe/selfserve.project/test/main.go:24 +0x14e
  github.com/gofiber/fiber/v2.(*App).next()
      C:/Users/TungDT/go/pkg/mod/github.com/gofiber/fiber/v2@v2.9.0/router.go:127 +0x441
  github.com/gofiber/fiber/v2.(*App).handler()
      C:/Users/TungDT/go/pkg/mod/github.com/gofiber/fiber/v2@v2.9.0/router.go:155 +0x1e4
  github.com/gofiber/fiber/v2.(*App).handler-fm()
      C:/Users/TungDT/go/pkg/mod/github.com/gofiber/fiber/v2@v2.9.0/router.go:143 +0x64
  github.com/valyala/fasthttp.(*Server).serveConn()
      C:/Users/TungDT/go/pkg/mod/github.com/valyala/fasthttp@v1.23.0/server.go:2207 +0x1db6
  github.com/valyala/fasthttp.(*Server).serveConn-fm()
      C:/Users/TungDT/go/pkg/mod/github.com/valyala/fasthttp@v1.23.0/server.go:1984 +0x6a
  github.com/valyala/fasthttp.(*workerPool).workerFunc()
      C:/Users/TungDT/go/pkg/mod/github.com/valyala/fasthttp@v1.23.0/workerpool.go:223 +0x10b
  github.com/valyala/fasthttp.(*workerPool).getCh.func1()
      C:/Users/TungDT/go/pkg/mod/github.com/valyala/fasthttp@v1.23.0/workerpool.go:195 +0x49

Previous write at 0x00c0003ae000 by goroutine 17:
  github.com/gofiber/fiber/v2/internal/bytebufferpool.(*ByteBuffer).Write()
      C:/Users/TungDT/go/pkg/mod/github.com/gofiber/fiber/v2@v2.9.0/internal/bytebufferpool/bytebuffer.go:73 +0xc4
  text/template.(*state).walk()
      C:/Program Files/Go/src/text/template/exec.go:271 +0x763
  text/template.(*state).walk()
      C:/Program Files/Go/src/text/template/exec.go:264 +0x1ad
  text/template.(*Template).execute()
      C:/Program Files/Go/src/text/template/exec.go:220 +0x2fe
  text/template.(*Template).Execute()
      C:/Program Files/Go/src/text/template/exec.go:203 +0xda
  html/template.(*Template).Execute()
      C:/Program Files/Go/src/html/template/template.go:124 +0x8a
  github.com/gofiber/template/html.(*Engine).Render()
      C:/Users/TungDT/go/pkg/mod/github.com/gofiber/template@v1.6.9/html/html.go:211 +0x3a6
  github.com/gofiber/fiber/v2.(*Ctx).Render()
      C:/Users/TungDT/go/pkg/mod/github.com/gofiber/fiber/v2@v2.9.0/ctx.go:875 +0x1cf
  main.main.func1()
      D:/WORK/SelfServe/selfserve.project/test/main.go:24 +0x14e
  github.com/gofiber/fiber/v2.(*App).next()
      C:/Users/TungDT/go/pkg/mod/github.com/gofiber/fiber/v2@v2.9.0/router.go:127 +0x441
  github.com/gofiber/fiber/v2.(*App).handler()
      C:/Users/TungDT/go/pkg/mod/github.com/gofiber/fiber/v2@v2.9.0/router.go:155 +0x1e4
  github.com/gofiber/fiber/v2.(*App).handler-fm()
      C:/Users/TungDT/go/pkg/mod/github.com/gofiber/fiber/v2@v2.9.0/router.go:143 +0x64
  github.com/valyala/fasthttp.(*Server).serveConn()
      C:/Users/TungDT/go/pkg/mod/github.com/valyala/fasthttp@v1.23.0/server.go:2207 +0x1db6
  github.com/valyala/fasthttp.(*Server).serveConn-fm()
      C:/Users/TungDT/go/pkg/mod/github.com/valyala/fasthttp@v1.23.0/server.go:1984 +0x6a
  github.com/valyala/fasthttp.(*workerPool).workerFunc()
      C:/Users/TungDT/go/pkg/mod/github.com/valyala/fasthttp@v1.23.0/workerpool.go:223 +0x10b
  github.com/valyala/fasthttp.(*workerPool).getCh.func1()
      C:/Users/TungDT/go/pkg/mod/github.com/valyala/fasthttp@v1.23.0/workerpool.go:195 +0x49

Goroutine 16 (running) created at:
  github.com/valyala/fasthttp.(*workerPool).getCh()
      C:/Users/TungDT/go/pkg/mod/github.com/valyala/fasthttp@v1.23.0/workerpool.go:194 +0x1c4
  github.com/valyala/fasthttp.(*workerPool).Serve()
      C:/Users/TungDT/go/pkg/mod/github.com/valyala/fasthttp@v1.23.0/workerpool.go:147 +0x6a6
  github.com/valyala/fasthttp.(*Server).Serve()
      C:/Users/TungDT/go/pkg/mod/github.com/valyala/fasthttp@v1.23.0/server.go:1737 +0x6b5
  github.com/gofiber/fiber/v2.(*App).Listen()
      C:/Users/TungDT/go/pkg/mod/github.com/gofiber/fiber/v2@v2.9.0/app.go:602 +0x13c
  main.main()
      D:/WORK/SelfServe/selfserve.project/test/main.go:36 +0x211

Goroutine 17 (running) created at:
  github.com/valyala/fasthttp.(*workerPool).getCh()
      C:/Users/TungDT/go/pkg/mod/github.com/valyala/fasthttp@v1.23.0/workerpool.go:194 +0x1c4
  github.com/valyala/fasthttp.(*workerPool).Serve()
      C:/Users/TungDT/go/pkg/mod/github.com/valyala/fasthttp@v1.23.0/workerpool.go:147 +0x6a6
  github.com/valyala/fasthttp.(*Server).Serve()
      C:/Users/TungDT/go/pkg/mod/github.com/valyala/fasthttp@v1.23.0/server.go:1737 +0x6b5
  github.com/gofiber/fiber/v2.(*App).Listen()
      C:/Users/TungDT/go/pkg/mod/github.com/gofiber/fiber/v2@v2.9.0/app.go:602 +0x13c
  main.main()
      D:/WORK/SelfServe/selfserve.project/test/main.go:36 +0x211

How do I fix this problem?

Also, is there a way to define the layout path one time only to avoid re-define it again inside Render function?

Thanks!

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 3
  • Comments: 21 (11 by maintainers)

Commits related to this issue

Most upvoted comments

for the fix in version 1.17 they also used mutex locks^^ https://go-review.googlesource.com/c/go/+/316669/2/src/text/template/template.go https://go-review.googlesource.com/c/go/+/316669/2/src/text/template/exec.go

because i think it can also come to problems when users register own functions