in src/connection.rs [378:441]
fn parse_body(
&mut self,
line_start_index: &mut usize,
end_cursor: usize,
) -> Result<bool, ConnectionError> {
// If what we have just read is not enough to complete the request and
// there are more bytes pertaining to the body of the request.
if end_cursor > self.buffer.len() {
return Err(ConnectionError::ParseError(RequestError::Overflow));
}
let start_to_end = end_cursor
.checked_sub(*line_start_index)
.ok_or(ConnectionError::ParseError(RequestError::Underflow))?
as u32;
if self.body_bytes_to_be_read > start_to_end {
// Append everything that we read to our current incomplete body and update
// `body_bytes_to_be_read`.
// The slice access is safe, otherwise `checked_sub` would have failed.
self.body_vec
.extend_from_slice(&self.buffer[*line_start_index..end_cursor]);
// Safe to subtract directly as the `if` condition prevents underflow.
self.body_bytes_to_be_read -= start_to_end;
// Clear the buffer and reset the starting index.
for i in 0..BUFFER_SIZE {
self.buffer[i] = 0;
}
self.read_cursor = 0;
return Ok(false);
}
// Append only the remaining necessary bytes to the body of the request.
let line_end = line_start_index
.checked_add(self.body_bytes_to_be_read as usize)
.ok_or(ConnectionError::ParseError(RequestError::Overflow))?;
// The slice access is safe as `line_end` is a sum of `line_start_index` + something else.
self.body_vec
.extend_from_slice(&self.buffer[*line_start_index..line_end]);
*line_start_index = line_end;
self.body_bytes_to_be_read = 0;
let request = self
.pending_request
.as_mut()
.ok_or(ConnectionError::ParseError(
RequestError::BodyWithoutPendingRequest,
))?;
// If there are no more bytes to be read for this request.
// Assign the body of the request.
let placeholder: Vec<_> = self
.body_vec
.drain(..request.headers.content_length() as usize)
.collect();
request.body = Some(Body::new(placeholder));
// If we read more bytes than we should have into the body of the request.
if !self.body_vec.is_empty() {
return Err(ConnectionError::ParseError(RequestError::InvalidRequest));
}
self.state = ConnectionState::RequestReady;
Ok(true)
}