From cbb92993b592e6b68dbce7f283fb73d19fd1793e Mon Sep 17 00:00:00 2001 From: Tyler Murphy Date: Sun, 2 Jul 2023 18:45:41 -0400 Subject: hi --- src/main.rs | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 src/main.rs (limited to 'src/main.rs') diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..9cf8e90 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,92 @@ +use std::collections::HashMap; +use std::sync::Arc; +use http::code::Code; +use http::header::Header; +use http::request::Request; +use http::response::Response; +use tokio::net::{TcpListener, TcpStream}; +use tokio::io::{AsyncReadExt, AsyncWriteExt}; + +use crate::bash::handle_script; + +mod http; +mod bash; + +async fn handle_response(mut socket: TcpStream, code: Code, 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; +} + +async fn handle_connection(mut socket: TcpStream, config: Arc>) { + + 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.uri.route) else { + handle_response(socket, Code::MethodNotAllowed, "Method Not Allowed".to_owned()).await; + return + }; + + match handle_script(script, req.body.as_ref()) { + Ok(out) => { + handle_response(socket, Code::Success, out).await; + }, + Err(err) => { + handle_response(socket, Code::MethodNotAllowed, err).await; + }, + } +} + +#[tokio::main] +async fn main() { + + let config = Arc::new(bash::load_config()); + + let port = std::env::var("PORT") + .unwrap_or_else(|_| String::from("8080")) + .parse::() + .unwrap_or_else(|_| 8080); + + let addr = format!("127.0.0.1:{port}"); + + let Ok(listener) = TcpListener::bind(&addr).await else { + println!("failed to bind {addr}"); + return + }; + + println!("listening to tcp requests on {addr}"); + + loop { + let Ok((socket, _)) = listener.accept().await else { + println!("failed to accept new connection"); + continue + }; + + let config = config.clone(); + + tokio::spawn(async move { + handle_connection(socket, config).await; + }); + } +} -- cgit v1.2.3-freya