moonbitstack/moonhttp/ws does not have a README file

    Refused

    pub(all) suberror Refused {
    Protocol(String)
    Payload(String)
    Exceeded(limit~ : Int, got~ : Int64)
    } derive(Eq,
    Debug
    )

    A protocol violation, carrying the status the connection must then be failed with (RFC 6455 §7.4.1, §7.1.7).

    This is not end of stream: a peer that simply stops sending has not violated anything, and the connection closes without a status.
    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::status

    fn Refused::status(self : Refused) -> Int

    The §7.4.1 status a violation is closed with: 1002 for framing, 1007 for payload, 1009 for size.

    Refused::to_repr

    Refused::to_string

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

    Frame

    pub(all) struct Frame {
    fin : Bool
    opcode : Opcode
    payload : Bytes
    } derive(Eq,
    Debug
    )

    A frame (RFC 6455 §5.2): its FIN bit, its opcode, and its payload already unmasked.

    Frame::encode

    fn Frame::encode(self : Frame, mask? : Bytes) -> Bytes

    A frame on the wire (RFC 6455 §5.2).

    A four-byte mask sets the MASK bit and masks the payload. A client must mask every frame and a server must mask none (§5.1), and the key has to be unpredictable, so it comes from the caller: this package has no randomness and should not pretend to.

    The length takes the shortest of the three forms — seven bits up to 125, sixteen bits under 126, sixty-four under 127.

    Frame::encode_extension

    fn Frame::encode_extension(self : Frame, mask? : Bytes, rsv1? : Bool) -> Bytes

    The frame with RSV1 set, for a connection where an extension has claimed the bit (RFC 7692 §6).

    The bit is not part of Frame because it is not part of §5.2's frame: it means whatever the negotiated extension says it means, and a frame carrying one is only readable by a peer that agreed to that extension.

    Frame::equal

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

    Frame::not_equal

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

    Frame::to_repr

    Message

    pub(all) enum Message {
    Text(String)
    Binary(Bytes)
    Close(status~ : Int, reason~ : Bytes)
    } derive(Eq,
    Debug
    )

    A complete application message: text with its payload decoded, binary with its bytes, or a close with its status and reason.

    Control frames do not surface here — a Reader answers a ping itself — so an application sees what it sent and received and nothing of the protocol's upkeep.

    Text carries a String rather than bytes because §8.1 makes invalid UTF-8 a 1007 failure: bytes that would not decode never get this far, so nothing hands an application a message the peer did not send.

    Message::equal

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

    Message::not_equal

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

    Message::to_repr

    Opcode

    pub(all) enum Opcode {
    Continuation
    Text
    Binary
    Close
    Ping
    Pong
    } derive(Eq,
    Debug
    )

    A frame opcode (RFC 6455 §5.2): the three data opcodes and the three control ones.

    Opcode::code

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

    The four-bit value on the wire.

    Opcode::equal

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

    Opcode::is_control

    fn Opcode::is_control(self : Opcode) -> Bool

    Whether this is a control opcode, which §5.5 holds to tighter rules than a data frame: at most 125 bytes of payload, and never fragmented.

    Opcode::not_equal

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

    Opcode::of

    fn Opcode::of(code : Int) -> Opcode?

    The opcode a wire value names, or None when §5.2 reserves it.

    Opcode::to_repr

    Reader

    pub struct Reader {
    payload :
    Buffer

    kind : Opcode?
    limit : Int
    }

    The state of one direction: what has been assembled so far, and of what kind.

    Reader::feed

    fn Reader::feed(self : Reader, frame : Frame) -> Step raise Refused

    Take one frame (RFC 6455 §5.4 for fragments, §5.5 for the control frames interleaved with them).

    A ping is answered with a pong carrying the same payload, a pong is dropped, and a close is echoed and then reported. A data frame extends or finishes the message.

    Reader::new

    fn Reader::new(limit? : Int) -> Reader

    A reader with nothing assembled.

    Reader::pending

    fn Reader::pending(self : Reader) -> Int

    How many bytes of the message in progress have been assembled.

    Reader::room

    fn Reader::room(self : Reader) -> Int

    How many more bytes the message in progress may take before the ceiling.

    A layer that expands what it is given before handing it here — the permessage-deflate reader — asks this so it can stop expanding at the same ceiling, rather than expand the whole frame and learn of the overrun after.

    Step

    pub(all) struct Step {
    message : Message?
    reply : Frame?
    } derive(Eq,
    Debug
    )

    What a frame made of the connection: a message when it finished one, and a frame to send back when the protocol owes one.

    A ping owes a pong, and a close owes a close (§5.5.1). The reply comes back as a frame rather than as bytes because a client has to mask what it sends and only the caller has the randomness to do it with.

    Step::equal

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

    Step::not_equal

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

    Step::to_repr

    allowed

    fn allowed(status : Int) -> Bool

    Whether a status may appear on the wire (RFC 6455 §7.4.1 and the IANA registry).

    1004 is reserved, and 1005, 1006 and 1015 are sentinels an endpoint sets locally — a peer that sends one has broken the protocol. 1012 through 1014 were registered after RFC 6455 and are allowed here, because refusing a registered status would break a real deployment for the sake of a closed reading of §7.4.1.

    check

    fn check(b0 : Int, b1 : Int, len : Int64, client~ : Bool, limit? : Int) -> Opcode raise Refused

    Check a frame's first two bytes and its announced length, answering with the opcode.

    client says the frames being read came from a client, whose frames must be masked (§5.1); a server's must not be, and reading those takes client=false.

    Run this before reading the payload. It is the length check that keeps a sixty-four bit length from being truncated into a short allocation, and keeps an honest but enormous one from being allocated at all — the sign bit included, which §5.2 reserves.

    check_extension

    fn check_extension(b0 : Int, b1 : Int, len : Int64, client~ : Bool, limit? : Int) -> (Opcode, Bool) raise Refused

    Check a frame's first two bytes when an extension has claimed RSV1, answering with the opcode and whether the bit was set (RFC 7692 §6).

    The bit belongs to an extension negotiated for the whole connection, so a caller that has none must not read frames this way; check is that caller.

    What the bit may say is narrower than a data frame: §6.1 forbids it on control frames and on a continuation, whose RSV bits belong to whichever frame started the message. Both are refused here, which leaves the extension only the question of what a set bit on a first data frame means.

    close

    fn close(status : Int, reason? : String) -> Bytes

    A close frame's payload (RFC 6455 §5.5.1): the status big-endian, then the reason.

    decode

    fn decode(b : BytesView, client? : Bool, limit? : Int) -> (Frame, Int)? raise Refused

    One frame at the start of b, with its payload unmasked, and how many bytes it took.

    None means b does not hold a whole frame yet, so a caller feeds it more and asks again. A frame that breaks the rules is refused rather than answered None, so a violation is never mistaken for a short buffer.

    decode_extension

    fn decode_extension(b : BytesView, client? : Bool, limit? : Int) -> (Frame, Int, Bool)? raise Refused

    One frame at the start of b, read under an extension that claimed RSV1, with the bit's value reported alongside (RFC 7692 §6).

    Everything decode says about a short buffer and a broken frame holds here too; what is added is that RSV1 is allowed on a first data frame, and is that extension's to interpret.

    limit

    let limit : Int

    How many bytes of payload this endpoint accepts, in one frame and in a message reassembled from many.

    Sixteen mebibytes is uvicorn's --ws-max-size. The ceiling has to bound the reassembled message and not only each fragment, because a message split into enough small frames would otherwise pass every per-frame check and still exhaust memory.

    reason

    fn reason(payload : BytesView) -> Bytes

    The reason a close payload carries — everything after the two status bytes.

    status

    fn status(payload : BytesView) -> Int

    The status a close payload carries, or 1005 when it carries none (§7.1.5).

    1005 is a local sentinel and must never be sent: a close that came with no status is echoed with no status, not with this number.

    Source Files