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::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.

    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.

    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.

    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