# `Quiver.Conn.HTTP2`
[🔗](https://github.com/edlontech/quiver/blob/main/lib/quiver/conn/http2.ex#L1)

HTTP/2 connection as a stateless data struct.

Wraps a TLS transport with ALPN h2 negotiation. Multiplexes concurrent
streams with HPACK compression and flow control.

# `t`

```elixir
@type t() :: %Quiver.Conn.HTTP2{
  buffer: binary(),
  cached_initial_window_size: pos_integer(),
  cached_max_frame_size: pos_integer(),
  client_settings: map(),
  decode_table: HPAX.Table.t() | nil,
  encode_table: HPAX.Table.t() | nil,
  headers_being_processed: {pos_integer(), iolist(), boolean()} | nil,
  host: String.t(),
  next_stream_id: pos_integer(),
  open_stream_count: non_neg_integer(),
  ping_queue: :queue.queue(),
  port: :inet.port_number(),
  received_server_settings?: boolean(),
  recv_timeout: timeout(),
  recv_window: integer(),
  recv_window_consumed: non_neg_integer(),
  ref_to_stream_id: map(),
  scheme: :http | :https,
  send_window: integer(),
  server_settings: map(),
  settings_queue: :queue.queue(),
  state: :handshaking | :open | :goaway | :closed,
  streams: map(),
  transport: Quiver.Transport.t(),
  transport_mod: module()
}
```

# `prepare_request`

```elixir
@spec prepare_request(t(), atom(), String.t(), list(), iodata() | nil) ::
  {:ok, t(), reference(), iodata()} | {:error, t(), term()}
```

Prepares a request without sending any frames over the transport.

Returns `{:ok, conn, ref, frames}` where `frames` is iodata ready
to be sent via `transport.send`. The caller is responsible for sending
the frames, enabling batching of multiple requests into a single write.

# `prepare_stream_data`

```elixir
@spec prepare_stream_data(t(), reference(), iodata()) ::
  {:ok, t(), iodata()} | {:would_block, t(), iodata()} | {:error, t(), term()}
```

Encodes DATA frames for a streaming chunk, respecting flow control.

Returns:
- `{:ok, conn, frames}` when the chunk fits in the send window
- `{:would_block, conn, frames}` when the window is partially or fully exhausted
- `{:error, conn, reason}` when the stream ref is unknown

# `prepare_stream_end`

```elixir
@spec prepare_stream_end(t(), reference()) ::
  {:ok, t(), iodata()} | {:error, t(), term()}
```

Sends an empty DATA frame with END_STREAM to finish a streaming request.

Transitions the stream to `:half_closed_local`.

# `prepare_stream_request`

```elixir
@spec prepare_stream_request(t(), atom(), String.t(), list()) ::
  {:ok, t(), reference(), iodata()} | {:error, t(), term()}
```

Prepares a streaming request by sending only HEADERS (without END_STREAM).

Returns `{:ok, conn, ref, frames}` where `frames` contains the HEADERS frame
ready to be sent. The stream remains in `:open` state, allowing subsequent
`prepare_stream_data/3` and `prepare_stream_end/2` calls.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
