// end delimiter for the metadata not yet located, but in here somewhere
initial: Box<[u8]>,
initial_remaining: usize,
+ length_hint: usize,
body: hyper::body::Body,
reply_to: tokio::sync::oneshot::Sender<WebResponse>,
warnings: Warnings,
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;
},
};
+ 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(), &mut body
+ METADATA_MAX_LEN, default(), length_hint, &mut body
).await {
Ok(all) => all,
Err(ReadLimitedError::Truncated { sofar,.. }) => sofar,
let wreq = WebRequest {
initial,
initial_remaining,
+ length_hint,
body,
warnings: mem::take(&mut warnings),
reply_to
}
#[allow(unused_variables)] // xxx
-async fn run_client(_ic: Arc<InstanceConfig>,
+async fn run_client(ic: Arc<InstanceConfig>,
mut web: mpsc::Receiver<WebRequest>)
-> Result<Void, AE>
{
req = web.recv() =>
{
let WebRequest {
- initial, initial_remaining, body,
+ initial, initial_remaining, length_hint, mut body,
reply_to, warnings,
} = req.ok_or_else(|| anyhow!("webservers all shut down!"))?;
match async {
- // xxx size limit
-
- let whole_request = body.try_fold(
- initial.into_vec(),
- |mut w, by| async move { w.extend_from_slice(&by); Ok(w) },
+ let whole_request = read_limited_bytes(
+ ic.max_batch_up.sat(),
+ initial,
+ length_hint,
+ &mut body
).await.context("read request body")?;
dbg!(whole_request.len());