Skip to content

Commit

Permalink
feat(http): introduce Error::is_header_section_too_large (fixes hyper…
Browse files Browse the repository at this point in the history
…ium#2462)

We rename Parse::TooLarge into Parse::HeaderSectionTooLarge while at it.
  • Loading branch information
nox committed Mar 15, 2021
1 parent 4c946af commit a8a73c7
Show file tree
Hide file tree
Showing 5 changed files with 17 additions and 11 deletions.
2 changes: 1 addition & 1 deletion src/body/length.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ impl DecodedLength {
Ok(DecodedLength(len))
} else {
warn!("content-length bigger than maximum: {} > {}", len, MAX_LEN);
Err(crate::error::Parse::TooLarge)
Err(crate::error::Parse::HeaderSectionTooLarge)
}
}

Expand Down
16 changes: 11 additions & 5 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ pub(super) enum Parse {
VersionH2,
Uri,
Header,
TooLarge,
HeaderSectionTooLarge,
Status,
}

Expand Down Expand Up @@ -132,6 +132,12 @@ impl Error {
matches!(self.inner.kind, Kind::Parse(_))
}

/// Returns true if this was an HTTP parse error about the header section
/// being too large.
pub fn is_header_section_too_large(&self) -> bool {
self.inner.kind == Kind::Parse(Parse::HeaderSectionTooLarge)
}

/// Returns true if this error was caused by user code.
pub fn is_user(&self) -> bool {
matches!(self.inner.kind, Kind::User(_))
Expand Down Expand Up @@ -220,8 +226,8 @@ impl Error {
}

#[cfg(feature = "http1")]
pub(super) fn new_too_large() -> Error {
Error::new(Kind::Parse(Parse::TooLarge))
pub(super) fn new_header_section_too_large() -> Error {
Error::new(Kind::Parse(Parse::HeaderSectionTooLarge))
}

#[cfg(feature = "http1")]
Expand Down Expand Up @@ -361,7 +367,7 @@ impl Error {
Kind::Parse(Parse::VersionH2) => "invalid HTTP version parsed (found HTTP2 preface)",
Kind::Parse(Parse::Uri) => "invalid URI",
Kind::Parse(Parse::Header) => "invalid HTTP header parsed",
Kind::Parse(Parse::TooLarge) => "message head is too large",
Kind::Parse(Parse::HeaderSectionTooLarge) => "message head is too large",
Kind::Parse(Parse::Status) => "invalid HTTP status-code parsed",
Kind::IncompleteMessage => "connection closed before message completed",
#[cfg(feature = "http1")]
Expand Down Expand Up @@ -465,7 +471,7 @@ impl From<httparse::Error> for Parse {
| httparse::Error::NewLine
| httparse::Error::Token => Parse::Header,
httparse::Error::Status => Parse::Status,
httparse::Error::TooManyHeaders => Parse::TooLarge,
httparse::Error::TooManyHeaders => Parse::HeaderSectionTooLarge,
httparse::Error::Version => Parse::Version,
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/proto/h1/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pub(crate) const INIT_BUFFER_SIZE: usize = 8192;
pub(crate) const MINIMUM_MAX_BUFFER_SIZE: usize = INIT_BUFFER_SIZE;

/// The default maximum read buffer size. If the buffer gets this big and
/// a message is still not complete, a `TooLarge` error is triggered.
/// a message is still not complete, a `HeaderSectionTooLarge` error is triggered.
// Note: if this changes, update server::conn::Http::max_buf_size docs.
pub(crate) const DEFAULT_MAX_BUFFER_SIZE: usize = 8192 + 4096 * 100;

Expand Down Expand Up @@ -171,7 +171,7 @@ where
let max = self.read_buf_strategy.max();
if self.read_buf.len() >= max {
debug!("max_buf_size ({}) reached, closing", max);
return Poll::Ready(Err(crate::Error::new_too_large()));
return Poll::Ready(Err(crate::Error::new_header_section_too_large()));
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/proto/h1/role.rs
Original file line number Diff line number Diff line change
Expand Up @@ -609,7 +609,7 @@ impl Http1Transaction for Server {
| Kind::Parse(Parse::Header)
| Kind::Parse(Parse::Uri)
| Kind::Parse(Parse::Version) => StatusCode::BAD_REQUEST,
Kind::Parse(Parse::TooLarge) => StatusCode::REQUEST_HEADER_FIELDS_TOO_LARGE,
Kind::Parse(Parse::HeaderSectionTooLarge) => StatusCode::REQUEST_HEADER_FIELDS_TOO_LARGE,
_ => return None,
};

Expand Down Expand Up @@ -1077,7 +1077,7 @@ fn record_header_indices(
for (header, indices) in headers.iter().zip(indices.iter_mut()) {
if header.name.len() >= (1 << 16) {
debug!("header name larger than 64kb: {:?}", header.name);
return Err(crate::error::Parse::TooLarge);
return Err(crate::error::Parse::HeaderSectionTooLarge);
}
let name_start = header.name.as_ptr() as usize - bytes_ptr;
let name_end = name_start + header.name.len();
Expand Down
2 changes: 1 addition & 1 deletion tests/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1566,7 +1566,7 @@ async fn max_buf_size() {
.max_buf_size(MAX)
.serve_connection(socket, HelloWorld)
.await
.expect_err("should TooLarge error");
.expect_err("should HeaderSectionTooLarge error");
}

#[cfg(feature = "stream")]
Expand Down

0 comments on commit a8a73c7

Please sign in to comment.