Patch release for 1.6.2. Recommended upgrade for anyone on 1.6.2 — it fixes a startup panic affecting any setup whose config disables a middleware that sits before blocklist in the chain (e.g. reflex, kubernetes, hostsfile).
What's Changed
Bug Fixes
- Fix
middleware.Get("name")returning the wrong handler when a disabled (typed-nil) middleware sits earlier in the chain. In 1.6.2 this causedpanic: interface conversion: middleware.Handler is *kubernetes.Kubernetes, not *blocklist.BlockListat startup whenever the API was enabled. The lookup now resolves by name against an O(1) map on an immutable compiled pipeline, so the index can no longer drift.
Performance
Redesigned the middleware package around an immutable Pipeline published via atomic.Pointer, and eliminated the per-query allocation inside responseWriter.Reset.
Microbenchmarks on Apple M4 / Go 1.26 for the realistic 15-handler production chain (BenchmarkChainNext/15):
| ns/op | B/op | allocs/op | |
|---|---|---|---|
| 1.6.2 | 79.3 | 32 | 2 |
| 1.6.3 | 32.8 | 0 | 0 |
That's ~58% faster per query walk with zero allocations on the hot path. At 100k QPS that removes ~200k allocs/s and ~3.2 MB/s of GC pressure per core. middleware.Get is ~4x faster (21.9 → 5.3 ns/op) though that's off the request path.
Internal
- Middleware package redesigned:
Registry+ immutablePipeline+ lock-freeatomic.Pointerreads; constructors no longer run under a write lock;Handlers()/Get()/Ready()are race-free by construction. All middleware packages kept their existing Handler API — no downstream changes. Chain.Nextdrops the unreachable modulo and the unusedtailfield.responseWriter.ResetreplacesRemoteAddr().String() == "127.0.0.255:0"with a direct IP+port compare against a preparsed sentinel.- Build badge in the README now points at
ci.ymlafter the workflow consolidation.
New Tests
Test_Get_SkipsDisabled— regression guard for the 1.6.2 crash.Test_Registry_Build_ConcurrentReads— race coverage for lock-free pipeline reads.BenchmarkChainNext,BenchmarkGet,BenchmarkGet_Legacy— so the performance numbers are reproducible.
Full Changelog: v1.6.2...v1.6.3