package handler import ( "context" "encoding/json" "errors" "io" "net/http" "time" ) const ( defaultRequestTimeout = 2 * time.Minute reportRequestTimeout = 10 * time.Minute longRunningRequestTimeout = 2 * time.Hour defaultJSONBodyLimitBytes = 1 << 20 // 1 MiB ) func withRequestTimeout(r *http.Request, timeout time.Duration) (context.Context, context.CancelFunc) { base := context.Background() if r != nil { base = r.Context() } if timeout <= 0 { return base, func() {} } return context.WithTimeout(base, timeout) } func decodeJSONBody(w http.ResponseWriter, r *http.Request, dst any) error { if r == nil || r.Body == nil { return errors.New("request body is required") } decoder := json.NewDecoder(http.MaxBytesReader(w, r.Body, defaultJSONBodyLimitBytes)) if err := decoder.Decode(dst); err != nil { return err } var trailing any if err := decoder.Decode(&trailing); err != io.EOF { if err == nil { return errors.New("request body must contain only one JSON object") } return err } return nil }