Skip to content

Fluxheim 1.6.30

Choose a tag to compare

@eldryoth eldryoth released this 24 Jun 09:57
· 59 commits to main since this release
Immutable release. Only release title and notes can be modified.
v1.6.30
4d980e5

Fluxheim 1.6.30 Release Notes

Fluxheim 1.6.30 continues the Pingora-exit work by moving plaintext upstream
HTTP/2 forwarding into the native HTTP/1 proxy path.

Highlights

  • Native HTTP/1 proxy configs can now use
    proxy.upstream_http_version = "http2" with plaintext upstreams that speak
    h2c/prior-knowledge HTTP/2.
  • Native upstream HTTP/2 connections are pooled instead of torn down after a
    single request. The pool keeps the h2 connection driver alive, reserves stream
    capacity with proxy.upstream_h2_max_streams, invalidates stale handles after
    h2 errors, and retries safe methods once after a pre-response pooled-handle
    failure.
  • Native upstream H2 policy now receives proxy.read_timeout_secs,
    proxy.send_timeout_secs, proxy.upstream_h2_max_streams, and
    proxy.upstream_h2_ping_interval_secs.
  • TLS ALPN-negotiated upstream HTTP/2 is now supported for
    proxy.upstream_http_version = "http2" with the existing upstream TLS/SNI/CA
    policy. TLS http1-and-http2 fallback now advertises h2 and http/1.1
    and dispatches each request with the protocol selected by ALPN.
  • Plaintext proxy.upstream_http_version = "http1-and-http2" can now attempt
    HTTP/1.1 h2c Upgrade only when the new proxy.upstream_h2c_upgrade = true
    opt-in is set. The default remains false; refused upgrades fall back to a
    fresh HTTP/1.1 connection.
  • Live native proxy tests now prove downstream HTTP/1 requests can be forwarded
    to an in-process HTTP/2 origin, and that two downstream requests reuse one
    upstream H2 connection.
  • Additional native proxy tests prove H2 upstream pools reconnect after an
    origin closes a pooled H2 connection and round-robin across multiple static
    H2 upstreams.
  • Native proxy live tests now also prove weighted static upstream selection
    preserves the configured slot order while forwarding every selected upstream
    request over HTTP/2.
  • Native proxy live tests now prove safe-method failover works across static
    HTTP/2 upstreams and that unsafe methods are not replayed to another H2
    upstream after a failed first attempt.
  • Native upstream client tests now prove explicit plaintext h2c Upgrade reaches
    a real in-process HTTP/2 origin, and that origins refusing Upgrade fall back
    to HTTP/1.1 without replaying the downstream request during the probe.

