Skip to content

Commit

Permalink
refactor(http1): return Parse::Internal error if there's an illegal h…
Browse files Browse the repository at this point in the history
…eader name or value (#2544)
  • Loading branch information
bensadiku committed Jun 4, 2021
1 parent 6a6a240 commit 55d9a58
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 27 deletions.
5 changes: 5 additions & 0 deletions src/error.rs
Expand Up @@ -73,6 +73,8 @@ pub(super) enum Parse {
Header,
TooLarge,
Status,
#[cfg_attr(debug_assertions, allow(unused))]
Internal,
}

#[derive(Debug, PartialEq)]
Expand Down Expand Up @@ -374,6 +376,9 @@ impl Error {
Kind::Parse(Parse::Header) => "invalid HTTP header parsed",
Kind::Parse(Parse::TooLarge) => "message head is too large",
Kind::Parse(Parse::Status) => "invalid HTTP status-code parsed",
Kind::Parse(Parse::Internal) => {
"internal error inside Hyper and/or its dependencies, please report"
}
Kind::IncompleteMessage => "connection closed before message completed",
#[cfg(feature = "http1")]
Kind::UnexpectedMessage => "received unexpected message from connection",
Expand Down
42 changes: 15 additions & 27 deletions src/proto/h1/role.rs
Expand Up @@ -8,9 +8,9 @@ use std::mem;
#[cfg(any(test, feature = "server", feature = "ffi"))]
use bytes::Bytes;
use bytes::BytesMut;
use http::header::{self, Entry, HeaderName, HeaderValue};
#[cfg(feature = "server")]
use http::header::ValueIter;
use http::header::{self, Entry, HeaderName, HeaderValue};
use http::{HeaderMap, Method, StatusCode, Version};

use crate::body::DecodedLength;
Expand All @@ -29,46 +29,35 @@ const AVERAGE_HEADER_SIZE: usize = 30; // totally scientific

macro_rules! header_name {
($bytes:expr) => {{
#[cfg(debug_assertions)]
{
match HeaderName::from_bytes($bytes) {
Ok(name) => name,
Err(_) => panic!(
"illegal header name from httparse: {:?}",
::bytes::Bytes::copy_from_slice($bytes)
),
}
}

#[cfg(not(debug_assertions))]
{
match HeaderName::from_bytes($bytes) {
Ok(name) => name,
Err(_) => panic!("illegal header name from httparse: {:?}", $bytes),
Err(e) => maybe_panic!(e),
}
}
}};
}

macro_rules! header_value {
($bytes:expr) => {{
#[cfg(debug_assertions)]
{
let __hvb: ::bytes::Bytes = $bytes;
match HeaderValue::from_maybe_shared(__hvb.clone()) {
Ok(name) => name,
Err(_) => panic!("illegal header value from httparse: {:?}", __hvb),
}
}

#[cfg(not(debug_assertions))]
{
// Unsafe: httparse already validated header value
unsafe { HeaderValue::from_maybe_shared_unchecked($bytes) }
}
}};
}

macro_rules! maybe_panic {
($($arg:tt)*) => ({
let _err = ($($arg)*);
if cfg!(debug_assertions) {
panic!("{:?}", _err);
} else {
error!("Internal Hyper error, please report {:?}", _err);
return Err(Parse::Internal)
}
})
}

pub(super) fn parse_headers<T>(
bytes: &mut BytesMut,
ctx: ParseContext<'_>,
Expand Down Expand Up @@ -891,8 +880,7 @@ impl Http1Transaction for Client {
);
let mut res = httparse::Response::new(&mut headers);
let bytes = buf.as_ref();
match ctx.h1_parser_config.parse_response(&mut res, bytes)
{
match ctx.h1_parser_config.parse_response(&mut res, bytes) {
Ok(httparse::Status::Complete(len)) => {
trace!("Response.parse Complete({})", len);
let status = StatusCode::from_u16(res.code.unwrap())?;
Expand Down

0 comments on commit 55d9a58

Please sign in to comment.