From a8a73c78189c36669559a9d431083f44967484eb Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Mon, 15 Mar 2021 12:00:46 +0100 Subject: [PATCH] feat(http): introduce Error::is_header_section_too_large (fixes #2462) We rename Parse::TooLarge into Parse::HeaderSectionTooLarge while at it. --- src/body/length.rs | 2 +- src/error.rs | 16 +++++++++++----- src/proto/h1/io.rs | 4 ++-- src/proto/h1/role.rs | 4 ++-- tests/server.rs | 2 +- 5 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/body/length.rs b/src/body/length.rs index aa9cf3dcd5..35d42b1dee 100644 --- a/src/body/length.rs +++ b/src/body/length.rs @@ -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) } } diff --git a/src/error.rs b/src/error.rs index 663156e0a9..6217a0746b 100644 --- a/src/error.rs +++ b/src/error.rs @@ -71,7 +71,7 @@ pub(super) enum Parse { VersionH2, Uri, Header, - TooLarge, + HeaderSectionTooLarge, Status, } @@ -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(_)) @@ -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")] @@ -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")] @@ -465,7 +471,7 @@ impl From 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, } } diff --git a/src/proto/h1/io.rs b/src/proto/h1/io.rs index 5536b5d164..637b8adbb2 100644 --- a/src/proto/h1/io.rs +++ b/src/proto/h1/io.rs @@ -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; @@ -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())); } } } diff --git a/src/proto/h1/role.rs b/src/proto/h1/role.rs index a9f2f0074f..4765c05132 100644 --- a/src/proto/h1/role.rs +++ b/src/proto/h1/role.rs @@ -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, }; @@ -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(); diff --git a/tests/server.rs b/tests/server.rs index 72d2e459d8..174cd2a19b 100644 --- a/tests/server.rs +++ b/tests/server.rs @@ -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")]