From 72f3ccd7c58cc217e7cb0df12dbf64e063d616ae Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Thu, 31 May 2018 17:56:27 -0700 Subject: [PATCH] refactor(h1): in debug builds, assert payload known length matchs custom content-length headers --- src/proto/h1/role.rs | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/src/proto/h1/role.rs b/src/proto/h1/role.rs index 261179eb..46a41840 100644 --- a/src/proto/h1/role.rs +++ b/src/proto/h1/role.rs @@ -241,7 +241,7 @@ where return Err(::Error::new_header()); } match msg.body { - Some(BodyLength::Known(len)) => { + Some(BodyLength::Known(known_len)) => { // The Payload claims to know a length, and // the headers are already set. For performance // reasons, we are just going to trust that @@ -249,7 +249,42 @@ where // // In debug builds, we'll assert they are the // same to help developers find bugs. - encoder = Encoder::length(len); + encoder = Encoder::length(known_len); + + #[cfg(debug_assertions)] + { + let mut folded = None::<(u64, HeaderValue)>; + for value in values { + if let Some(len) = headers::content_length_parse(&value) { + if let Some(fold) = folded { + if fold.0 != len { + panic!("multiple Content-Length values found: [{}, {}]", fold.0, len); + } + folded = Some(fold); + } else { + folded = Some((len, value)); + } + } else { + panic!("illegal Content-Length value: {:?}", value); + } + } + if let Some((len, value)) = folded { + assert!( + len == known_len, + "payload claims content-length of {}, custom content-length header claims {}", + known_len, + len, + ); + extend(dst, b"content-length: "); + extend(dst, value.as_bytes()); + extend(dst, b"\r\n"); + wrote_len = true; + continue 'headers; + } else { + // No values in content-length... ignore? + continue 'headers; + } + } }, Some(BodyLength::Unknown) => { // The Payload impl didn't know how long the