avx_http/
server.rs

1//! HTTP Server implementation
2
3use crate::error::{Error, Result};
4use bytes::Bytes;
5use http::{HeaderMap, HeaderName, HeaderValue, Method, StatusCode};
6use std::collections::HashMap;
7use std::future::Future;
8use std::pin::Pin;
9use std::sync::Arc;
10use tokio::io::{AsyncReadExt, AsyncWriteExt};
11use tokio::net::{TcpListener, TcpStream};
12
13/// HTTP Server
14pub struct Server {
15    addr: String,
16    router: Option<Router>,
17    compression: bool,
18    telemetry: bool,
19}
20
21impl Server {
22    /// Bind server to address
23    pub fn bind(addr: impl Into<String>) -> Self {
24        Self {
25            addr: addr.into(),
26            router: None,
27            compression: false,
28            telemetry: false,
29        }
30    }
31
32    /// Set router for handling requests
33    pub fn router(mut self, router: Router) -> Self {
34        self.router = Some(router);
35        self
36    }
37
38    /// Enable response compression
39    pub fn compression(mut self, enabled: bool) -> Self {
40        self.compression = enabled;
41        self
42    }
43
44    /// Enable telemetry logging
45    pub fn telemetry(mut self, enabled: bool) -> Self {
46        self.telemetry = enabled;
47        self
48    }
49
50    /// Run the server
51    pub async fn run(self) -> Result<()> {
52        let listener = TcpListener::bind(&self.addr)
53            .await
54            .map_err(|e| Error::Internal {
55                message: format!("Failed to bind to {}: {}", self.addr, e),
56            })?;
57
58        println!("🚀 Server listening on {}", self.addr);
59
60        let router = Arc::new(self.router.unwrap_or_default());
61
62        loop {
63            let (stream, peer_addr) = listener.accept().await.map_err(|e| Error::Internal {
64                message: format!("Failed to accept connection: {}", e),
65            })?;
66
67            let router = Arc::clone(&router);
68            let telemetry = self.telemetry;
69
70            tokio::spawn(async move {
71                if let Err(e) = handle_connection(stream, router, telemetry).await {
72                    eprintln!("Error handling connection from {}: {}", peer_addr, e);
73                }
74            });
75        }
76    }
77}
78
79async fn handle_connection(
80    mut stream: TcpStream,
81    router: Arc<Router>,
82    telemetry: bool,
83) -> Result<()> {
84    // Read request
85    let mut buffer = vec![0u8; 8192];
86    let n = stream.read(&mut buffer).await?;
87    let request_data = &buffer[..n];
88
89    // Parse request
90    let request = parse_request(request_data)?;
91
92    if telemetry {
93        println!("📥 {} {}", request.method, request.path);
94    }
95
96    // Route request
97    let response = router.handle(request).await;
98
99    // Send response
100    let mut response_bytes = format!(
101        "HTTP/1.1 {} {}\r\n",
102        response.status.as_u16(),
103        response.status.canonical_reason().unwrap_or("Unknown")
104    );
105
106    // Add headers
107    for (name, value) in response.headers.iter() {
108        response_bytes.push_str(&format!("{}: {}\r\n", name, value.to_str().unwrap_or("")));
109    }
110
111    // Add content-length
112    response_bytes.push_str(&format!("Content-Length: {}\r\n", response.body.len()));
113    response_bytes.push_str("Connection: close\r\n");
114    response_bytes.push_str("\r\n");
115
116    stream.write_all(response_bytes.as_bytes()).await?;
117    stream.write_all(&response.body).await?;
118    stream.flush().await?;
119
120    Ok(())
121}
122
123fn parse_request(data: &[u8]) -> Result<Request> {
124    let request_str = String::from_utf8_lossy(data);
125    let mut lines = request_str.lines();
126
127    // Parse request line
128    let request_line = lines.next().ok_or_else(|| Error::Internal {
129        message: "Empty request".to_string(),
130    })?;
131
132    let mut parts = request_line.split_whitespace();
133    let method_str = parts.next().ok_or_else(|| Error::Internal {
134        message: "Missing method".to_string(),
135    })?;
136    let path = parts.next().ok_or_else(|| Error::Internal {
137        message: "Missing path".to_string(),
138    })?;
139
140    let method = match method_str {
141        "GET" => Method::GET,
142        "POST" => Method::POST,
143        "PUT" => Method::PUT,
144        "DELETE" => Method::DELETE,
145        "PATCH" => Method::PATCH,
146        "HEAD" => Method::HEAD,
147        "OPTIONS" => Method::OPTIONS,
148        _ => {
149            return Err(Error::InvalidMethod {
150                method: method_str.to_string(),
151            })
152        }
153    };
154
155    // Parse headers
156    let mut headers = HeaderMap::new();
157    let mut body_start = 0;
158
159    for (i, line) in lines.clone().enumerate() {
160        if line.is_empty() {
161            body_start = request_str.lines().take(i + 2).collect::<Vec<_>>().join("\n").len();
162            break;
163        }
164
165        if let Some(pos) = line.find(':') {
166            let name = &line[..pos].trim();
167            let value = &line[pos + 1..].trim();
168
169            if let (Ok(name), Ok(value)) = (
170                HeaderName::from_bytes(name.as_bytes()),
171                HeaderValue::from_str(value),
172            ) {
173                headers.insert(name, value);
174            }
175        }
176    }
177
178    // Extract body
179    let body = if body_start < data.len() {
180        Bytes::copy_from_slice(&data[body_start..])
181    } else {
182        Bytes::new()
183    };
184
185    Ok(Request {
186        method,
187        path: path.to_string(),
188        headers,
189        body,
190    })
191}
192
193/// HTTP Request received by server
194pub struct Request {
195    /// HTTP method
196    pub method: Method,
197    /// Request path
198    pub path: String,
199    /// Request headers
200    pub headers: HeaderMap,
201    /// Request body
202    pub body: Bytes,
203}
204
205impl Request {
206    /// Get request body as text
207    pub fn text(&self) -> Result<String> {
208        String::from_utf8(self.body.to_vec())
209            .map_err(|e| Error::Internal { message: e.to_string() })
210    }
211
212    /// Parse request body as JSON
213    pub fn json<T: serde::de::DeserializeOwned>(&self) -> Result<T> {
214        serde_json::from_slice(&self.body)
215            .map_err(|e| Error::JsonError { source: e.to_string() })
216    }
217}
218
219/// HTTP Response to send to client
220pub struct Response {
221    status: StatusCode,
222    headers: HeaderMap,
223    body: Bytes,
224}
225
226impl Response {
227    /// Create new response
228    pub fn new(status: StatusCode) -> Self {
229        Self {
230            status,
231            headers: HeaderMap::new(),
232            body: Bytes::new(),
233        }
234    }
235
236    /// Create 200 OK response with text body
237    pub fn text(body: impl Into<String>) -> Self {
238        let body_str = body.into();
239        let mut response = Self::new(StatusCode::OK);
240        response.body = Bytes::from(body_str);
241        response.headers.insert(
242            HeaderName::from_static("content-type"),
243            HeaderValue::from_static("text/plain; charset=utf-8"),
244        );
245        response
246    }
247
248    /// Create 200 OK response with JSON body
249    pub fn json<T: serde::Serialize>(value: &T) -> Self {
250        match serde_json::to_vec(value) {
251            Ok(json_bytes) => {
252                let mut response = Self::new(StatusCode::OK);
253                response.body = Bytes::from(json_bytes);
254                response.headers.insert(
255                    HeaderName::from_static("content-type"),
256                    HeaderValue::from_static("application/json"),
257                );
258                response
259            }
260            Err(_) => Self::new(StatusCode::INTERNAL_SERVER_ERROR),
261        }
262    }
263
264    /// Create 404 Not Found response
265    pub fn not_found() -> Self {
266        Self::text("Not Found")
267            .with_status(StatusCode::NOT_FOUND)
268    }
269
270    /// Create 500 Internal Server Error response
271    pub fn internal_error() -> Self {
272        Self::text("Internal Server Error")
273            .with_status(StatusCode::INTERNAL_SERVER_ERROR)
274    }
275
276    /// Set response status
277    pub fn with_status(mut self, status: StatusCode) -> Self {
278        self.status = status;
279        self
280    }
281
282    /// Add header to response
283    pub fn with_header(mut self, name: HeaderName, value: HeaderValue) -> Self {
284        self.headers.insert(name, value);
285        self
286    }
287
288    /// Get response status
289    pub fn status(&self) -> StatusCode {
290        self.status
291    }
292
293    /// Get response headers
294    pub fn headers(&self) -> &HeaderMap {
295        &self.headers
296    }
297
298    /// Get mutable reference to headers
299    pub fn headers_mut(&mut self) -> &mut HeaderMap {
300        &mut self.headers
301    }
302}
303
304type HandlerFn = Arc<dyn Fn(Request) -> Pin<Box<dyn Future<Output = Response> + Send>> + Send + Sync>;
305
306/// Router for mapping paths to handlers
307pub struct Router {
308    /// Registered routes
309    pub routes: HashMap<(Method, String), HandlerFn>,
310}
311
312impl Router {
313    /// Create new router
314    pub fn new() -> Self {
315        Self {
316            routes: HashMap::new(),
317        }
318    }
319
320    /// Register GET route
321    pub fn get<F, Fut>(mut self, path: impl Into<String>, handler: F) -> Self
322    where
323        F: Fn() -> Fut + Send + Sync + 'static,
324        Fut: Future<Output = Response> + Send + 'static,
325    {
326        let handler = Arc::new(move |_req: Request| {
327            let fut = handler();
328            Box::pin(fut) as Pin<Box<dyn Future<Output = Response> + Send>>
329        });
330        self.routes.insert((Method::GET, path.into()), handler);
331        self
332    }
333
334    /// Register POST route
335    pub fn post<F, Fut>(mut self, path: impl Into<String>, handler: F) -> Self
336    where
337        F: Fn(Request) -> Fut + Send + Sync + 'static,
338        Fut: Future<Output = Response> + Send + 'static,
339    {
340        let handler = Arc::new(move |req: Request| {
341            let fut = handler(req);
342            Box::pin(fut) as Pin<Box<dyn Future<Output = Response> + Send>>
343        });
344        self.routes.insert((Method::POST, path.into()), handler);
345        self
346    }
347
348    /// Register PUT route
349    pub fn put<F, Fut>(mut self, path: impl Into<String>, handler: F) -> Self
350    where
351        F: Fn(Request) -> Fut + Send + Sync + 'static,
352        Fut: Future<Output = Response> + Send + 'static,
353    {
354        let handler = Arc::new(move |req: Request| {
355            let fut = handler(req);
356            Box::pin(fut) as Pin<Box<dyn Future<Output = Response> + Send>>
357        });
358        self.routes.insert((Method::PUT, path.into()), handler);
359        self
360    }
361
362    /// Register DELETE route
363    pub fn delete<F, Fut>(mut self, path: impl Into<String>, handler: F) -> Self
364    where
365        F: Fn(Request) -> Fut + Send + Sync + 'static,
366        Fut: Future<Output = Response> + Send + 'static,
367    {
368        let handler = Arc::new(move |req: Request| {
369            let fut = handler(req);
370            Box::pin(fut) as Pin<Box<dyn Future<Output = Response> + Send>>
371        });
372        self.routes.insert((Method::DELETE, path.into()), handler);
373        self
374    }
375
376    async fn handle(&self, request: Request) -> Response {
377        let key = (request.method.clone(), request.path.clone());
378
379        if let Some(handler) = self.routes.get(&key) {
380            handler(request).await
381        } else {
382            Response::not_found()
383        }
384    }
385}
386
387impl Default for Router {
388    fn default() -> Self {
389        Self::new()
390    }
391}
392
393#[cfg(test)]
394mod tests {
395    use super::*;
396
397    #[test]
398    fn test_router_creation() {
399        let router = Router::new();
400        assert_eq!(router.routes.len(), 0);
401    }
402
403    #[test]
404    fn test_response_text() {
405        let response = Response::text("Hello, World!");
406        assert_eq!(response.status, StatusCode::OK);
407        assert_eq!(response.body, Bytes::from("Hello, World!"));
408    }
409
410    #[test]
411    fn test_response_json() {
412        let data = serde_json::json!({"message": "Hello"});
413        let response = Response::json(&data);
414        assert_eq!(response.status, StatusCode::OK);
415        assert!(response.headers.contains_key("content-type"));
416    }
417
418    #[test]
419    fn test_parse_request() {
420        let request_data = b"GET /hello HTTP/1.1\r\nHost: localhost\r\n\r\n";
421        let request = parse_request(request_data).unwrap();
422
423        assert_eq!(request.method, Method::GET);
424        assert_eq!(request.path, "/hello");
425    }
426}