diff --git a/README.md b/README.md index c98692e..a391934 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,8 @@ for stream in server.incoming() { Introduction ------------ -[![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE) +[![MIT licensed](https://img.shields.io/badge/License-MIT-blue.svg)](./LICENSE-MIT) +[![Apache-2.0 licensed](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](./LICENSE-APACHE) This library provides an implementation of WebSockets, [RFC6455](https://tools.ietf.org/html/rfc6455). It allows for both synchronous (like TcpStream) diff --git a/src/handshake/machine.rs b/src/handshake/machine.rs index a7fe04a..ec98f7e 100644 --- a/src/handshake/machine.rs +++ b/src/handshake/machine.rs @@ -40,50 +40,58 @@ impl HandshakeMachine { /// Perform a single handshake round. pub fn single_round(mut self) -> Result> { trace!("Doing handshake round."); - Ok(match self.state { + match self.state { HandshakeState::Reading(mut buf) => { buf.reserve(MIN_READ, usize::max_value()) // TODO limit size .map_err(|_| Error::Capacity("Header too long".into()))?; - if let Some(_) = buf.read_from(&mut self.stream).no_block()? { - if let Some((size, obj)) = Obj::try_parse(Buf::bytes(&buf))? { - buf.advance(size); - RoundResult::StageFinished(StageResult::DoneReading { - result: obj, - stream: self.stream, - tail: buf.into_vec(), + match buf.read_from(&mut self.stream).no_block()? { + Some(0) => { + Err(Error::Protocol("Handshake not finished".into())) + } + Some(_) => { + Ok(if let Some((size, obj)) = Obj::try_parse(Buf::bytes(&buf))? { + buf.advance(size); + RoundResult::StageFinished(StageResult::DoneReading { + result: obj, + stream: self.stream, + tail: buf.into_vec(), + }) + } else { + RoundResult::Incomplete(HandshakeMachine { + state: HandshakeState::Reading(buf), + ..self + }) }) - } else { - RoundResult::Incomplete(HandshakeMachine { + } + None => { + Ok(RoundResult::WouldBlock(HandshakeMachine { state: HandshakeState::Reading(buf), ..self - }) + })) } - } else { - RoundResult::WouldBlock(HandshakeMachine { - state: HandshakeState::Reading(buf), - ..self - }) } } HandshakeState::Writing(mut buf) => { + assert!(buf.has_remaining()); if let Some(size) = self.stream.write(Buf::bytes(&buf)).no_block()? { + assert!(size > 0); buf.advance(size); - if buf.has_remaining() { + Ok(if buf.has_remaining() { RoundResult::Incomplete(HandshakeMachine { state: HandshakeState::Writing(buf), ..self }) } else { RoundResult::StageFinished(StageResult::DoneWriting(self.stream)) - } + }) } else { - RoundResult::WouldBlock(HandshakeMachine { + Ok(RoundResult::WouldBlock(HandshakeMachine { state: HandshakeState::Writing(buf), ..self - }) + })) } } - }) + } } } diff --git a/src/protocol/mod.rs b/src/protocol/mod.rs index b4ac9c2..6266dcb 100644 --- a/src/protocol/mod.rs +++ b/src/protocol/mod.rs @@ -28,7 +28,7 @@ pub enum Role { /// WebSocket input-output stream. /// -/// This is THE structure you want to create to me able to talk the WebSocket protocol. +/// This is THE structure you want to create to be able to speak the WebSocket protocol. /// It may be created by calling `connect`, `accept` or `client` functions. pub struct WebSocket { /// Server or client?