websocket_sans_io

Struct WebsocketFrameDecoder

Source
pub struct WebsocketFrameDecoder { /* private fields */ }
Expand description

A low-level WebSocket frames decoder.

It is a push parser: you can add offer it bytes that come from a socket and it emites events.

You typically need two loops to process incoming data: outer loop reads chunks of data from sockets, inner loop supplies this chunk to the decoder instance until no more events get emitted.

Example usage:

use std::io::Read;

use tungstenite::{protocol::Role, Message};
use websocket_sans_io::{FrameInfo, Opcode, WebsocketFrameEvent};

fn main() {
    let (tunstenite_end, mut sansio_end) = pipe::bipipe();
    std::thread::spawn(move || {
        let mut tunstenite =
            tungstenite::protocol::WebSocket::from_raw_socket(tunstenite_end, Role::Client, None);
        tunstenite
            .send(Message::Text("Hello, world\n".to_owned()))
            .unwrap();
    });

    let mut frame_decoder = websocket_sans_io::WebsocketFrameDecoder::new();
    let mut result = Vec::<u8>::new();
    let mut buf = [0u8; 1024];

    // This loop should handle multi-frame message and control messages interrupting stream of data frames,
    // but it does not reply to WebSocket pings
    'read_loop: loop {
        let n = sansio_end.read(&mut buf).unwrap();
        let mut processed_offset = 0;
        'decode_chunk_loop: loop {
            let unprocessed_part_of_buf = &mut buf[processed_offset..n];
            let ret = frame_decoder.add_data(unprocessed_part_of_buf).unwrap();
            processed_offset += ret.consumed_bytes;

            if ret.event.is_none() && ret.consumed_bytes == 0 {
                break 'decode_chunk_loop;
            }

            match ret.event {
                Some(WebsocketFrameEvent::PayloadChunk {
                    original_opcode: Opcode::Text,
                }) => {
                    result.extend_from_slice(&unprocessed_part_of_buf[0..ret.consumed_bytes]);
                }
                Some(WebsocketFrameEvent::End {
                    frame_info: FrameInfo { fin: true, .. },
                    original_opcode: Opcode::Text,
                }) => break 'read_loop,
                _ => (),
            }
        }
    }
    assert_eq!(result, b"Hello, world\n");
}

Any sequence of bytes result in a some (sensial or not) WebsocketFrameEvent sequence (exception: when large_frames crate feature is disabled).

You may want to validate it (e.g. using FrameInfo::is_reasonable method) before using.

Implementations§

Source§

impl WebsocketFrameDecoder

Source

pub fn add_data<'a, 'b>( &'a mut self, data: &'b mut [u8], ) -> Result<WebsocketFrameDecoderAddDataResult, FrameDecoderError>

Add some bytes to the decoder and return events, if any.

Call this function again if any of the following conditions are met:

You may need call it with empty data buffer to get some final WebsocketFrameEvent::End.

Input buffer needs to be mutable because it is also used to transform (unmask) payload content chunks in-place.

Source

pub fn eof_valid(&self) -> bool

There is no incomplete WebSocket frame at this moment and EOF is valid here.

This method is not related to Opcode::ConnectionClose in any way.

Source

pub const fn new() -> Self

Create new instance.

Trait Implementations§

Source§

impl Clone for WebsocketFrameDecoder

Source§

fn clone(&self) -> WebsocketFrameDecoder

Returns a copy of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for WebsocketFrameDecoder

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for WebsocketFrameDecoder

Source§

fn default() -> WebsocketFrameDecoder

Returns the “default value” for a type. Read more
Source§

impl Copy for WebsocketFrameDecoder

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dst: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dst. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.