1pub mod thread_pool {
2 use std::sync::mpsc;
3 use std::sync::Arc;
4 use std::sync::Mutex;
5 use std::thread;
6 type Job = Box<dyn FnOnce() + Send + 'static>;
7
8 enum ThreadState {
9 Doing(Job),
10 Terminate,
11 }
12 pub struct Worker {
13 id: usize,
14 thread: Option<thread::JoinHandle<()>>,
15 }
16
17 impl Worker {
18 fn new(id: usize, receiver: Arc<Mutex<mpsc::Receiver<ThreadState>>>) -> Worker {
19 let thread = thread::spawn(move || loop {
20 let state = receiver.lock().unwrap().recv().unwrap();
21 match state {
22 ThreadState::Doing(job) => {
23 println!("Worder {}, got a job; executing.", id);
24 job();
25 }
26 ThreadState::Terminate => {
27 println!("Worker {} was told to terminate.", id);
28 break;
29 }
30 }
31 });
32 Worker {
33 id,
34 thread: Some(thread),
35 }
36 }
37 }
38 pub struct ThreadPool {
39 workers: Vec<Worker>,
40 sender: mpsc::Sender<ThreadState>,
41 }
42
43 impl ThreadPool {
44 pub fn new(size: usize) -> ThreadPool {
45 assert!(size > 0);
46
47 let (sender, receiver) = mpsc::channel();
48 let receiver = Arc::new(Mutex::new(receiver));
49 let mut workers = Vec::with_capacity(size);
50 for id in 0..size {
51 workers.push(Worker::new(id, Arc::clone(&receiver)));
52 }
53 ThreadPool { workers, sender }
54 }
55 pub fn execute<F>(&self, f: F)
56 where
57 F: FnOnce() + Send + 'static,
58 {
59 let job = Box::new(f);
60 self.sender.send(ThreadState::Doing(job)).unwrap();
61 }
62 }
63 impl Drop for ThreadPool {
64 fn drop(&mut self) {
65 for _ in &self.workers {
66 self.sender.send(ThreadState::Terminate).unwrap();
67 }
68 for worker in &mut self.workers {
69 println!("shutting down worker {}", worker.id);
70 if let Some(thread) = worker.thread.take() {
71 thread.join().unwrap();
72 }
73 }
74 }
75 }
76}
77
78pub mod server {
79 use crate::thread_pool;
80 use std::collections::HashMap;
81 use std::fs;
82 use std::io::prelude::*;
83 use std::net::TcpListener;
84 use std::net::TcpStream;
85 #[derive(Clone)]
86 pub struct Server {
87 pub req_hash: HashMap<String, String>,
88 pub port: String
89 }
90 impl Server {
91 pub fn new() -> Server {
92 Server {
93 req_hash: HashMap::new(),
94 port: "8080".to_string(),
95 }
96 }
97 pub fn get(&mut self, path: &str, serve: &str) {
98 self.req_hash
99 .insert(format!("GET {} HTTP/1.1\r\n", path), serve.to_string());
100 }
101
102 fn check_req(&mut self, buffer: [u8; 1024]) -> (String, String) {
103 let buffer = String::from_utf8_lossy(&buffer[..]);
104 for req in self.req_hash.keys() {
105 if buffer.starts_with(req) {
106 return (
107 "HTTP/1.1 200 OK".to_string(),
108 match self.req_hash.get(&req.clone()) {
109 Some(addr) => addr.to_string(),
110 None => {
111 panic!("error while handleing {}", req);
113 }
114 },
115 );
116 }
117 }
118 (
119 "HTTP/1.1 404 NOT FOUND".to_string(),
120 "public/404.html".to_string(),
121 )
122 }
123
124 fn handle_connection(&mut self, mut stream: TcpStream) {
125 let mut buffer = [0; 1024];
126 stream.read(&mut buffer).unwrap();
127 let (status_line, mut content) = self.check_req(buffer.clone());
128 if content.starts_with("public") {
129 content = fs::read_to_string(content).unwrap();
130 }
131
132 let responce = format!(
133 "{}\r\nContent-Lenght: {}\r\n\r\n{}",
134 status_line,
135 content.len(),
136 content
137 );
138 stream.write(responce.as_bytes()).unwrap();
139 stream.flush().unwrap();
140 }
141 pub fn bind(&mut self, port: &str) {
142 self.port = port.to_string();
143 }
144 pub fn start(&self) {
145 let listener = TcpListener::bind(String::from("127.0.0.1:") + &self.port).unwrap();
146 let pool = thread_pool::ThreadPool::new(4);
147 for stream in listener.incoming() {
148 let stream = stream.unwrap();
149 let mut inst = self.clone();
150 pool.execute(move || {
151 inst.handle_connection(stream);
152 });
153 }
154 println!("Shutting the server down");
155 }
156 }
157}