summaryrefslogtreecommitdiff
path: root/src/server.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/server.rs')
-rw-r--r--src/server.rs51
1 files changed, 51 insertions, 0 deletions
diff --git a/src/server.rs b/src/server.rs
new file mode 100644
index 0000000..4b1f2b3
--- /dev/null
+++ b/src/server.rs
@@ -0,0 +1,51 @@
+use std::sync::Arc;
+use tokio::{net::TcpStream, io::{AsyncWriteExt, AsyncReadExt}};
+use crate::{http::{header::Header, response::Response, request::Request}, script::Config};
+
+async fn send_response(mut socket: TcpStream, code: u16, body: String) {
+ let mut res = Response::new();
+ res.headers.put(Header::new("Content-Type", "text/plain"));
+ res.status = code;
+ res.body = Some(body);
+
+ let res_str = res.deserialize();
+
+ let _ = socket.write(res_str.as_bytes()).await;
+}
+
+pub async fn handle_connection(mut socket: TcpStream, config: Arc<Config>) {
+
+ let mut buf = [0; 1204];
+
+ let n: usize = match socket.read(&mut buf).await {
+ Ok(n) if n == 0 => return,
+ Ok(n) => n as usize,
+ Err(e) => {
+ eprintln!("failed to read from socket; err = {:?}", e);
+ return
+ }
+ };
+
+ let str = String::from_utf8_lossy(&buf[0..n]);
+
+ let Some(req) = Request::serialize(&str) else {
+ return
+ };
+
+
+ let Some(script) = config.get(&req.method, &req.uri.route) else {
+ send_response(socket, 405, "Method Not Allowed".to_owned()).await;
+ return
+ };
+
+ match script.run(req.body.as_ref()) {
+ Ok(res) => {
+ let res_str = res.deserialize();
+ let _ = socket.write(res_str.as_bytes()).await;
+ },
+ Err(err) => {
+ println!("{err}");
+ send_response(socket, 500, format!("{err}")).await;
+ },
+ }
+}