fasthttp @ v1.75.0
integrity
- size
- 487.3 KiB
- downloaded
- last checked
- overlays
- go
- detected
- go module github.com/valyala/fasthttp
release notes
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
ServerandDatelines, faster HTTP date formatting, and fewer flushes around chunked trailers. Large buffered responses can usewritevon 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.LazyRequestTimeavoids reading the clock untilRequestCtx.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
StreamRequestBodyenabled, 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-continuerequests 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.SetCookieand 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
BodyUnzstdWithLimitlimits now select a memory-limited decoder, with caps rounded up in 8 MiB buckets; exceeding the decoder limit returnsErrBodyTooLarge. #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-LengthandTransfer-Encodingon 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.MaxResponseBodySizeto a positive value to reject oversized responses, including withResponse.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
- Require Go 1.26 for golang.org/x by @erikdubbelboer in https://github.com/valyala/fasthttp/pull/2395
Security and hardening
- discard unread streamed request body before the next request by @alhudz in https://github.com/valyala/fasthttp/pull/2368
- close the connection when ContinueHandler denies a request by @alhudz in https://github.com/valyala/fasthttp/pull/2450
- limit zstd decoder memory in WithLimit methods by @erikdubbelboer in https://github.com/valyala/fasthttp/pull/2407
- Strip semicolons in RequestHeader.SetCookie by @youdie006 in https://github.com/valyala/fasthttp/pull/2393
- make normalizePath linear in the length of the path by @alhudz in https://github.com/valyala/fasthttp/pull/2453
- Omit the trailer section from a response without a body by @h2zi in https://github.com/valyala/fasthttp/pull/2441
- Omit Transfer-Encoding on 1xx and 204 responses by @davidscottpope-gif in https://github.com/valyala/fasthttp/pull/2457
- Omit Content-Length/Content-Type on a parsed bodyless response when re-serializing by @januththedev in https://github.com/valyala/fasthttp/pull/2447
- Add MaxResponseBodySize to PipelineClient by @erikdubbelboer in https://github.com/valyala/fasthttp/pull/2427
- fix: stop idle PipelineClient workers after errors by @erikdubbelboer in https://github.com/valyala/fasthttp/pull/2458
Performance
- perf: parse request headers in one validating pass by @h2zi in https://github.com/valyala/fasthttp/pull/2413
- perf: scan the request header block once while parsing by @gaby in https://github.com/valyala/fasthttp/pull/2424
- perf: serve small cached files from memory in FS by @gaby in https://github.com/valyala/fasthttp/pull/2446
- perf: serialize responses with fewer copies and send large ones with writev by @h2zi in https://github.com/valyala/fasthttp/pull/2415
- perf: cut redundant copies out of header serialization by @gaby in https://github.com/valyala/fasthttp/pull/2425
- perf: scan header values, control bytes and case eight bytes at a time by @gaby in https://github.com/valyala/fasthttp/pull/2428
- perf: speed up host validation and query/path quoting- #154 by @gaby in https://github.com/valyala/fasthttp/pull/2423
- perf: memoize authority parsing and fast-path the root path by @h2zi in https://github.com/valyala/fasthttp/pull/2411
- perf: recognize GET, POST, HEAD and HTTP/1.1 without byte-wise validation by @h2zi in https://github.com/valyala/fasthttp/pull/2414
- perf: scan the request target for control bytes a word at a time by @h2zi in https://github.com/valyala/fasthttp/pull/2412
- perf: skip redundant deadline updates on client connections by @gaby in https://github.com/valyala/fasthttp/pull/2439
- perf: preform the Date header line once a second by @h2zi in https://github.com/valyala/fasthttp/pull/2434
- perf: format HTTP dates without time.AppendFormat by @gaby in https://github.com/valyala/fasthttp/pull/2426
- perf: keep the last chunk buffered for the trailer section by @h2zi in https://github.com/valyala/fasthttp/pull/2433
- perf: keep the control-byte scans inlinable by @h2zi in https://github.com/valyala/fasthttp/pull/2438
- fix: request time left at zero, and an opt in Server.LazyRequestTime by @ReneWerner87 in https://github.com/valyala/fasthttp/pull/2404
Features
- Add opt-in ETag support to FS by @anandghegde in https://github.com/valyala/fasthttp/pull/2399
- Add ConvertNetHttpRequestToFastHttpRequest adaptor function by @aaydin-tr in https://github.com/valyala/fasthttp/pull/2104
Fixes
- fix: preserve response behavior while draining streamed requests by @erikdubbelboer in https://github.com/valyala/fasthttp/pull/2461
- fix: per-IP wrapper lifetime, TLS state unwrapping and ConnState timing by @h2zi in https://github.com/valyala/fasthttp/pull/2352
- fix: carry net/http handler contracts through the fasthttpadaptor by @h2zi in https://github.com/valyala/fasthttp/pull/2429
- Carry response trailers through the fasthttpadaptor by @h2zi in https://github.com/valyala/fasthttp/pull/2445
- fix: write trailers for buffered bodies in Request.Write and Response.Write by @aaydin-tr in https://github.com/valyala/fasthttp/pull/2378
- Start compressing a streamed body when the server reads it by @h2zi in https://github.com/valyala/fasthttp/pull/2442
- fix: synchronize RequestCtx.Done() with ShutdownWithContext by @cpsc in https://github.com/valyala/fasthttp/pull/2402
- fix: admit TimeoutHandler requests on servers driven by ServeConn by @h2zi in https://github.com/valyala/fasthttp/pull/2431
- fix: serve queued waiters when SetMaxConns grows the limit by @h2zi in https://github.com/valyala/fasthttp/pull/2430
- fix: recheck idle connections before queuing waiters by @HarveyBase in https://github.com/valyala/fasthttp/pull/2394
- fix: recognize case-insensitive and multi-value Connection: close (#2418) by @littfed in https://github.com/valyala/fasthttp/pull/2420
- fix: preserve zero Max-Age when parsing cookies by @jakezwang in https://github.com/valyala/fasthttp/pull/2405
- fix: accept a negative Max-Age when parsing cookies by @SulimanAbdulrazzaq in https://github.com/valyala/fasthttp/pull/2416
- Preserve NoDefaultContentType across client response resets by @CSXizhang in https://github.com/valyala/fasthttp/pull/2455
- fix(fs): reject zero-length suffix byte ranges by @kevin9327 in https://github.com/valyala/fasthttp/pull/2460
- fix(args): use comparator sign in Sort and SortKeys by @sergioperezcheco in https://github.com/valyala/fasthttp/pull/2459
- fix: preserve redirect path normalization setting in Request.CopyTo by @cuishuang in https://github.com/valyala/fasthttp/pull/2389
- fix: normalize a trailing /. path segment by @sachhg in https://github.com/valyala/fasthttp/pull/2392
- fix: mask ConnRequestNum into its 32-bit RequestCtx.ID field by @h2zi in https://github.com/valyala/fasthttp/pull/2432
- Return no values from PeekAll for absent special headers by @youdie006 in https://github.com/valyala/fasthttp/pull/2401
- Leave an empty upfront Server or User-Agent out of PeekAll by @h2zi in https://github.com/valyala/fasthttp/pull/2443
- Skip RFC-valid empty elements in VisitHeaderParams by @vzer200 in https://github.com/valyala/fasthttp/pull/2388
- fix(request): warn when Request.Body() is called on streamed requests by @VedantMadane in https://github.com/valyala/fasthttp/pull/2350
Documentation, tests and tooling
- docs: show how to read a bounded response prefix by @fzlzjerry in https://github.com/valyala/fasthttp/pull/2369
- docs: clarify that ShutdownWithContext error does not freeze the Server by @hazyhaar in https://github.com/valyala/fasthttp/pull/2422
- test: add benchmarks for pipelined and browser-shaped serving by @h2zi in https://github.com/valyala/fasthttp/pull/2409
- test: scale hard-coded deadlines with testTimeout by @h2zi in https://github.com/valyala/fasthttp/pull/2410
- Update golangci-lint to v2.13.2 and get rid of the separate gosec action by @erikdubbelboer in https://github.com/valyala/fasthttp/pull/2386
Dependency updates
- chore(deps): bump github.com/klauspost/compress from 1.20.0 to 1.20.1 by @dependabot[bot] in https://github.com/valyala/fasthttp/pull/2448
- chore(deps): bump golang.org/x/net from 0.58.0 to 0.59.0 by @dependabot[bot] in https://github.com/valyala/fasthttp/pull/2397
- chore(deps): bump github.com/molecule-man/go-brrr from 1.0.1 to 1.1.1 by @dependabot[bot] in https://github.com/valyala/fasthttp/pull/2417
New Contributors
- @vzer200 made their first contribution in https://github.com/valyala/fasthttp/pull/2388
- @youdie006 made their first contribution in https://github.com/valyala/fasthttp/pull/2393
- @aaydin-tr made their first contribution in https://github.com/valyala/fasthttp/pull/2378
- @sachhg made their first contribution in https://github.com/valyala/fasthttp/pull/2392
- @cpsc made their first contribution in https://github.com/valyala/fasthttp/pull/2402
- @jakezwang made their first contribution in https://github.com/valyala/fasthttp/pull/2405
- @SulimanAbdulrazzaq made their first contribution in https://github.com/valyala/fasthttp/pull/2416
- @HarveyBase made their first contribution in https://github.com/valyala/fasthttp/pull/2394
- @anandghegde made their first contribution in https://github.com/valyala/fasthttp/pull/2399
- @littfed made their first contribution in https://github.com/valyala/fasthttp/pull/2420
- @januththedev made their first contribution in https://github.com/valyala/fasthttp/pull/2447
- @hazyhaar made their first contribution in https://github.com/valyala/fasthttp/pull/2422
- @CSXizhang made their first contribution in https://github.com/valyala/fasthttp/pull/2455
- @VedantMadane made their first contribution in https://github.com/valyala/fasthttp/pull/2350
- @davidscottpope-gif made their first contribution in https://github.com/valyala/fasthttp/pull/2457
- @sergioperezcheco made their first contribution in https://github.com/valyala/fasthttp/pull/2459
- @kevin9327 made their first contribution in https://github.com/valyala/fasthttp/pull/2460
Full Changelog: https://github.com/valyala/fasthttp/compare/v1.74.0...v1.75.0
download
curl -fL -o v1.75.0.zip https://ratatoskr.space/pkg/fasthttp/v1.75.0.zip
printf '%s %s\n' '771d8f7ff9633c4ae4c60f61d22784c4b45eb164df500818d6d2ce0afd2f3b35' 'v1.75.0.zip' | sha256sum -c -
$url = "https://ratatoskr.space/pkg/fasthttp/v1.75.0.zip"
$out = "v1.75.0.zip"
Invoke-WebRequest -Uri $url -OutFile $out
if ((Get-FileHash $out -Algorithm SHA256).Hash.ToLowerInvariant() -ne "771d8f7ff9633c4ae4c60f61d22784c4b45eb164df500818d6d2ce0afd2f3b35") { throw "sha256 mismatch" }
curl -fL -o v1.75.0.tar.gz https://ratatoskr.space/pkg/fasthttp/v1.75.0.tar.gz
printf '%s %s\n' 'df3795e5aa2b40288dee4d0f103513e7c1b61694a4080496cbe50602598ca0bc' 'v1.75.0.tar.gz' | sha256sum -c -
$url = "https://ratatoskr.space/pkg/fasthttp/v1.75.0.tar.gz"
$out = "v1.75.0.tar.gz"
Invoke-WebRequest -Uri $url -OutFile $out
if ((Get-FileHash $out -Algorithm SHA256).Hash.ToLowerInvariant() -ne "df3795e5aa2b40288dee4d0f103513e7c1b61694a4080496cbe50602598ca0bc") { throw "sha256 mismatch" }
download via yggdrasil mesh
curl -fL -o v1.75.0.zip http://14cc7d57b5e70f679b851fe5b272ce17c70632ff4beb5b35ab64bc706b2485af.pk.ygg/pkg/fasthttp/v1.75.0.zip
printf '%s %s\n' '771d8f7ff9633c4ae4c60f61d22784c4b45eb164df500818d6d2ce0afd2f3b35' 'v1.75.0.zip' | sha256sum -c -
$url = "http://14cc7d57b5e70f679b851fe5b272ce17c70632ff4beb5b35ab64bc706b2485af.pk.ygg/pkg/fasthttp/v1.75.0.zip"
$out = "v1.75.0.zip"
Invoke-WebRequest -Uri $url -OutFile $out
if ((Get-FileHash $out -Algorithm SHA256).Hash.ToLowerInvariant() -ne "771d8f7ff9633c4ae4c60f61d22784c4b45eb164df500818d6d2ce0afd2f3b35") { throw "sha256 mismatch" }
curl -fL -o v1.75.0.tar.gz http://14cc7d57b5e70f679b851fe5b272ce17c70632ff4beb5b35ab64bc706b2485af.pk.ygg/pkg/fasthttp/v1.75.0.tar.gz
printf '%s %s\n' 'df3795e5aa2b40288dee4d0f103513e7c1b61694a4080496cbe50602598ca0bc' 'v1.75.0.tar.gz' | sha256sum -c -
$url = "http://14cc7d57b5e70f679b851fe5b272ce17c70632ff4beb5b35ab64bc706b2485af.pk.ygg/pkg/fasthttp/v1.75.0.tar.gz"
$out = "v1.75.0.tar.gz"
Invoke-WebRequest -Uri $url -OutFile $out
if ((Get-FileHash $out -Algorithm SHA256).Hash.ToLowerInvariant() -ne "df3795e5aa2b40288dee4d0f103513e7c1b61694a4080496cbe50602598ca0bc") { throw "sha256 mismatch" }
| artifact | format | size | hashes |
|---|---|---|---|
| v1.75.0.zip | zip | 493.3 KiB |
blake3-24 472f99c778260c4320ca50f9f9345c75c69f08eaf43dc040
sha256 771d8f7ff9633c4ae4c60f61d22784c4b45eb164df500818d6d2ce0afd2f3b35
sha1 612b91bce165018f16be19333d02d23dd811fe63
|
| v1.75.0.tar.gz | tar.gz | 423.9 KiB |
blake3-24 cc597464daf26f085e93dd7e9abed736bf9c71a9dd7988f8
sha256 df3795e5aa2b40288dee4d0f103513e7c1b61694a4080496cbe50602598ca0bc
sha1 3116255b08619a2b26cca36ea8090788391c5964
|
go module archive
module zip with the module path rewritten to this mirror; fetched by go get through the
GOPROXY route
| artifact | format | size | hashes |
|---|---|---|---|
| v1.75.0.zip | zip | 497.4 KiB |
blake3-24 42325471fcca6d1d70837e91ec93968e98729d3c9af7119d
sha256 961c179971ae0dc3b2def553be45ba93dda82d394b0f42a8bbd2242fb833087b
sha1 4b3b96377cd195c6a4fcc3af7066af8bca7d5263
|
install
http_archive(
name = "fasthttp",
urls = ["https://ratatoskr.space/pkg/fasthttp/v1.75.0.tar.gz"],
integrity = "sha256-3zeV5aorQCiN7k0PEDUT58G2FpSkCASWy+UGAlmMoLw=",
strip_prefix = "fasthttp-v1.75.0",
)
.url = "https://ratatoskr.space/pkg/fasthttp/v1.75.0.tar.gz",
GOPROXY=https://ratatoskr.space GOSUMDB=off go get ratatoskr.space/pkg/fasthttp@v1.75.0
install via yggdrasil mesh
http_archive(
name = "fasthttp",
urls = ["http://14cc7d57b5e70f679b851fe5b272ce17c70632ff4beb5b35ab64bc706b2485af.pk.ygg/pkg/fasthttp/v1.75.0.tar.gz"],
integrity = "sha256-3zeV5aorQCiN7k0PEDUT58G2FpSkCASWy+UGAlmMoLw=",
strip_prefix = "fasthttp-v1.75.0",
)
.url = "http://14cc7d57b5e70f679b851fe5b272ce17c70632ff4beb5b35ab64bc706b2485af.pk.ygg/pkg/fasthttp/v1.75.0.tar.gz",
GOPROXY=http://14cc7d57b5e70f679b851fe5b272ce17c70632ff4beb5b35ab64bc706b2485af.pk.ygg GOSUMDB=off GOINSECURE=14cc7d57b5e70f679b851fe5b272ce17c70632ff4beb5b35ab64bc706b2485af.pk.ygg/* go get 14cc7d57b5e70f679b851fe5b272ce17c70632ff4beb5b35ab64bc706b2485af.pk.ygg/pkg/fasthttp@v1.75.0