All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[Unreleased]

[0.21.17] - 2026-10-24

Added

  • Support disabling QUIC local idle expiry with idle_timeout: :infinity and bounded public PING admission for caller-managed keepalive. Preserve peer idle constraints and independent handshake, operation and closing bounds (#143).

[0.21.16] - 2026-10-22

Added

  • Document the role-neutral HTTP.HTTP2.HPACK public codec API, including stateful contexts, encoding policies, complete-block decoding limits and SETTINGS table-size coordination for client and server consumers (#141).

[0.21.15] - 2026-10-22

Fixed

  • Preserve opaque request-completion types across the public Fetch and Promise APIs so consumer Fetch/await composition passes Dialyzer without suppressing opacity checks (#139).

[0.21.14] - 2026-10-19

Added

  • Confirmed pre-HTTP TLS setup failure evidence for ordinary direct HTTP/1 structured requests after ServerHello, with tracked receiver/sender cleanup. Earlier or ambiguous TLS failures remain unconfirmed; caller-managed failover still requires successful completion and deadline/cancellation checks (#135).

Fixed

  • Redact private WebSocket connection state, messages and errors from OTP status and termination diagnostics. Normalize abnormal process exits and cleanup failures to :shutdown to suppress independent private crash reports while preserving normal transport processing (#136).
  • Report cleanup as unconfirmed when OTP TLS setup fails without returning a trackable TLS socket, including proxy and HTTP/2 setup. TCP closure or dial helper termination cannot certify the missing TLS receiver/sender cleanup (#135).

[0.21.13] - 2026-10-16

Added

  • Per-request ordinary HTTP/1 response consumer delivery/acknowledgement deadlines, including :infinity, across both Stream and socket producer waits. Existing finite defaults, network idle policies, cancellation and total limits stay independent (#131).

Fixed

  • Confirm fixed-length HTTP/1 upload source completion before exposing an immediate peer response, preserving enumerable resource finalization. Source failures and bounded completion expiry fail the request; genuinely early responses and cancellation retain bounded teardown (#132).

[0.21.12] - 2026-10-16

Added

  • Per-request HTTP/1 response stream idle policy, including :infinity, without changing global configuration or consumer acknowledgement safety. Response readers follow the policy; socket idle deadlines, cancellation and owned cleanup remain independent (#129).

[0.21.11] - 2026-10-15

Added

  • Independent HTTP/1 read and write idle deadlines for TCP, OTP TLS and ExSSL, with positive millisecond options, direction-specific progress, typed timeout reasons and owned cleanup. Preserve total request/connect limits, cancellation and streaming backpressure; reject unsupported protocols and managed scopes explicitly (#126).

[0.21.10] - 2026-10-15

Fixed

  • Preserve HTTP/1 cancellation when cleanup closes the socket during post-send activation or final send result delivery, retaining independent transport and protocol failures and the existing logical cleanup barrier (#122).
  • Reject non-HTTP/1 textual response versions before accepting headers or bodies on OTP TLS and ex_ssl, preserving compatible HTTP/1 minor versions and closing rejected connections without replay or reuse (#121).

[0.21.9] - 2026-10-15

Fixed

  • Support unlimited HTTP/1 request and connection timeouts without deadline arithmetic crashes. Preserve independent finite connection/request limits, streamed upload/download cancellation and owner cleanup.

[0.21.8] - 2026-10-14

Fixed

  • Reject malformed HTTP/1 status lines and chunk syntax, conflicting response Transfer-Encoding/Content-Length, and oversized completed chunk lines while preserving valid extension grammar and connection cleanup without replay.
  • Accept valid ASCII HTTP extension methods, including DAV PROPFIND and REPORT, preserving binary method case, bodies and authorization without creating atoms from caller-supplied method strings.
  • Validate a certificate path ending at a supplied trust anchor when the peer includes trailing cross-signed alternatives. Preserve PKIX signatures, hostname, validity, depth and certificate-signature policy checks.

[0.21.7] - 2026-10-14

Fixed

  • Observe connection worker exits and promptly return a sanitized connection failure instead of waiting for the connect timeout. Preserve socket cleanup, cancellation, subscriber death and finite deadlines during connection setup.

[0.21.6] - 2026-10-14

Added

  • Accept the optional fixed alpn_advertised_protocols: ["http/1.1"] policy for managed HTTP/1 OTP TLS scopes. Preserve the default without ALPN and reject conflicting protocol overrides.

Fixed

  • Bound QUIC receive ACK history by retiring old ranges instead of closing active connections when historical packet-number gaps fill the range limit. Ignore duplicate and retired packets before applying stream or control effects, while preserving valid reordering and retransmissions with fresh packet numbers.

[0.21.5] - 2026-10-13

Fixed

  • Make HTTP/3 Session uploads progress when peer stream or connection credit cannot admit a complete transport fragment. Split definitely blocked sends while preserving byte order, the terminal FIN and the original deadline; reconcile uncertain sends without replaying accepted data.

[0.21.4] - 2026-10-13

Fixed

  • Send ordered, repeated HTTP/3 request trailers through HTTP.Stream.finish/2, including zero-DATA uploads and valid Trailer declarations. Trailing HEADERS finish the request exactly once; asynchronous failures, cancellation, finite deadlines and unknown-operation reconciliation retain their existing behavior.
  • Use a stable managed HTTP/1 response writer session with consumer-driven chunk acknowledgements instead of creating a stream monitor for every chunk. Retain uncertain chunk ownership after timeout, abort and deadline.
  • Coalesce HTTP/1 pool expiration into a reference-matched maintenance timer while enforcing pending handoff and idle checkout deadlines independently. Validate handoff deadlines before tracker monitors are released; ignore stale scope reconciliation timers and wait for tracker termination on completion.

Documentation

  • Record the pinned OTP managed-H1 control-accounting audit, workload/build manifest, proof gaps and empirical TLS stress evidence. These hardening changes do not certify native/deferred memory reclamation or a numerical activation budget. Issue #97 remains open; Gaoxy numerical managed production stays disabled.

[0.21.3] - 2026-10-11

Fixed

  • Preserve the original streamed response failure during internal request cleanup, including HTTP/1 chunk-line and trailer parser errors. Late first readers can observe the terminal error; unread responses retain their request lease and keep completion pending until consumed or explicitly cancelled.
  • Preserve abort and deadline errors for late readers of response streams from requests without a completion tracker, including default redirect-follow requests.

[0.21.2] - 2026-10-11

Fixed

  • Track OTP 27 and OTP 28 TLS receiver and sender processes independently through connection setup, HTTP/1 reuse and HTTP/2 pool handoff. Retain managed connection capacity and retirement barriers until both processes terminate.
  • Retire managed generations with unconfirmed cleanup when TLS setup returns no resource inventory or an unsupported socket representation. Preserve durable retirement receipts after the coordinator has terminated.

[0.21.1] - 2026-10-11

Fixed

  • Bound HTTP/2 informational response notifications per request and coalesce pool capacity updates, preserving sibling streams and shared HPACK state. Compact retained header fragments, raw HPACK literals and frame remainders.
  • Normalize managed request inputs into owned binaries, bound buffered iodata traversal, and charge generated HTTP/1 and HTTP/2 fields before admission.
  • Own compact frozen TLS/socket policy binaries while preserving credential verification, policy identity and redacted status. Document retained payload, representation and preparation transient limits separately.
  • Return the documented managed connection-capacity error while HTTP/2 connections drain, preserving completion, retirement and explicit replacement.

[0.21.0] - 2026-10-11

Added

  • Add caller-owned managed HTTP/1 and HTTP/2 transport scopes with private pools, finite admission, frozen destination and TLS policy, bounded status, and durable graceful/abort retirement receipts. Keep request cleanup completion separate from whole-scope retirement. Managed scopes support direct TCP/OTP TLS, explicit protocols, and raw streamed responses with manual/error redirects; reject unsupported policies before dialing.
  • Extend request completion to supported explicit HTTP/HTTPS proxy routes, including pending CONNECT/TLS, uploads, response streams, cancellation and safe pooled return. Preserve proxy identity and authentication isolation.

Fixed

  • Limit each inbound HTTP/2 header block to 256 frames, including empty HEADERS/CONTINUATION and the final frame, and omit empty fragment storage. Reject excess fragmentation at connection scope while preserving separate connections and existing compressed-byte, HPACK and decoded-header limits.

[0.20.0] - 2026-10-10

Added

  • Extend request cleanup completion to pooled HTTP/1 and explicit HTTP/2/h2c requests. Confirm safe HTTP/1 pool handoff or closure, and HTTP/2 stream, helper, delivery and reservation release without closing healthy siblings.
  • Support bounded HTTP/2 upload trailers through HTTP.Stream.finish/2, with ordered fields, shared HPACK encoding, atomic HEADERS/CONTINUATION writes, peer header-list limits and request-local validation failures.
  • Add opt-in error_mode: :structured and HTTP.RequestError.pre_send?/1 evidence for confirmed failures before direct TCP establishment. Preserve raw errors by default and leave validated-address failover to the caller.
  • Support explicit HTTPS proxies for HTTP origins with verified proxy TLS, absolute-form HTTP/1 forwarding and isolated pooled connections. Reject HTTPS origins through HTTPS proxies before dialing; never fall back directly.

Fixed

  • Stop caller upload streams and wake blocked producers on terminal request failures, including proxy and pooled-route failures before connection setup. Preserve successful header-first responses and early-response cleanup.

[0.19.1] - 2026-10-10

Fixed

  • Preserve the ? delimiter for a present empty query in HTTP request targets, including streaming proxy-mode requests and HTTP proxy absolute-form targets.

[0.19.0] - 2026-10-10

Added

  • Expose HTTP.Promise.completion/1 and bounded HTTP.RequestCompletion.await/2 / abort_and_await/2 for request-scoped cleanup confirmation on explicit HTTP/1 requests without connection reuse, using manual/error redirects and direct TCP or OTP TLS transport.
  • Distinguish confirmed cleanup, cleanup still pending at the caller's deadline, and cleanup whose completion cannot be confirmed. Preserve asynchronous AbortController cancellation and streaming Promise response behavior.

Fixed

  • Abort the WebSocket transport when its owner exits during a blocked TLS write, and settle pending writes before stopping the connection.

[0.18.1] - 2026-10-10

Fixed

  • Preserve the original IPv4/IPv6 certificate identity with ExSSL when upgrading HTTP proxy CONNECT tunnels or dialing a different pinned address.
  • Allow an explicit ExSSL certificate reference identity independently of SNI while retaining mandatory peer verification and socket upgrade checks.
  • Isolate TLS session tickets by both certificate reference identity and SNI.
  • Retain SNI-derived certificate verification for ordinary ExSSL calls unless an explicit independent reference identity is supplied.
  • Process already-delivered HTTP/1 WebSocket frames before finalizing TCP or TLS read termination; retain abnormal closure when no valid peer Close exists.

[0.18.0] - 2026-10-10

Added

  • Return header-first Fetch responses with stream_response: true and retain acknowledged streaming backpressure and cancellation.
  • Preserve GET, HEAD and DELETE request bodies with request_mode: :proxy; ordinary Fetch behavior remains the default.
  • Expose bounded HTTP/1 WebSocket proxy frames, acknowledged frame writes, configurable automatic pong and validated wire close codes.
  • Support explicit HTTP proxies with absolute-form forwarding and HTTPS CONNECT tunnels, isolated proxy authorization and origin TLS verification.
  • Add opt-in bounded HTTP/1 keep-alive reuse with route, TLS and caller isolation.
  • Accept validated IPv4/IPv6 connect_address pins while preserving original HTTP authority, TLS identity and trust. Require explicit redirect handling; reject unsupported proxy, Unix and HTTP/3 combinations before network I/O. ExSSL cannot yet verify a distinct original literal IP against a pinned address; this case rejects explicitly pending upstream issue #49.

Fixed

  • Return consistent closed readiness errors when a QUIC connection exits normally during a call; retain timeouts and unexpected exit reasons.

Changed

  • Update Dialyxir, Earmark Parser, Erlex, ExDoc, Jason, Makeup, Makeup Erlang and Telemetry to current compatible releases. Retain Credo 1.7.13 because newer releases report unrelated existing nesting violations.
  • Verify candidate-package Telemetry archives against the version and checksum in the lockfile instead of a fixed historical version.

[0.17.2] - 2026-10-09

Added

  • Expose bounded HTTP/1 request and response trailers, including HTTP.Stream.finish/2 for streamed request trailers.
  • Provide acknowledged WebSocket writes with finite deadlines and document the public WebSocket client boundary for reverse proxies.
  • Support decode_body: false to preserve original response bytes across HTTP/1, HTTP/2 and HTTP/3, for both buffered and streamed responses.

Fixed

  • Read HTTP/1 responses while streaming uploads are backpressured; stop unfinished uploads on early final responses and bound cancellation for plain TCP, OTP TLS and ExSSL without replaying uncertain writes.
  • Remove credentials and nested request secrets from Fetch telemetry by default and honor per-request and global telemetry opt-outs.
  • Validate WebSocket handshakes and clean up blocked writes on cancellation, deadlines and owner loss, including verified secure connections.

[0.17.1] - 2026-10-09

Fixed

  • Preserve declared Content-Length for streaming HTTP/1 and HTTP/2 uploads, reject length mismatches, and retain producer backpressure and cancellation.
  • Transparently decode gzip and zlib-wrapped deflate response Content-Encoding for buffered and streamed Fetch consumers across HTTP/1, HTTP/2, and HTTP/3; preserve archive bytes when Content-Encoding is absent.
  • Strip URL credentials from every WebSocket telemetry event and support omitting or explicitly replacing telemetry URLs without changing handshakes.
  • Correct migration provenance to describe the available synchronized Hex graph.

[0.17.0] - 2026-10-06

Added

  • Preserve bounded, ordered HTTP/2 informational responses and separate buffered and streamed trailers through the existing response and stream APIs.
  • Gate shared transport and tooling changes against affected Fetch, EventSource and WebSocket consumers, with independent peer traffic and package evidence.
  • Document the scoped HTTP/2 beta support contract and rollout/rollback runbook.

Fixed

  • Bound reusable automatic HTTPS negotiation before dialing, settle HTTP/1.1 fallback claims, and clean up admission on cancellation, deadlines and exit.
  • Honor peer stream capacity after the single initial automatic H2 reservation, including zero capacity and saturated admission queues.

Validation

  • Frozen HTTP/2 candidate passed all 78 acceptance gates, both genuine 30-minute soaks, automatic CI and full CI/Test/E2E. Retain measured resources, package checksums, rejected attempts and limits in docs/http2-beta-validation.md.

[0.16.7] - 2026-10-06

Added

  • Report HTTP/3 beta and static/literal QPACK capabilities in the companion; keep raw QUIC HTTP/3 and deferred application features unsupported.
  • Require digest-pinned Caddy and aioquic public acceptance, isolated candidate and published Hex traffic, negative TLS checks, and retained peer diagnostics in coordinated releases.
  • Add the scoped 24-hour canary with explicit cleanup, memory, mailbox, process, endpoint and error thresholds, as separate asynchronous validation against the release tag and published packages; interrupted pre-release evidence is retained without claiming a completed 24-hour pass.

Fixed

  • Transfer owner-proven unopened requests at concurrent lifetime rotation using their original deadlines and untouched bodies; sent or unknown admissions retain their original reconciliation path.

[0.16.6] - 2026-10-05

Added

  • Enable strict, verified HTTP/3 Fetch with binary and streamed uploads, process-backed downloads, abort and total-deadline handling.
  • Expose actual network protocol in Response and request-stop telemetry; retain bounded informational fields and expose buffered/streamed trailers.
  • Add explicit HTTP/3 EventSource with acknowledged deliveries, cursor-aware reconnect, secure readiness, redirects and native error classification.

Fixed

  • Remove known-unsent queued requests promptly on abort or subscriber death; preserve reconciliation for already-pending native operations.
  • Reject streamed-body redirect replay and cross-origin client-identity reuse.

Validation

  • Native public API regressions and pinned independent aioquic/Caddy public integrity, TLS negatives, multiplexing, SSE and connection-rotation evidence. Final required CI/artifact/canary acceptance is recorded separately in WP5.

[0.16.5] - 2026-10-05

Added

  • Supervised HTTP/3 owners, bounded leases and request relays, demand-driven body bridges, safe connection identity, GOAWAY draining and lifetime rotation.
  • Bounded receive credit for 32 concurrent streams, with explicit validation of owned and borrowed endpoints and isolation for paused consumers.

Fixed

  • Accept valid QUIC NEW_TOKEN frames and authenticated RFC 9001 peer key updates, preserving reordered previous-phase packets and rejecting invalid transitions.
  • Install production dependencies before each staged Hex publication and verify the prepared package still rebuilds to the audited archive bytes.
  • Move the HTTP/3 facade into runtime and declare its companion dependency in source, CI closures, portable packages and isolated consumers.

Validation

  • Native and pinned aioquic runtime integrity, concurrency, backpressure and cleanup gates; authenticated stock Caddy binary POST interoperability. Public Fetch HTTP/3 remains unsupported until WP4.

[0.16.4] - 2026-10-05

Fixed

  • Frame binary and demand-driven uploads as HTTP/3 DATA, retain blocked work without freezing sibling reads, and retire completed requests exactly once.
  • Decode responses incrementally with separate header and retained-byte limits, informational/final/trailer validation, critical streams, and GOAWAY admission.
  • Correct all 99 QPACK static indexes and preserve indexed/literal field order.
  • Use uv to install the release peer dependencies in its Python environment.

Validation

  • Native adapter regressions and a pinned independent aioquic binary echo gate. Public Fetch HTTP/3 remains unsupported pending runtime integration.

[0.16.3] - 2026-10-05

Fixed

  • Compose HTTP/3 sessions with native QUIC generations, authenticated H3 readiness, consistent stream handles, retained operation references, and explicit endpoint ownership and terminal teardown.
  • Preserve cancellation isolation and reconcile ambiguous admission without replaying request bytes or destructive reads.
  • Repair the baseline ServerHello Dialyzer warning without changing GREASE handling, and make release tests independent of the prepared patch version.

Validation

  • WP1 native-contract seams and local UDP session tests; public Fetch HTTP/3 remains unsupported until the runtime and independent acceptance gates.

[0.16.2] - 2026-10-05

Fixed

  • Restore Fetch's test dependency in isolated WebSocket and EventSource CI jobs.
  • Inspect candidate Hex archives in memory using Hex's supported unpack mode.

Validation

  • WP0 baseline restoration; see docs/http3-wp0-baseline.md and docs/http3-implementation-audit.md. HTTP/3 remains unsupported at this step.

[0.16.1] - 2026-10-01

Changed

  • Remove the elixir_quic_http3 sub-app after its migration to gsmlg-dev/ex_quic, including unused dependencies from Fetch and WebTransport.
  • Update six-package CI, release, and consumer tooling and current documentation to reflect the new ownership boundary. HTTP/3 and WebTransport selectors remain explicitly unsupported pending integration and interoperability work.

Fixed

  • Keep isolated package consumers on explicit shared local dependency overrides after removing the migrated package.

[0.16.0] - 2026-10-01

Added

  • Extract http_runtime as the shared, independently installable HTTP/2 owner, pool and stream application used by Fetch, EventSource and WebSocket.
  • Add explicitly selected HTTP/2/h2c EventSource and RFC 8441 WebSocket support, acknowledged delivery, finite parsing/send/delivery bounds and actual-version accessors. Preserve HTTP/1 defaults and explicit TLS backend selection.
  • Add independent SSE/WebSocket/mixed peers, standalone package traffic gates and a reproducible final acceptance entrypoint with original Fetch42 workloads.

Fixed

  • Preserve ordinary Fetch early-response upload cleanup while accepted CONNECT tunnels remain duplex; gate admission on peer capability without blocking ordinary siblings or consuming stream capacity while waiting.
  • Settle logical stream resources on close, owner death, reset and runtime restart, retain accepted bytes before terminal errors, and stop parsing after an internal WebSocket terminal failure.
  • Mask WebSocket payloads using binary words to avoid per-byte list heap growth.

Validation

  • See docs/http2-stream-clients-validation.md for exact phase/final-candidate results, source and artifact checksums, backend/peer matrices and resource observations. Short runner checks are explicitly distinct from 30-minute soaks.

[0.15.1] - 2026-09-30

Fixed

  • Stop abandoned HTTP/2 uploads atomically after final response headers, retain incomplete response bodies and trailers, and close unfinished request halves before releasing peer capacity without replaying upload DATA.
  • Promote queued, never-sent requests when connection capacity becomes available, including owner shutdown, draining, cross-origin capacity release, and a saturated surviving sibling, while preserving deadlines and connection limits.
  • Preserve sibling upload scheduling when an already-stopped stream is removed again during cleanup.

Validation

  • Add deterministic wire-level early-response, queued-admission, lifecycle and package-consumer regressions with explicit event barriers.
  • Complete all 42 local HTTP/2 acceptance gates, including both independent peers, supported transports, 10-MiB transfers, 10,000-request reuse workloads and a full 30-minute mixed soak. See docs/http2-production-validation.md for exact candidate provenance, outcomes, resource bounds and archived evidence.

[0.15.0] - 2026-09-30

Added

  • Include elixir_quic_http3 in the coordinated six-package release, with versioned HTTP/3 dependencies for Fetch and WebTransport and standalone package-consumer validation.

Changed

  • Route explicit HTTP/2 and h2c requests through supervised, profile-aware pooled owners, including requests without an explicit wire profile.
  • Reclaim completed protocol streams; slice binary and streaming uploads by available peer credit; bound download admission and return stream credit on consumption.
  • Validate frame boundaries, response phases and lengths, HPACK table updates, and peer settings; preserve typed reset/GOAWAY outcomes and original deadlines.
  • Advertise no server push in wire-profile revision 2, with cold/warm header ordering applied once. Keep synthetic profiles explicitly synthetic.
  • Add redacted connection/pool telemetry and independent peer/package/soak gates.

Known limitations

  • HTTP/2 production acceptance remains in progress; see docs/http2-production-validation.md for failing or unrun blocking gates.

[0.14.0] - 2026-09-29

Added

  • Add an internal authenticated QUIC client adapter with bounded stream I/O, cancellation, operation outcome tracking, and lifecycle validation.
  • Add published TLS consumer provenance and independent resumption coverage for HTTP/1.1, HTTP/2, WebSocket, and EventSource.
  • Add validated versioned HTTP/2 wire profiles, ordered serialization controls, pure connection/stream state models, and bounded redacted fingerprint observations.
  • Add flat HTTP/2 profile, reuse, scope, and priority option validation.
  • Add bounded PRIORITY_UPDATE handling, upload credit recovery after WINDOW_UPDATE, peer MAX_FRAME_SIZE DATA fragmentation, and capture provenance manifest validation.

Changed

  • Use Hex elixir_quic ~> 0.2.2 and ex_ssl ~> 0.7.2, with no runtime Git pins.
  • Preserve OTP TLS defaults and existing production HTTP/3/WebTransport paths.

Known limitations

  • The new adapter does not implement HTTP/3 sessions or QPACK. The Abyss joint raw-stream test awaits its published-engine namespace migration (abyss #5).
  • Full drain-deadline policy, broader independent mature-implementation interoperability, and captured browser-profile verification remain pending. Profiled h2c and HTTPS h2 pooling support overlapping socket streams while preserving TLS/profile identity isolation.

[0.13.0] - 2026-09-22

Changed

  • Publish all five packages at the shared 0.13.0 version and update their internal http_core dependency requirements to ~> 0.13.0.
  • Retain the ex_ssl ~> 0.4.0 integration from 0.12.0 without further runtime changes; OTP :ssl remains the default TLS backend.

[0.12.0] - 2026-09-22

Added

  • Add verified ex_ssl 0.4.0 TLS 1.2 support across Fetch, HTTP/2, WebSocket, and EventSource, and opt-in TLS 1.3 ticket resumption over fresh HTTP/1.1 connections. The default remains verified TLS 1.3 with tickets disabled.
  • Forward validated ex_ssl client identities, TCP socket options, and ordered TLS 1.3 algorithm preferences. Pin client identities to the redirect origin.

Changed

  • Keep OTP :ssl as the default TCP TLS backend while allowing verified TLS 1.3 or explicitly selected TLS 1.2 through the optional :ex_ssl backend. HTTP/3 and WebTransport continue to use QUIC's independent TLS implementation.
  • Run individual app tests and E2E suites from the umbrella root after explicit test-environment preparation, so transitive runtime applications are compiled and on the code path even on cold checkouts.
  • Validate all five built packages in an isolated external consumer, including transitive dependencies and verified local TLS requests.

Fixed

  • Deliver complete HTTP/2 responses when the peer closes immediately after an END_STREAM DATA frame and a non-essential WINDOW_UPDATE or acknowledgement returns :closed. Incomplete responses and required request writes before response completion still fail normally.
  • Preserve unread ex_ssl TLS records when an HTTP/2 control write fails after normal peer closure. Drain them through the existing active-once receiver and require a complete HTTP/2 response, without extending deadlines or accepting truncated responses, error resets, or protocol errors.
  • Preserve valid HTTP/2 early final responses while cancelling remaining upload DATA, including queued DATA released by WINDOW_UPDATE. Accept NO_ERROR resets only after response completion; require END_STREAM and a complete field block even for responses with no body.
  • Enforce HTTP/2 response Content-Length and bounded frame/header parsing while preserving valid cross-record and streaming completion after peer closure.

[0.11.0] - 2026-07-04

Added

  • Added Fetch-style streaming response bodies by exposing the stream PID in response.body, while keeping response.stream as a compatibility alias.
  • Added HTTP/1.1 streaming request uploads with HTTP.Stream bodies and duplex: "half" chunked request framing.

Changed

  • Updated response helpers, docs, and e2e coverage for the new streamed body shape.
  • Return explicit unsupported errors for streaming request bodies on HTTP/2 and HTTP/3 instead of buffering or misframing them.

[0.10.0] - 2026-07-01

Added

  • Added independent http_web_socket, http_event_source, and http_web_transport umbrella apps with browser-like protocol APIs.
  • Added e2e coverage for EventSource, WebSocket, and WebTransport workflows.

Changed

  • Extracted shared HTTP primitives into the http_core app so protocol apps share common code without depending on http_fetch.
  • Updated CI, test, e2e, and release workflows to cover every umbrella app and publish all packages with one shared version.

[0.9.1] - 2026-06-23

Changed

  • Removed legacy :httpc compatibility option buckets from HTTP.fetch/2. Fetch init options are now flat, and redirects use redirect: :follow | :manual | :error.

Fixed

  • Validate response Transfer-Encoding framing instead of falling back to Content-Length for unsupported transfer codings.
  • Keep completed empty streams readable for late consumers.
  • Make the Unix socket e2e coverage independent of a host Docker daemon.
  • Align release metadata, README examples, and project guidance with the socket transport.

[0.9.0] - 2026-06-17

Changed

  • Replaced :httpc with the internal socket transport while preserving the default redirect-following behavior; pass autoredirect: false to return redirect responses.
  • Legacy :httpc options that are not implemented by the socket transport are documented as compatibility-only options.

[0.7.0] - 2025-01-XX

Added - Browser Fetch API Compatibility (~85% API Parity)

  • HTTP.StatusText module - Maps HTTP status codes to standard status text messages (60+ codes)
  • Response.status_text - Status message property (e.g., "OK", "Not Found")
  • Response.ok - Boolean property indicating success (true for 200-299 status codes)
  • Response.body_used - Tracks body consumption (field exists for API compatibility)
  • Response.redirected - Indicates if response was redirected
  • Response.type - Response type (:basic, :cors, :error, :opaque)
  • Response.new/1 - Constructor helper that auto-populates Browser API fields
  • Response.clone/1 - Clone response for multiple reads (buffers streaming responses)
  • Response.arrayBuffer/1 - Read body as binary (ArrayBuffer equivalent)
  • Response.array_buffer/1 - Snake_case alias for arrayBuffer
  • HTTP.Blob module - Blob struct with data, type, and size fields
  • Response.blob/1 - Read body as Blob with metadata (extracts MIME type from headers)
  • Comprehensive Browser API compatibility documentation in README
  • 41 new tests covering all Browser Fetch API features

Changed - Breaking Changes for Browser API Compatibility

  • Response struct fields added: status_text, ok, body_used, redirected, type
    • Migration: Update pattern matches to ignore new fields or use variable binding
    • Example: %Response{status: 200} = response (ignores new fields)
  • Response construction: All internal Response creation now uses Response.new/1
    • Ensures consistent Browser API field population
    • Migration: Use Response.new/1 instead of direct %Response{} for consistency
  • body_used field: Present for Browser API compatibility but doesn't enforce in Elixir
    • Due to Elixir's immutability, multiple reads of the same response value work
    • Use clone/1 for clarity when reading multiple times

Documentation

  • Added "Browser Fetch API Compatibility" section to README with examples
  • Documented Elixir-specific differences (immutability, synchronous returns, streams)
  • Updated all Response documentation to reflect new Browser API properties
  • Added comprehensive examples for clone/1, arrayBuffer/1, and blob/1

Notes

  • This release prioritizes Browser Fetch API compatibility over Elixir-specific patterns
  • The body_used field exists for API compatibility but cannot prevent multiple reads due to immutability
  • All critical Browser Fetch API Response properties and methods are now supported

[0.5.0] - 2025-08-01

Added

  • HTTP.Telemetry module - Complete telemetry integration for HTTP request monitoring
    • Request lifecycle events with rich metadata
    • Response body reading events for tracking download progress
    • Streaming events for real-time data transfer monitoring
    • Zero configuration integration with Elixir's :telemetry library

Changed

  • Updated default User-Agent string format to include library version 0.5.0
  • Enhanced telemetry event metadata with improved error reporting

[0.4.3] - 2025-08-01

Added

  • Added HTTP.Headers.set_default/3 method to set headers only if they don't already exist
    • Uses case-insensitive header name matching
    • Preserves existing headers when they already contain the specified name
  • Added automatic default User-Agent header to all HTTP requests
    • Format: Mozilla/5.0 (macOS; aarch64-apple-darwin24.3.0) OTP/27 BEAM/15.2.3 Elixir/1.18.3 http_fetch/0.4.3
    • Includes OS information, system architecture, OTP version, BEAM version, Elixir version, and library version
    • Uses dynamic version detection via Application.spec(:http_fetch, :vsn)
    • Preserves custom User-Agent headers when provided
  • Added HTTP.Headers.user_agent/0 method to access the default User-Agent string
  • Added comprehensive HTTP.Telemetry module for HTTP request metrics and monitoring
    • Request lifecycle events: [:http_fetch, :request, :start], [:http_fetch, :request, :stop], [:http_fetch, :request, :exception]
    • Response body reading events: [:http_fetch, :response, :body_read_start], [:http_fetch, :response, :body_read_stop]
    • Streaming events: [:http_fetch, :streaming, :start], [:http_fetch, :streaming, :chunk], [:http_fetch, :streaming, :stop]
    • Rich metadata: Includes URLs, HTTP status codes, response sizes, durations, and error reasons
    • Automatic integration: All HTTP.fetch operations automatically emit telemetry events
    • Zero configuration: Works out of the box with Elixir's :telemetry library

Changed

  • Enhanced User-Agent string to include system architecture information
  • Refactored User-Agent generation for consistency across the codebase
  • Updated default headers handling to use set_default/3 for better extensibility

[0.4.2] - 2025-08-01

Added

  • Added HTTP.Response.write_to/2 method to write response bodies to files
    • Supports both streaming and non-streaming responses
    • Automatically creates directories if they don't exist
    • Returns :ok or {:error, reason} for proper error handling

Fixed

  • Fixed streaming implementation message format for complete responses
  • Increased streaming threshold from 100KB to 5MB to prevent issues with large files
  • Fixed test assertion for content-length comparison using byte_size/1 instead of length/1

Changed

  • Updated streaming threshold to prevent streaming for files under 5MB
  • Improved streaming process error handling

[0.4.1] - 2025-07-31

Added

  • URI struct support - HTTP.fetch/2 now accepts both string URLs and %URI{} structs
  • Enhanced URL handling - Automatic conversion from string to %URI{} for internal processing
  • Type safety improvements - HTTP.Request and HTTP.Response now use %URI{} internally
  • Improved Request field naming - More intuitive field names for :httpc.request mapping

Changed

  • Refactored URL handling - All internal representations now use %URI{} instead of string
  • Updated type specifications - HTTP.Request.url type changed from String.t() | charlist() to URI.t()

  • Updated Response.url type - Changed from String.t() to URI.t()
  • Updated function signatures - handle_httpc_response and related functions now accept URI.t()
  • HTTP.Request field renaming for better clarity:
    • options → http_options (3rd argument to :httpc.request)
    • opts → options (4th argument to :httpc.request)

Technical Details

  • Backward compatibility - String URLs are automatically parsed to URI structs
  • Consistent URI handling - All internal operations use parsed URI structs
  • Eliminated redundant parsing - Removed duplicate URI.parse calls in streaming functions
  • Enhanced type safety - Stronger typing throughout the codebase
  • Updated test suite - Request tests updated to use URI.parse/1 for consistency
  • Improved field documentation - Clear mapping to :httpc.request arguments

[0.4.0] - 2025-07-30

Added

  • HTTP.FetchOptions module - New dedicated module for processing fetch options with full httpc support
  • Enhanced option handling - Support for all :httpc.request options including timeout, SSL, streaming, etc.
  • Multiple input formats - Accept keyword lists, maps, or HTTP.FetchOptions struct
  • Complete httpc integration - Proper separation of HttpOptions and Options for :httpc.request
  • Type-safe configuration - Structured approach to HTTP request configuration
  • Comprehensive option coverage - All documented :httpc.request options supported
  • HTTP.FormData module - New dedicated module for handling form data and multipart/form-data encoding
  • File upload support - Support for file uploads with streaming via File.Stream.t()
  • Automatic content type detection - Automatically chooses between application/x-www-form-urlencoded and multipart/form-data
  • Streaming file uploads - Efficient large file uploads using Elixir streams
  • Form data builder API - Fluent interface with new/0, append_field/3, append_file/4-5
  • Multipart boundary generation - Automatic random boundary generation for multipart requests
  • Comprehensive test coverage - Full test suite for form data and fetch options functionality

Changed

  • HTTP.fetch refactored - Now uses HTTP.FetchOptions for consistent option processing
  • HTTP.Request body parameter - Now accepts HTTP.FormData.t() for form submissions
  • Enhanced content type handling - Automatic content-type detection and header setting
  • Improved multipart encoding - Proper multipart/form-data format with boundaries
  • Unified configuration API - All configuration goes through HTTP.FetchOptions

Technical Details

  • HTTP.FetchOptions struct with comprehensive field support for all httpc options
  • FormData struct with parts array for form fields and file uploads
  • Streaming support via File.Stream.t() for memory-efficient file uploads
  • URL encoding fallback for simple form data without file uploads
  • Backward compatibility maintained for existing string/charlist body usage

[0.3.0] - 2025-07-30

Fixed

  • HTTP option placement - Fixed body_format: :binary option being passed to wrong :httpc argument
  • Eliminated warning messages - Removed "Invalid option {body_format,binary} ignored" notices during tests
  • Improved error handling - Enhanced response handling for malformed URLs and network errors

Technical Details

  • Corrected httpc arguments - Proper separation of request options vs client options
  • Cleaned up streaming setup - Removed redundant option configurations
  • Enhanced test reliability - Reduced external dependency flakiness

[0.2.0] - 2025-07-30

Added

  • HTTP.Headers module - New dedicated module for HTTP header processing
  • Structured headers - HTTP.Request and HTTP.Response now use HTTP.Headers.t() struct
  • Header manipulation utilities - new/1, get/2, set/3, merge/2, delete/2, etc.
  • Header parsing - Content-Type parsing with media type and parameters extraction
  • Case-insensitive header access via HTTP.Headers.get/2 and HTTP.Response.get_header/2
  • Backward compatibility - HTTP.fetch still accepts list/map formats with auto-conversion

Changed

  • Refactored header storage from plain lists to HTTP.Headers struct
  • Enhanced type safety with proper struct types throughout the codebase
  • Updated Response API - Added get_header/2 and content_type/1 helper methods

Technical Details

  • New HTTP.Headers struct with comprehensive header manipulation capabilities
  • Immutable operations - All header operations return new struct instances
  • Automatic conversion - Input formats (list/map) auto-converted to struct
  • Enhanced documentation with examples for new header functionality
  • Maintained backward compatibility - Existing code continues to work

[0.1.0] - 2025-07-30

Added

  • Initial project setup with Mix
  • Basic project structure and configuration
  • Core HTTP fetch functionality
  • Response and Request struct definitions
  • Promise implementation for async operations
  • AbortController for request cancellation
  • Comprehensive test coverage
  • Documentation and README