cs431_homework/hello_server/
handler.rs1use std::io::prelude::*;
4use std::net::TcpStream;
5use std::sync::{Arc, OnceLock};
6use std::thread;
7use std::time::Duration;
8
9use regex::bytes::Regex;
10
11use super::cache::Cache;
12use super::statistics::Report;
13
14fn very_expensive_computation_that_takes_a_few_seconds(key: String) -> String {
16 println!("[handler] doing computation for key: {key}");
17 thread::sleep(Duration::from_secs(3));
18 format!("{key}🐕")
19}
20
21#[derive(Debug, Default, Clone)]
23pub struct Handler {
24 cache: Arc<Cache<String, String>>,
25}
26
27impl Handler {
28 const OK: &'static str = "<!DOCTYPE html>
29<html lang=\"en\">
30 <head>
31 <meta charset=\"utf-8\">
32 <title>Hello!</title>
33 </head>
34 <body>
35 <p>Result for key \"{key}\" is \"{result}\"</p>
36 </body>
37</html>";
38
39 const NOT_FOUND: &'static str = "<!DOCTYPE html>
40<html lang=\"en\">
41 <head>
42 <meta charset=\"utf-8\">
43 <title>Hello!</title>
44 </head>
45 <body>
46 <h1>Oops!</h1>
47 <p>Sorry, I don't know what you're asking for.</p>
48 </body>
49</html>";
50
51 pub fn handle_conn(&self, request_id: usize, mut stream: TcpStream) -> Report {
53 let mut buf = [0; 512];
54 let _ = stream.read(&mut buf).unwrap();
55
56 static REQUEST_REGEX: OnceLock<Regex> = OnceLock::<Regex>::new();
57
58 let key = REQUEST_REGEX
59 .get_or_init(|| Regex::new(r"GET /(?P<key>\w+) HTTP/1.1\r\n").unwrap())
60 .captures(&buf)
61 .and_then(|cap| cap.name("key"))
62 .map(|key| String::from_utf8_lossy(key.as_bytes()));
63 #[allow(clippy::literal_string_with_formatting_args)]
65 let resp = if let Some(ref key) = key {
66 let result = self.cache.get_or_insert_with(
67 key.to_string(),
68 very_expensive_computation_that_takes_a_few_seconds,
69 );
70 format!(
71 "HTTP/1.1 200 OK\r\n\r\n{}",
72 Self::OK.replace("{key}", key).replace("{result}", &result)
73 )
74 } else {
75 format!("HTTP/1.1 404 NOT FOUND\r\n\r\n{}", Self::NOT_FOUND)
76 };
77
78 stream.write_all(resp.as_bytes()).unwrap();
79
80 Report::new(request_id, key.map(String::from))
81 }
82}