valyala/fasthttp
 Watch   
 Star   
 Fork   
2 days ago
fasthttp

v1.78.0

v1.78.0 fixes lost responses during graceful shutdown and makes streamed bodies report truncation reliably. It also improves redirect handling, preserves multipart uploads when copying requests, and speeds up path normalization, query parsing, header operations, and concurrent client requests.

Server and streaming fixes

  • Graceful shutdown preserves responses on keep-alive connections. An idle connection could be closed just as its next request entered the handler, leaving the client with EOF even though the handler had done the work. Shutdown now closes the idle connection before the handler runs or lets the active request finish. Buffered pipelined responses are flushed before the connection closes. #2537
  • Incomplete chunked streams report an error. Streamed request and response bodies now report io.ErrUnexpectedEOF if the peer closes at a chunk boundary before the terminating chunk arrives. If the trailer section is incomplete, the stream returns ErrBrokenChunk wrapping io.ErrUnexpectedEOF. #2515, #2538
  • Adapted net/http handlers preserve the final response after a 1xx status. A handler that writes 103 Early Hints followed by 200 OK now sends the 200 and its body. The adaptor does not forward the interim status; 101 Switching Protocols remains final. #2516
  • Body-buffer retention is scoped to the request that enabled it. The server clears a handler's Request.KeepBodyBuffer and Response.KeepBodyBuffer settings before resetting for the next keep-alive request, so oversized buffers can be released according to the configured pool limit. #2508

Redirects, URIs, and authentication

  • Redirects preserve links such as mailto: and native-app callbacks. RequestCtx.Redirect keeps targets with a scheme but no // intact. When the client receives a non-HTTP target of that form, it returns the 3xx response with its Location and no error. For references matching the base scheme, URI.Update resolves the remainder as relative: http:next against http://host/a/b resolves to http://host/a/next. #2503, #2506, #2507
  • An invalid redirect location stops the client before it sends another request. When Location cannot be parsed, the client returns the redirect response and the parse error. The new URI.UpdateBytesErr exposes that error to callers; URI.Update and URI.UpdateBytes retain their existing behavior. #2523
  • An explicit Authorization header takes precedence over URL credentials. When the header is empty, Basic authentication uses the percent-decoded username and password from the URI: p%40ss becomes p@ss, and a literal + stays +. URI.Parse also validates IPv6 literals with zone identifiers and rejects an empty zone. #2526, #2529, #2535

Forms, cookies, and compression

  • Multipart forms parse and copy correctly. Form media types and the boundary parameter name are matched case-insensitively. Multipart parsing accepts optional whitespace around ; and preserves semicolons inside quoted parameter values. Request.CopyTo also preserves uploads parsed directly from the incoming body, so forwarding the copy no longer sends an empty body. #2511, #2512, #2517, #2521
  • Cookie parsing preserves usable attributes. Expires again accepts RFC 1123 dates with zone names such as UTC. An unusable Domain or Path is ignored without discarding the cookie or skipping later attributes such as HttpOnly. #2519, #2524
  • Compression works with single-file roots, mixed-case encodings, and zstd level zero. FS can again serve compressed content when Root names a file, keeping compressed copies in its parent directory. Body decoders match Content-Encoding case-insensitively, and zstd level 0 selects the default level instead of panicking. #2505, #2509, #2510

Performance improvements

Path normalization skips unnecessary dot-segment checks for filenames such as /app.min.js. Query parsing locates escapes while splitting arguments, header operations avoid redundant scans, and Client.Do reduces contention between concurrent callers. #2513

In the PR benchmarks, parsing paths with file extensions took 40% less time, query parsing took 29% less time, and concurrent Client.Do dispatch with a no-op transport took 19% less time at GOMAXPROCS=4. End-to-end improvements were smaller: 4–6% less time for cached small files and 6–8% less time for in-memory client requests. Allocation counts were unchanged, and the pipelined server benchmarks showed no significant change. #2513

What's Changed

Performance

Server, streaming, and adaptor fixes

Redirects, URIs, and authentication

Forms and cookies

Compression and other fixes

Dependency updates

New Contributors

Full Changelog: https://github.com/valyala/fasthttp/compare/v1.77.0...v1.78.0

16 days ago
fasthttp

v1.77.0

v1.77.0 strengthens static-file confinement, fixes hijacked connection handling, and improves HTTP and cookie compatibility. It also adds an opt-in bounded stream reader, configurable body-buffer retention, and deadline support for adapted net/http handlers.

