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;
6use std::sync::atomic::{AtomicBool, Ordering};
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, Clone)]
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]);
209response_from_for!(&str);
210response_from_for!(Vec<u8>);
211response_from_for!(String);
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 Float(f32),
471}
472
473pub struct Path {
474 pub expr: String,
475 pub handler: RequestHandler,
476 pub method: HTTPMethod,
477}
478
479impl Clone for Path {
480 fn clone(&self) -> Self {
481 Self {
482 expr: self.expr.clone(),
483 handler: self.handler.clone(),
484 method: self.method.clone(),
485 }
486 }
487}
488
489impl PartialEq for Path {
490 fn eq(&self, other: &Self) -> bool {
491 self.r#match(other.expr.clone()) && self.method == other.method
492 }
493}
494
495pub struct Listener {
496 handler: EventHandler,
497}
498
499impl Clone for Listener {
500 fn clone(&self) -> Self {
501 Self {
502 handler: self.handler.clone(),
503 }
504 }
505}
506
507pub struct SoftListener {
508 handler: SoftEventHandler,
509}
510
511impl Clone for SoftListener {
512 fn clone(&self) -> Self {
513 Self {
514 handler: self.handler.clone(),
515 }
516 }
517}
518
519pub struct ErrorListener {
520 handler: ErrorEventHandler,
521}
522
523impl Clone for ErrorListener {
524 fn clone(&self) -> Self {
525 Self {
526 handler: self.handler.clone(),
527 }
528 }
529}
530
531impl Path {
532 pub fn new<T>(expr: &str, handler: T, method: HTTPMethod) -> Self
533 where
534 T: Fn(HTTPRequest, PathMap) -> HTTPResponse + Send + Sync + 'static,
535 {
536 Path {
537 expr: expr.to_string(),
538 handler: RequestHandler(Arc::new(Box::new(handler))),
539 method,
540 }
541 }
542
543 fn parse(&self, expr: String) -> PathMap {
544 let mut exprs = PathMap::new();
545 if self.r#match(expr.clone()) {
546 let other_part: Vec<_> = expr.split('/').filter(|x| !x.is_empty()).collect();
547 let self_part: Vec<_> = self.expr.split('/').filter(|x| !x.is_empty()).collect();
548
549 for (o_chunck, s_chunck) in zip(other_part, self_part) {
550 if s_chunck.starts_with("#F") {
551 let name = s_chunck.strip_prefix("#F").unwrap().to_string();
552 let value = o_chunck.parse::<f32>().unwrap();
553 exprs.insert(name, PathExpr::Float(value));
554 } else if s_chunck.starts_with('#') {
555 let name = s_chunck.strip_prefix('#').unwrap().to_string();
556 let value = o_chunck.parse::<i32>().unwrap();
557 exprs.insert(name, PathExpr::Number(value));
558 } else if s_chunck.starts_with('@') {
559 let name = s_chunck.strip_prefix('@').unwrap().to_string();
560 let value = o_chunck.to_string();
561 exprs.insert(name, PathExpr::String(value));
562 } else {
563 continue;
564 }
565 }
566 }
567
568 exprs
569 }
570
571 fn r#match(&self, expr: String) -> bool {
572 if expr == self.expr {
573 true
574 } else {
575 let other_part: Vec<_> = expr.split('/').filter(|x| !x.is_empty()).collect();
576 let self_part: Vec<_> = self.expr.split('/').filter(|x| !x.is_empty()).collect();
577
578 if other_part.len() != self_part.len() {
579 false
580 } else {
581 for (o_chunck, s_chunck) in zip(other_part, self_part) {
582 if s_chunck.starts_with("#F") {
583 if o_chunck.parse::<f32>().is_ok() {
584 continue;
585 } else {
586 return false;
587 }
588 } else if s_chunck.starts_with('#') {
589 if o_chunck.parse::<i32>().is_ok() {
590 continue;
591 } else {
592 return false;
593 }
594 } else if s_chunck.starts_with('@') {
595 continue;
596 } else if o_chunck != s_chunck {
597 return false;
598 }
599 }
600
601 true
602 }
603 }
604 }
605
606 fn handle_request(&self, request: HTTPRequest) -> HTTPResponse {
607 let exprs = self.parse(request.path.clone());
608 (self.handler.0)(request, exprs)
609 }
610}
611
612impl Listener {
613 pub fn new<T>(handler: T) -> Self
614 where
615 T: Fn(&HTTPRequest, &mut HTTPResponse) + Send + Sync + 'static,
616 {
617 Listener {
618 handler: EventHandler(Arc::new(Box::new(handler))),
619 }
620 }
621
622 pub fn notify(&self, req: &HTTPRequest, res: &mut HTTPResponse) {
623 (self.handler.0)(req, res)
624 }
625}
626
627impl SoftListener {
628 pub fn new<T>(handler: T) -> Self
629 where
630 T: Fn() + Send + Sync + 'static,
631 {
632 SoftListener {
633 handler: SoftEventHandler(Arc::new(Box::new(handler))),
634 }
635 }
636
637 pub fn notify(&self) {
638 (self.handler.0)()
639 }
640}
641
642impl ErrorListener {
643 pub fn new<T>(handler: T) -> Self
644 where
645 T: Fn(RunError) + Send + Sync + 'static,
646 {
647 Self {
648 handler: ErrorEventHandler(Arc::new(Box::new(handler))),
649 }
650 }
651
652 pub fn notify(&self, error: RunError) {
653 (self.handler.0)(error)
654 }
655}
656
657pub trait Server<U, V> {
658 fn handle_request(&self, stream: U, req: V);
659 fn run(&self);
660}
661
662pub type Request = Vec<u8>;
664pub type Response = Vec<u8>;
666
667pub struct HTTPServer {
692 pub addr: Vec<SocketAddr>,
693 pub paths: Vec<Path>,
694 pub listeners: Vec<Listener>,
695 pub on_ready: Option<SoftListener>,
696 pub on_shutdown: Option<SoftListener>, pub on_error: Option<ErrorListener>,
698 pub thread_pool: worker::ThreadPool,
699 pub should_shutdown: ShutdownWrapper,
700}
701
702pub struct ShutdownWrapper(AtomicBool);
703
704impl Default for HTTPServer {
705 fn default() -> Self {
706 Self {
707 addr: vec![SocketAddr::new(
708 std::net::IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)),
709 4221,
710 )],
711 paths: vec![],
712 listeners: vec![],
713 on_ready: None,
714 on_shutdown: None,
715 on_error: None,
716 thread_pool: worker::ThreadPool::new(14),
717 should_shutdown: ShutdownWrapper(AtomicBool::new(false)),
718 }
719 }
720}
721
722impl Clone for HTTPServer {
723 fn clone(&self) -> Self {
724 let new_should_shutdown = self.should_shutdown.0.load(Ordering::Relaxed);
725
726 Self {
727 addr: self.addr.clone(),
728 paths: self.paths.clone(),
729 listeners: self.listeners.clone(),
730 on_ready: self.on_ready.clone(),
731 on_shutdown: self.on_shutdown.clone(),
732 on_error: self.on_error.clone(),
733 thread_pool: worker::EMPTY_POOL,
734 should_shutdown: ShutdownWrapper(AtomicBool::new(new_should_shutdown)),
735 }
736 }
737}
738
739pub enum RunError {
740 CannotBindToAddr(Vec<SocketAddr>),
741}
742
743impl std::fmt::Display for RunError {
744 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
745 match self {
746 RunError::CannotBindToAddr(addr) => {
747 write!(f, "Unable to bind to those addresses: {addr:?}")
748 }
749 }
750 }
751}
752
753impl Server<&mut TcpStream, HTTPRequest> for HTTPServer {
754 fn handle_request(&self, stream: &mut TcpStream, req: HTTPRequest) {
755 let mut handled = false;
756 for path in &self.paths {
757 if path.method == req.method && path.r#match(req.path.clone()) {
758 let mut response = path.handle_request(req.clone());
759 for listener in &self.listeners {
760 listener.notify(&req, &mut response);
761 }
762 let _ = stream.write(response.raw().as_slice());
763 handled = true;
764 break;
765 }
766 }
767 if !handled {
768 let mut response = HTTPResponse::default();
769 response.set_status(404);
770
771 let data: String = format!(
772 "Unreachable path `{:?} - {}`. Resource NOT FOUND",
773 req.method, req.path
774 );
775
776 let data_bytes: Vec<u8> = data.into_bytes();
777 response.set_body(data_bytes);
778 for listener in &self.listeners {
779 listener.notify(&req, &mut response);
780 }
781 let _ = stream.write(response.raw().as_slice());
782 }
783 }
784
785 fn run(&self) {
786 if let Ok(listener) = TcpListener::bind(self.addr.as_slice()) {
787 if let Some(ready_fn) = &self.on_ready {
788 ready_fn.notify();
789 }
790
791 for stream in listener.incoming() {
792 match stream {
793 Ok(stream) => {
794 let self_clone = Arc::new(self.clone());
795 self.thread_pool.execute(move || {
796 let s = self_clone.clone();
797 let mut st = stream;
798 s.handle_connection(&mut st);
799 });
800 }
801 Err(e) => {
802 eprintln!("{e}")
803 }
804 }
805 }
806 } else {
807 if let Some(onerror) = &self.on_error {
808 onerror.notify(RunError::CannotBindToAddr(self.addr.clone()));
809 }
810 }
811 }
812}
813
814macro_rules! define_all_route_methods {
815 ($($name:ident => $method:expr),* $(,)?) => {
816 impl HTTPServer {
817 $(
818 pub fn $name<T>(&mut self, path: &'static str, handler: T)
819 where
820 T: Fn(HTTPRequest, PathMap) -> HTTPResponse + Send + Sync + 'static,
821 {
822 self.add_path(Path::new(path, handler, $method));
823 }
824 )*
825 }
826 };
827}
828
829define_all_route_methods! {
830 get => HTTPMethod::GET,
831 post => HTTPMethod::POST,
832 put => HTTPMethod::PUT,
833 delete => HTTPMethod::DELETE,
834 patch => HTTPMethod::PATCH,
835 options => HTTPMethod::OPTIONS,
836 head => HTTPMethod::HEAD,
837 trace => HTTPMethod::TRACE,
838 connect => HTTPMethod::CONNECT,
839}
840
841impl HTTPServer {
842 pub fn new<A>(addr: A) -> Self
843 where
844 A: std::net::ToSocketAddrs,
845 {
846 Self {
847 addr: addr.to_socket_addrs().unwrap().collect(),
848 paths: Vec::new(),
849 listeners: Vec::new(),
850 on_ready: None,
851 on_shutdown: None,
852 on_error: None,
853 thread_pool: worker::ThreadPool::new(14),
854 should_shutdown: ShutdownWrapper(AtomicBool::new(false)),
855 }
856 }
857
858 pub fn on_ready<T>(&mut self, handler: T)
859 where
860 T: Fn() + Send + Sync + 'static,
861 {
862 self.on_ready = Some(SoftListener::new(handler));
863 }
864
865 pub fn shutdown(&self) {
866 self.should_shutdown.0.store(true, Ordering::Relaxed)
867 }
868
869 pub fn on_shutdown<T>(&mut self, handler: T)
870 where
871 T: Fn() + Send + Sync + 'static,
872 {
873 self.on_shutdown = Some(SoftListener::new(handler));
874 }
875
876 pub fn on_error<T>(&mut self, handler: T)
877 where
878 T: Fn(RunError) + Send + Sync + 'static,
879 {
880 self.on_error = Some(ErrorListener::new(handler));
881 }
882
883 fn add_path(&mut self, path: Path) {
884 let path_name = path.expr.clone();
885 if !self.paths.contains(&path) {
886 self.paths.push(path);
887 } else {
888 eprintln!(
889 "..warn `{}` path redefinition is not allowed. Only the first definition matter",
890 path_name
891 );
892 }
893 }
894
895 fn handle_connection(&self, stream: &mut TcpStream) {
896 match stream.try_clone() {
897 Ok(s) => {
898 let mut reader = std::io::BufReader::new(s);
899 let mut head = String::new();
900 'read_req_head: loop {
901 let mut temp = String::new();
902 let _ = reader.read_line(&mut temp);
903
904 if temp.trim().is_empty() {
905 break 'read_req_head;
906 } else {
907 head.push_str(&temp);
908 }
909 }
910
911 let mut headers = [httparse::EMPTY_HEADER; 16];
912 let mut req = httparse::Request::new(&mut headers);
913 let is_complete = req.parse(&head.as_bytes()).unwrap().is_complete();
914 let raw_path = match req.path {
915 Some(p) => p.to_string(),
916 None => String::from("/"),
917 };
918 let (path, params) = parse_path(&raw_path);
919
920 let mut parsed_headers: HashMap<String, String> = HashMap::new();
921 for field in req.headers {
922 parsed_headers.insert(
923 field.name.to_lowercase(),
924 String::from_utf8(field.value.to_vec()).unwrap(),
925 );
926 }
927
928 let body_len: Option<usize> =
929 if let Some(len) = parsed_headers.get("content-length") {
930 Some(len.parse().unwrap())
931 } else {
932 None
933 };
934
935 let method = get_method(req.method);
936
937 if let Some(body_size) = body_len {
938 let mut body_buf = vec![0; body_size];
939 let _ = reader.read_exact(&mut body_buf);
940 if is_complete {
941 self.handle_request(
942 stream,
943 HTTPRequest {
944 method,
945 path,
946 raw_path,
947 params,
948 http_version: if req.version.unwrap() == 1 {
949 "1.1".into()
950 } else {
951 "1.2".into()
952 },
953 headers: parsed_headers,
954 body: body_buf,
955 },
956 );
957 };
958 } else {
959 let request = HTTPRequest {
960 method,
961 path,
962 raw_path,
963 params,
964 http_version: get_version(req.version),
965 headers: parsed_headers,
966 body: vec![],
967 };
968 self.handle_request(stream, request);
969 }
970 }
971 Err(e) => {
972 eprintln!("{e}");
973 }
974 }
975 }
976
977 pub fn on_any<T>(&mut self, handler: T)
978 where
979 T: Fn(&HTTPRequest, &mut HTTPResponse) + Send + Sync + 'static,
980 {
981 self.listeners.push(Listener::new(handler));
982 }
983}
984
985pub struct TcpServer {
986 pub addr: Vec<SocketAddr>,
987 listeners: Vec<SimpleEventHandler>,
988 on_ready: Option<SoftListener>,
989 on_shutdown: Option<SoftListener>, max_buffer: Option<usize>,
991}
992
993impl Default for TcpServer {
994 fn default() -> Self {
995 Self {
996 addr: vec![SocketAddr::new(
997 std::net::IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)),
998 4221,
999 )],
1000 listeners: vec![],
1001 on_ready: None,
1002 on_shutdown: None,
1003 max_buffer: None,
1004 }
1005 }
1006}
1007
1008impl Server<&mut TcpStream, Request> for TcpServer {
1009 fn handle_request(&self, stream: &mut TcpStream, req: Request) {
1010 for listener in &self.listeners {
1011 if let Some(response) = listener.0(stream, req.clone()) {
1012 let _ = stream.write(&response);
1013 }
1014 }
1015 }
1016
1017 fn run(&self) {
1018 let listener = TcpListener::bind(self.addr.as_slice()).unwrap();
1019 if let Some(ready_fn) = &self.on_ready {
1020 ready_fn.notify();
1021 }
1022
1023 for stream in listener.incoming() {
1024 let mut max_buffer = MAX_BUFFER;
1025 if let Some(mxb) = self.max_buffer {
1026 max_buffer = mxb;
1027 }
1028 match stream {
1029 Ok(mut stream) => {
1030 let mut data = vec![0; max_buffer];
1031 let _ = stream.read(&mut data);
1032 self.handle_request(&mut stream, data);
1033 }
1034 Err(e) => {
1035 eprintln!("{e}")
1036 }
1037 }
1038 }
1039 }
1040}
1041
1042impl TcpServer {
1043 pub fn new<A>(addr: A) -> Self
1044 where
1045 A: std::net::ToSocketAddrs,
1046 {
1047 Self {
1048 addr: addr.to_socket_addrs().unwrap().collect(),
1049 on_ready: None,
1050 listeners: Vec::new(),
1051 on_shutdown: None,
1052 max_buffer: None,
1053 }
1054 }
1055
1056 pub fn on_ready<T>(&mut self, handler: T)
1057 where
1058 T: Fn() + Send + Sync + 'static,
1059 {
1060 self.on_ready = Some(SoftListener::new(handler));
1061 }
1062
1063 pub fn on_shutdown<T>(&mut self, handler: T)
1064 where
1065 T: Fn() + Send + Sync + 'static,
1066 {
1067 self.on_shutdown = Some(SoftListener::new(handler));
1068 }
1069
1070 pub fn set_buffer_to(&mut self, size: usize) {
1071 self.max_buffer = Some(size);
1072 }
1073}