fn parse_headers()

in src/connection.rs [262:371]


    fn parse_headers(
        &mut self,
        line_start_index: &mut usize,
        end_cursor: usize,
    ) -> Result<bool, ConnectionError> {
        if end_cursor > self.buffer.len() {
            return Err(ConnectionError::ParseError(RequestError::Overflow));
        }
        if end_cursor < *line_start_index {
            return Err(ConnectionError::ParseError(RequestError::Underflow));
        }
        // Safe to access the slice as the bounds are checked above.
        match find(&self.buffer[*line_start_index..end_cursor], &[CR, LF]) {
            // `line_start_index` points to the end of the most recently found CR LF
            // sequence. That means that if we found the next CR LF sequence at this index,
            // they are, in fact, a CR LF CR LF sequence, which marks the end of the header
            // fields, per HTTP specification.

            // We have found the end of the header.
            Some(0) => {
                // The current state is `WaitingForHeaders`, ensuring a valid request formed from a
                // request line.
                let request = self
                    .pending_request
                    .as_mut()
                    .ok_or(ConnectionError::ParseError(
                        RequestError::HeadersWithoutPendingRequest,
                    ))?;
                if request.headers.content_length() == 0 {
                    self.state = ConnectionState::RequestReady;
                } else {
                    if request.headers.content_length() as usize > self.payload_max_size {
                        return Err(ConnectionError::ParseError(
                            RequestError::SizeLimitExceeded(
                                self.payload_max_size,
                                request.headers.content_length() as usize,
                            ),
                        ));
                    }
                    if request.headers.expect() {
                        // Send expect.
                        let expect_response =
                            Response::new(request.http_version(), StatusCode::Continue);
                        self.response_queue.push_back(expect_response);
                    }

                    self.body_bytes_to_be_read = request.headers.content_length();
                    request.body = Some(Body::new(vec![]));
                    self.state = ConnectionState::WaitingForBody;
                }

                // Update the index for the next header.
                *line_start_index = line_start_index
                    .checked_add(CRLF_LEN)
                    .ok_or(ConnectionError::ParseError(RequestError::Overflow))?;
                Ok(true)
            }
            // We have found the end of a header line.
            Some(relative_line_end_index) => {
                let request = self
                    .pending_request
                    .as_mut()
                    .ok_or(ConnectionError::ParseError(
                        RequestError::HeadersWithoutPendingRequest,
                    ))?;
                // The `line_end_index` relative to the whole buffer.
                let line_end_index = relative_line_end_index
                    .checked_add(*line_start_index)
                    .ok_or(ConnectionError::ParseError(RequestError::Overflow))?;

                // Get the line slice and parse it.
                // The slice access is safe because `line_end_index` is a sum of `line_end_index`
                // and something else, and `line_end_index` itself is guaranteed to be within
                // `self.buffer`'s bounds by the `find()`.
                let line = &self.buffer[*line_start_index..line_end_index];
                match request.headers.parse_header_line(line) {
                    // If a header is unsupported we ignore it.
                    Ok(_)
                    | Err(RequestError::HeaderError(HttpHeaderError::UnsupportedValue(_, _))) => {}
                    // If parsing the header invalidates the request, we propagate
                    // the error.
                    Err(e) => return Err(ConnectionError::ParseError(e)),
                };

                // Update the `line_start_index` to where we finished parsing.
                *line_start_index = line_end_index
                    .checked_add(CRLF_LEN)
                    .ok_or(ConnectionError::ParseError(RequestError::Overflow))?;
                Ok(true)
            }
            // If we have an incomplete header line.
            None => {
                // If we have parsed BUFFER_SIZE bytes and still haven't found the header
                // line end sequence.
                if *line_start_index == 0 && end_cursor == BUFFER_SIZE {
                    // Header line is longer than BUFFER_SIZE bytes, so it is invalid.
                    let utf8_string = String::from_utf8_lossy(&self.buffer);
                    return Err(ConnectionError::ParseError(RequestError::HeaderError(
                        HttpHeaderError::SizeLimitExceeded(utf8_string.to_string()),
                    )));
                }
                // Move the incomplete header line from the end of the buffer to
                // the beginning, so that we can append the rest of the line and
                // parse it in the next `try_read` call.
                self.shift_buffer_left(*line_start_index, end_cursor)
                    .map_err(ConnectionError::ParseError)?;
                Ok(false)
            }
        }
    }