1pub mod handlers {
24 use std::net::TcpListener;
26 use std::net::TcpStream;
27 use std::io::prelude::*;
28 use std::collections::HashMap;
29 use colored;
30
31 pub struct AppHandler<'a> {
32 host: String,
33 port: i32,
34 routes: HashMap<String, &'a dyn Fn([u8; 1024]) -> String>,
35 }
36 impl<'a> AppHandler<'a> {
37 pub fn new(host: String, port: i32) -> AppHandler<'a> {
38 AppHandler {
39 host: host,
40 port: port,
41 routes: HashMap::new(),
42 }
43 }
44 pub fn route(&mut self, path: String, dest: &'a (dyn (Fn([u8; 1024]) -> String) + 'a)) {
45 self.routes.insert(path, dest);
46 }
47 pub fn serve(&mut self) {
48 let mut found_err_page = false;
49 self.routes.retain(|key, _value| {
50
51 if *key == ".".to_string() {
52 found_err_page = true;
53 }
54 true
55 });
56 if !found_err_page {
57 println!("Error: web server has no error page");
58 println!("Help: consider adding a error page");
59 println!("{}", colored::Colorize::green("app.route(\".\".to_string(), &err_page_function);"));
60 println!("Note: replace err_page_function with the name of your own function that returns html for the error page");
61 println!("Note: remember to add a parameter with type RequestBuffer ({})", colored::Colorize::green("fn err_page(buffer: RequestBuffer) -> String"));
62 println!("Note: remember to {} if you haven't already", colored::Colorize::green("use haws::types::{RequestBuffer};"));
63 panic!("UnsafeWebserver")
64 }
65 let mut handle_connection = |mut stream: TcpStream| {
66 let mut buffer = [0; 1024];
67 stream.read(&mut buffer).unwrap();
68 let mut gets = vec![];
69 let mut paths = vec![];
70
71 self.routes.retain(|key, _value| {
72 if *key != ".".to_string() {
73 gets.push(format!("GET {} HTTP/1.1\r\n", key));
74 paths.push(format!("{}", key));
75 }
76 true
77 });
78 let mut idx: usize = 0;
79 let mut contents: String = String::new();
80 let mut found_route = false;
81 for g in gets.iter() {
82 if buffer.starts_with(String::as_bytes(g)) {
83 contents = self.routes.get(paths.get(idx).unwrap()).unwrap()(buffer);
84 found_route = true;
85 }
86 idx += 1;
87 }
88 if !found_route {
89
90 contents = self.routes.get(&".".to_string()).unwrap()(buffer);
91
92 }
93
94
95 let response = format!(
96 "HTTP/1.1 200 OK\r\nContent-Length: {}\r\n\r\n{}",
97 contents.len(),
98 contents
99 );
100 stream.write(response.as_bytes()).unwrap();
101 stream.flush().unwrap();
102 };
103
104 let listener = TcpListener::bind(format!("{}:{}", self.host, self.port)).unwrap();
105 for stream in listener.incoming() {
106 let ustream = stream.unwrap();
107
108 handle_connection(ustream);
109 }
110 }
111 }
112}
113
114pub mod types {
115 pub type RequestBuffer = [u8; 1024];
117
118}