Sign in

    moonbitstack/moonhttp/http2 does not have a README file

    Refused

    pub(all) suberror Refused {
    Incomplete
    FrameSizeError(String)
    ProtocolError(String)
    Connection(code~ : Int, String)
    Order(String)
    } derive(Eq)

    Why a frame or a connection was refused.

    Incomplete is the normal "need more bytes" signal a streaming reader catches to wait for the rest, and FrameSizeError and ProtocolError are frames that do not decode. A [Conn] raises only the last two kinds: Connection when the peer broke the connection, with the GOAWAY that says so already queued, and Order when this side sent something the protocol does not allow now.
    impl Show for Refused

    Refused::equal

    fn Refused::equal(Refused, Refused) -> Bool

    Refused::not_equal

    fn Refused::not_equal(x : Refused, y : Refused) -> Bool

    Refused::output

    fn Refused::output(self : Refused, logger : &Logger) -> Unit

    Refused::to_string

    fn Refused::to_string(self : Refused) -> String

    Conn

    type Conn

    An HTTP/2 connection without a socket (RFC 9113): octets in, events out; calls in, octets out.

    The caller owns the I/O. It hands what it reads to [Conn::receive], takes events from [Conn::next] until NeedData, and writes whatever [Conn::take] returns, which may be frames the connection queued on its own: the opening SETTINGS, acknowledgements, window updates, resets. The design is python-hyper h2's (https://python-hyper.org/projects/h2/): stream states, flow control, settings, header compression and field validation are kept here once, so a server, a client and a test over recorded octets all run the same code.

    Conn::acknowledge

    fn Conn::acknowledge(self : Conn, stream : Int, size : Int) -> Unit raise Refused

    Hand back size octets of stream's data, now processed, so the peer may send more (§6.9). WINDOW_UPDATE goes out when half a window has come back, as h2 does; a caller that never acknowledges stalls the peer.

    Conn::data

    fn Conn::data(self : Conn, stream : Int, data : BytesView, end? : Bool) -> Unit raise Refused

    Send data on stream, in frames no longer than the peer allows.

    It must fit in [Conn::window]; a caller with more waits for WindowUpdated. Empty data with end sends the END_STREAM alone.

    Conn::end

    fn Conn::end(self : Conn, stream : Int) -> Unit raise Refused

    End stream from this side with an empty DATA frame.

    Conn::goaway

    fn Conn::goaway(self : Conn, code? : Int, debug? : Bytes) -> Unit raise Refused

    Tell the peer this side will process no stream past the last one it opened (§6.8). Streams already open carry on; new ones from the peer are ignored.

    Conn::headers

    fn Conn::headers(self : Conn, stream : Int, fields : Array[
    Header
    ], end? : Bool) -> Unit raise Refused

    Send a head on stream: a client's request on a stream it opens with this, a server's informational or final response, or either side's trailers.

    Which one it is follows from the stream: a new id from a client is a request, the first head a server sends is its response (a 1xx leaves room for another), and a head after the final one is the trailers, which must end the stream. The fields are checked against RFC 9113 §8.2 and §8.3 as a peer would check them, and a block longer than the peer's frame size is carried on in CONTINUATION frames. Raises [Refused::Order] for a head the protocol does not allow here.

    Conn::new

    fn Conn::new(role : Role, settings? : Settings) -> Conn

    A connection at its start, with its opening frames queued: the client's preface and SETTINGS, or the server's SETTINGS (§3.4).

    settings take effect when the peer acknowledges them; until then both ends go by [initial]. Settings outside what §6.5.2 allows abort, since no peer could accept them.

    Conn::next

    fn Conn::next(self : Conn) -> Event raise Refused

    The next event from the peer.

    A connection error raises Connection with the GOAWAY already queued in [Conn::take], after which the connection is finished. A stream error does not raise: the RST_STREAM is queued and the stream ends with Reset.

    Conn::next_stream

    fn Conn::next_stream(self : Conn) -> Int

    The id the next stream this side opens, or the next push it promises, will have.

    Conn::peer_settings

    fn Conn::peer_settings(self : Conn) -> Settings

    The peer's settings in force.

    Conn::ping

    fn Conn::ping(self : Conn, payload : Bytes) -> Unit raise Refused

    Send a PING with eight octets of payload; the answer comes as PingAcked.

    Conn::push

    fn Conn::push(self : Conn, stream : Int, fields : Array[
    Header
    ]) -> Int raise Refused

    Promise the response to the request in fields on the client's stream, and the id of the new stream the response goes on (§8.4).

    The response is then sent with [Conn::headers] and [Conn::data] on the returned id.

    Conn::receive

    fn Conn::receive(self : Conn, data : BytesView) -> Unit raise Refused

    Octets read from the peer. Empty means the peer closed the transport.

    Conn::reset

    fn Conn::reset(self : Conn, stream : Int, code? : Int) -> Unit raise Refused

    Reset stream (§6.4). NO_ERROR is h2's default too: a reset is as often a caller that no longer wants the stream as a fault.

    Conn::settings

    fn Conn::settings(self : Conn) -> Settings

    This side's settings in force.

    Conn::take

    fn Conn::take(self : Conn) -> Bytes

    The octets queued for the peer since the last call.

    Conn::update

    fn Conn::update(self : Conn, settings : Settings) -> Unit raise Refused

    Move this side to settings. They take effect when the peer acknowledges them, reported as SettingsAcked.

    Conn::widen

    fn Conn::widen(self : Conn, stream : Int, by : Int) -> Unit raise Refused

    Widen the receive window of stream, or of the connection for stream 0, by by octets at once, beyond what acknowledgement would.

    Conn::window

    fn Conn::window(self : Conn, stream : Int) -> Int

    How much this side may send on stream now, the smaller of its own window and the connection's; stream 0 is the connection alone.

    Event

    pub(all) enum Event {
    Request(stream~ : Int, fields~ : Array[
    Header
    ])
    Response(stream~ : Int, fields~ : Array[
    Header
    ])
    Informational(stream~ : Int, fields~ : Array[
    Header
    ])
    Trailers(stream~ : Int, fields~ : Array[
    Header
    ])
    Data(stream~ : Int, data~ : Bytes)
    End(stream~ : Int)
    Reset(stream~ : Int, code~ : Int, remote~ : Bool)
    Pushed(stream~ : Int, promised~ : Int, fields~ : Array[
    Header
    ])
    WindowUpdated(stream~ : Int, delta~ : Int)
    Settings(Settings)
    SettingsAcked(Settings)
    Ping(Bytes)
    PingAcked(Bytes)
    GoAway(code~ : Int, last~ : Int, debug~ : Bytes)
    NeedData
    Closed
    } derive(Eq,
    Debug
    )

    What a connection reads from its peer.

    As in http1, a message is a head, any number of Data, then End; trailers come as Trailers before the End. Reset with remote=false is a stream this side refused, with the RST_STREAM already queued. Settings and Ping have already been acknowledged when they are read.

    Event::equal

    fn Event::equal(Event, Event) -> Bool

    Event::not_equal

    fn Event::not_equal(x : Event, y : Event) -> Bool

    Event::to_repr

    Frame

    pub(all) enum Frame {
    Data(stream_id~ : Int, data~ : Bytes, end_stream~ : Bool, padding~ : Int)
    Headers(stream_id~ : Int, fragment~ : Bytes, end_stream~ : Bool, end_headers~ : Bool, priority~ : Priority?, padding~ : Int)
    Priority(stream_id~ : Int, priority~ : Priority)
    RstStream(stream_id~ : Int, error_code~ : Int)
    Settings(params~ : Array[(Int, Int)], ack~ : Bool)
    PushPromise(stream_id~ : Int, promised_id~ : Int, fragment~ : Bytes, end_headers~ : Bool, padding~ : Int)
    Ping(payload~ : Bytes, ack~ : Bool)
    GoAway(last_stream_id~ : Int, error_code~ : Int, debug~ : Bytes)
    WindowUpdate(stream_id~ : Int, increment~ : Int)
    Continuation(stream_id~ : Int, fragment~ : Bytes, end_headers~ : Bool)
    Unknown(ftype~ : Int, flags~ : Int, stream_id~ : Int, payload~ : Bytes)
    } derive(Eq)

    A decoded HTTP/2 frame (RFC 9113 §6). Each variant carries the semantic payload with padding already stripped; padding is the number of padding bytes to (re)emit. Unknown preserves extension/unrecognised frames verbatim so a reader can forward or ignore them (RFC 9113 §4.1).

    Frame::code

    fn Frame::code(self : Frame) -> Int

    The numeric frame-type code of this frame (RFC 9113 §6).

    Frame::encode

    fn Frame::encode(self : Frame) -> Bytes

    Encode this frame to its complete wire representation (9-octet header + payload), the exact inverse of decode_frame.

    Frame::equal

    fn Frame::equal(Frame, Frame) -> Bool

    Frame::not_equal

    fn Frame::not_equal(x : Frame, y : Frame) -> Bool

    FrameHeader

    pub(all) struct FrameHeader {
    length : Int
    ftype : Int
    flags : Int
    stream_id : Int
    } derive(Eq)

    The fixed 9-octet frame header (RFC 9113 §4.1): a 24-bit payload length, an 8-bit type, 8-bit flags, a reserved bit, and a 31-bit stream identifier.

    FrameHeader::decode

    fn FrameHeader::decode(data : Bytes, offset? : Int) -> FrameHeader raise Refused

    Decode the 9-octet frame header at offset. Raises Incomplete when fewer than 9 octets are available. The reserved bit is masked off the stream id.

    FrameHeader::encode

    fn FrameHeader::encode(self : FrameHeader) -> Bytes

    Encode a FrameHeader to its 9 wire octets.

    FrameHeader::equal

    fn FrameHeader::equal(FrameHeader, FrameHeader) -> Bool

    FrameHeader::not_equal

    fn FrameHeader::not_equal(x : FrameHeader, y : FrameHeader) -> Bool

    Priority

    pub(all) struct Priority {
    exclusive : Bool
    stream_dependency : Int
    weight : Int
    } derive(Eq)

    The stream-priority block shared by PRIORITY frames and the optional priority section of HEADERS (RFC 9113 §5.3.2). weight is the raw wire byte (0..255); the effective priority weight is weight + 1 (§6.3).

    Priority::equal

    fn Priority::equal(Priority, Priority) -> Bool

    Priority::not_equal

    fn Priority::not_equal(x : Priority, y : Priority) -> Bool

    Role

    pub(all) enum Role {
    Server
    Client
    } derive(Eq,
    Debug
    )

    Which end of a connection a [Conn] is.

    Role::equal

    fn Role::equal(Role, Role) -> Bool

    Role::not_equal

    fn Role::not_equal(x : Role, y : Role) -> Bool

    Role::to_repr

    Settings

    pub(all) struct Settings {
    header_table_size : Int
    enable_push : Bool
    max_concurrent_streams : Int?
    initial_window_size : Int
    max_frame_size : Int
    max_header_list_size : Int?
    enable_connect_protocol : Bool
    } derive(Eq,
    Debug
    )

    An endpoint's settings (RFC 9113 §6.5.2, RFC 8441 §3).

    None is the RFC's "unlimited". The preset is [settings]; [initial] is what both ends assume before any SETTINGS frame, and so what the peer's settings start from. Build others with [Settings::new] or { ..settings, max_frame_size: n }.

    Settings::equal

    fn Settings::equal(Settings, Settings) -> Bool

    Settings::new

    fn Settings::new(header_table_size? : Int, enable_push? : Bool, max_concurrent_streams? : Int?, initial_window_size? : Int, max_frame_size? : Int, max_header_list_size? : Int?, enable_connect_protocol? : Bool) -> Settings

    Settings by name, every one with the preset's value.

    Settings::not_equal

    fn Settings::not_equal(x : Settings, y : Settings) -> Bool

    Settings::to_repr

    decode

    fn decode(data : Bytes, offset? : Int) -> (Frame, Int) raise Refused

    Decode exactly one frame at offset, returning (frame, bytes_consumed) where bytes_consumed is 9 + payload_length. Raises Incomplete when the buffer does not yet hold the whole frame, or a protocol error when the payload is malformed for its type. The inverse of Frame::encode.

    error_cancel

    let error_cancel : Int

    CANCEL: the stream is no longer wanted.

    error_compression_error

    let error_compression_error : Int

    COMPRESSION_ERROR: the HPACK context is corrupt, which kills the connection.

    error_connect_error

    let error_connect_error : Int

    CONNECT_ERROR: the TCP connection behind a CONNECT stream failed.

    error_enhance_your_calm

    let error_enhance_your_calm : Int

    ENHANCE_YOUR_CALM: the peer is generating too much load.

    error_flow_control_error

    let error_flow_control_error : Int

    FLOW_CONTROL_ERROR: the peer sent more than its credit allowed.

    error_frame_size_error

    let error_frame_size_error : Int

    FRAME_SIZE_ERROR: the frame's length is invalid for its type.

    error_http_1_1_required

    let error_http_1_1_required : Int

    HTTP_1_1_REQUIRED: the request cannot be served over HTTP/2.

    error_inadequate_security

    let error_inadequate_security : Int

    INADEQUATE_SECURITY: the transport does not meet the minimum this endpoint requires.

    error_internal_error

    let error_internal_error : Int

    INTERNAL_ERROR: the endpoint failed for reasons of its own.

    error_no_error

    let error_no_error : Int

    HTTP/2 error codes (RFC 9113 §7), carried by RST_STREAM and GOAWAY.

    error_protocol_error

    let error_protocol_error : Int

    PROTOCOL_ERROR: the peer broke the protocol in a way not covered below.

    error_refused_stream

    let error_refused_stream : Int

    REFUSED_STREAM: the stream was declined before any processing, so it is safe to retry.

    error_settings_timeout

    let error_settings_timeout : Int

    SETTINGS_TIMEOUT: a SETTINGS frame went unacknowledged too long.

    error_stream_closed

    let error_stream_closed : Int

    STREAM_CLOSED: a frame arrived for a stream that was already finished.

    flag_ack

    let flag_ack : Int

    ACK on SETTINGS and PING shares bit 0x1 with END_STREAM.

    flag_end_headers

    let flag_end_headers : Int

    END_HEADERS: no CONTINUATION follows this header block.

    flag_end_stream

    let flag_end_stream : Int

    HTTP/2 frame flags (RFC 9113 §6). Flags are type-specific; the same bit carries different meaning per frame type, hence the shared numeric values.

    flag_padded

    let flag_padded : Int

    PADDED: a length byte and that many padding bytes wrap the payload.

    flag_priority

    let flag_priority : Int

    PRIORITY: this HEADERS frame carries a stream-dependency block.

    frame_continuation

    let frame_continuation : Int

    CONTINUATION: the rest of a header block too large for one frame.

    frame_data

    let frame_data : Int

    HTTP/2 frame type codes (RFC 9113 §6).

    frame_goaway

    let frame_goaway : Int

    GOAWAY: stop opening streams, and here is the last id I accepted.

    frame_headers

    let frame_headers : Int

    HEADERS: opens a stream and carries its HPACK header block.

    frame_ping

    let frame_ping : Int

    PING: the round-trip probe keepalive is built on.

    frame_priority

    let frame_priority : Int

    PRIORITY: the deprecated stream-dependency hint; accepted and ignored.

    frame_push_promise

    let frame_push_promise : Int

    PUSH_PROMISE: server push, which gRPC never uses.

    frame_rst_stream

    let frame_rst_stream : Int

    RST_STREAM: abort one stream without touching the connection.

    frame_settings

    let frame_settings : Int

    SETTINGS: the connection parameters each peer announces, and their ack.

    frame_window_update

    let frame_window_update : Int

    WINDOW_UPDATE: hand the peer more flow-control credit.

    has_preface

    fn has_preface(data : Bytes) -> Bool

    Whether data begins with the exact 24-octet HTTP/2 connection preface.

    initial

    let initial : Settings

    The value RFC 9113 §6.5.2 gives every setting before an endpoint has said otherwise.

    preface

    let preface : Bytes

    The HTTP/2 client connection preface (RFC 9113 §3.5): the fixed, case-sensitive 24-octet sequence PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n a client sends before its first frame, which must be a SETTINGS frame. Its bytes deliberately form a malformed HTTP/1.1 request so an HTTP/1.1-only server rejects it cleanly.

    settings

    let settings : Settings

    What a connection advertises unless told otherwise: the RFC's values, with a hundred concurrent streams and 64 KiB of header list.

    Those two are python-hyper h2's own defaults, and a hundred streams is also where nghttp2 and gRPC settle. Left unlimited, every stream a peer opens and never finishes holds memory, and a few octets of HPACK can name one large table entry thousands of times.

    settings_enable_connect_protocol

    let settings_enable_connect_protocol : Int

    SETTINGS_ENABLE_CONNECT_PROTOCOL (RFC 8441 §3): the extended CONNECT that carries WebSockets over HTTP/2.

    settings_enable_push

    let settings_enable_push : Int

    SETTINGS_ENABLE_PUSH: whether the peer may send PUSH_PROMISE.

    settings_header_table_size

    let settings_header_table_size : Int

    SETTINGS parameter identifiers (RFC 9113 §6.5.2).

    settings_initial_window_size

    let settings_initial_window_size : Int

    SETTINGS_INITIAL_WINDOW_SIZE: the flow-control credit a new stream starts with.

    settings_max_concurrent_streams

    let settings_max_concurrent_streams : Int

    SETTINGS_MAX_CONCURRENT_STREAMS: how many streams may be open at once.

    settings_max_frame_size

    let settings_max_frame_size : Int

    SETTINGS_MAX_FRAME_SIZE: the largest payload the peer will accept in one frame.

    settings_max_header_list_size

    let settings_max_header_list_size : Int

    SETTINGS_MAX_HEADER_LIST_SIZE: the advisory ceiling on a decoded header list.