Static-file symlink behavior changes by default. The default OS-backed FS now rejects symlinks that leave Root or CompressRoot, as well as absolute symlinks even when their targets are inside the root. Relative symlinks that stay inside the root continue to work. Set FS.AllowSymlinksOutsideRoot to restore the previous behavior when external symlinks are intentional. Custom FS.FS implementations are unaffected. #2490

Security fixes and hardening

  • Default static-file operations stay within their configured roots. File reads and compressed-cache operations use os.Root to prevent symlink traversal outside Root and CompressRoot. Each root is confined independently; empty roots with AllowEmptyRoot and whole-volume roots retain their existing behavior. #2490
  • Custom filesystems no longer trigger unrelated disk deletions. A stale compressed file in a custom FS.FS previously caused an os.Remove call using its filesystem-relative name, potentially deleting a matching file in the process working directory. Custom filesystems now regenerate stale compressed content in memory without removing a disk file. #2489
  • Kept hijacked connections no longer depend on a recycled request context. With both KeepHijackedConns and ReduceMemoryUsage enabled, the hijacked reader is detached from the context before the hijack handler runs. This prevents later reads from panicking or accessing another client's connection after context reuse. #2495

Features and resource management

  • An opt-in stream reader bounds copied payload buffering. NewBoundedStreamReader works with SetBodyStream and applies backpressure when consumers fall behind. Active copied payload is limited to 160 KiB per bridge, or 320 KiB across the two bridges used by its bounded compression path. These limits exclude caller buffers, codecs, sockets, and other overhead; wrapping the reader loses the combined compression bound. Existing NewStreamReader and SetBodyStreamWriter behavior is unchanged. #2488
  • Request and response body buffers can be retained explicitly. The exported Request.KeepBodyBuffer and Response.KeepBodyBuffer fields preserve body buffers across resets for reuse. Releasing a request or response to the pool clears the retention setting. #2451
  • Adapted handlers can configure connection deadlines. RequestCtx.SetReadDeadline and SetWriteDeadline are also exposed through fasthttpadaptor, enabling http.ResponseController deadline calls. The adaptor still buffers the request body before invoking the handler, so a read deadline set inside an adapted handler cannot govern the preceding upload. #2452

HTTP compatibility and connection handling

  • Weighted compression codings are recognized. Accept-Encoding entries such as gzip;q=0.8 now match, while q=0 makes a coding unacceptable. Matching remains case-insensitive and requires a complete coding token; quality-based preference ordering and wildcard matching are not added. #2491
  • HTTP/1.0 clients no longer receive unsupported informational responses. Expect: 100-continue is ignored for HTTP/1.0 requests, and 103 Early Hints is not sent to HTTP/1.0 clients. #2492, #2496
  • Hijacking works with server keep-alive limits. DisableKeepalive and reaching MaxRequestsPerConn no longer suppress a registered hijack handler or add an unwanted Connection: close to an upgrade response. Explicit connection-close requests and other existing close conditions still apply. #2494
  • Pipe connection deadlines interrupt pending operations. Updating deadlines on fasthttputil.PipeConns now affects blocked reads and writes, and write-deadline updates no longer race with writes. #2471
  • Cookie parsing tolerates invalid attributes and handles names consistently. Invalid Max-Age attributes are ignored, Secure, HttpOnly, and Partitioned are recognized even with a value, and surrounding tabs are trimmed. Set-Cookie values without = are stored under the same empty key returned by Cookie.ParseBytes, keeping lookup and deletion consistent. #2497, #2498, #2500, #2501

Proxy authentication now uses decoded credentials in Proxy-Authorization, and static-file 416 Range Not Satisfiable responses include Content-Range. #2499, #2502

What's Changed

Security and hardening

Features

Fixes

New Contributors

Full Changelog: https://github.com/valyala/fasthttp/compare/v1.76.0...v1.77.0

24 days ago
fasthttp

v1.76.0

v1.76.0 strengthens HTTP message framing, static-file isolation, and server connection handling. It also improves HTTP compatibility, avoids quadratic work when parsing large trailer sets, and adds configurable TCP keep-alives to TCPDialer.

Security fixes and hardening

  • Multipart parsing consumes the entire declared body. Bytes after the closing multipart boundary are drained before the connection is reused, preventing a multipart epilogue from being interpreted as another request. #2336
  • Outgoing messages preserve framing. Raw Content-Length headers are synchronized with the outgoing body, duplicate or conflicting framing headers are rejected, and fixed-length request and response streams cannot write beyond their declared size. FS and SendFile also stop at the advertised Content-Length when a file grows during serving. #2470, #2462
  • Requests with both Content-Length and Transfer-Encoding close the connection. The connection is no longer reused after a request containing both framing headers. #2476
  • Virtual-host file serving preserves directory isolation. NewVHostPathRewriter avoids decoding the host and path twice and handles invalid hosts safely, preventing crafted requests from escaping the virtual-host directory and accessing files directly under FS.Root. This affects FS handlers using NewVHostPathRewriter. #2487
  • Rejected TLS connections no longer block the accept loop. Connections rejected by MaxConnsPerIP or Concurrency are closed without attempting an HTTP error response, which could otherwise trigger a TLS handshake and stall while waiting for a ClientHello. IPv6 clients are now also counted against MaxConnsPerIP. #2486, #2468

