From bd37c71609f293bfa6e57a72bf349912851f58b6 Mon Sep 17 00:00:00 2001 From: Alexey Galakhov Date: Mon, 3 Apr 2017 15:52:33 +0200 Subject: [PATCH] Replace tuple with CloseFrame struct Signed-off-by: Alexey Galakhov --- src/protocol/frame/frame.rs | 18 ++++++++++++++---- src/protocol/frame/mod.rs | 1 + src/protocol/mod.rs | 15 +++++++++++---- 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/protocol/frame/frame.rs b/src/protocol/frame/frame.rs index 3992bc5..610a7ea 100644 --- a/src/protocol/frame/frame.rs +++ b/src/protocol/frame/frame.rs @@ -1,4 +1,5 @@ use std::fmt; +use std::borrow::Cow; use std::mem::transmute; use std::io::{Cursor, Read, Write}; use std::default::Default; @@ -25,6 +26,15 @@ fn generate_mask() -> [u8; 4] { unsafe { transmute(rand::random::()) } } +/// A struct representing the close command. +#[derive(Debug, Clone)] +pub struct CloseFrame<'t> { + /// The reason as a code. + pub code: CloseCode, + /// The reason as text string. + pub reason: Cow<'t, str>, +} + /// A struct representing a WebSocket frame. #[derive(Debug, Clone)] pub struct Frame { @@ -194,7 +204,7 @@ impl Frame { /// Consume the frame into a closing frame. #[inline] - pub fn into_close(self) -> Result> { + pub fn into_close(self) -> Result>> { match self.payload.len() { 0 => Ok(None), 1 => Err(Error::Protocol("Invalid close sequence".into())), @@ -203,7 +213,7 @@ impl Frame { let code = NetworkEndian::read_u16(&data[0..2]).into(); data.drain(0..2); let text = String::from_utf8(data)?; - Ok(Some((code, text))) + Ok(Some(CloseFrame { code: code, reason: text.into() })) } } } @@ -246,8 +256,8 @@ impl Frame { /// Create a new Close control frame. #[inline] - pub fn close(msg: Option<(CloseCode, &str)>) -> Frame { - let payload = if let Some((code, reason)) = msg { + pub fn close(msg: Option) -> Frame { + let payload = if let Some(CloseFrame { code, reason }) = msg { let raw: [u8; 2] = unsafe { let u: u16 = code.into(); transmute(u.to_be()) diff --git a/src/protocol/frame/mod.rs b/src/protocol/frame/mod.rs index 14b937b..8973db7 100644 --- a/src/protocol/frame/mod.rs +++ b/src/protocol/frame/mod.rs @@ -5,6 +5,7 @@ pub mod coding; mod frame; pub use self::frame::Frame; +pub use self::frame::CloseFrame; use std::io::{Read, Write}; diff --git a/src/protocol/mod.rs b/src/protocol/mod.rs index 970d99e..74a3cac 100644 --- a/src/protocol/mod.rs +++ b/src/protocol/mod.rs @@ -5,6 +5,7 @@ pub mod frame; mod message; pub use self::message::Message; +pub use self::frame::CloseFrame; use std::collections::VecDeque; use std::io::{Read, Write}; @@ -293,15 +294,21 @@ impl WebSocket { } /// Received a close frame. - fn do_close(&mut self, close: Option<(CloseCode, String)>) -> Result<()> { + fn do_close(&mut self, close: Option) -> Result<()> { match self.state { WebSocketState::Active => { self.state = WebSocketState::ClosedByPeer; - let reply = if let Some((code, _)) = close { + let reply = if let Some(CloseFrame { code, .. }) = close { if code.is_allowed() { - Frame::close(Some((CloseCode::Normal, ""))) + Frame::close(Some(CloseFrame { + code: CloseCode::Normal, + reason: "".into(), + })) } else { - Frame::close(Some((CloseCode::Protocol, "Protocol violation"))) + Frame::close(Some(CloseFrame { + code: CloseCode::Protocol, + reason: "Protocol violation".into() + })) } } else { Frame::close(None)