Skip to content

v1.18.1 (v1.18.0, v1.17.1, v1.17.0)

Latest

Choose a tag to compare

@bogdanfinn bogdanfinn released this 11 Nov 18:19
· 2 commits to master since this release
9525980

What's Changed

  • Do not write the transport cache from a reconnecting dial by @Mootjelh in #270
  • reworked and restructured examples by @bogdanfinn in #271
  • Key the transport cache by the port the scheme implies by @Mootjelh in #272
  • CONNECT headers follow the given order by @Mootjelh in #274
  • feat: add WithCertificatePinner option for custom certificate validation by @tahafatih in #278
  • Expose HTTP/2 ReadIdleTimeout and PingTimeout in TransportOptions by @titwn in #282
  • feat: generate the Chrome trust anchors from the Chrome Root Store by @nihiloid in #277
  • Add CI for the tests by @ayn2op in #286
  • Expose WebSocket over the shared library (wsConnect / wsRead / wsWrite / wsClose / wsStats) by @marinionroids in #284
  • Bound the HTTP/2 transport's redial by the client timeout by @datawisebets in #287
  • fix(transport): handle non-ASCII hosts and stale stashed connections by @roachadam in #291
  • fix(proxy): bound proxy dials by the request context and timeout by @roachadam in #292
  • Bump andybalholm/brotli to v1.2.7 (CVE-2026-111497) by @pxCaptcha in #293
  • Add ResponseHeaderTimeout to TransportOptions by @pagpeter in #294
  • Add the trust_anchors extension to Chrome 150 profiles by @reverseSHA256 in #297
  • Percent-encode invalid bytes in request URLs before they hit the wire by @reverseSHA256 in #298
  • Add Chrome 154 and Chrome 154 PSK profiles with sorted trust anchors by @nihiloid in #301
  • Add Safari 27.2 desktop TLS and HTTP/2 profile by @reverseSHA256 in #299

New Contributors

There was no separate release for 1.17.x, so this release covers everything since 1.16.0.

Breaking Changes

  • Go 1.27 or newer is required (tls-client, fhttp, utls, quic-go-utls and websocket).
  • The license changed to BSD-3-Clause. The advertising clause of the previous BSD-4-Clause license no longer applies.
  • HttpClient has a new method Close(). Custom implementations and mocks of the interface have to add it.
  • The default Accept-Encoding now includes zstd: gzip, deflate, br, zstd.
  • HTTP/1.1 responses are now decompressed automatically based on Content-Encoding, also when you set Accept-Encoding yourself (as HTTP/2 already did). Calling DecompressBody on such a response is a no-op. If you read the compressed bytes yourself, set DisableCompression: true in the TransportOptions.
  • chrome_150 and chrome_150_PSK now send the trust_anchors extension and match real Chrome 150 (JA4 t13d1517h2_8daaf6152771_cb7bf5808d99). chrome_150 is the default profile, so the default fingerprint changes.
  • HTTP/3: every profile except Firefox sends SETTINGS_MAX_FIELD_SECTION_SIZE again (a regression in 1.16.0).

New Features

  • WithCertificatePinner for custom certificate validation (subject, SAN, issuer, ...). It takes precedence over WithCertificatePinning.
  • TransportOptions.ReadIdleTimeout and PingTimeout for HTTP/2 health check PINGs, which keep idle connections open.
  • TransportOptions.ResponseHeaderTimeout limits the wait for response headers over HTTP/1.1 and HTTP/2.
  • HttpClient.Close() releases all transports, including the UDP sockets of HTTP/3, which CloseIdleConnections() keeps open.
  • WebSocket option WithEnableCompression() (permessage-deflate).
  • New package trust_anchors, generated from the Chrome Root Store. profiles.BuildTrustAnchorsPayload is deprecated, use trust_anchors.BuildPayload.
  • Invalid bytes in URL queries (spaces, control characters, non-ASCII) are percent-encoded before sending, as browsers do.
  • Content-Length, Transfer-Encoding and Trailer are written under the spelling you used in the request headers.
  • CONNECT headers follow http.HeaderOrderKey regardless of case, and are sorted alphabetically without one.

New Profiles

  • Chrome 154 (chrome_154) & Chrome 154 PSK (chrome_154_PSK), with sorted trust anchors like real Chrome 154+
  • Safari 27.2 desktop (safari_27_2), contributed

Shared Library & Standalone API

  • WebSocket support: wsConnect, wsRead, wsWrite, wsClose, wsStats in the shared library, and /api/ws/connect, /api/ws/read, /api/ws/write, /api/ws/close, /api/ws/stats in the standalone API
  • New transportOptions fields readIdleTimeout, pingTimeout and responseHeaderTimeout
  • Clients of requests without sessionId are now closed after the request. destroySession / destroyAll and /api/free-session / /api/free-all close the clients of the freed sessions. Before, every one of them leaked a UDP socket and several goroutines when HTTP/3 was used.

Bug Fixes

  • HTTP/3 transports of lost or failed protocol races are closed, and the winning transport is reused instead of building a new one
  • Proxy dials (HTTP, HTTPS, SOCKS4, SOCKS5) and the CONNECT request are bounded by the client timeout and the request context. A stalled proxy no longer hangs the client.
  • WithTimeoutSeconds(0) no longer makes every request through an HTTP proxy fail immediately
  • HTTPS proxies now respect WithDialer and WithLocalAddr
  • HTTP/2 redials are bounded by the client timeout (DefaultTimeoutSeconds when the timeout is 0)
  • Hosts with non-ASCII characters (IDN) work, and a stale stashed connection no longer causes a panic and a deadlocked client
  • The transport cache is keyed by the port the scheme implies, which fixes https → http redirects
  • Reconnecting dials no longer write the transport cache (data race)
  • No empty User-Agent: line is sent on HTTP/1.1 when the header is set to nil or ""
  • Deflate bodies are decompressed when they are read, and closing an HTTP/2 response body is idempotent
  • An HTTP/2 connection that serves only one request now works when its first stream ID is not 1
  • brotli bumped to v1.2.7 (CVE-2026-111497)

Dependencies

  • utls v1.8.2-barnius (rebased on upstream), fhttp v0.7.3, quic-go-utls v1.0.13-utls, websocket v1.5.9-barnius

Known Issues
Both only affect clients that actually use HTTP/3, so a client without WithProtocolRacing() is unaffected.

  • Only chrome_144, chrome_144_PSK, firefox_147, firefox_147_PSK and firefox_148 carry their own HTTP/3 settings. Every other profile sends a minimal SETTINGS frame that does not match the browser it imitates, and its two settings go out in random order per connection. TLS and HTTP/2 fingerprints are unaffected. Use one of those five profiles, or set WithDisableHttp3() if the HTTP/3 fingerprint matters.
  • Both racing legs share one *http.Request, which is a data race on the header map. It shows up once many requests race at the same time and can crash the process. Prefer WithDisableHttp3() for high concurrent volume.

Full Changelog: v1.16.0...v1.18.1