|
|
|
@ -11,37 +11,68 @@ pub fn feed(chain: &mut Chain<String>, what: impl AsRef<str>)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub async fn full(who: &IpAddr, state: State, mut body: impl Unpin + Stream<Item = Result<impl Buf, impl std::error::Error + 'static>>) -> Result<usize, FillBodyError> {
|
|
|
|
|
let mut buffer = Vec::new();
|
|
|
|
|
pub async fn full(who: &IpAddr, state: State, body: impl Unpin + Stream<Item = Result<impl Buf, impl std::error::Error + 'static>>) -> Result<usize, FillBodyError> {
|
|
|
|
|
|
|
|
|
|
let mut written = 0usize;
|
|
|
|
|
//TODO: Change to pushing lines to mpsc channel, instead of manually aggregating.
|
|
|
|
|
while let Some(buf) = body.next().await {
|
|
|
|
|
let mut body = buf.map_err(|_| FillBodyError)?;
|
|
|
|
|
while body.has_remaining() {
|
|
|
|
|
if body.bytes().len() > 0 {
|
|
|
|
|
buffer.extend_from_slice(body.bytes());
|
|
|
|
|
let cnt = body.bytes().len();
|
|
|
|
|
body.advance(cnt);
|
|
|
|
|
written += cnt;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if_debug! {
|
|
|
|
|
let timer = std::time::Instant::now();
|
|
|
|
|
}
|
|
|
|
|
let buffer = std::str::from_utf8(&buffer[..]).map_err(|_| FillBodyError)?;
|
|
|
|
|
info!("{} -> {:?}", who, buffer);
|
|
|
|
|
let mut chain = state.chain().write().await;
|
|
|
|
|
cfg_if! {
|
|
|
|
|
if #[cfg(feature="split-newlines")] {
|
|
|
|
|
for buffer in buffer.split('\n').filter(|line| !line.trim().is_empty()) {
|
|
|
|
|
feed(&mut chain, buffer);
|
|
|
|
|
cfg_if!{
|
|
|
|
|
if #[cfg(any(not(feature="split-newlines"), feature="always-aggregate"))] {
|
|
|
|
|
let mut body = body;
|
|
|
|
|
let mut buffer = Vec::new();
|
|
|
|
|
while let Some(buf) = body.next().await {
|
|
|
|
|
let mut body = buf.map_err(|_| FillBodyError)?;
|
|
|
|
|
while body.has_remaining() {
|
|
|
|
|
if body.bytes().len() > 0 {
|
|
|
|
|
buffer.extend_from_slice(body.bytes());
|
|
|
|
|
let cnt = body.bytes().len();
|
|
|
|
|
body.advance(cnt);
|
|
|
|
|
written += cnt;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
let buffer = std::str::from_utf8(&buffer[..]).map_err(|_| FillBodyError)?;
|
|
|
|
|
info!("{} -> {:?}", who, buffer);
|
|
|
|
|
let mut chain = state.chain().write().await;
|
|
|
|
|
cfg_if! {
|
|
|
|
|
if #[cfg(feature="split-newlines")] {
|
|
|
|
|
for buffer in buffer.split('\n').filter(|line| !line.trim().is_empty()) {
|
|
|
|
|
feed(&mut chain, buffer);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
feed(&mut chain, buffer);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
feed(&mut chain, buffer);
|
|
|
|
|
use tokio::prelude::*;
|
|
|
|
|
|
|
|
|
|
let reader = chunking::StreamReader::new(body.map(|x| x.map(|mut x| x.to_bytes()).unwrap_or_default()));
|
|
|
|
|
let mut lines = reader.lines();
|
|
|
|
|
|
|
|
|
|
#[cfg(feature="hog-buffer")]
|
|
|
|
|
let mut chain = state.chain().write().await;
|
|
|
|
|
while let Some(line) = lines.next_line().await.map_err(|_| FillBodyError)? {
|
|
|
|
|
let line = line.trim();
|
|
|
|
|
if !line.is_empty() {
|
|
|
|
|
#[cfg(not(feature="hog-buffer"))]
|
|
|
|
|
let mut chain = state.chain().write().await; // Acquire mutex once per line? Is this right?
|
|
|
|
|
|
|
|
|
|
feed(&mut chain, line);
|
|
|
|
|
info!("{} -> {:?}", who, line);
|
|
|
|
|
}
|
|
|
|
|
written+=line.len();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if_debug!{
|
|
|
|
|
trace!("Write took {}ms", timer.elapsed().as_millis());
|
|
|
|
|
}
|
|
|
|
|
state.notify_save();
|
|
|
|
|
Ok(written)
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|