Introduce a commercial license option alongside AGPL-3.0-only, require a CLA for contributors, and document the terms in COMMERCIAL.md and NOTICE. Add a script to stamp SPDX headers on Go files and apply it across the tree.
25 lines
1020 B
Go
25 lines
1020 B
Go
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Commercial
|
|
// SPDX-FileCopyrightText: 2025-2026 Christian Galo
|
|
|
|
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")
|
|
}
|
|
}
|