Performance improvements

  • Trailer parsing avoids quadratic work. Large sets of trailer names use indexed membership checks instead of repeatedly scanning all previously recorded names. This reduces CPU amplification from crafted Trailer headers and chunked trailer sections while preserving trailer order. #2465

HTTP compatibility and features

  • Static files handle range and conditional requests more accurately. Unsupported range units and multiple ranges are ignored instead of returning 416; invalid single byte ranges still return 416. Range is also ignored when If-Range does not match, and both Range and If-Modified-Since are ignored for methods other than GET and HEAD. #2467, #2473, #2474, #2475
  • Pipeline clients handle HEAD responses without reading a body. PipelineClient skips the response body for HEAD requests. #2469
  • HTTP parsing accepts valid legacy formats and matches tokens correctly. ParseHTTPDate accepts obsolete HTTP-date formats, cookies with an invalid Expires attribute remain parseable, Expect: 100-continue is matched case-insensitively, and Accept-Encoding matches complete tokens. Asterisk-form request targets are rejected for methods other than OPTIONS. #2466, #2481, #2482, #2479, #2463
  • TCP keep-alives are configurable. The new TCPDialer.KeepAlive field sets the keep-alive period for connections created by the dialer; a negative value disables keep-alives. #2484

What's Changed

Security and hardening

Performance

Features

Fixes

Documentation

Dependency updates

New Contributors

Full Changelog: https://github.com/valyala/fasthttp/compare/v1.75.0...v1.76.0

2026-10-05 15:01:35
fasthttp

v1.75.0

v1.75.0 improves HTTP parsing and serialization, URI processing, cached file serving, and client connection handling. It also fixes cookie injection, request/response framing problems, and excessive CPU or memory consumption from certain inputs.

Go 1.26 or newer is now required. #2395

Performance improvements

  • HTTP parsing: request headers are parsed and validated in one pass, with common methods and HTTP/1.1 recognized directly. Header values, case conversion, host validation, and control-byte checks process multiple bytes at a time. The parser also avoids repeatedly scanning the same incomplete header block when data arrives in small reads. #2413, #2414, #2428, #2423, #2412, #2438
  • HTTP writing: fewer header and response copies, cached serialized Server and Date lines, faster HTTP date formatting, and fewer flushes around chunked trailers. Large buffered responses can use writev on TCP and Unix connections; TLS and streamed bodies retain the buffered path. #2425, #2415, #2434, #2426, #2433
  • URI processing: memoized authority parsing, a fast path for /, faster quoting and validation, and linear-time path normalization. #2411, #2423, #2453
  • Static files: cached files of up to 8 KiB can be served from memory, avoiding a file read on each cache hit and releasing the file descriptor. The new small-file content cache is bounded to 4096 files, or at most 32 MiB per FS; the existing cache metadata is separate. Changes to these files become visible after cache expiration (CacheDuration, 10 seconds by default). #2446
  • Client and server overhead: clients avoid redundant deadline updates when no timeout is active. The opt-in Server.LazyRequestTime avoids reading the clock until RequestCtx.Time() is called; with this option, the returned time is the time of the first call. The benchmark comparison below uses the default setting. #2439, #2404

