Merge pull request #250 from Voronar/message_raw_frame

feature: Raw frame message
pull/254/head
Daniel Abramov 3 years ago committed by GitHub
commit cd79500d25
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      examples/autobahn-client.rs
  2. 2
      examples/autobahn-server.rs
  3. 11
      src/protocol/frame/frame.rs
  4. 10
      src/protocol/message.rs
  5. 1
      src/protocol/mod.rs

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

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

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

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

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

Loading…
Cancel
Save