Skip to content

Commit 5e15390

Browse files
authored
When reading avoid over-reserving the in the case WouldBlock causes multiple read_frame calls (#501)
* When reading avoid over-reserving the in the case WouldBlock causes multiple read_frame calls * Do max_size check once after header parse
1 parent d8b45ee commit 5e15390

1 file changed

Lines changed: 16 additions & 19 deletions

File tree

src/protocol/frame/mod.rs

Lines changed: 16 additions & 19 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-
}
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 _);
179176

180177
if let Some((_, len)) = &self.header {
181178
let len = *len as usize;
182179

183-
// Enforce frame size limit early and make sure `length`
184-
// is not too big (fits into `usize`).
180+
// Enforce frame size limit early
185181
if len > max_size {
186182
return Err(Error::Capacity(CapacityError::MessageTooLong {
187183
size: len,
188184
max_size,
189185
}));
190186
}
191187

192-
if len <= self.in_buffer.len() {
193-
break self.in_buffer.split_to(len);
194-
}
188+
// Reserve full message length only once, even for multiple
189+
// loops or if WouldBlock errors cause multiple fn calls.
190+
self.in_buffer.reserve(len);
191+
} else {
192+
self.in_buffer.reserve(FrameHeader::MAX_SIZE);
195193
}
196194
}
197195

198-
// Not enough data in buffer.
199196
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;
197+
let len = *len as usize;
198+
if len <= self.in_buffer.len() {
199+
break self.in_buffer.split_to(len);
203200
}
204-
} else {
205-
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)