Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

go-http-middleware

CI Release Go Reference Go Report Card

Explicit, bounded server-side HTTP middleware built on net/http. The root package composes only the middleware supplied by the caller. There is no registry, router, server runtime, service container, background process, or global default chain.

Five-minute chain

must := func(value middleware.Middleware, err error) middleware.Middleware {
    if err != nil {
        panic(err) // Fail startup on invalid transport policy.
    }
    return value
}

ids := must(requestid.New(requestid.Policy{}))
recoverPanics := must(recovery.New(recovery.Policy{}))
limitBodies := must(bodylimit.New(bodylimit.Policy{MaxBytes: 1 << 20}))
security := must(secureheader.New(secureheader.APIDefaults()))

chain, err := middleware.New(
    recoverPanics,
    ids,
    limitBodies,
    security,
)
if err != nil {
    panic(err)
}
handler, err := chain.Handler(application)
if err != nil {
    panic(err)
}
if err := http.ListenAndServe(":8080", handler); err != nil {
    panic(err)
}

The first middleware receives the request first. The response returns through the list in reverse. Handler rejects nil terminals, invalid descriptors, and middleware that returns nil.

Independently importable middleware

Every subpackage returns the standard func(http.Handler) http.Handler shape:

limit, err := bodylimit.New(bodylimit.Policy{MaxBytes: 8 << 20})
if err != nil {
    return err
}
handler := limit(uploadHandler)

Importing the root does not import codecs, telemetry SDKs, authentication, authorization, rate limiting, idempotency, routing, or server lifecycle.

Packages

Package Owns Important boundary
root chains, descriptors, conditions 256-layer maximum
requestid request/correlation IDs inbound values untrusted by default
recovery panic containment never rewrites committed responses
bodylimit encoded request byte limit no payload decoding
deadline context and buffered handler timeouts no arbitrary-code interruption
proxy effective peer/host/scheme/prefix explicit trusted networks only
cors server CORS responses and preflights not authentication or CSRF
secureheader explicit response headers HSTS requires acknowledgement
compress bounded gzip negotiation buffered mode is not streaming
observe bounded completion events no raw path, query, body, or headers
content 406/415 media guards no encoder or decoder
admission local in-flight bounds not distributed rate limiting
responsepolicy no-store and readiness admission no response cache
adapter ownership names and overlap checks no sibling policy reimplementation
middlewaretest deterministic fixtures test-only behavior helpers

Recommended API order

recovery -> trusted proxy -> request ID -> observe -> CORS -> security headers -> admission -> deadline/body limit -> owning-package policies -> compression -> application

Order is application-specific. Compression must remain outside handlers whose already-encoded responses it should observe, and recovery must surround every layer whose panic it should contain. See the ordering reference.

Security posture

Defaults deny forwarding and inbound identifier trust. All configured header values reject controls. Parsing and retained buffers have explicit limits. These controls complement, but do not replace, ingress validation, server timeouts, TLS, request-header limits, authentication, authorization, CSRF defenses, or application validation.

Read SECURITY.md, the threat model, and deployment guidance before production use.

Compatibility

The minimum toolchain is Go 1.26.5. Normal tracking and header wrappers preserve the exact Flusher, Hijacker, Pusher, and ReaderFrom set of the underlying writer. Buffered timeout and compression intentionally do not expose streaming interfaces. See the complete matrix.

Development

make check

Every blocking CI command has a local target. make nilaway is advisory. Hosted release publication remains separate from local verification.

The CI badge covers the blocking quality, lint, staticcheck, and vulnerability jobs. Release verification repeats make check before a signed provenance attestation and release assets are published.

License

MIT. See LICENSE and NOTICE.

About

Composable server-side HTTP middleware with explicit ordering and transport-safe behavior.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages