use crate::{byte::stream::JuriStream, Config, Request};
use async_std::{io::ReadExt, net::TcpStream};
use std::sync::Arc;
use std::time::Duration;
mod newline;
use self::newline::Newline;
const BUFFER_SIZE: usize = 1024 * 2;
async fn read_buffer(
stream: &mut TcpStream,
config: &Arc<Config>,
) -> std::result::Result<(usize, Vec<u8>), crate::Error> {
let mut buffer = vec![0u8; BUFFER_SIZE];
let dur = Duration::from_secs(config.keep_alive_timeout);
let bytes_count = async_std::future::timeout(dur, async {
let bytes_count = stream.read(&mut buffer).await.map_err(|e| crate::Error {
code: 500,
reason: e.to_string(),
})?;
Ok(bytes_count)
})
.await
.map_err(|e| crate::Error {
code: 500,
reason: e.to_string(),
})??;
Ok((bytes_count, buffer))
}
pub async fn handle_bytes(
stream: &mut TcpStream,
config: &Arc<Config>,
) -> std::result::Result<Request, crate::Error> {
let mut juri_stream = JuriStream::new();
let mut newline = Newline::new();
let is_read_body_finish = loop {
let (bytes_count, buffer) = read_buffer(stream, &config).await?;
if bytes_count == 0 {
break None;
}
let bytes = &mut buffer[..bytes_count].to_vec();
newline.push(bytes);
let is_exist_body = loop {
if let Some(header_bytes) = newline.next() {
if header_bytes.is_empty() {
break true;
}
juri_stream.handle_request_header_bytes(header_bytes);
} else {
break false;
}
};
if is_exist_body {
break Some(bytes_count < BUFFER_SIZE);
}
if bytes_count < BUFFER_SIZE {
break None;
}
};
juri_stream.header_end();
if let Some(is_read_body_finish) = is_read_body_finish {
let mut already_read_body_length: usize = 0;
if let Some(body_bytes) = &mut newline.get_residue_bytes() {
already_read_body_length = body_bytes.len();
juri_stream.handle_request_body_bytes(body_bytes).await;
}
if !is_read_body_finish {
loop {
let (bytes_count, buffer) = read_buffer(stream, &config).await?;
if bytes_count == 0 {
break;
}
let body_bytes = &mut buffer[..bytes_count].to_vec();
juri_stream.handle_request_body_bytes(body_bytes).await;
if bytes_count < BUFFER_SIZE {
break;
}
}
} else if let Some(content_length) = juri_stream.header_map.get("Content-Length") {
if let Ok(content_length) = content_length.parse::<usize>() {
if content_length != 0 && content_length > already_read_body_length {
loop {
let (bytes_count, buffer) = read_buffer(stream, &config).await?;
if bytes_count == 0 {
break;
}
let body_bytes = &mut buffer[..bytes_count].to_vec();
juri_stream.handle_request_body_bytes(body_bytes).await;
if bytes_count < BUFFER_SIZE {
break;
}
}
}
}
}
}
juri_stream.get_request()
}