livery_adapter behaviour (livery v0.13.0)

View Source

Behaviour implemented by livery_h1, livery_h2, livery_h3, and livery_test_adapter. An adapter written outside Livery implements it the same way.

Adapters translate engine events into #livery_req{} values and drive the response back onto the wire. They own no state machines; framing, header compression, flow control, and TLS belong upstream in h1, h2, quic, and ws.

Each adapter spawns a livery_req_proc for every incoming request and routes body/trailers/eof messages to that pid. Once the handler returns a #livery_resp{}, the core walks the body variant and calls back into the adapter via the callbacks defined here.

Callbacks

  • start(Name, ListenSpec, Opts) -> {ok, Listener} | {error, _}: start a listener for this adapter.

  • stop(Listener) -> ok: stop a listener cleanly.
  • send_headers(Stream, Status, Headers, SendOpts) -> SendResult: emit response headers. SendOpts may carry end_stream => true when the response has no body.
  • send_data(Stream, IoData, SendOpts) -> SendResult: emit body bytes. end_stream => true closes the send half; flush => true hints the adapter to push immediately rather than batch.
  • send_trailers(Stream, Trailers) -> SendResult: emit trailers (and implicitly close the send half).
  • send_informational(Stream, Status, Headers) -> SendResult: optional: emit an interim (1xx) response, e.g. 103 Early Hints, ahead of the final response. May be called several times per stream. Adapters that cannot (or do not) implement it are reported as informational => false in capabilities/1, and livery_req:inform/3 returns {error, unsupported}.
  • accept_ws(Stream, Req, HandlerMod, Opts) -> {ok, Pid} | {error, _}: optional: hand the stream to a WebSocket session. livery_ws:upgrade/3 answers 501 on an adapter that does not implement it.

  • accept_wt(Stream, Req, HandlerMod, Opts) -> {ok, Pid} | {error, _}: optional: hand the stream to a WebTransport session. livery_wt:upgrade/3 answers 501 on an adapter that does not implement it.

  • reset(Stream, Reason) -> ok: reset a stream with a protocol-specific reason.
  • peer_info(Stream) -> peer_info(): return peer/TLS info for a stream.
  • capabilities(Listener) -> capabilities(): return the capability bitmap of a listener.

Summary

Functions

Whether Adapter implements the optional callback Fun/Arity.

Types

capabilities()

-type capabilities() ::
          #{trailers => boolean(),
            extended_connect => boolean(),
            datagrams => boolean(),
            capsules => boolean(),
            informational => boolean()}.

listen_spec()

-type listen_spec() :: term().

listener()

-type listener() :: term().

opts()

-type opts() :: map().

peer_info()

-type peer_info() ::
          #{peer => {inet:ip_address(), inet:port_number()} | undefined,
            tls => undefined | map(),
            alpn => binary() | undefined}.

reset_reason()

-type reset_reason() :: term().

send_opts()

-type send_opts() ::
          #{end_stream => boolean(), flush => boolean(), early_response_drain => livery_resp:drain()}.

send_result()

-type send_result() :: ok | {error, closed | send_buffer_full | send_timeout | term()}.

stream()

-type stream() :: term().

Callbacks

accept_ws/4

(optional)
-callback accept_ws(stream(), livery_req:req(), module(), term()) -> {ok, pid()} | {error, term()}.

accept_wt/4

(optional)
-callback accept_wt(stream(), livery_req:req(), module(), term()) -> {ok, pid()} | {error, term()}.

capabilities/1

-callback capabilities(listener()) -> capabilities().

peer_info/1

-callback peer_info(stream()) -> peer_info().

reset/2

-callback reset(stream(), reset_reason()) -> ok.

send_data/3

-callback send_data(stream(), iodata(), send_opts()) -> send_result().

send_full/5

(optional)
-callback send_full(stream(), 100..599, [{binary(), binary()}], iodata(), send_opts()) -> send_result().

send_headers/4

-callback send_headers(stream(), 100..599, [{binary(), binary()}], send_opts()) -> send_result().

send_informational/3

(optional)
-callback send_informational(stream(), 100..199, [{binary(), binary()}]) -> send_result().

send_trailers/2

-callback send_trailers(stream(), [{binary(), binary()}]) -> send_result().

start/3

-callback start(Name :: atom(), listen_spec(), opts()) -> {ok, listener()} | {error, term()}.

stop/1

-callback stop(listener()) -> ok.

Functions

implements/3

-spec implements(module() | undefined, atom(), arity()) -> boolean().

Whether Adapter implements the optional callback Fun/Arity.

Optional features (send_full/5, send_informational/3, accept_ws/4, accept_wt/4) are offered by implementing the callback; callers check here instead of keeping a list of adapters.