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.
* 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>
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.
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.
This change updates header parsing to match the behavior of net/http more closely.
**Breaking change**: headers delimited by `\n` (instead of `\r\n`) are no longer supported.
Previously, fasthttp accepted `\n` as a delimiter, which is not spec compliant.
This made it difficult to correctly parse headers containing both `\n` and `\r\n`.
Locking and unlocking a mutex multiple times per request is a major
slowdown that we can avoid with clever use of atomics.
Before:
```
BenchmarkServerGet100ReqPerConn10KClients-12 84167428 867.7 ns/op
```
After:
```
BenchmarkServerGet100ReqPerConn10KClients-12 187397954 386.3 ns/op
```
* fix: accept invalid headers with a space #1917
Make behavior consistent with net/http by allowing header keys and trailers containing spaces without canonicalizing them
* fix: lint paramTypeCombine
* fix: https://github.com/valyala/fasthttp/pull/1953#issuecomment-2660691298
* fix: golangci-lint nestingReduce
In some cases, the goroutines started by one test do not terminate smoothly before the next round of tests begins, causing interference between tests.
Performance Impact: This results in test completion times not increasing linearly with the count value.
Correctness Impact: It affects the accuracy of memory allocation test cases.
* The StreamRequestBody should not read content beyond what is required.
The StreamRequestBody feature on the server side should not read content that does not belong to the current request body.This is more logical and consistent with the result of not using the StreamRequestBody feature.Fixes: https://github.com/valyala/fasthttp/issues/1816.
* Update server_test.go
Co-authored-by: Erik Dubbelboer <erik@dubbelboer.com>
* Update http.go
Co-authored-by: Erik Dubbelboer <erik@dubbelboer.com>
---------
Co-authored-by: Erik Dubbelboer <erik@dubbelboer.com>
* Auto add 'Vary' header after compression
Add config `SetAddVaryHeaderForCompression` to enable
'Vary: Accept-Encoding' header when compression is used.
* feat: always set the Vary header
* create and use `ResponseHeader.AddVaryBytes`
* not export 'AddVaryBytes'
* Response.ContentEncoding(): store as field
The CE is not so often used for plain APIs responses and even not so often used for static files and on the fly compression.
But still it should be checked each time.
Also having a dedicated field getter and setter simplifies code
* header.go Use shorter Response.setNonSpecial() and Request.setNonSpecial() methods instead of SetCanonical()
The change should improve performance because the setSpecialHeader() call is omitted.
As a downside on adding a new basic header field all putHeader() must be replaced with a direct getter and setter.