From: Ian Jackson Date: Sun, 15 Aug 2021 17:14:31 +0000 (+0100) Subject: server: use Content-Length length hint X-Git-Tag: hippotat/1.0.0~177 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=hippotat.git;a=commitdiff_plain;h=3ad612ad9f8c57d2b17235a619dedefbf157f857 server: use Content-Length length hint Signed-off-by: Ian Jackson --- diff --git a/src/bin/server.rs b/src/bin/server.rs index b0bac2a..ceceddb 100644 --- a/src/bin/server.rs +++ b/src/bin/server.rs @@ -61,12 +61,17 @@ async fn handle( match async { + let get_header = |hn: &str| { + let mut values = req.headers().get_all(hn).iter(); + let v = values.next().ok_or_else(|| anyhow!("missing {}", hn))?; + if values.next().is_some() { throw!(anyhow!("multiple {}!", hn)); } + let v = v.to_str().context(anyhow!("interpret {} as UTF-8", hn))?; + Ok::<_,AE>(v) + }; + let mkboundary = |b: &'_ _| format!("\n--{}", b).into_bytes(); let boundary = match (||{ - let mut ctypes = req.headers().get_all("Content-Type").iter(); - let t = ctypes.next().ok_or_else(|| anyhow!("missing Content-Type"))?; - if ctypes.next().is_some() { throw!(anyhow!("several Content-Type")) } - let t = t.to_str().context("interpret Content-Type as utf-8")?; + let t = get_header("Content-Type")?; let t: mime::Mime = t.parse().context("parse Content-Type")?; if t.type_() != "multipart" { throw!(anyhow!("not multipart/")) } let b = mime::BOUNDARY; @@ -84,9 +89,17 @@ async fn handle( }, }; + let length_hint: usize = (||{ + let clength = get_header("Content-Length")?; + let clength = clength.parse().context("parse Content-Length")?; + Ok::<_,AE>(clength) + })().unwrap_or_else( + |e| { let _ = warnings.add(&e.wrap_err("parsing Content-Length")); 0 } + ); + let mut body = req.into_body(); let initial = match read_limited_bytes( - METADATA_MAX_LEN, default(), default(), &mut body + METADATA_MAX_LEN, default(), length_hint, &mut body ).await { Ok(all) => all, Err(ReadLimitedError::Truncated { sofar,.. }) => sofar,