Security fixes and hardening

  • Streamed request bodies are drained before connection reuse. With StreamRequestBody enabled, the server drains unread body data before reusing the connection, with a 256 KiB drain limit, or closes the connection when safe draining is not possible. Responses are flushed before draining so early replies reach clients still uploading, and response streams can consume the request body before its remaining size is checked. #2368, #2461
  • Rejected 100-continue requests close the connection. A denied request could previously leave its body unread and have those bytes interpreted as the next request, desynchronizing a reused connection. #2450
  • Cookie setters prevent additional-cookie injection. RequestHeader.SetCookie and its byte variants now sanitize semicolons in names and values, so one logical cookie cannot become multiple cookies on the wire. #2393
  • Bounded zstd decoding limits decoder memory demand as well as output. A small compressed frame could previously declare a large decoder window even when a decoded-body limit was configured. Positive BodyUnzstdWithLimit limits now select a memory-limited decoder, with caps rounded up in 8 MiB buckets; exceeding the decoder limit returns ErrBodyTooLarge. #2407
  • Path normalization avoids quadratic work. Repeated separators and dot segments are processed in linear time, reducing the CPU amplification possible with crafted request targets. Incomplete headers arriving one byte at a time also avoid repeated full-block scans. #2453, #2413
  • Bodyless responses preserve framing. HEAD and status-defined bodyless responses no longer emit trailer bytes that can be mistaken for the next response. Serialization suppresses forbidden Content-Length and Transfer-Encoding on 1xx/204 responses. Explicit content-type metadata and permitted 304 metadata remain supported. #2441, #2447, #2457
  • Pipeline clients gain a response-body limit and better failure cleanup. Set the new PipelineClient.MaxResponseBodySize to a positive value to reject oversized responses, including with Response.StreamBody; the default remains unlimited. Idle workers now retire after errors, abandoned requests release their streams, and failed connection establishment is throttled. #2427, #2458

Argument sorting now honors any negative comparator result in Args.Sort and Args.SortKeys, and static-file serving rejects zero-length suffix byte ranges (bytes=-0) with 416 Range Not Satisfiable. #2459, #2460

Other significant changes include opt-in ETags for FS, a net/http request conversion function, improved adaptor handling of flushes, aborts and trailers, and fixes to shutdown and per-IP connection lifetimes. #2399, #2104, #2429, #2445, #2352, #2402

Benchmark results

Compared v1.74.0 with master 6141d3a on Ubuntu 26.04, an AMD EPYC 9454, and Go 1.27.1. Each benchmark has ten samples per revision, run alternately with the same inputs and CPU affinity. Negative percentages mean less time per operation. All rows below have p < 0.001.

Benchmark v1.74.0 Release candidate Time/op change
Minimal GET, pipeline depth 64 484.30 ns 278.05 ns -42.6%
Browser-shaped GET, pipeline depth 16 1.080 µs 722.55 ns -33.1%
Request-header parsing 561.80 ns 348.15 ns -38.0%
Response-header parsing 466.95 ns 277.55 ns -40.6%
Request-header writing 49.84 ns 37.45 ns -24.8%
Response-header writing 68.64 ns 40.99 ns -40.3%
Cached 1 KiB file, directory 2.324 µs 611.85 ns -73.7%
Cached 1 KiB file, os.DirFS 3.805 µs 612.30 ns -83.9%
URI path with query string 91.39 ns 46.06 ns -49.6%
HTTP date formatting 108.25 ns 28.59 ns -73.6%
Trickled ~4 KiB headers, one byte per read 1385.784 µs 191.257 µs -86.2%
8 KiB path of repeated / 352.529 µs 54.330 µs -84.6%
~8 KiB path of repeated /a/.. 96.733 µs 22.253 µs -77.0%
TCP client/server round trips, small response 5.193 µs 5.030 µs -3.1%
TCP client/server round trips, 64 KiB response 15.302 µs 13.478 µs -11.9%

The pipelined serving and file benchmarks use an in-memory connection with writes discarded. The two TCP rows include real loopback networking. These results describe the selected workloads; TCP gains are smaller than the gains in parsing and serialization. Server.LazyRequestTime remains disabled in this comparison.

What's Changed

Compatibility

Security and hardening

Performance

Features

Fixes

Documentation, tests and tooling

Dependency updates

New Contributors

Full Changelog: https://github.com/valyala/fasthttp/compare/v1.74.0...v1.75.0

2026-09-07 17:55:09
fasthttp

v1.74.0

What's Changed

New Contributors

Full Changelog: https://github.com/valyala/fasthttp/compare/v1.73.0...v1.74.0

2026-07-27 21:17:45
fasthttp

v1.73.0

What's Changed

New Contributors

Full Changelog: https://github.com/valyala/fasthttp/compare/v1.72.0...v1.73.0

2026-06-27 15:16:48
fasthttp

v1.72.0

What's Changed

New Contributors

Full Changelog: https://github.com/valyala/fasthttp/compare/v1.71.0...v1.72.0

2026-05-02 20:09:35
fasthttp

v1.71.0

What's Changed

New Contributors

Full Changelog: https://github.com/valyala/fasthttp/compare/v1.70.0...v1.71.0

2026-04-05 13:03:35
fasthttp

v1.70.0

What's Changed

New Contributors

Full Changelog: https://github.com/valyala/fasthttp/compare/v1.69.0...v1.70.0

2026-01-05 22:10:34
fasthttp

v1.69.0

What's Changed

Full Changelog: https://github.com/valyala/fasthttp/compare/v1.68.0...v1.69.0