feature: Raw fragment message

This commit is contained in:
Kirill A. Khalitov 2021-11-02 17:05:03 +03:00
parent 4729b0f000
commit 469aaf37be
5 changed files with 20 additions and 6 deletions

View File

@ -30,7 +30,7 @@ fn run_test(case: u32) -> Result<()> {
msg @ Message::Text(_) | msg @ Message::Binary(_) => {
socket.write_message(msg)?;
}
Message::Ping(_) | Message::Pong(_) | Message::Close(_) => {}
Message::Ping(_) | Message::Pong(_) | Message::Close(_) | Message::Frame(_) => {}
}
}
}

View File

@ -21,7 +21,7 @@ fn handle_client(stream: TcpStream) -> Result<()> {
msg @ Message::Text(_) | msg @ Message::Binary(_) => {
socket.write_message(msg)?;
}
Message::Ping(_) | Message::Pong(_) | Message::Close(_) => {}
Message::Ping(_) | Message::Pong(_) | Message::Close(_) | Message::Frame(_) => {}
}
}
}

View File

@ -6,6 +6,7 @@ use std::{
fmt,
io::{Cursor, ErrorKind, Read, Write},
result::Result as StdResult,
str::Utf8Error,
string::{FromUtf8Error, String},
};
@ -39,7 +40,7 @@ impl<'t> fmt::Display for CloseFrame<'t> {
/// A struct representing a WebSocket frame header.
#[allow(missing_copy_implementations)]
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct FrameHeader {
/// Indicates that the frame is the last one of a possibly fragmented message.
pub is_final: bool,
@ -199,7 +200,7 @@ impl FrameHeader {
}
/// A struct representing a WebSocket frame.
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct Frame {
header: FrameHeader,
payload: Vec<u8>,
@ -280,6 +281,12 @@ impl Frame {
String::from_utf8(self.payload)
}
/// Get frame payload as `&str`.
#[inline]
pub fn to_text<'a>(&'a self) -> Result<&'a str, Utf8Error> {
std::str::from_utf8(&self.payload)
}
/// Consume the frame into a closing frame.
#[inline]
pub(crate) fn into_close(self) -> Result<Option<CloseFrame<'static>>> {

View File

@ -5,7 +5,7 @@ use std::{
str,
};
use super::frame::CloseFrame;
use super::frame::{CloseFrame, Frame};
use crate::error::{CapacityError, Error, Result};
mod string_collect {
@ -172,6 +172,8 @@ pub enum Message {
Pong(Vec<u8>),
/// A close message with the optional close frame.
Close(Option<CloseFrame<'static>>),
/// Raw frame. Note, that you're not going to get this value while reading the message.
Frame(Frame),
}
impl Message {
@ -224,6 +226,7 @@ impl Message {
data.len()
}
Message::Close(ref data) => data.as_ref().map(|d| d.reason.len()).unwrap_or(0),
Message::Frame(ref frame) => frame.len(),
}
}
@ -240,6 +243,7 @@ impl Message {
Message::Binary(data) | Message::Ping(data) | Message::Pong(data) => data,
Message::Close(None) => Vec::new(),
Message::Close(Some(frame)) => frame.reason.into_owned().into_bytes(),
Message::Frame(frame) => frame.into_data(),
}
}
@ -248,10 +252,11 @@ impl Message {
match self {
Message::Text(string) => Ok(string),
Message::Binary(data) | Message::Ping(data) | Message::Pong(data) => {
Ok(String::from_utf8(data).map_err(|err| err.utf8_error())?)
Ok(String::from_utf8(data)?)
}
Message::Close(None) => Ok(String::new()),
Message::Close(Some(frame)) => Ok(frame.reason.into_owned()),
Message::Frame(frame) => Ok(frame.into_string()?),
}
}
@ -265,6 +270,7 @@ impl Message {
}
Message::Close(None) => Ok(""),
Message::Close(Some(ref frame)) => Ok(&frame.reason),
Message::Frame(ref frame) => Ok(frame.to_text()?),
}
}
}

View File

@ -356,6 +356,7 @@ impl WebSocketContext {
return self.write_pending(stream);
}
Message::Close(code) => return self.close(stream, code),
Message::Frame(f) => f,
};
self.send_queue.push_back(frame);