RRuna

Timeout Middleware

Set a maximum duration for normal HTTP requests

middleware/timeout creates a timeout context.Context for the request and returns 408 Request Timeout when the request exceeds the configured duration. It protects normal HTTP APIs from slow requests occupying connections and goroutines for too long.

Install

go get github.com/duxweb/runa/middleware

Basic usage

import "github.com/duxweb/runa/middleware/timeout"

route.Default().Use(timeout.New())

The default timeout is 30s, and the default response text is request timeout.

Custom timeout

route.Default().Use(timeout.New(timeout.Config{
    Timeout: 10 * time.Second,
    Message: "request timeout",
}))

Skip long-running routes

route.Default().Use(timeout.New(timeout.Config{
    Timeout: 5 * time.Second,
    Next: func(ctx *route.Context) bool {
        return ctx.Request().URL.Path == "/exports"
    },
}))

Export, upload, SSE, and long-polling requests may not fit a short global timeout. Use Next to skip them and design timeout behavior separately.

WebSocket and Upgrade

WebSocket and other Upgrade requests skip timeout automatically. These are long-lived connections and should not be treated like normal HTTP requests.

Config fields

Field Type Default Description
Next func(*route.Context) bool nil Skip when true
Timeout time.Duration 30 * time.Second Max request duration
Message string request timeout Timeout response body

Relationship with context

Handlers should pass ctx.Context() to databases, caches, HTTP clients, and other downstream calls:

route.Default().Get("/users", func(ctx *route.Context) error {
    users, err := service.ListUsers(ctx.Context())
    if err != nil {
        return err
    }
    return ctx.JSON(users)
})

Then downstream calls can stop when timeout triggers.

Relationship with security

security.New(...) includes timeout by default. Production uses 30s, and development uses 120s. Adjust it like this:

route.Default().Use(security.New(
    security.Production(),
    security.Timeout(15*time.Second),
))

Common problems

  • timeout cannot forcibly kill already-running business code; it cancels request context and stops normal response flow.
  • If a handler writes a response after timeout, the write is discarded or invalid.
  • Be careful with global timeout on WebSocket, SSE, and long-running task routes.
Edit this page