diff --git a/edge-http/src/io/client.rs b/edge-http/src/io/client.rs index 9f11f1f..054baee 100644 --- a/edge-http/src/io/client.rs +++ b/edge-http/src/io/client.rs @@ -4,7 +4,10 @@ use embedded_io_async::{ErrorType, Read, Write}; use embedded_nal_async::{SocketAddr, TcpConnect}; -use crate::ws::{upgrade_request_headers, MAX_BASE64_KEY_LEN, NONCE_LEN}; +use crate::{ + ws::{upgrade_request_headers, MAX_BASE64_KEY_LEN, NONCE_LEN}, + DEFAULT_MAX_HEADERS_COUNT, +}; use super::{ send_headers, send_headers_end, send_request, Body, BodyType, Error, ResponseHeaders, SendBody, @@ -18,7 +21,7 @@ use super::Method; const COMPLETION_BUF_SIZE: usize = 64; -pub enum Connection<'b, T, const N: usize = 128> +pub enum Connection<'b, T, const N: usize = DEFAULT_MAX_HEADERS_COUNT> where T: TcpConnect, { diff --git a/edge-http/src/io/server.rs b/edge-http/src/io/server.rs index 2905357..c541ad5 100644 --- a/edge-http/src/io/server.rs +++ b/edge-http/src/io/server.rs @@ -1,5 +1,5 @@ use core::fmt::{self, Debug}; -use core::mem; +use core::mem::{self, MaybeUninit}; use core::pin::pin; use embassy_sync::blocking_mutex::raw::NoopRawMutex; @@ -7,6 +7,11 @@ use embedded_io_async::{ErrorType, Read, Write}; use log::{debug, info, warn}; +use crate::DEFAULT_MAX_HEADERS_COUNT; + +const DEFAULT_HANDLERS_COUNT: usize = 4; +const DEFAULT_BUF_SIZE: usize = 2048; + use super::{ send_headers, send_headers_end, send_status, Body, BodyType, Error, RequestHeaders, SendBody, }; @@ -17,7 +22,7 @@ pub use embedded_svc_compat::*; const COMPLETION_BUF_SIZE: usize = 64; -pub enum Connection<'b, T, const N: usize = 128> { +pub enum Connection<'b, T, const N: usize = DEFAULT_MAX_HEADERS_COUNT> { Transition(TransitionState), Unbound(T), Request(RequestState<'b, T, N>), @@ -286,20 +291,19 @@ where } } -pub async fn handle_connection( +pub async fn handle_connection( mut io: T, + buf: &mut [u8], handler_id: usize, handler: &H, ) where H: for<'b> Handler<'b, &'b mut T, N>, T: Read + Write, { - let mut buf = [0_u8; B]; - loop { debug!("Handler {}: Waiting for new request", handler_id); - let result = handle_request::(&mut buf, &mut io, handler).await; + let result = handle_request::(buf, &mut io, handler).await; match result { Err(e) => { @@ -385,12 +389,23 @@ where Ok(connection.needs_close()) } -pub struct Server { +pub struct ServerBuffers( + [MaybeUninit<[u8; B]>; P], +); + +impl ServerBuffers { + #[inline(always)] + pub const fn new() -> Self { + Self([MaybeUninit::uninit(); P]) + } +} + +pub struct Server { acceptor: A, handler: H, } -impl Server +impl Server where A: embedded_nal_async_xtra::TcpAccept, H: for<'b, 't> Handler<'b, &'b mut A::Connection<'t>, N>, @@ -400,7 +415,10 @@ where Self { acceptor, handler } } - pub async fn process(&mut self) -> Result<(), Error> { + pub async fn process( + &mut self, + bufs: &mut ServerBuffers, + ) -> Result<(), Error> { info!("Creating queue for {W} requests"); let channel = embassy_sync::channel::Channel::::new(); @@ -411,6 +429,7 @@ where let channel = &channel; let handler_id = index; let handler = &self.handler; + let buf = bufs.0[index].as_mut_ptr(); handlers .push(async move { @@ -420,7 +439,13 @@ where let io = channel.receive().await; debug!("Handler {}: Got connection request", handler_id); - handle_connection::(io, handler_id, handler).await; + handle_connection::( + io, + unsafe { buf.as_mut() }.unwrap(), + handler_id, + handler, + ) + .await; } }) .map_err(|_| ()) diff --git a/edge-http/src/lib.rs b/edge-http/src/lib.rs index c61e0dd..1394af6 100644 --- a/edge-http/src/lib.rs +++ b/edge-http/src/lib.rs @@ -6,6 +6,8 @@ use core::str; use httparse::{Header, EMPTY_HEADER}; +pub(crate) const DEFAULT_MAX_HEADERS_COUNT: usize = 64; + #[cfg(feature = "io")] pub mod io; diff --git a/examples/http_server.rs b/examples/http_server.rs index 612034f..a094704 100644 --- a/examples/http_server.rs +++ b/examples/http_server.rs @@ -1,4 +1,4 @@ -use edge_http::io::server::{Connection, Handler, Server}; +use edge_http::io::server::{Connection, Handler, Server, ServerBuffers}; use edge_http::Method; use edge_std_nal_async::StdTcpListen; @@ -13,10 +13,14 @@ fn main() { env_logger::Env::default().filter_or(env_logger::DEFAULT_FILTER_ENV, "info"), ); - futures_lite::future::block_on(run()).unwrap(); + let mut buffers: ServerBuffers = ServerBuffers::new(); + + futures_lite::future::block_on(run(&mut buffers)).unwrap(); } -pub async fn run() -> Result<(), anyhow::Error> { +pub async fn run( + buffers: &mut ServerBuffers, +) -> Result<(), anyhow::Error> { let addr = "0.0.0.0:8881"; info!("Running HTTP server on {addr}"); @@ -25,7 +29,7 @@ pub async fn run() -> Result<(), anyhow::Error> { let mut server: Server<_, _> = Server::new(acceptor, HttpHandler); - server.process::<4, 4>().await?; + server.process::<2, P, B>(buffers).await?; Ok(()) }