Security Notes

  • Native upstream H2 handshakes are now bounded by the selected H2 policy
    timeout so an origin that accepts TCP and then stalls the HTTP/2 preface cannot
    freeze upstream setup indefinitely.
  • Native upstream H2 stream-slot waits are now bounded by the read timeout so
    later downstream requests cannot wait indefinitely when all upstream H2 stream
    capacity is occupied by slow responses.
  • Native upstream H2 requests and responses use the existing bounded H2 client
    policy: decoded header-count/list limits, URI/body limits, response body
    timeout, request upload lifetime, response header validation, and prohibited
    hop-by-hop response-header rejection.
  • Pooled native upstream H2 requests now run the same outbound H2 validation as
    one-shot H2 requests before acquiring stream capacity or opening an upstream
    connection.
  • Invalid programmatic upstream H2 stream limits now fail closed instead of
    silently reverting to the default policy.
  • Native upstream H2 pool creation no longer holds the pool mutex across TCP
    connect and H2 handshake work, avoiding serialized cold-start failures when an
    origin is unavailable.
  • Native upstream H2 pool creation is serialized by a dedicated setup lock, so a
    cold pool or post-invalidation retry cannot open one TCP/H2 connection per
    waiting stream slot.
  • proxy.read_timeout_secs now also bounds native H2 request readiness and
    response-header waits, not only response-body reads.
  • proxy.upstream_total_connection_timeout_secs now caps native H2 setup plus
    the first stream-readiness/response-header phase on a newly initialized H2
    connection.
  • Stream-scoped H2 failures no longer invalidate the whole H2 pool unless the
    h2 error reports a GOAWAY/connection-level condition.
  • Native plaintext upstream H2 keepalive pings run in a separate bounded task,
    wait for PONGs with the selected H2 handler timeout, and abort the connection
    driver when the peer stops acknowledging pings.
  • A wire-level native upstream H2 test now observes an actual client PING frame
    through a real h2 server IO wrapper, proving configured keepalive is emitted
    instead of only accepted by config.
  • A live rustls upstream test now proves the native proxy negotiates h2 with
    ALPN, forwards downstream HTTP/1.1 requests to a TLS HTTP/2 origin, and sends
    an HTTPS-scheme upstream H2 request.
  • Live rustls upstream tests now prove TLS http1-and-http2 fallback selects
    HTTP/2 when the origin negotiates h2 and falls back to HTTP/1.1 when no
    HTTP/2 ALPN protocol is selected.
  • Native cutover-plan tests now prove TLS http1-and-http2 upstream fallback
    is native-ready when a TLS backend is compiled, while plaintext
    http1-and-http2 remains HTTP/1.1-only unless proxy.upstream_h2c_upgrade
    is explicitly enabled.
  • Native upstream H2 stream permits are now named and explicitly released after
    response conversion, keeping the lifetime visible to reviewers and avoiding
    accidental future movement of the permit guard.
  • Native upstream H2 outbound request validation now has one enforcement point
    inside the H2 sender, avoiding duplicate prevalidation paths with drift-prone
    policy inputs.
  • Native upstream H2 programmatic configuration now enforces the same 1-1024
    stream cap as TOML validation, with a debug assertion on pool construction.
  • H2-only knobs on HTTP/1 upstream configs are rejected instead of silently
    ignored, and H1/H2 upstream request writers now share the same predicate for
    Fluxheim-owned header stripping.
  • Native diagnostics now distinguish supported upstream H2 modes from invalid
    mixed-mode configurations. Plaintext http1-and-http2 does not use H2 unless
    the explicit h2c Upgrade opt-in is enabled.
  • Native H2-to-HTTP/1 response conversion now strips hop-by-hop and
    proxy-owned headers such as transfer-encoding, upgrade, keep-alive,
    proxy-connection, te, and trailer, in addition to content-length,
    connection, and date.
  • Native upstream H2 retry handling now releases the stream-capacity permit
    before rebuilding a failed pooled H2 connection, then reacquires capacity
    immediately before sending the retry stream.
  • Non-TLS native builds now support plaintext http1-and-http2 only through
    the explicit h2c Upgrade opt-in; without it, mixed-mode plaintext fallback
    stays on HTTP/1.1.
  • proxy.upstream_h2c_upgrade is rejected unless an upstream is configured,
    the upstream is plaintext, and proxy.upstream_http_version = "http1-and-http2", keeping h2c Upgrade out of TLS and prior-knowledge H2
    configurations.
  • Explicit h2c Upgrade fallback now treats a closed/reset probe connection as
    an upgrade refusal and retries the original downstream request on a fresh
    HTTP/1.1 connection, while still treating probe timeouts as ambiguous and
    non-replayable.
  • H2 stream-capacity closure is no longer classified as a transport-level
    broken pipe, so explicit h2c mixed-mode fallback cannot downgrade and replay
    a request after an upstream H2 stream has already been opened.
  • The h2c HTTP2-Settings header now uses the infallible fixed-input encoder
    added by base64-ng 1.2.2, removing the previous local dead error branch
    while keeping Fluxheim on the hardened base64-ng dependency.
  • The h2c Upgrade response-head reader now checks only the trailing terminator
    bytes while reading one byte at a time, preserving post-upgrade H2 frames
    without an O(n²) scan.

Compatibility Notes

  • This release enables plaintext h2c/prior-knowledge, TLS ALPN H2 origins, and
    TLS http1-and-http2 fallback negotiation on the native path. Plaintext
    http1-and-http2 uses HTTP/1.1 by default; set
    proxy.upstream_h2c_upgrade = true only for origins known to implement
    HTTP/1.1 h2c Upgrade. This is intentionally not default because cleartext
    origins have no ALPN negotiation point and h2c Upgrade support varies by
    server.

