use crate::enums::http_error::HttpError;
use crate::structures::http_request::HttpRequest;
use crate::structures::http_response::HttpResponse;
use crate::structures::http_stream::HttpStream;
use crate::structures::http_message::HttpMessage;
use futures::{AsyncBufRead, AsyncWrite, AsyncWriteExt};
pub struct HttpServerConnection<R: AsyncBufRead + Unpin, W: AsyncWrite + Unpin> {
pub stream: HttpStream<R, W>,
}
impl<R: AsyncBufRead + Unpin, W: AsyncWrite + Unpin> HttpServerConnection<R, W> {
pub fn new(stream_reader: R, stream_writer: W) -> Self {
let stream = HttpStream::new(stream_reader, stream_writer);
HttpServerConnection { stream }
}
pub async fn read_request(&mut self) -> Result<HttpRequest, HttpError> {
let message = HttpMessage::read(&mut self.stream.reader).await?;
HttpRequest::new(message)
}
pub async fn send_response(&mut self, response: HttpResponse) -> Result<usize, HttpError> {
let bytes = response.as_bytes();
let size = self.stream.writer.write(&bytes).await?;
self.stream.writer.flush().await?;
Ok(size)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::enums::http_body::HttpBody;
use crate::enums::http_request_method::HttpRequestMethod;
use crate::enums::http_status_code::HttpStatusCode;
use futures::executor::block_on;
use futures::io::Cursor;
#[test]
fn test_read_request() {
let input = b"POST /submit HTTP/1.1\r\nContent-Length: 5\r\n\r\nHello";
let reader = Cursor::new(input);
let writer = Cursor::new(Vec::new());
let mut connection = HttpServerConnection::new(reader, writer);
let request = block_on(connection.read_request()).unwrap();
assert!(matches!(request.method, HttpRequestMethod::Post));
assert_eq!(request.path, "/submit");
assert_eq!(request.body.get_content(), b"Hello");
}
#[test]
fn test_send_response() {
let reader = Cursor::new(Vec::new());
let writer = Cursor::new(Vec::new());
let mut connection = HttpServerConnection::new(reader, writer);
let body = HttpBody::Content("Response".into());
let response = HttpResponse::new(HttpStatusCode::Ok, body);
block_on(connection.send_response(response)).unwrap();
let output = connection.stream.writer.into_inner();
let output_str = std::str::from_utf8(&output).unwrap();
assert!(output_str.starts_with("HTTP/1.1 200 OK"));
assert!(output_str.contains("Content-Length:8"));
assert!(output_str.ends_with("Response"));
}
}