1use std::collections::HashMap;
2use std::io::{BufRead, Read, Write};
3use std::iter::zip;
4use std::net::{Ipv4Addr, SocketAddr, TcpListener, TcpStream};
5use std::sync::Arc;
6pub mod worker;
7
8pub const CRLF: &str = "\r\n";
21
22pub const MAX_BUFFER: usize = 16384;
51
52#[derive(Debug, Clone)]
56pub struct HTTPRequest {
57 pub method: HTTPMethod,
59 pub path: String,
61 pub raw_path: String,
63 pub params: URLSearchParams,
65 pub http_version: String,
67 pub headers: Headers,
69 pub body: Vec<u8>,
72}
73
74impl Default for HTTPRequest {
75 fn default() -> Self {
76 Self {
77 method: HTTPMethod::GET,
78 path: String::from("/"),
79 raw_path: String::new(),
80 params: HashMap::new(),
81 http_version: String::from("1.1"),
82 headers: HashMap::new(),
83 body: Vec::new(),
84 }
85 }
86}
87
88pub type URLSearchParams = HashMap<String, String>;
92
93pub type Headers = HashMap<String, String>;
96
97fn parse_path(data: &str) -> (String, URLSearchParams) {
101 let split_data = data.split_once('?');
102 if split_data.is_none() {
103 (data.into(), HashMap::new())
104 } else {
105 let (ph, pr) = split_data.unwrap();
106 let params: URLSearchParams = pr
107 .split('&')
108 .filter_map(|param| {
109 let mut parts = param.split('=');
110 let key = parts.next()?.to_string();
111 let value = parts.next()?.to_string();
112 Some((key, value))
113 })
114 .collect();
115
116 (ph.to_string(), params)
117 }
118}
119
120fn get_method(raw: Option<&str>) -> HTTPMethod {
121 if let Some(raw) = raw {
122 match raw {
123 "GET" => HTTPMethod::GET,
124 "HEAD" => HTTPMethod::HEAD,
125 "POST" => HTTPMethod::POST,
126 "PUT" => HTTPMethod::PUT,
127 "DELETE" => HTTPMethod::DELETE,
128 "CONNECT" => HTTPMethod::CONNECT,
129 "OPTIONS" => HTTPMethod::OPTIONS,
130 "TRACE" => HTTPMethod::TRACE,
131 "PATCH" => HTTPMethod::PATCH,
132 _ => HTTPMethod::GET,
133 }
134 } else {
135 HTTPMethod::GET
136 }
137}
138
139fn get_version(v: Option<u8>) -> String {
140 if let Some(v) = v {
141 if v == 1 {
142 return "1.1".into();
143 } else {
144 return "1.2".into();
145 }
146 } else {
147 "1.1".into()
148 }
149}
150
151#[derive(Debug)]
172pub struct HTTPResponse {
173 pub body: Vec<u8>,
175 pub headers: Headers,
177 pub status: u16,
179 pub status_text: String,
181 pub http_version: String,
183}
184
185fn default_headers() -> Headers {
186 let mut h = Headers::new();
187 h.insert("Server".into(), "miniserver".into());
188 h
189}
190
191impl Default for HTTPResponse {
192 fn default() -> Self {
193 HTTPResponse {
194 body: Vec::new(),
195 headers: default_headers(),
196 status: 200,
197 status_text: String::from("OK"),
198 http_version: String::from("1.1"),
199 }
200 }
201}
202
203impl HTTPResponse {
204 pub fn new() -> Self {
206 HTTPResponse::default()
207 }
208
209 pub fn set_body(&mut self, body: Vec<u8>) {
213 self.body = body;
214 self.headers
215 .insert("Content-Length".to_string(), self.body.len().to_string());
216 }
217
218 pub fn set_headers(&mut self, headers: Headers) {
221 for (key, value) in headers {
222 self.headers.insert(key, value);
223 }
224 }
225
226 pub fn set_header(&mut self, k: &str, v: &str) {
228 self.headers.insert(k.into(), v.into());
229 }
230
231 fn apply_status(&mut self, status: u16, text: &str) {
232 self.status = status;
233 self.status_text = text.to_string();
234 }
235
236 pub fn set_status(&mut self, status: u16) {
240 match status {
241 100 => self.apply_status(status, "Continue"),
242 101 => self.apply_status(status, "Switching Protocols"),
243 102 => self.apply_status(status, "Processing"),
244 103 => self.apply_status(status, "Early Hints"),
245
246 200 => self.apply_status(status, "OK"),
247 201 => self.apply_status(status, "Created"),
248 202 => self.apply_status(status, "Accepted"),
249 203 => self.apply_status(status, "Non-Authoritative Information"),
250 204 => self.apply_status(status, "No Content"),
251 205 => self.apply_status(status, "Reset Content"),
252 206 => self.apply_status(status, "Partial Content"),
253 207 => self.apply_status(status, "Multi-Status"),
254 208 => self.apply_status(status, "Already Reported"),
255 226 => self.apply_status(status, "IM Used"),
256
257 300 => self.apply_status(status, "Multiple Choices"),
258 301 => self.apply_status(status, "Moved Permanently"),
259 302 => self.apply_status(status, "Found"),
260 303 => self.apply_status(status, "See Other"),
261 304 => self.apply_status(status, "Not Modified"),
262 305 => self.apply_status(status, "Use Proxy"),
263 306 => self.apply_status(status, "Switch Proxy"),
264 307 => self.apply_status(status, "Temporary Redirect"),
265 308 => self.apply_status(status, "Permanent Redirect"),
266
267 400 => self.apply_status(status, "Bad Request"),
268 401 => self.apply_status(status, "Unauthorized"),
269 402 => self.apply_status(status, "Payment Required"),
270 403 => self.apply_status(status, "Forbidden"),
271 404 => self.apply_status(status, "Not Found"),
272 405 => self.apply_status(status, "Method Not Allowed"),
273 406 => self.apply_status(status, "Not Acceptable"),
274 407 => self.apply_status(status, "Proxy Authentication Required"),
275 408 => self.apply_status(status, "Request Timeout"),
276 409 => self.apply_status(status, "Conflict"),
277 410 => self.apply_status(status, "Gone"),
278 411 => self.apply_status(status, "Length Required"),
279 412 => self.apply_status(status, "Precondition Failed"),
280 413 => self.apply_status(status, "Payload Too Large"),
281 414 => self.apply_status(status, "URI Too Long"),
282 415 => self.apply_status(status, "Unsupported Media Type"),
283 416 => self.apply_status(status, "Range Not Satisfiable"),
284 417 => self.apply_status(status, "Expectation Failed"),
285 418 => self.apply_status(status, "I'm a teapot"),
286 421 => self.apply_status(status, "Misdirected Request"),
287 422 => self.apply_status(status, "Unprocessable Entity"),
288 423 => self.apply_status(status, "Locked"),
289 424 => self.apply_status(status, "Failed Dependency"),
290 425 => self.apply_status(status, "Too Early"),
291 426 => self.apply_status(status, "Upgrade Required"),
292 428 => self.apply_status(status, "Precondition Required"),
293 429 => self.apply_status(status, "Too Many Requests"),
294 431 => self.apply_status(status, "Request Header Fields Too Large"),
295 451 => self.apply_status(status, "Unavailable For Legal Reasons"),
296
297 500 => self.apply_status(status, "Internal Server Error"),
298 501 => self.apply_status(status, "Not Implemented"),
299 502 => self.apply_status(status, "Bad Gateway"),
300 503 => self.apply_status(status, "Service Unavailable"),
301 504 => self.apply_status(status, "Gateway Timeout"),
302 505 => self.apply_status(status, "HTTP Version Not Supported"),
303 506 => self.apply_status(status, "Variant Also Negotiates"),
304 507 => self.apply_status(status, "Insufficient Storage"),
305 508 => self.apply_status(status, "Loop Detected"),
306 510 => self.apply_status(status, "Not Extended"),
307 511 => self.apply_status(status, "Network Authentication Required"),
308
309 _ => self.apply_status(500, "Internal Server Error"),
310 }
311 }
312
313 pub fn set_version(&mut self, version: String) {
315 self.http_version = version;
316 }
317
318 fn format_header(&self) -> String {
319 let mut headers = String::new();
320 for (key, value) in &self.headers {
321 headers.push_str(format!("{}: {}{}", key, value, CRLF).as_str());
322 }
323 headers
324 }
325
326 pub fn raw(&mut self) -> Vec<u8> {
340 let mut bytes = format!(
341 "HTTP/{version} {status} {status_text}{CRLF}{headers}{CRLF}",
342 version = self.http_version,
343 status = self.status,
344 status_text = self.status_text,
345 CRLF = CRLF,
346 headers = self.format_header(),
347 )
348 .as_bytes()
349 .to_vec();
350
351 bytes.extend(self.body.iter());
352
353 bytes
354 }
355}
356
357#[macro_export]
377macro_rules! expand {
378 ($exprs: expr, $name: expr, $against: path) => {
379 match $exprs.get(&String::from($name)).unwrap() {
380 $against(value) => value,
381 _ => unreachable!(),
382 }
383 };
384}
385
386pub type PathMap = HashMap<String, PathExpr>;
388
389pub struct RequestHandler(
392 Arc<Box<dyn Fn(HTTPRequest, PathMap) -> HTTPResponse + Send + Sync + 'static>>,
393);
394
395impl Clone for RequestHandler {
396 fn clone(&self) -> Self {
397 Self(self.0.clone())
398 }
399}
400
401pub struct EventHandler(Arc<Box<dyn Fn(&HTTPRequest, &mut HTTPResponse) + Send + Sync + 'static>>);
404
405impl Clone for EventHandler {
406 fn clone(&self) -> Self {
407 Self(self.0.clone())
408 }
409}
410
411pub struct SimpleEventHandler(
412 Arc<Box<dyn Fn(&mut TcpStream, Request) -> Option<Response> + Send + Sync + 'static>>,
413);
414
415impl Clone for SimpleEventHandler {
416 fn clone(&self) -> Self {
417 Self(self.0.clone())
418 }
419}
420
421pub struct SoftEventHandler(Arc<Box<dyn Fn() + Send + Sync + 'static>>);
424
425impl Clone for SoftEventHandler {
426 fn clone(&self) -> Self {
427 Self(self.0.clone())
428 }
429}
430
431pub struct ErrorEventHandler(Arc<Box<dyn Fn(RunError) + Send + Sync + 'static>>);
432
433impl Clone for ErrorEventHandler {
434 fn clone(&self) -> Self {
435 Self(self.0.clone())
436 }
437}
438#[derive(Debug, PartialEq, Clone)]
441pub enum HTTPMethod {
442 CONNECT,
444 DELETE,
446 GET,
448 HEAD,
450 OPTIONS,
452 PATCH,
454 POST,
456 PUT,
458 TRACE,
460}
461
462#[derive(Debug, Clone)]
464pub enum PathExpr {
465 String(String),
466 Number(i32),
467}
468
469pub struct Path {
470 pub expr: String,
471 pub handler: RequestHandler,
472 pub method: HTTPMethod,
473}
474
475impl Clone for Path {
476 fn clone(&self) -> Self {
477 Self {
478 expr: self.expr.clone(),
479 handler: self.handler.clone(),
480 method: self.method.clone(),
481 }
482 }
483}
484
485impl PartialEq for Path {
486 fn eq(&self, other: &Self) -> bool {
487 self.r#match(other.expr.clone()) && self.method == other.method
488 }
489}
490
491pub struct Listener {
492 handler: EventHandler,
493}
494
495impl Clone for Listener {
496 fn clone(&self) -> Self {
497 Self {
498 handler: self.handler.clone(),
499 }
500 }
501}
502
503pub struct SoftListener {
504 handler: SoftEventHandler,
505}
506
507impl Clone for SoftListener {
508 fn clone(&self) -> Self {
509 Self {
510 handler: self.handler.clone(),
511 }
512 }
513}
514
515pub struct ErrorListener {
516 handler: ErrorEventHandler,
517}
518
519impl Clone for ErrorListener {
520 fn clone(&self) -> Self {
521 Self {
522 handler: self.handler.clone(),
523 }
524 }
525}
526
527impl Path {
528 pub fn new<T>(expr: &str, handler: T, method: HTTPMethod) -> Self
529 where
530 T: Fn(HTTPRequest, PathMap) -> HTTPResponse + Send + Sync + 'static,
531 {
532 Path {
533 expr: expr.to_string(),
534 handler: RequestHandler(Arc::new(Box::new(handler))),
535 method,
536 }
537 }
538
539 fn parse(&self, expr: String) -> PathMap {
540 let mut exprs = PathMap::new();
541 if self.r#match(expr.clone()) {
542 let other_part: Vec<_> = expr.split('/').filter(|x| !x.is_empty()).collect();
543 let self_part: Vec<_> = self.expr.split('/').filter(|x| !x.is_empty()).collect();
544
545 for (o_chunck, s_chunck) in zip(other_part, self_part) {
546 if s_chunck.starts_with('#') {
547 let name = s_chunck.strip_prefix('#').unwrap().to_string();
548 let value = o_chunck.parse::<i32>().unwrap();
549 exprs.insert(name, PathExpr::Number(value));
550 } else if s_chunck.starts_with('@') {
551 let name = s_chunck.strip_prefix('@').unwrap().to_string();
552 let value = o_chunck.to_string();
553 exprs.insert(name, PathExpr::String(value));
554 } else {
555 continue;
556 }
557 }
558 }
559
560 exprs
561 }
562
563 fn r#match(&self, expr: String) -> bool {
564 if expr == self.expr {
565 true
566 } else {
567 let other_part: Vec<_> = expr.split('/').filter(|x| !x.is_empty()).collect();
568 let self_part: Vec<_> = self.expr.split('/').filter(|x| !x.is_empty()).collect();
569
570 if other_part.len() != self_part.len() {
571 false
572 } else {
573 for (o_chunck, s_chunck) in zip(other_part, self_part) {
574 if s_chunck.starts_with('#') {
575 if o_chunck.parse::<i32>().is_ok() {
576 continue;
577 } else {
578 return false;
579 }
580 } else if s_chunck.starts_with('@') {
581 continue;
582 } else if o_chunck != s_chunck {
583 return false;
584 }
585 }
586
587 true
588 }
589 }
590 }
591
592 fn handle_request(&self, request: HTTPRequest) -> HTTPResponse {
593 let exprs = self.parse(request.path.clone());
594 (self.handler.0)(request, exprs)
595 }
596}
597
598impl Listener {
599 pub fn new<T>(handler: T) -> Self
600 where
601 T: Fn(&HTTPRequest, &mut HTTPResponse) + Send + Sync + 'static,
602 {
603 Listener {
604 handler: EventHandler(Arc::new(Box::new(handler))),
605 }
606 }
607
608 pub fn notify(&self, req: &HTTPRequest, res: &mut HTTPResponse) {
609 (self.handler.0)(req, res)
610 }
611}
612
613impl SoftListener {
614 pub fn new<T>(handler: T) -> Self
615 where
616 T: Fn() + Send + Sync + 'static,
617 {
618 SoftListener {
619 handler: SoftEventHandler(Arc::new(Box::new(handler))),
620 }
621 }
622
623 pub fn notify(&self) {
624 (self.handler.0)()
625 }
626}
627
628impl ErrorListener {
629 pub fn new<T>(handler: T) -> Self
630 where
631 T: Fn(RunError) + Send + Sync + 'static,
632 {
633 Self {
634 handler: ErrorEventHandler(Arc::new(Box::new(handler))),
635 }
636 }
637
638 pub fn notify(&self, error: RunError) {
639 (self.handler.0)(error)
640 }
641}
642
643pub trait Server<U, V> {
644 fn handle_request(&self, stream: U, req: V);
645 fn run(&self);
646}
647
648pub type Request = Vec<u8>;
650pub type Response = Vec<u8>;
652
653pub struct HTTPServer {
681 pub addr: Vec<SocketAddr>,
682 pub paths: Vec<Path>,
683 pub listeners: Vec<Listener>,
684 pub on_ready: Option<SoftListener>,
685 pub on_shutdown: Option<SoftListener>, pub on_error: Option<ErrorListener>,
687 pub thread_pool: worker::ThreadPool,
688}
689
690impl Default for HTTPServer {
691 fn default() -> Self {
692 Self {
693 addr: vec![SocketAddr::new(
694 std::net::IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)),
695 4221,
696 )],
697 paths: vec![],
698 listeners: vec![],
699 on_ready: None,
700 on_shutdown: None,
701 on_error: None,
702 thread_pool: worker::ThreadPool::new(14),
703 }
704 }
705}
706
707impl Clone for HTTPServer {
708 fn clone(&self) -> Self {
709 Self {
710 addr: self.addr.clone(),
711 paths: self.paths.clone(),
712 listeners: self.listeners.clone(),
713 on_ready: self.on_ready.clone(),
714 on_shutdown: self.on_shutdown.clone(),
715 on_error: self.on_error.clone(),
716 thread_pool: worker::EMPTY_POOL,
717 }
718 }
719}
720
721pub enum RunError {
722 CannotBindToAddr(Vec<SocketAddr>),
723}
724
725impl std::fmt::Display for RunError {
726 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
727 match self {
728 RunError::CannotBindToAddr(addr) => {
729 write!(f, "Unable to bind to those addresses: {addr:?}")
730 }
731 }
732 }
733}
734
735impl Server<&mut TcpStream, HTTPRequest> for HTTPServer {
736 fn handle_request(&self, stream: &mut TcpStream, req: HTTPRequest) {
737 let mut handled = false;
738 for path in &self.paths {
739 if path.method == req.method && path.r#match(req.path.clone()) {
740 let mut response = path.handle_request(req.clone());
741 for listener in &self.listeners {
742 listener.notify(&req, &mut response);
743 }
744 let _ = stream.write(response.raw().as_slice());
745 handled = true;
746 break;
747 }
748 }
749 if !handled {
750 let mut response = HTTPResponse::default();
751 response.set_status(404);
752
753 let data: String = format!(
754 "Unreachable path `{:?} - {}`. Resource NOT FOUND",
755 req.method, req.path
756 );
757
758 let data_bytes: Vec<u8> = data.into_bytes();
759 response.set_body(data_bytes);
760 for listener in &self.listeners {
761 listener.notify(&req, &mut response);
762 }
763 let _ = stream.write(response.raw().as_slice());
764 }
765 }
766
767 fn run(&self) {
768 if let Ok(listener) = TcpListener::bind(self.addr.as_slice()) {
769 if let Some(ready_fn) = &self.on_ready {
770 ready_fn.notify();
771 }
772
773 for stream in listener.incoming() {
774 match stream {
775 Ok(stream) => {
776 let self_clone = Arc::new(self.clone());
777 self.thread_pool.execute(move || {
778 let s = self_clone.clone();
779 let mut st = stream;
780 s.handle_connection(&mut st);
781 });
782 }
783 Err(e) => {
784 eprintln!("{e}")
785 }
786 }
787 }
788 } else {
789 if let Some(onerror) = &self.on_error {
790 onerror.notify(RunError::CannotBindToAddr(self.addr.clone()));
791 }
792 }
793 }
794}
795
796impl HTTPServer {
797 pub fn new<A>(addr: A) -> Self
798 where
799 A: std::net::ToSocketAddrs,
800 {
801 Self {
802 addr: addr.to_socket_addrs().unwrap().collect(),
803 paths: Vec::new(),
804 listeners: Vec::new(),
805 on_ready: None,
806 on_shutdown: None,
807 on_error: None,
808 thread_pool: worker::ThreadPool::new(14),
809 }
810 }
811
812 pub fn on_ready<T>(&mut self, handler: T)
813 where
814 T: Fn() + Send + Sync + 'static,
815 {
816 self.on_ready = Some(SoftListener::new(handler));
817 }
818
819 pub fn on_shutdown<T>(&mut self, handler: T)
820 where
821 T: Fn() + Send + Sync + 'static,
822 {
823 self.on_shutdown = Some(SoftListener::new(handler));
824 }
825
826 pub fn on_error<T>(&mut self, handler: T)
827 where
828 T: Fn(RunError) + Send + Sync + 'static,
829 {
830 self.on_error = Some(ErrorListener::new(handler));
831 }
832
833 fn add_path(&mut self, path: Path) {
834 let path_name = path.expr.clone();
835 if !self.paths.contains(&path) {
836 self.paths.push(path);
837 } else {
838 eprintln!(
839 "..warn `{}` path redefinition is not allowed. Only the first definition matter",
840 path_name
841 );
842 }
843 }
844
845 fn handle_connection(&self, stream: &mut TcpStream) {
846 match stream.try_clone() {
847 Ok(s) => {
848 let mut reader = std::io::BufReader::new(s);
849 let mut head = String::new();
850 'read_req_head: loop {
851 let mut temp = String::new();
852 let _ = reader.read_line(&mut temp);
853
854 if temp.trim().is_empty() {
855 break 'read_req_head;
856 } else {
857 head.push_str(&temp);
858 }
859 }
860
861 let mut headers = [httparse::EMPTY_HEADER; 16];
862 let mut req = httparse::Request::new(&mut headers);
863 let is_complete = req.parse(&head.as_bytes()).unwrap().is_complete();
864 let raw_path = match req.path {
865 Some(p) => p.to_string(),
866 None => String::from("/"),
867 };
868 let (path, params) = parse_path(&raw_path);
869
870 let mut parsed_headers: HashMap<String, String> = HashMap::new();
871 for field in req.headers {
872 parsed_headers.insert(
873 field.name.to_lowercase(),
874 String::from_utf8(field.value.to_vec()).unwrap(),
875 );
876 }
877
878 let body_len: Option<usize> =
879 if let Some(len) = parsed_headers.get("content-length") {
880 Some(len.parse().unwrap())
881 } else {
882 None
883 };
884
885 let method = get_method(req.method);
886
887 if let Some(body_size) = body_len {
888 let mut body_buf = vec![0; body_size];
889 let _ = reader.read_exact(&mut body_buf);
890 if is_complete {
891 self.handle_request(
892 stream,
893 HTTPRequest {
894 method,
895 path,
896 raw_path,
897 params,
898 http_version: if req.version.unwrap() == 1 {
899 "1.1".into()
900 } else {
901 "1.2".into()
902 },
903 headers: parsed_headers,
904 body: body_buf,
905 },
906 );
907 };
908 } else {
909 let request = HTTPRequest {
910 method,
911 path,
912 raw_path,
913 params,
914 http_version: get_version(req.version),
915 headers: parsed_headers,
916 body: vec![],
917 };
918 self.handle_request(stream, request);
919 }
920 }
921 Err(e) => {
922 eprintln!("{e}");
923 }
924 }
925 }
926
927 pub fn connect<T>(&mut self, path: &'static str, handler: T)
928 where
929 T: Fn(HTTPRequest, PathMap) -> HTTPResponse + Send + Sync + 'static,
930 {
931 self.add_path(Path::new(path, handler, HTTPMethod::CONNECT));
932 }
933
934 pub fn delete<T>(&mut self, path: &'static str, handler: T)
935 where
936 T: Fn(HTTPRequest, PathMap) -> HTTPResponse + Send + Sync + 'static,
937 {
938 self.add_path(Path::new(path, handler, HTTPMethod::DELETE));
939 }
940
941 pub fn get<T>(&mut self, path: &'static str, handler: T)
942 where
943 T: Fn(HTTPRequest, PathMap) -> HTTPResponse + Send + Sync + 'static,
944 {
945 self.add_path(Path::new(path, handler, HTTPMethod::GET));
946 }
947
948 pub fn head<T>(&mut self, path: &'static str, handler: T)
949 where
950 T: Fn(HTTPRequest, PathMap) -> HTTPResponse + Send + Sync + 'static,
951 {
952 self.add_path(Path::new(path, handler, HTTPMethod::HEAD));
953 }
954
955 pub fn options<T>(&mut self, path: &'static str, handler: T)
956 where
957 T: Fn(HTTPRequest, PathMap) -> HTTPResponse + Send + Sync + 'static,
958 {
959 self.add_path(Path::new(path, handler, HTTPMethod::OPTIONS));
960 }
961
962 pub fn patch<T>(&mut self, path: &'static str, handler: T)
963 where
964 T: Fn(HTTPRequest, PathMap) -> HTTPResponse + Send + Sync + 'static,
965 {
966 self.add_path(Path::new(path, handler, HTTPMethod::PATCH));
967 }
968
969 pub fn post<T>(&mut self, path: &'static str, handler: T)
970 where
971 T: Fn(HTTPRequest, PathMap) -> HTTPResponse + Send + Sync + 'static,
972 {
973 self.add_path(Path::new(path, handler, HTTPMethod::POST));
974 }
975
976 pub fn put<T>(&mut self, path: &'static str, handler: T)
977 where
978 T: Fn(HTTPRequest, PathMap) -> HTTPResponse + Send + Sync + 'static,
979 {
980 self.add_path(Path::new(path, handler, HTTPMethod::PUT));
981 }
982
983 pub fn trace<T>(&mut self, path: &'static str, handler: T)
984 where
985 T: Fn(HTTPRequest, PathMap) -> HTTPResponse + Send + Sync + 'static,
986 {
987 self.add_path(Path::new(path, handler, HTTPMethod::TRACE));
988 }
989
990 pub fn on_any<T>(&mut self, handler: T)
991 where
992 T: Fn(&HTTPRequest, &mut HTTPResponse) + Send + Sync + 'static,
993 {
994 self.listeners.push(Listener::new(handler));
995 }
996}
997
998pub struct TcpServer {
999 pub addr: Vec<SocketAddr>,
1000 listeners: Vec<SimpleEventHandler>,
1001 on_ready: Option<SoftListener>,
1002 on_shutdown: Option<SoftListener>, max_buffer: Option<usize>,
1004}
1005
1006impl Default for TcpServer {
1007 fn default() -> Self {
1008 Self {
1009 addr: vec![SocketAddr::new(
1010 std::net::IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)),
1011 4221,
1012 )],
1013 listeners: vec![],
1014 on_ready: None,
1015 on_shutdown: None,
1016 max_buffer: None,
1017 }
1018 }
1019}
1020
1021impl Server<&mut TcpStream, Request> for TcpServer {
1022 fn handle_request(&self, stream: &mut TcpStream, req: Request) {
1023 for listener in &self.listeners {
1024 if let Some(response) = listener.0(stream, req.clone()) {
1025 let _ = stream.write(&response);
1026 }
1027 }
1028 }
1029
1030 fn run(&self) {
1031 let listener = TcpListener::bind(self.addr.as_slice()).unwrap();
1032 if let Some(ready_fn) = &self.on_ready {
1033 ready_fn.notify();
1034 }
1035
1036 for stream in listener.incoming() {
1037 let mut max_buffer = MAX_BUFFER;
1038 if let Some(mxb) = self.max_buffer {
1039 max_buffer = mxb;
1040 }
1041 match stream {
1042 Ok(mut stream) => {
1043 let mut data = vec![0; max_buffer];
1044 let _ = stream.read(&mut data);
1045 self.handle_request(&mut stream, data);
1046 }
1047 Err(e) => {
1048 eprintln!("{e}")
1049 }
1050 }
1051 }
1052 }
1053}
1054
1055impl TcpServer {
1056 pub fn new<A>(addr: A) -> Self
1057 where
1058 A: std::net::ToSocketAddrs,
1059 {
1060 Self {
1061 addr: addr.to_socket_addrs().unwrap().collect(),
1062 on_ready: None,
1063 listeners: Vec::new(),
1064 on_shutdown: None,
1065 max_buffer: None,
1066 }
1067 }
1068
1069 pub fn on_ready<T>(&mut self, handler: T)
1070 where
1071 T: Fn() + Send + Sync + 'static,
1072 {
1073 self.on_ready = Some(SoftListener::new(handler));
1074 }
1075
1076 pub fn on_shutdown<T>(&mut self, handler: T)
1077 where
1078 T: Fn() + Send + Sync + 'static,
1079 {
1080 self.on_shutdown = Some(SoftListener::new(handler));
1081 }
1082
1083 pub fn set_buffer_to(&mut self, size: usize) {
1084 self.max_buffer = Some(size);
1085 }
1086}