1use 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
13pub struct Server {
15 addr: String,
16 router: Option<Router>,
17 compression: bool,
18 telemetry: bool,
19}
20
21impl Server {
22 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 pub fn router(mut self, router: Router) -> Self {
34 self.router = Some(router);
35 self
36 }
37
38 pub fn compression(mut self, enabled: bool) -> Self {
40 self.compression = enabled;
41 self
42 }
43
44 pub fn telemetry(mut self, enabled: bool) -> Self {
46 self.telemetry = enabled;
47 self
48 }
49
50 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 let mut buffer = vec![0u8; 8192];
86 let n = stream.read(&mut buffer).await?;
87 let request_data = &buffer[..n];
88
89 let request = parse_request(request_data)?;
91
92 if telemetry {
93 println!("📥 {} {}", request.method, request.path);
94 }
95
96 let response = router.handle(request).await;
98
99 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 for (name, value) in response.headers.iter() {
108 response_bytes.push_str(&format!("{}: {}\r\n", name, value.to_str().unwrap_or("")));
109 }
110
111 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 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 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 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
193pub struct Request {
195 pub method: Method,
197 pub path: String,
199 pub headers: HeaderMap,
201 pub body: Bytes,
203}
204
205impl Request {
206 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 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
219pub struct Response {
221 status: StatusCode,
222 headers: HeaderMap,
223 body: Bytes,
224}
225
226impl Response {
227 pub fn new(status: StatusCode) -> Self {
229 Self {
230 status,
231 headers: HeaderMap::new(),
232 body: Bytes::new(),
233 }
234 }
235
236 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 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 pub fn not_found() -> Self {
266 Self::text("Not Found")
267 .with_status(StatusCode::NOT_FOUND)
268 }
269
270 pub fn internal_error() -> Self {
272 Self::text("Internal Server Error")
273 .with_status(StatusCode::INTERNAL_SERVER_ERROR)
274 }
275
276 pub fn with_status(mut self, status: StatusCode) -> Self {
278 self.status = status;
279 self
280 }
281
282 pub fn with_header(mut self, name: HeaderName, value: HeaderValue) -> Self {
284 self.headers.insert(name, value);
285 self
286 }
287
288 pub fn status(&self) -> StatusCode {
290 self.status
291 }
292
293 pub fn headers(&self) -> &HeaderMap {
295 &self.headers
296 }
297
298 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
306pub struct Router {
308 pub routes: HashMap<(Method, String), HandlerFn>,
310}
311
312impl Router {
313 pub fn new() -> Self {
315 Self {
316 routes: HashMap::new(),
317 }
318 }
319
320 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 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 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 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}