Replace the old RunShutdown and RunTLS style entry points with a single Run(opts...) API for v1. Add focused startup semantics tests, keep TLS and graceful shutdown independent, ensure sibling servers are cleaned up on startup failure, and update docs to match the new option-based startup model.
Encode the built-in 404 and 405 payload with a fixed struct instead of a map so default error pages allocate less on the hot miss path. Add a regression test to keep the JSON shape stable.
Use safe string copies for pooled header buffers and simplify case-insensitive lookup buffering now that the pseudo stack path was ineffective. This addresses review concerns without changing the routing semantics.
Reuse fixed-path and Allow-header buffers so redirect and OPTIONS handling stop rebuilding temporary data on every request. Cache fallback chains and add regression coverage for redirect, 404, 405, and Allow behavior to keep the faster miss paths stable.
Make Context keys lazy so requests that never call Set stop allocating on reset. Reuse stable 404 and 405 handlers and add focused benchmarks so ServeHTTP miss paths stay measurable.
Avoid rebuilding skipped-node state during wildcard fallback so the matcher no longer loops on the same static branch and stops allocating on the hot path. Add focused route benchmarks and regression coverage to keep the optimized path stable.
- FileText: now respects the provided status code instead of defaulting to 200 OK
- Request body limits: prepareRequestBody() is now only called when MaxRequestBodySize > 0
- ShouldBindJSON, ShouldBindWANF, ShouldBindGOB, ShouldBindForm, GetReqBody, PostForm
all now use the original c.Request.Body path when no limit is configured
- maxBytesReader: fixed exact-limit boundary case where body size == limit was
incorrectly rejected
- Added regression tests for FileText status codes and body limit behavior
All existing tests pass, and new tests verify the corrected behavior.
- Remove fallback to HTML() on template rendering failure
- Return 500 error without writing any content on error
- Only fallback to HTML() when renderer is nil or unsupported type
- Prevents multiple response writes
Reduce code duplication by calling c.HTML() for fallback cases:
- When template rendering fails
- When HTMLRender is not configured
- When HTMLRender is not a *template.Template
This ensures consistent behavior between HTMLBuf and HTML methods.
Add buffered rendering methods that encode to a buffer first, then
write the response. This allows returning a proper 500 status code
if encoding fails, unlike the streaming variants which must write
the status code before encoding (an inherent HTTP constraint).
New methods:
- JSONBuf(code int, obj any)
- GOBBuf(code int, obj any)
- WANFBuf(code int, obj any)
- HTMLBuf(code int, name string, obj any)
Trade-off: one extra memory allocation per call in exchange for
correct error status codes on encoding failure.
Address PR review feedback:
- Capture w := c.Writer before goroutine start, use w (not c.Writer)
inside the goroutine to avoid holding *Context reference
- Move channel send into select alongside context cancellation in all
examples and tests, preventing goroutine leak when client disconnects
while blocked on unbuffered send
BREAKING CHANGE: EventStreamChan signature changed from
(chan<- Event, <-chan error)
to
(eventChan <-chan Event)
The caller now creates and passes the channel instead of receiving it.
The errChan return value is removed.
The old non-blocking design allowed the handler to return before the SSE
stream ended, causing ServeHTTP to return the Context to the pool while
the internal goroutine was still writing to the pooled writer — a data
race across requests. The new blocking design keeps the handler inside
EventStreamChan until the event channel is closed or the client
disconnects, ensuring the Context remains bound throughout the stream.
- Caller creates channel, producer goroutine sends events
- EventStreamChan blocks handler until stream ends
- Internal goroutine captures stable references (Flusher, context.Context)
instead of holding *Context pointer
- Nil guard on Flusher type assertion
- Add sse_test.go covering blocking, disconnect, and event format
- Update docs/sse.md for new API
Clarify that outgoing proxy queries are normalized before forwarding, which may re-encode or drop non-standard fragments to keep parsing behavior consistent across proxy chains.
Preserve final headers when forwarding 1xx responses, reject invalid 101 upgrade negotiations, and make the default Via token RFC-safe. Tighten the reverse proxy tests around goroutine synchronization and document the Via fallback behavior more clearly.
Document BufferPool usage and explain why trailer fallback and disconnect compatibility logic intentionally mirror the standard library reverse proxy. Add a regression test covering unannounced trailer forwarding so that proxy trailer behavior stays aligned with Go's semantics.