Checksums And Signatures

  • Commit: 4d980e5c43ca8367f1fe565b6fa4143851690f82
  • Local gate: GitHub CI green before tag; local release metadata checks passed
  • CodeQL/code scanning: no open release-blocking alerts before tag
  • Source archive checksums:
    • 53af386c0d69b4e4a042e798941b5ff909d43e7e2a53425fb17a44637b716182 fluxheim-1.6.30.tar.gz
    • 6c086aaf82a2418ab85c78ec0da77bbabd5772e76230ae012c3338df5381c810 fluxheim-1.6.30.zip
  • Binary checksums:
    • x86_64:
      • 177db59096d82545c62707a27c3b1dc67cb64de04c61782ca301a8ef4d7d1cf0 fluxheim-1.6.30-full-x86_64-linux.tar.gz
      • bce9ebc9861a46257a676c8ef1affff07db60ee50bbddc0be61759c41a177ab4 fluxheim-1.6.30-cache-x86_64-linux.tar.gz
      • d1d158b9f09363b3f7b40d5ef4af7b76323084bc0c3b95b2951ddcb8ec2514b1 fluxheim-1.6.30-proxy-x86_64-linux.tar.gz
      • ddfe961305d7ae080348889b77c47e6581506dc9b36025aa051c5eca5640e382 fluxheim-1.6.30-php-x86_64-linux.tar.gz
      • f4fd78ee7ed05976caf7d6a2b5d454076a4b09900795a598edcc3aade308b6c8 fluxheim-1.6.30-load-balancer-x86_64-linux.tar.gz
      • 6f3fdd89a56891c1f163a131d634e9aaade6dc26965de54b05183545ab184a91 fluxheim-1.6.30-config-tester-x86_64-linux.tar.gz
    • aarch64:
      • 7e26f2adb2acbff62b3472743fc8fd18da747d1a00c8522ee2ba12738d0df44b fluxheim-1.6.30-full-aarch64-linux.tar.gz
      • 21778a66eec1ac9dab53b74f31c93a9eed02b61b912c6b6d02e2fd62d8b59654 fluxheim-1.6.30-cache-aarch64-linux.tar.gz
      • 08cd3188228c01993219c3c42c1fa681b43139d83e3c3d68de3ab1e7085ab6fb fluxheim-1.6.30-proxy-aarch64-linux.tar.gz
      • 1a54a3603baf4d33046363d7da4089fde8875a58a0a1adeba248bdf9c6b43c31 fluxheim-1.6.30-php-aarch64-linux.tar.gz
      • 01f89c5caebf5b9d1ac81d62b92ccf94453ac15005c4e3167cb46ce72499e4db fluxheim-1.6.30-load-balancer-aarch64-linux.tar.gz
      • a14a357f91b4263d6329163136cf6b3ad6b9bc3fbb9664e7e46092c98b3eb560 fluxheim-1.6.30-config-tester-aarch64-linux.tar.gz
    • macos:
      • 043e5cdd45e137a137f9ab1cc8e259c950e9687741b660c6db805c0e3f5e0f6a fluxheim-1.6.30-dev-aarch64-macos.tar.gz
  • SBOM checksums:
    • 1229f11218a6536c2856a562feaee2e4ec174a37799f04801bb9974013c02175 fluxheim.spdx.json
    • 02f037ddb23123964809e3bab85b2402def7c3756369d607b188f060f5e53f1f fluxheim.cyclonedx.json
  • Reproducible build:
    • 1cf47ba69a785a618a2097026c73305813cad68f2e0bf45fce903990453fd40b x86_64
    • 9108bfa48d0ba68635512de6bbef28d766ec15c62a1162e4078d6e41fa21e2cf aarch64
    • 44e8ef1fe73fd22ddec3118c895be3e1ee870564189262ed5ef22d1eb511b00a macos
  • Full Build Container digests:
    • Wolfi: ghcr.io/valkyoth/fluxheim@sha256:12ce09ad2e04fa09651c331402bbd54729b0f4a8dcf06e55ec312a143fbae8d9
    • Alpine: ghcr.io/valkyoth/fluxheim@sha256:0ae73c1cbc93501ffb7e9bc48aa5e5323fc74d41196e70e0240c570089b2f248
    • SUSE Micro: ghcr.io/valkyoth/fluxheim@sha256:f3bba93cce77cecaf3337c658b3d50195d81b5531465a12f7db2633b27989c85
    • Debian: ghcr.io/valkyoth/fluxheim@sha256:a4c1616d24b0e3a1f3f9dbe2dc96f27fa0098c38ee6de2595c90028f57631561
  • Cache Build Container digests:
    • Wolfi: ghcr.io/valkyoth/fluxheim@sha256:4cb0a051bb9b090f7b2cbc7fbe71ed45466f84c16df4b807792e2d6c8c828c43
    • Alpine: ghcr.io/valkyoth/fluxheim@sha256:4d05a44f4ecba24796d2640a98aa29ee68682e6d50352efde1ccba3393c9d54b
    • SUSE Micro: ghcr.io/valkyoth/fluxheim@sha256:08eb743a3deba42eee5c85ae5e8ea5c8c7b1ba2f09aedff0a2ae9f45c2cf0984
    • Debian: ghcr.io/valkyoth/fluxheim@sha256:7ae2fc69dd6fc06737d92d61767e3570aa1b90be98c3c39f683a575d078654af
  • Proxy Build Container digests:
    • Wolfi: ghcr.io/valkyoth/fluxheim@sha256:e48b1bac06fec79305f64cf31bee574317ba6a9425a64ad346559b4b9747230d
    • Alpine: ghcr.io/valkyoth/fluxheim@sha256:283765a6d9040f3e137733e67f22ceb473312e28f39690a1e132de7754252b6e
    • SUSE Micro: ghcr.io/valkyoth/fluxheim@sha256:d66413f3cfc8a458548aad05630d8c107f5e245a53b8a0094706a931b7e8e3e9
    • Debian: ghcr.io/valkyoth/fluxheim@sha256:e31880c640fd8975213d7a6c3150218fc037ed51d20724d878a614c917f66f56
  • PHP Build Container digests:
    • Wolfi: ghcr.io/valkyoth/fluxheim@sha256:791575afaa1212fd79e6a39ca42fbfe84b1b4ada54e51eaabe06f8aa8e9793dd
    • Alpine: ghcr.io/valkyoth/fluxheim@sha256:254c5304c8f68d132f8b10bb459d14e3d4e57ab056b40c9f766130729380edd6
    • SUSE Micro: ghcr.io/valkyoth/fluxheim@sha256:10251c1e8fef43e709f5ca4794ef289fe1185551c261438ce3690d337efb62aa
    • Debian: ghcr.io/valkyoth/fluxheim@sha256:15f0c6440cf01cbc594fc29dd4804c5b2eecbfd8b102323f20fbcf5a8f2d91fc
  • Load Balancer Build Container digests:
    • Wolfi: ghcr.io/valkyoth/fluxheim@sha256:9c12823b46c102155d45daccab4ac8eafbc1426c3a4e86523368cd73327eee6e
    • Alpine: ghcr.io/valkyoth/fluxheim@sha256:ceeec7a6b0e1d55f6d911651048a701033a94e2f8bf2fe6db50181fcdfebca5e
    • SUSE Micro: ghcr.io/valkyoth/fluxheim@sha256:3146e248b5fed0b1992600ee10723e8f3538f5d25ce05c72dad75609e68f3fdf
    • Debian: ghcr.io/valkyoth/fluxheim@sha256:313baf621cf4923be9cbcf561a5775b7dc1ba35e0cbb8e3211b1f6ad3797e75a
  • Tag signature:
    • Good "git" signature for 1921261+eldryoth@users.noreply.github.com with ED25519 key SHA256:EoLRQ5k4J5pYz3UMFmkrV798gYFNkToGS2xEPvebqB4