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: :infinityand 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.HPACKpublic 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
:shutdownto 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
PROPFINDandREPORT, 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 validTrailerdeclarations. 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: :structuredandHTTP.RequestError.pre_send?/1evidence 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/1and boundedHTTP.RequestCompletion.await/2/abort_and_await/2for 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: trueand 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_addresspins 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/2for streamed request trailers. - Provide acknowledged WebSocket writes with finite deadlines and document the public WebSocket client boundary for reverse proxies.
- Support
decode_body: falseto 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.mdanddocs/http3-implementation-audit.md. HTTP/3 remains unsupported at this step.
[0.16.1] - 2026-10-01
Changed
- Remove the
elixir_quic_http3sub-app after its migration togsmlg-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_runtimeas 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.mdfor 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.mdfor exact candidate provenance, outcomes, resource bounds and archived evidence.
[0.15.0] - 2026-09-30
Added
- Include
elixir_quic_http3in 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.mdfor 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.2andex_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_coredependency requirements to~> 0.13.0. - Retain the ex_ssl
~> 0.4.0integration from 0.12.0 without further runtime changes; OTP:sslremains 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
:sslas the default TCP TLS backend while allowing verified TLS 1.3 or explicitly selected TLS 1.2 through the optional:ex_sslbackend. 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 keepingresponse.streamas a compatibility alias. - Added HTTP/1.1 streaming request uploads with
HTTP.Streambodies andduplex: "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, andhttp_web_transportumbrella apps with browser-like protocol APIs. - Added e2e coverage for EventSource, WebSocket, and WebTransport workflows.
Changed
- Extracted shared HTTP primitives into the
http_coreapp so protocol apps share common code without depending onhttp_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
:httpccompatibility option buckets fromHTTP.fetch/2. Fetch init options are now flat, and redirects useredirect: :follow | :manual | :error.
Fixed
- Validate response
Transfer-Encodingframing instead of falling back toContent-Lengthfor 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
:httpcwith the internal socket transport while preserving the default redirect-following behavior; passautoredirect: falseto return redirect responses. - Legacy
:httpcoptions 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, andsizefields - 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/1instead 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/1for 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, andblob/1
Notes
- This release prioritizes Browser Fetch API compatibility over Elixir-specific patterns
- The
body_usedfield 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/3method 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-Agentheader 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-Agentheaders when provided
- Format:
- Added
HTTP.Headers.user_agent/0method to access the default User-Agent string - Added comprehensive
HTTP.Telemetrymodule 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
- Request lifecycle events:
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/3for better extensibility
[0.4.2] - 2025-08-01
Added
- Added
HTTP.Response.write_to/2method to write response bodies to files- Supports both streaming and non-streaming responses
- Automatically creates directories if they don't exist
- Returns
:okor{: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/1instead oflength/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-urlencodedandmultipart/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: :binaryoption 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/2andHTTP.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.Headersstruct - Enhanced type safety with proper struct types throughout the codebase
- Updated Response API - Added
get_header/2andcontent_type/1helper 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