From 91b08d09e49c7f4e06db351e065599b76df62c83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= Date: Tue, 26 Jun 2018 01:17:08 +0200 Subject: [PATCH] chore(headers): use HeaderValue::from for content-length (#1583) --- src/headers.rs | 78 +------------------------------------------- src/proto/h1/role.rs | 6 ++-- 2 files changed, 4 insertions(+), 80 deletions(-) diff --git a/src/headers.rs b/src/headers.rs index 37142e93..32131e02 100644 --- a/src/headers.rs +++ b/src/headers.rs @@ -1,13 +1,8 @@ -use std::mem; - use bytes::BytesMut; use http::HeaderMap; use http::header::{CONTENT_LENGTH, TRANSFER_ENCODING}; use http::header::{HeaderValue, OccupiedEntry, ValueIter}; -/// Maximum number of bytes needed to serialize a u64 into ASCII decimal. -const MAX_DECIMAL_U64_BYTES: usize = 20; - pub fn connection_keep_alive(value: &HeaderValue) -> bool { connection_has(value, "keep-alive") } @@ -68,39 +63,11 @@ pub fn content_length_parse_all_values(values: ValueIter) -> Option } } -pub fn content_length_value(len: u64) -> HeaderValue { - let mut len_buf = if mem::size_of::() - 1 < MAX_DECIMAL_U64_BYTES { - // when ptr size is 32bits... - // max bytes don't fit inline, but the likelihood of the length - // actually needing that many bytes is super tiny. So, only - // allocate if we really need to. - // constant version of 10.pow(15) - 1... - const MAX_DECIMAL_INLINE: u64 = 999_999_999_999_999; - if len <= MAX_DECIMAL_INLINE { - // Still fits inline of 15 bytes... - BytesMut::new() - } else { - // the number is huge, and doesn't fit into 15 bytes (on 32bit), - // so we gotta allocate ;_; - BytesMut::with_capacity(MAX_DECIMAL_U64_BYTES) - } - } else { - // max bytes fit inline - BytesMut::with_capacity(MAX_DECIMAL_U64_BYTES) - }; - ::itoa::fmt(&mut len_buf, len) - .expect("BytesMut can hold a decimal u64"); - // safe because u64 Display is ascii numerals - unsafe { - HeaderValue::from_shared_unchecked(len_buf.freeze()) - } -} - pub fn set_content_length_if_missing(headers: &mut HeaderMap, len: u64) { headers .entry(CONTENT_LENGTH) .unwrap() - .or_insert(content_length_value(len)); + .or_insert_with(|| HeaderValue::from(len)); } pub fn transfer_encoding_is_chunked(headers: &HeaderMap) -> bool { @@ -156,46 +123,3 @@ fn eq_ascii(left: &str, right: &str) -> bool { left.eq_ignore_ascii_case(right) } - -#[cfg(test)] -mod tests { - - #[cfg(feature = "nightly")] - use test::Bencher; - - #[test] - fn assert_max_decimal_u64_bytes() { - assert_eq!( - super::MAX_DECIMAL_U64_BYTES, - ::std::u64::MAX.to_string().len() - ); - } - - #[cfg(feature = "nightly")] - #[bench] - fn bench_content_length_fmt_small(b: &mut Bencher) { - let n = 13; - let s = n.to_string(); - b.bytes = s.len() as u64; - - b.iter(|| { - let val = super::content_length_value(n); - debug_assert_eq!(val, s); - ::test::black_box(&val); - }) - } - - #[cfg(feature = "nightly")] - #[bench] - fn bench_content_length_fmt_big(b: &mut Bencher) { - let n = 326_893_010; - let s = n.to_string(); - b.bytes = s.len() as u64; - - b.iter(|| { - let val = super::content_length_value(n); - debug_assert_eq!(val, s); - ::test::black_box(&val); - }) - } -} diff --git a/src/proto/h1/role.rs b/src/proto/h1/role.rs index 20c565f6..8d13be03 100644 --- a/src/proto/h1/role.rs +++ b/src/proto/h1/role.rs @@ -842,16 +842,16 @@ fn set_content_length(headers: &mut HeaderMap, len: u64) -> Encoder { // with our known good length. error!("user provided content-length header was invalid"); - cl.insert(headers::content_length_value(len)); + cl.insert(HeaderValue::from(len)); Encoder::length(len) }, Entry::Vacant(cl) => { - cl.insert(headers::content_length_value(len)); + cl.insert(HeaderValue::from(len)); Encoder::length(len) } } } else { - headers.insert(header::CONTENT_LENGTH, headers::content_length_value(len)); + headers.insert(header::CONTENT_LENGTH, HeaderValue::from(len)); Encoder::length(len) } }