|
|
@ -14,17 +14,17 @@ use futures::{
|
|
|
|
},
|
|
|
|
},
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
fn aggregate(mut body: impl Buf) -> Result<String, std::string::FromUtf8Error>
|
|
|
|
#[inline] fn aggregate(mut body: impl Buf) -> Result<String, std::str::Utf8Error>
|
|
|
|
{
|
|
|
|
{
|
|
|
|
let mut output = Vec::new();
|
|
|
|
/*let mut output = Vec::new();
|
|
|
|
while body.has_remaining() {
|
|
|
|
while body.has_remaining() {
|
|
|
|
let bytes = body.bytes();
|
|
|
|
let bytes = body.bytes();
|
|
|
|
output.extend_from_slice(&bytes[..]);
|
|
|
|
output.extend_from_slice(&bytes[..]);
|
|
|
|
let cnt = bytes.len();
|
|
|
|
let cnt = bytes.len();
|
|
|
|
body.advance(cnt);
|
|
|
|
body.advance(cnt);
|
|
|
|
}
|
|
|
|
}*/
|
|
|
|
|
|
|
|
|
|
|
|
String::from_utf8(output)
|
|
|
|
std::str::from_utf8(&body.to_bytes()).map(ToOwned::to_owned)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub async fn single(host: IpAddr, num: Option<usize>, body: impl Buf) -> Result<impl warp::Reply, warp::reject::Rejection>
|
|
|
|
pub async fn single(host: IpAddr, num: Option<usize>, body: impl Buf) -> Result<impl warp::Reply, warp::reject::Rejection>
|
|
|
@ -37,13 +37,18 @@ pub async fn single(host: IpAddr, num: Option<usize>, body: impl Buf) -> Result<
|
|
|
|
.map_err(warp::reject::custom)
|
|
|
|
.map_err(warp::reject::custom)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//TODO: Change to stream impl like normal `feed` has, instead of taking aggregate?
|
|
|
|
async fn single_stream(host: IpAddr, num: Option<usize>, body: impl Buf) -> Result<BoxStream<'static, Result<String, Infallible>>, ApiError>
|
|
|
|
async fn single_stream(host: IpAddr, num: Option<usize>, body: impl Buf) -> Result<BoxStream<'static, Result<String, Infallible>>, ApiError>
|
|
|
|
{
|
|
|
|
{
|
|
|
|
let body = aggregate(body)?;
|
|
|
|
let body = aggregate(body)?;
|
|
|
|
info!("{} <- {:?}", host, &body[..]);
|
|
|
|
info!("{} <- {:?}", host, &body[..]);
|
|
|
|
|
|
|
|
|
|
|
|
let mut chain = Chain::new();
|
|
|
|
let mut chain = Chain::new();
|
|
|
|
cfg_if!{
|
|
|
|
|
|
|
|
|
|
|
|
if_debug! {
|
|
|
|
|
|
|
|
let timer = std::time::Instant::now();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
cfg_if! {
|
|
|
|
if #[cfg(feature="split-newlines")] {
|
|
|
|
if #[cfg(feature="split-newlines")] {
|
|
|
|
for body in body.split('\n').filter(|line| !line.trim().is_empty()) {
|
|
|
|
for body in body.split('\n').filter(|line| !line.trim().is_empty()) {
|
|
|
|
feed::feed(&mut chain, body);
|
|
|
|
feed::feed(&mut chain, body);
|
|
|
@ -52,6 +57,9 @@ async fn single_stream(host: IpAddr, num: Option<usize>, body: impl Buf) -> Resu
|
|
|
|
feed::feed(&mut chain, body);
|
|
|
|
feed::feed(&mut chain, body);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if_debug!{
|
|
|
|
|
|
|
|
trace!("Write took {}ms", timer.elapsed().as_millis());
|
|
|
|
|
|
|
|
}
|
|
|
|
match num {
|
|
|
|
match num {
|
|
|
|
None => Ok(stream::iter(iter::once(Ok(chain.generate_str()))).boxed()),
|
|
|
|
None => Ok(stream::iter(iter::once(Ok(chain.generate_str()))).boxed()),
|
|
|
|
Some(num) => {
|
|
|
|
Some(num) => {
|
|
|
@ -82,9 +90,9 @@ impl std::fmt::Display for ApiError
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl From<std::string::FromUtf8Error> for ApiError
|
|
|
|
impl From<std::str::Utf8Error> for ApiError
|
|
|
|
{
|
|
|
|
{
|
|
|
|
fn from(_: std::string::FromUtf8Error) -> Self
|
|
|
|
fn from(_: std::str::Utf8Error) -> Self
|
|
|
|
{
|
|
|
|
{
|
|
|
|
Self::Body
|
|
|
|
Self::Body
|
|
|
|
}
|
|
|
|
}
|
|
|
|