Match net/http behavior when requests or responses contain both
Content-Length and Transfer-Encoding.
Parse and validate Content-Length even when Transfer-Encoding is present, so
invalid lengths are rejected. For valid Content-Length with chunked
Transfer-Encoding, keep chunked framing as authoritative. Also apply the same
precedence when RequestHeader.DisableSpecialHeader is used.
Reject HTTP/1.1 response Transfer-Encoding values unless they are a single
chunked header, matching net/http's strict transfer parser behavior.
This prevents arbitrary or compound response Transfer-Encoding values from
being silently normalized to chunked and avoids desync/body parsing ambiguity
when parsing upstream responses.
Reject space and tab between the chunk-size and chunk-extension separator while
preserving net/http-compatible trailing OWS before CRLF.
This avoids parser divergence for chunk lines such as "3 ;ext\r\n" without
breaking the existing acceptance of padded chunk-size lines like "3 \r\n".
Add parser regression coverage for both accepted and rejected forms.
* feat: add ExpectHandler for richer Expect: 100-continue handling
ContinueHandler only returns a bool, limiting the server to either
accepting (100) or rejecting with 417. ExpectHandler allows returning
any HTTP status code, and closes the connection on rejection since
the client may have already started sending body data per RFC 9110.
ExpectHandler takes precedence when both handlers are set.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* refactor: use *RequestCtx in ExpectHandler for richer access
Allows callers to inspect RemoteAddr, TLS state, or any other
connection metadata alongside headers, addressing reviewer feedback.
Documents that the response must not be modified by the handler.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* Update server.go
Co-authored-by: Erik Dubbelboer <erik@dubbelboer.com>
* Update server.go
Co-authored-by: Erik Dubbelboer <erik@dubbelboer.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Erik Dubbelboer <erik@dubbelboer.com>
Prevent cookie APIs from serializing embedded CR or LF bytes into
Cookie and Set-Cookie header lines.
Route Cookie key, value, domain, and path setters, parsed cookie
fields, and RequestHeader/ResponseHeader SetCookie paths through the
existing newline sanitization. Sanitize paths after normalization so
percent-decoded CR/LF bytes cannot bypass the guard.
Thanks to @vnykmshr for reporting this issue.
When KeepHijackedConns is enabled, the hijacked connection may outlive the
HijackHandler. The wrapper continues reading through the buffered reader
after the handler returns, so returning that reader to the pool can let
another connection reset it while the hijacked connection is still in use.
Keep the buffered reader owned by the escaped hijacked connection in
keep-open mode. Add a regression test that forces reader-pool reuse
and verifies buffered data remains available after the handler returns.
Route RequestCtx.Redirect Location updates through the canonical response
header setter so CR and LF bytes are normalized before serialization.
Add regression coverage for query-only and fragment-only redirects containing
CRLF, and verify the serialized response cannot emit an injected header line.
Reject request header field names with whitespace immediately before the
colon instead of trimming them before special-header handling.
This prevents parser differentials for malformed framing and routing
headers such as Content-Length, Transfer-Encoding, and Host when a frontend
forwards raw invalid request headers.
Keep the existing response and trailer compatibility behavior unchanged, and
add regression coverage for both header-only parsing and full request body
reads.
Validate trailer names added through AddTrailerBytes before storing them
for Trailer header serialization.
Trim OWS around comma-separated trailer names, reject names containing
bytes outside the HTTP field-name token set, and keep the existing
forbidden-trailer filtering in place. This prevents CRLF injection through
dynamic trailer names while preserving valid trailer declarations.
Add request and response regression coverage for invalid trailer names and
tab-trimmed OWS.
On new connections with ReduceMemoryUsage enabled, serveConn could reach
acquireByteReader before installing a read deadline. That left the first
blocking read outside ReadTimeout and allowed silent clients to keep the
connection open until some external timeout closed it.
Apply ReadTimeout before the first read on a new connection, while keeping
the existing idle-timeout behavior for keep-alive requests. Add a regression
test that verifies the server closes a silent ReduceMemoryUsage connection
after the first-byte timeout.
Prevent request and response first-line setters from serializing
embedded CR or LF bytes into the start line.
Route SetMethod, SetRequestURI, SetProtocol, and SetStatusMessage
through the existing newline sanitization used by other header-value
setters. This preserves behavior for valid inputs while preventing
header injection through malformed first-line values.
Thanks to @vnykmshr for reporting this issue.
Reject dial target addresses containing CR or LF before building the
HTTP CONNECT request in httpProxyDial.
This prevents header injection through HTTP proxies when callers pass
unsanitized target addresses via low-level dial paths such as
HostClient.Addr or direct proxy dialer usage.
Reported by https://github.com/OLU-DEVX
Rewritten FS paths were only checked for the "/../" substring, which
allowed leading "../" values to bypass the traversal guard.
Reject any rewritten path containing a ".." path segment before joining
it with FS.Root. This closes the PathRewrite/NewPathPrefixStripper escape
in the default OS-backed handler and keeps rewritten paths within the
intended static root.
This vulnerability was discovered and reported by bugbunny.ai
Keep headerScanner strict so malformed MIME header lines are still rejected.
Move trimming before ':' into the HTTP header handling paths that
intentionally normalize header names, and add a fuzz seed for the
regression case.
* fix: detect master process death in prefork children
Prefork child processes had no mechanism to detect if the master process
died unexpectedly. Children would become orphans, get reparented to
PID 1, and keep running silently with no supervision.
Add a watchMaster goroutine that stores the original parent PID at
startup and exits when the parent PID changes, matching the approach
used in gofiber/fiber.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* test: add integration test for watchMaster orphan detection
Verifies that prefork children exit when the master process is killed,
using a two-level subprocess chain (test → master → child) with pipe-based
synchronization to ensure the child has recorded its PPID before the
master is killed.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* refactor: pass masterPID to watchMaster and clean up tests
Capture PPID before launching the goroutine to eliminate a race between
the PPID snapshot and the ready signal. Align test style with the rest
of the project (t.Parallel, naming, ASCII-only comments).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: make prefork orphan detection configurable via OnMasterDeath callback
Address review feedback: make watchMaster opt-in via an OnMasterDeath
callback field (nil/off by default for backwards compatibility). Users
can set DefaultOnMasterDeath for os.Exit(1) or provide custom cleanup.
Also fixes ticker leak in watchMaster.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* address review feedback: remove DefaultOnMasterDeath, delete tests, fix log message
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: enhance performance
* fix: improve request URI parsing condition
* feat: validate HTTP date parsing and optimize status code length calculation
* Address parsing and lint issues
* chore: update Go version to 1.24.x in CI configuration
* feat: enhance HTTP date parsing and request URI handling
* refactor: optimize month and day name parsing using bitwise operations
* refactor: replace cookie token comparison with case insensitive function and streamline request URI parsing
* refactor: streamline request body handling and simplify request URI assignment
* chore: update Go version to 1.25.x in CI configuration
* feat: add fuzz testing for HTTP date parsing to improve robustness
* refactor: avoid unused return values in HTTP date parsing benchmarks
* refactor: update HTTP date parsing to use http.TimeFormat for consistency
ServeFile and ServeFS interpret the path as a URI, so percent-encoded
sequences are decoded and characters like '?' and '#' act as URI
delimiters. This makes it impossible to serve files whose names
contain those characters.
Changing this behavior would be backwards incompatible. So instead the
new ServeFileLiteral, ServeFSLiteral and SendFileLiteral are added.
The new Literal variants percent-encode the path before setting it as
the request URI, preserving every byte of the original filesystem path.
Thanks to @thesmartshadow for reporting this issue.
Prevents `header.Set("Key", "value\r\nEvil-Header: injected")` from
producing extra header lines in the HTTP response/request.
Thanks to @instantraaamen for reporting this issue.
- Apply `fs.Root` in non-`os.FS` path resolution.
- Normalize `fs.FS` roots (`./`, trailing slash, leading slash, separators).
- Handle `PathRewrite` outputs without a leading slash.
- Add tests for `MapFS` and `DirFS` root enforcement.
* Add WithLimit methods for uncompression
The current uncompress methods don't enforce a memory limit and are
susceptible to things like zip bombs. This pull introduces new methods
so retain backwards compatibility. The old methods might be deprecated
in the future.
* Fix suggestion