X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?a=blobdiff_plain;f=src%2Fbin%2Fserver.rs;h=ceceddbdd795f3105f3cab7202480099f91a67c4;hb=3ad612ad9f8c57d2b17235a619dedefbf157f857;hp=b0bac2a64af9453b033146bc19d9ba0767cee2f5;hpb=ca8d67d571b2a1e990405125ed469da56e3d01e9;p=hippotat.git 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,