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}
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
803macro_rules! define_all_route_methods {
804 ($($name:ident => $method:expr),* $(,)?) => {
805 impl HTTPServer {
806 $(
807 pub fn $name<T>(&mut self, path: &'static str, handler: T)
808 where
809 T: Fn(HTTPRequest, PathMap) -> HTTPResponse + Send + Sync + 'static,
810 {
811 self.add_path(Path::new(path, handler, $method));
812 }
813 )*
814 }
815 };
816}
817
818define_all_route_methods! {
819 get => HTTPMethod::GET,
820 post => HTTPMethod::POST,
821 put => HTTPMethod::PUT,
822 delete => HTTPMethod::DELETE,
823 patch => HTTPMethod::PATCH,
824 options => HTTPMethod::OPTIONS,
825 head => HTTPMethod::HEAD,
826 trace => HTTPMethod::TRACE,
827 connect => HTTPMethod::CONNECT,
828}
829
830impl HTTPServer {
831 pub fn new<A>(addr: A) -> Self
832 where
833 A: std::net::ToSocketAddrs,
834 {
835 Self {
836 addr: addr.to_socket_addrs().unwrap().collect(),
837 paths: Vec::new(),
838 listeners: Vec::new(),
839 on_ready: None,
840 on_shutdown: None,
841 on_error: None,
842 thread_pool: worker::ThreadPool::new(14),
843 should_shutdown: ShutdownWrapper(AtomicBool::new(false)),
844 }
845 }
846
847 pub fn on_ready<T>(&mut self, handler: T)
848 where
849 T: Fn() + Send + Sync + 'static,
850 {
851 self.on_ready = Some(SoftListener::new(handler));
852 }
853
854 pub fn shutdown(&self) {
855 self.should_shutdown.0.store(true, Ordering::Relaxed)
856 }
857
858 pub fn on_shutdown<T>(&mut self, handler: T)
859 where
860 T: Fn() + Send + Sync + 'static,
861 {
862 self.on_shutdown = Some(SoftListener::new(handler));
863 }
864
865 pub fn on_error<T>(&mut self, handler: T)
866 where
867 T: Fn(RunError) + Send + Sync + 'static,
868 {
869 self.on_error = Some(ErrorListener::new(handler));
870 }
871
872 fn add_path(&mut self, path: Path) {
873 let path_name = path.expr.clone();
874 if !self.paths.contains(&path) {
875 self.paths.push(path);
876 } else {
877 eprintln!(
878 "..warn `{}` path redefinition is not allowed. Only the first definition matter",
879 path_name
880 );
881 }
882 }
883
884 fn handle_connection(&self, stream: &mut TcpStream) {
885 match stream.try_clone() {
886 Ok(s) => {
887 let mut reader = std::io::BufReader::new(s);
888 let mut head = String::new();
889 'read_req_head: loop {
890 let mut temp = String::new();
891 let _ = reader.read_line(&mut temp);
892
893 if temp.trim().is_empty() {
894 break 'read_req_head;
895 } else {
896 head.push_str(&temp);
897 }
898 }
899
900 let mut headers = [httparse::EMPTY_HEADER; 16];
901 let mut req = httparse::Request::new(&mut headers);
902 let is_complete = req.parse(&head.as_bytes()).unwrap().is_complete();
903 let raw_path = match req.path {
904 Some(p) => p.to_string(),
905 None => String::from("/"),
906 };
907 let (path, params) = parse_path(&raw_path);
908
909 let mut parsed_headers: HashMap<String, String> = HashMap::new();
910 for field in req.headers {
911 parsed_headers.insert(
912 field.name.to_lowercase(),
913 String::from_utf8(field.value.to_vec()).unwrap(),
914 );
915 }
916
917 let body_len: Option<usize> =
918 if let Some(len) = parsed_headers.get("content-length") {
919 Some(len.parse().unwrap())
920 } else {
921 None
922 };
923
924 let method = get_method(req.method);
925
926 if let Some(body_size) = body_len {
927 let mut body_buf = vec![0; body_size];
928 let _ = reader.read_exact(&mut body_buf);
929 if is_complete {
930 self.handle_request(
931 stream,
932 HTTPRequest {
933 method,
934 path,
935 raw_path,
936 params,
937 http_version: if req.version.unwrap() == 1 {
938 "1.1".into()
939 } else {
940 "1.2".into()
941 },
942 headers: parsed_headers,
943 body: body_buf,
944 },
945 );
946 };
947 } else {
948 let request = HTTPRequest {
949 method,
950 path,
951 raw_path,
952 params,
953 http_version: get_version(req.version),
954 headers: parsed_headers,
955 body: vec![],
956 };
957 self.handle_request(stream, request);
958 }
959 }
960 Err(e) => {
961 eprintln!("{e}");
962 }
963 }
964 }
965
966 pub fn on_any<T>(&mut self, handler: T)
967 where
968 T: Fn(&HTTPRequest, &mut HTTPResponse) + Send + Sync + 'static,
969 {
970 self.listeners.push(Listener::new(handler));
971 }
972}
973
974pub struct TcpServer {
975 pub addr: Vec<SocketAddr>,
976 listeners: Vec<SimpleEventHandler>,
977 on_ready: Option<SoftListener>,
978 on_shutdown: Option<SoftListener>, max_buffer: Option<usize>,
980}
981
982impl Default for TcpServer {
983 fn default() -> Self {
984 Self {
985 addr: vec![SocketAddr::new(
986 std::net::IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)),
987 4221,
988 )],
989 listeners: vec![],
990 on_ready: None,
991 on_shutdown: None,
992 max_buffer: None,
993 }
994 }
995}
996
997impl Server<&mut TcpStream, Request> for TcpServer {
998 fn handle_request(&self, stream: &mut TcpStream, req: Request) {
999 for listener in &self.listeners {
1000 if let Some(response) = listener.0(stream, req.clone()) {
1001 let _ = stream.write(&response);
1002 }
1003 }
1004 }
1005
1006 fn run(&self) {
1007 let listener = TcpListener::bind(self.addr.as_slice()).unwrap();
1008 if let Some(ready_fn) = &self.on_ready {
1009 ready_fn.notify();
1010 }
1011
1012 for stream in listener.incoming() {
1013 let mut max_buffer = MAX_BUFFER;
1014 if let Some(mxb) = self.max_buffer {
1015 max_buffer = mxb;
1016 }
1017 match stream {
1018 Ok(mut stream) => {
1019 let mut data = vec![0; max_buffer];
1020 let _ = stream.read(&mut data);
1021 self.handle_request(&mut stream, data);
1022 }
1023 Err(e) => {
1024 eprintln!("{e}")
1025 }
1026 }
1027 }
1028 }
1029}
1030
1031impl TcpServer {
1032 pub fn new<A>(addr: A) -> Self
1033 where
1034 A: std::net::ToSocketAddrs,
1035 {
1036 Self {
1037 addr: addr.to_socket_addrs().unwrap().collect(),
1038 on_ready: None,
1039 listeners: Vec::new(),
1040 on_shutdown: None,
1041 max_buffer: None,
1042 }
1043 }
1044
1045 pub fn on_ready<T>(&mut self, handler: T)
1046 where
1047 T: Fn() + Send + Sync + 'static,
1048 {
1049 self.on_ready = Some(SoftListener::new(handler));
1050 }
1051
1052 pub fn on_shutdown<T>(&mut self, handler: T)
1053 where
1054 T: Fn() + Send + Sync + 'static,
1055 {
1056 self.on_shutdown = Some(SoftListener::new(handler));
1057 }
1058
1059 pub fn set_buffer_to(&mut self, size: usize) {
1060 self.max_buffer = Some(size);
1061 }
1062}