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