1use std::io;
2use std::net::TcpListener;
3use std::net::TcpStream;
4use std::thread;
5
6use rusty_http::Http;
7use rusty_http::Request;
8use rusty_http::Response;
9use rusty_http::StatusCode;
10
11fn add(request: Request, response: Response) -> io::Result<()> {
12 let Some(a) = request.params.get("a") else {
13 response.status_code(StatusCode::BadRequest)
14 .set_header("Content-Type", "text/html").flush()?
15 .add_to_body("<h1>400 Bad Request</h1>")
16 .add_to_body("<p>Parameter 'a' not found</p>").flush()?;
17
18 return Ok(());
19 };
20
21 let Some(b) = request.params.get("b") else {
22 response.status_code(StatusCode::BadRequest)
23 .set_header("Content-Type", "text/html").flush()?
24 .add_to_body("<h1>400 Bad Request</h1>")
25 .add_to_body("<p>Parameter 'b' not found</p>").flush()?;
26
27 return Ok(());
28 };
29
30 let Ok(a) = a.parse::<u8>() else {
31 response.status_code(StatusCode::BadRequest)
32 .set_header("Content-Type", "text/html").flush()?
33 .add_to_body("<h1>400 Bad Request</h1>")
34 .add_to_body("<p>Parameter 'a' can only be a number from 0 to 255</p>").flush()?;
35
36 return Ok(());
37 };
38
39 let Ok(b) = b.parse::<u8>() else {
40 response.status_code(StatusCode::BadRequest)
41 .set_header("Content-Type", "text/html").flush()?
42 .add_to_body("<h1>400 Bad Request</h1>")
43 .add_to_body("<p>Parameter 'b' can only be a number from 0 to 255</p>").flush()?;
44
45 return Ok(());
46 };
47
48 let content = format!("<h1>{} + {} = {}</h1>", a, b, a as u16 + b as u16);
49
50 response.status_code(StatusCode::Ok)
51 .set_header("Content-Type", "text/html").flush()?
52 .add_to_body(content).flush()?;
53
54 Ok(())
55}
56
57fn sub(request: Request, response: Response) -> io::Result<()> {
58 let Some(a) = request.params.get("a") else {
59 response.status_code(StatusCode::BadRequest)
60 .set_header("Content-Type", "text/html").flush()?
61 .add_to_body("<h1>400 Bad Request</h1>")
62 .add_to_body("<p>Parameter 'a' not found</p>").flush()?;
63
64 return Ok(());
65 };
66
67 let Some(b) = request.params.get("b") else {
68 response.status_code(StatusCode::BadRequest)
69 .set_header("Content-Type", "text/html").flush()?
70 .add_to_body("<h1>400 Bad Request</h1>")
71 .add_to_body("<p>Parameter 'b' not found</p>").flush()?;
72
73 return Ok(());
74 };
75
76 let Ok(a) = a.parse::<u8>() else {
77 response.status_code(StatusCode::BadRequest)
78 .set_header("Content-Type", "text/html").flush()?
79 .add_to_body("<h1>400 Bad Request</h1>")
80 .add_to_body("<p>Parameter 'a' can only be a number from 0 to 255</p>").flush()?;
81
82 return Ok(());
83 };
84
85 let Ok(b) = b.parse::<u8>() else {
86 response.status_code(StatusCode::BadRequest)
87 .set_header("Content-Type", "text/html").flush()?
88 .add_to_body("<h1>400 Bad Request</h1>")
89 .add_to_body("<p>Parameter 'b' can only be a number from 0 to 255</p>").flush()?;
90
91 return Ok(());
92 };
93
94 let content = format!("<h1>{} - {} = {}</h1>", a, b, a as i16 - b as i16);
95
96 response.status_code(StatusCode::Ok)
97 .set_header("Content-Type", "text/html").flush()?
98 .add_to_body(content).flush()?;
99
100 Ok(())
101}
102
103fn not_found(request: Request, response: Response) -> io::Result<()> {
104 let content = format!("<p>Page '{}' could not been found</p>", request.uri);
105
106 response.status_code(StatusCode::NotFound)
107 .set_header("Content-Type", "text/html").flush()?
108 .add_to_body("<h1>404 Not Found</h1>")
109 .add_to_body(content).flush()?;
110
111 Ok(())
112}
113
114fn init_stream(stream: TcpStream) -> io::Result<()> {
115 let (request, response) = Http::from(stream)?;
116
117 match request.uri.as_str() {
118 "/add" => add(request, response)?,
119 "/sub" => sub(request, response)?,
120 _ => not_found(request, response)?
121 }
122
123 Ok(())
124}
125
126fn main() -> io::Result<()> {
127 let listener = TcpListener::bind("127.0.0.1:8080")?;
128
129 for stream in listener.incoming().filter_map(Result::ok) {
130 thread::spawn(|| init_stream(stream));
131 }
132
133 Ok(())
134}