From c52df15b77ba35e2e9cfe785b388fbb746c0fd85 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Sun, 8 Aug 2021 20:45:12 +0100 Subject: [PATCH] server: MetadataFieldIterator Signed-off-by: Ian Jackson --- src/bin/server.rs | 10 ++++++---- src/multipart.rs | 28 ++++++++++++++++++++++++++++ src/prelude.rs | 2 +- 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/src/bin/server.rs b/src/bin/server.rs index 1c8a64c..c5eaf92 100644 --- a/src/bin/server.rs +++ b/src/bin/server.rs @@ -88,11 +88,13 @@ async fn handle( r#"first multipart component must be name="m""# )) } - let nl = memchr::memchr2(b'\r', b'\n', comp.payload_start) - .ok_or_else(|| anyhow!("no newline in first metadata line?"))?; + let mut meta = MetadataFieldIterator::new(comp.payload_start); + + let client = meta.next() + .map(|r| r.map_err(Into::into)) + .unwrap_or_else(|| Err(anyhow!("missing"))) + .context("client addr")?; - let client = &comp.payload_start[0..nl]; - let client = str::from_utf8(client).context("client addr utf-8")?; let client: IpAddr = client.parse().context("client address")?; // let client = all_clients.get(&client).ok_or_else(|| anyhow!(BAD_CLIENT))?; diff --git a/src/multipart.rs b/src/multipart.rs index e01b0f3..112712b 100644 --- a/src/multipart.rs +++ b/src/multipart.rs @@ -73,3 +73,31 @@ pub fn process_component<'b>(warnings: &mut Warnings, Some(Component { name: part_name.unwrap_or(expected), payload_start: rhs }) } + +pub struct MetadataFieldIterator<'b> { + buf: &'b [u8], + last: Option, + iter: memchr::Memchr<'b>, +} + +impl<'b> MetadataFieldIterator<'b> { + pub fn new(buf: &'b [u8]) -> Self { Self { + buf, + last: Some(0), + iter: memchr::Memchr::new(b'\n', buf), + } } +} + +impl<'b> Iterator for MetadataFieldIterator<'b> { + type Item = Result<&'b str, std::str::Utf8Error>; + fn next(&mut self) -> Option> { + let last = self.last?; + let (s, last) = match self.iter.next() { + Some(nl) => (&self.buf[last..nl], Some(nl+1)), + None => (&self.buf[last..], None), + }; + self.last = last; + let s = str::from_utf8(s).map(|s| s.trim()); + Some(s) + } +} diff --git a/src/prelude.rs b/src/prelude.rs index 22a9c27..931a9fa 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -56,7 +56,7 @@ pub use eyre::Error as AE; pub use crate::config::{self, InstanceConfig, u32Ext as _}; pub use crate::ini; pub use crate::ipif::Ipif; -pub use crate::multipart::{self, PartName}; +pub use crate::multipart::{self, PartName, MetadataFieldIterator}; pub use crate::utils::*; pub use crate::queue::*; pub use crate::reporter::*; -- 2.30.2