No description
Find a file
juancwu b26ef7439e add realip, requestlog, recoverer middlewares
Initial implementation of lightmux-contrib, a sibling module to
lightmux that hosts opinionated middlewares with one sub-package per
middleware:

- realip: resolves the originating client IP from CF-Connecting-IP,
  True-Client-IP, X-Real-IP, or X-Forwarded-For. Optional peer-CIDR
  allowlist via netip.Prefix.
- requestlog: emits a structured http.request record (method, path,
  status, duration, client) per request via splinter.
- recoverer: catches panics, wraps with errx under op "recoverer",
  logs with stack, and writes a 500 response.

Each package exposes a single New(...) constructor returning
func(http.Handler) http.Handler. The contrib module intentionally
does not import lightmux — middlewares interoperate via the standard
stdlib middleware shape.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 14:03:04 +00:00
realip add realip, requestlog, recoverer middlewares 2026-04-26 14:03:04 +00:00
recoverer add realip, requestlog, recoverer middlewares 2026-04-26 14:03:04 +00:00
requestlog add realip, requestlog, recoverer middlewares 2026-04-26 14:03:04 +00:00
.gitignore Initial commit 2026-04-26 13:13:27 +00:00
go.mod add realip, requestlog, recoverer middlewares 2026-04-26 14:03:04 +00:00
go.sum add realip, requestlog, recoverer middlewares 2026-04-26 14:03:04 +00:00
LICENSE Initial commit 2026-04-26 13:13:27 +00:00
README.md add realip, requestlog, recoverer middlewares 2026-04-26 14:03:04 +00:00
Taskfile.yml add realip, requestlog, recoverer middlewares 2026-04-26 14:03:04 +00:00

lightmux-contrib

Opinionated middleware collection for lightmux. Each middleware lives in its own sub-package so consumers only pull in the dependencies they actually use.

Installation

go get git.juancwu.dev/juancwu/lightmux-contrib

Packages

realip

Replaces r.RemoteAddr with the originating client IP from CF-Connecting-IP, True-Client-IP, X-Real-IP, or X-Forwarded-For (in that order).

import "git.juancwu.dev/juancwu/lightmux-contrib/realip"

mux.Use(realip.New())                                    // always trust headers
mux.Use(realip.New(netip.MustParsePrefix("10.0.0.0/8"))) // gated by peer CIDR

With no arguments, realip.New() always honors the proxy headers — only register it when the service sits behind a trusted proxy. With one or more netip.Prefix arguments, the headers are honored only when the immediate peer's IP falls within one of them.

requestlog

Emits a structured http.request record (method, path, status, duration, client) per request via splinter.

import "git.juancwu.dev/juancwu/lightmux-contrib/requestlog"

mux.Use(requestlog.New(nil))    // splinter.Default() resolved at request time
mux.Use(requestlog.New(custom)) // custom *splinter.Logger

When pairing with realip, register realip first so the client field is the resolved client IP rather than the proxy peer:

mux.Use(realip.New(), requestlog.New(nil))

recoverer

Catches panics inside handlers, wraps the value with errx under op recoverer, logs it with stack via the standard log package, and writes a 500 response.

import "git.juancwu.dev/juancwu/lightmux-contrib/recoverer"

mux.Use(recoverer.New())