mirror of
https://github.com/gotenberg/gotenberg.git
synced 2026-08-12 02:12:15 +01:00
fix(webhook): detach async goroutine from pooled echo.Context
This commit is contained in:
@@ -334,13 +334,38 @@ func webhookMiddleware(w *Webhook) api.Middleware {
|
||||
|
||||
// As a webhook URL has been given, we handle the request in a
|
||||
// goroutine and return immediately.
|
||||
//
|
||||
// Echo returns the echo.Context back to its sync.Pool as
|
||||
// soon as this synchronous handler returns ErrAsyncProcess.
|
||||
// A concurrent request can then claim the recycled context
|
||||
// and c.Reset() wipes the shared store, which would cause
|
||||
// any c.Get("...").(T) assertion downstream of the webhook
|
||||
// goroutine to panic on a nil value and crash the process.
|
||||
// Snapshot the keys downstream reads onto a detached
|
||||
// wrapper before spawning the goroutine so pool reuse
|
||||
// cannot reach into our async work.
|
||||
detached := newPoolSafeContext(c, "logger", "context", "correlationId", "correlationIdHeader", "startTime")
|
||||
|
||||
w.asyncCount.Add(1)
|
||||
go func() {
|
||||
defer cancel()
|
||||
defer w.asyncCount.Add(-1)
|
||||
|
||||
// Defense in depth: any panic that escapes the
|
||||
// downstream chain (including future regressions of
|
||||
// the pool-reuse bug) routes through handleError and
|
||||
// leaves the process running.
|
||||
defer func() {
|
||||
r := recover()
|
||||
if r == nil {
|
||||
return
|
||||
}
|
||||
ctx.Log().Error(fmt.Sprintf("webhook goroutine panic: %v", r))
|
||||
handleError(fmt.Errorf("internal error: %v", r))
|
||||
}()
|
||||
|
||||
// Call the next middleware in the chain.
|
||||
err := next(c)
|
||||
err := next(detached)
|
||||
if err != nil {
|
||||
if errors.Is(err, api.ErrNoOutputFile) {
|
||||
errNoOutputFile := fmt.Errorf("%w - the webhook middleware cannot handle the result of this route", err)
|
||||
|
||||
Reference in New Issue
Block a user