Skip to main content

moirai_http/
server.rs

1//! Bounded one-shot HTTP/1.1 server transport over Moirai TCP sockets.
2
3use std::io;
4use std::net::SocketAddr;
5
6use moirai_async::net::{TcpListener, TcpServerConfig};
7
8mod config;
9mod connection;
10mod response;
11
12pub use config::{
13    DEFAULT_MAX_BODY_BYTES, DEFAULT_MAX_CONNECTIONS, DEFAULT_MAX_HEADER_BYTES,
14    DEFAULT_MAX_HEADER_COUNT, DEFAULT_MAX_RESPONSE_BYTES, DEFAULT_REQUEST_TIMEOUT, ServerConfig,
15};
16pub use connection::{AwaitingRequest, AwaitingResponse, HttpConnection, HttpRequest};
17pub use response::HttpResponse;
18
19/// A bound HTTP/1.1 server listener.
20pub struct HttpServer {
21    listener: TcpListener,
22    config: ServerConfig,
23}
24
25impl HttpServer {
26    /// Bind a one-shot HTTP server to the first address resolved from `addr`.
27    ///
28    /// # Errors
29    /// Returns invalid configuration, address resolution, or socket-bind
30    /// failures.
31    pub async fn bind(addr: &str, config: ServerConfig) -> io::Result<Self> {
32        config.validate()?;
33        let tcp_config = TcpServerConfig {
34            max_connections: Some(config.max_connections),
35            nodelay: true,
36            keep_alive: None,
37            timeout: Some(config.request_timeout),
38        };
39        let listener = TcpListener::bind_with_config(addr, tcp_config).await?;
40        Ok(Self { listener, config })
41    }
42
43    /// Return the local address assigned to the listener.
44    ///
45    /// # Errors
46    /// Propagates the underlying socket query failure.
47    pub fn local_addr(&self) -> io::Result<SocketAddr> {
48        self.listener.local_addr()
49    }
50
51    /// Accept one connection and enter the request-reading typestate.
52    ///
53    /// # Errors
54    /// Returns connection-pool exhaustion or an accept failure.
55    pub async fn accept(&self) -> io::Result<HttpConnection<AwaitingRequest>> {
56        let (stream, _) = self.listener.accept().await?;
57        Ok(HttpConnection {
58            stream,
59            config: self.config,
60            prefix: Vec::new(),
61            state: AwaitingRequest,
62        })
63    }
64}