package middleware import ( "net/http" "time" ) // Timeout caps each request's handler time at the application level, on top // of http.Server's network-level ReadTimeout/WriteTimeout. It wraps net/http's // TimeoutHandler: the handler runs with a deadline-carrying context, and once // the deadline passes the client gets a 503 while any late writes from the // handler goroutine are rejected with http.ErrHandlerTimeout. The previous // hand-rolled version wrote the timeout response concurrently with the // still-running handler goroutine — a concurrent map write on the header map // that crashed the whole process ("fatal error: concurrent map read and map // write") whenever a request outlived the deadline mid-write. func Timeout(duration time.Duration) Middleware { return func(next http.Handler) http.Handler { return http.TimeoutHandler(next, duration, "Request timed out") } }