Skip to content

Commit fadca62

Browse files
committed
When reading avoid over-reserving the in the case WouldBlock causes multiple read_frame calls
1 parent d8b45ee commit fadca62

1 file changed

Lines changed: 24 additions & 27 deletions

File tree

src/protocol/frame/mod.rs

Lines changed: 24 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -167,43 +167,40 @@ impl FrameCodec {
167167
) -> Result<Option<Frame>> {
168168
let max_size = max_size.unwrap_or_else(usize::max_value);
169169

170-
let mut reserved_full_msg_len = false;
171170
let mut payload = loop {
172-
{
173-
if self.header.is_none() {
174-
let mut cursor = Cursor::new(&mut self.in_buffer);
175-
self.header = FrameHeader::parse(&mut cursor)?;
176-
let advanced = cursor.position();
177-
bytes::Buf::advance(&mut self.in_buffer, advanced as _);
178-
}
179-
171+
if self.header.is_none() {
172+
let mut cursor = Cursor::new(&mut self.in_buffer);
173+
self.header = FrameHeader::parse(&mut cursor)?;
174+
let advanced = cursor.position();
175+
bytes::Buf::advance(&mut self.in_buffer, advanced as _);
180176
if let Some((_, len)) = &self.header {
181-
let len = *len as usize;
182-
183-
// Enforce frame size limit early and make sure `length`
184-
// is not too big (fits into `usize`).
185-
if len > max_size {
186-
return Err(Error::Capacity(CapacityError::MessageTooLong {
187-
size: len,
188-
max_size,
189-
}));
190-
}
191-
192-
if len <= self.in_buffer.len() {
193-
break self.in_buffer.split_to(len);
194-
}
177+
// reserve full message length only once, even
178+
// for multiple loops or if WouldBlock errors cause
179+
// multiple fn calls.
180+
self.in_buffer.reserve(*len as usize);
195181
}
196182
}
197183

198-
// Not enough data in buffer.
199184
if let Some((_, len)) = &self.header {
200-
if !reserved_full_msg_len {
201-
self.in_buffer.reserve(*len as usize);
202-
reserved_full_msg_len = true;
185+
let len = *len as usize;
186+
187+
// Enforce frame size limit early and make sure `length`
188+
// is not too big (fits into `usize`).
189+
if len > max_size {
190+
return Err(Error::Capacity(CapacityError::MessageTooLong {
191+
size: len,
192+
max_size,
193+
}));
194+
}
195+
196+
if len <= self.in_buffer.len() {
197+
break self.in_buffer.split_to(len);
203198
}
204199
} else {
205200
self.in_buffer.reserve(FrameHeader::MAX_SIZE);
206201
}
202+
203+
// Not enough data in buffer.
207204
if self.read_in(stream)? == 0 {
208205
trace!("no frame received");
209206
return Ok(None);

0 commit comments

Comments
 (0)