http2
Types
pub type Body {
Bytes(BitArray)
File(path: String, offset: Int, size: Int)
Streamed(@internal StreamedHandler)
SSE(@internal SSEHandler)
}
Constructors
-
Bytes(BitArray) -
File(path: String, offset: Int, size: Int) -
Streamed(@internal StreamedHandler) -
SSE(@internal SSEHandler)
pub type BodyReadError {
BodyTooLarge
BodyReadTimeout
}
Constructors
-
BodyTooLarge -
BodyReadTimeout
pub type ClientVerification {
CaCertFile(path: String)
CaCertData(certs: List(BitArray))
}
Constructors
-
CaCertFile(path: String)Path to a PEM file containing the CA certificate.
-
CaCertData(certs: List(BitArray))In-memory DER-encoded CA certificate.
pub type Connection =
@internal Connection
pub type ReadEvent {
Chunk(data: BitArray, request: request.Request(Connection))
Done(request: request.Request(Nil))
}
Constructors
-
Chunk(data: BitArray, request: request.Request(Connection)) -
Done(request: request.Request(Nil))
pub type ResponseWriter =
@internal ResponseWriter
pub type SSECloseReason =
@internal SSECloseReason
pub type SSEConnection =
@internal SSEConnection
pub type TlsKeyType {
RsaPrivateKey
EcPrivateKey
DsaPrivateKey
PrivateKeyInfo
}
Constructors
-
RsaPrivateKey -
EcPrivateKey -
DsaPrivateKey -
PrivateKeyInfo
Values
pub fn client_verification(
builder: Builder,
ca_cert: ClientVerification,
) -> Builder
Enables mTLS by requiring clients to present a certificate signed by the
given CA. Connections without a valid certificate are rejected. Requires
TLS to already be enabled via tls_files/tls_pem/tls_der.
pub fn drain_timeout_ms(builder: Builder, value: Int) -> Builder
How long in milliseconds a draining connection waits for streams to finish after GOAWAY before force-closing. Must be positive, out of range values are silently replaced with the default. Default value is 5000. The connection’s underlying OTP shutdown budget is always this value plus 1000ms, so draining always has room to finish cleanly before a forced kill.
pub fn event(data: String) -> SSEEvent
Creates a new SSE event with the given data. Use event_name,
event_id, and event_retry to set the other fields.
pub fn file(
path: String,
offset offset: option.Option(Int),
size size: option.Option(Int),
) -> Result(Body, @internal FileError)
Validates the path provided and builds a File response body from it.
offset skips bytes from the start, size caps how many bytes are
sent.
pub fn file_read_threshold(
builder: Builder,
value: Int,
) -> Builder
Files at or below this size in bytes are read into memory and sent
through the same batched multi-frame path as any other response body,
while larger files are streamed from disk using zero-copy sendfile.
Must be non-negative. An invalid value is silently replaced with the
default. Default value is 1MiB.
pub fn finish_chunk(
writer: ResponseWriter,
chunk: BitArray,
) -> Nil
Sends chunk as the final response body chunk and closes the stream.
pub fn finish_response(writer: ResponseWriter) -> Nil
Closes the stream with no further data. Use finish_chunk instead if
there’s one last chunk to send.
pub fn handshake_timeout_ms(
builder: Builder,
value: Int,
) -> Builder
How long in milliseconds a connection may sit in the preface and SETTINGS handshake before being dropped. Default value is 10000
pub fn header_table_size(builder: Builder, value: Int) -> Builder
SETTINGS_HEADER_TABLE_SIZE. Default value is 4096.
pub fn initial_window_size(
builder: Builder,
value: Int,
) -> Builder
SETTINGS_INITIAL_WINDOW_SIZE. Must stay within 0-2147483647, out of range
values are silently replaced with the default. Default value is 65535.
pub fn max_concurrent_streams(
builder: Builder,
value: option.Option(Int),
) -> Builder
SETTINGS_MAX_CONCURRENT_STREAMS. Use option.Some(n) to cap it, negative
values and zero are silently replaced with default. By default it is
unlimited
pub fn max_continuation_frames(
builder: Builder,
value: Int,
) -> Builder
Cap on CONTINUATION frames per HEADERS sequence. Default value is 100
pub fn max_frame_size(builder: Builder, value: Int) -> Builder
SETTINGS_MAX_FRAME_SIZE. Must stay within 16384-16777215, out of range
values are silently replaced with the default. Default value is 16384.
pub fn max_header_block_bytes(
builder: Builder,
value: Int,
) -> Builder
Cap on cumulative HEADERS and CONTINUATION bytes per header block, checked before HPACK decode. Default value is 65536
pub fn max_header_list_size(
builder: Builder,
value: option.Option(Int),
) -> Builder
SETTINGS_MAX_HEADER_LIST_SIZE. Use option.Some(n) to cap it. By default
it is unlimited.
pub fn new(
handler: fn(request.Request(Connection)) -> response.Response(
Body,
),
) -> Builder
pub fn rapid_reset(
builder: Builder,
window_ms window_ms: Int,
threshold threshold: Int,
) -> Builder
Rapid Reset (CVE-2023-44487) mitigation that trips GOAWAY(ENHANCE_YOUR_CALM)
once more than threshold client resets land within window_ms. Default
values are 10000ms window and 100 threshold.
pub fn read_body(
req: request.Request(Connection),
bytes_limit: Int,
) -> Result(request.Request(BitArray), BodyReadError)
pub fn read_body_chunk(
req: request.Request(Connection),
max_chunk_bytes: Int,
) -> Result(ReadEvent, BodyReadError)
Pulls up to max_chunk_bytes of body per call instead of buffering the whole body. The returned request carries the updated Connection, feed it back into the next call. Ends with Done that includes request with trailers merged in.
pub fn recv_window_water_marks(
builder: Builder,
low low: Int,
high high: Int,
) -> Builder
Recv window low and high water marks. Once a stream’s or the connection’s
recv window drops to or below low, it’s topped back up to high in
one shot instead of trickling small WINDOW_UPDATE deltas. The bigger gap
between the two means fewer WINDOW_UPDATE round trips for large bodies.
low must be positive and below high and high must not exceed
2147483647. An invalid pair is silently replaced with the defaults.
Default values are 256KiB low and 2MiB high.
pub fn send_chunk(
writer: ResponseWriter,
chunk: BitArray,
) -> ResponseWriter
Sends one response body chunk, blocking until it clears the stream’s
flow-control window before returning. For the last chunk use finish_chunk
instead: it closes the stream in the same round trip.
pub fn send_event(conn: SSEConnection, event: SSEEvent) -> Nil
Sends a Server-Sent Events event to the client.
pub fn sse(
conn: Connection,
on_init on_init: fn(process.Subject(user_message)) -> user_state,
handler handler: fn(SSEConnection, user_state, user_message) -> SSENext(
user_state,
),
on_close on_close: fn(SSEConnection, user_state, SSECloseReason) -> Nil,
) -> response.Response(Body)
Builds a Server-Sent Events response.
http2.sse(conn, on_init, handler, on_close)
on_init is called once, right after headers are sent. It’s handed a
Subject processes can push messages into. Returns the initial state.
handler is called for every message received on that Subject. Use
send_event to push data to the client, and sse_continue/sse_stop/
sse_stop_abnormal to decide what happens next.
on_close is called once the connection ends, with the reason: Closed
if handler returned sse_stop/sse_stop_abnormal on its own terms, or
Reset if the client reset the stream or the connection itself is going
away. No further send_event calls are valid after this.
pub fn sse_continue(
user_state: user_state,
) -> SSENext(user_state)
Instructs the SSE connection to keep running, waiting for the next message.
pub fn sse_stop() -> SSENext(user_state)
Instructs the SSE connection to stop. Sends the closing empty DATA frame
(END_STREAM) and calls on_close.
pub fn sse_stop_abnormal(reason: String) -> SSENext(user_state)
Instructs the SSE connection to stop abnormally. Calls on_close but,
unlike sse_stop, does not attempt to send a closing frame.
pub fn start(
builder: Builder,
) -> Result(
actor.Started(static_supervisor.Supervisor),
actor.StartError,
)
pub fn stream_response(
conn: Connection,
response: response.Response(a),
handler: fn(ResponseWriter) -> Nil,
) -> response.Response(Body)
Builds a streamed response. handler must end in finish_chunk or
finish_response since that’s what closes the stream.
use writer <- http2.stream_response(request.body, response.new(200))
http2.send_chunk(writer, first_chunk)
|> http2.finish_chunk(last_chunk)
pub fn tls_der(
builder: Builder,
cert cert: BitArray,
key_type key_type: TlsKeyType,
key key: BitArray,
) -> Builder
Enables TLS with ALPN negotiation of h2 with in-memory DER-encoded
certificate and key data. key_type must match the encoding of key.