HTTP/3 datagram channel API (RFC 9297).
Opens an HTTP/3 request stream that is kept open without auto-ending and
drives a user handler with response, datagram, stream-data, trailer, and
close events. The handler may call send_datagram/2 and
max_datagram_size/1 against an opaque %Quiver.HTTP3.Channel{} to push
datagrams back.
Sample usage
{:ok, final_acc} =
Quiver.HTTP3.open_datagram_channel(
"https://h3.example/wt/session",
[method: :connect, protocol: "webtransport"],
fn
{:response, 200, _hs}, channel, acc ->
Quiver.HTTP3.send_datagram(channel, "hello")
{:cont, acc}
{:datagram, _payload}, _ch, acc ->
{:cont, acc}
{:closed, _reason}, _ch, acc ->
{:halt, acc}
end,
[]
)See guides/http3.md for the full cookbook including extended CONNECT
and the WebTransport-style :protocol header.
Summary
Functions
Returns true if both peers negotiated SETTINGS_H3_DATAGRAM=1 and the
underlying QUIC connection has max_datagram_frame_size > 0.
Returns the maximum usable datagram payload size on channel.
Opens an HTTP/3 datagram channel and drives handler until it halts or
the channel closes.
Sends a datagram on channel. Bypasses the pool worker by calling
:quic_h3.send_datagram/3 directly for hot-path speed.
Types
@type close_reason() :: :peer | {:reset, non_neg_integer()} | {:goaway, non_neg_integer()} | {:transport, Quiver.Error.QUICTransportError.t()}
@type handler() :: (event(), Quiver.HTTP3.Channel.t(), term() -> {:cont, term()} | {:halt, term()})
@type payload() :: binary()
@type status() :: 100..599
Functions
@spec h3_datagrams_enabled?(Quiver.HTTP3.Channel.t()) :: boolean()
Returns true if both peers negotiated SETTINGS_H3_DATAGRAM=1 and the
underlying QUIC connection has max_datagram_frame_size > 0.
@spec max_datagram_size(Quiver.HTTP3.Channel.t()) :: non_neg_integer()
Returns the maximum usable datagram payload size on channel.
Returns 0 when the extension is not negotiated. Otherwise the value
is the per-datagram payload limit after subtracting the QSID varint
prefix :quic_h3 prepends internally.
@spec open_datagram_channel(String.t(), keyword(), handler(), term()) :: {:ok, term()} | {:error, term()}
Opens an HTTP/3 datagram channel and drives handler until it halts or
the channel closes.
Synchronous from the caller's perspective: the calling process owns the event mailbox and runs the reduce loop.
See module docs for options and event semantics.
Returns {:ok, acc} on normal close or halt, {:error, reason} on
open failure / timeout / disabled datagrams.
@spec send_datagram(Quiver.HTTP3.Channel.t(), iodata()) :: :ok | {:error, Exception.t()}
Sends a datagram on channel. Bypasses the pool worker by calling
:quic_h3.send_datagram/3 directly for hot-path speed.
Returns :ok on success or {:error, exception} where the exception is
either Quiver.Error.H3DatagramsDisabled (peer didn't negotiate) or
Quiver.Error.H3DatagramError (transport / sizing / lifecycle).