diff options
| author | Shravan Mandava <shravan@mandava8.com> | 2026-02-21 20:06:14 +0000 |
|---|---|---|
| committer | Shravan Mandava <shravan@mandava8.com> | 2026-02-21 20:06:14 +0000 |
| commit | fe4557addbe23a408f761634c885495dcf1df746 (patch) | |
| tree | f039a2deef008556a973b403479e815bf2531626 | |
Initial Commit
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | Cargo.lock | 7 | ||||
| -rw-r--r-- | Cargo.toml | 6 | ||||
| -rw-r--r-- | src/main.rs | 116 |
4 files changed, 130 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..110ec35 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "rttp" +version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..af936f5 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "rttp" +version = "0.1.0" +edition = "2024" + +[dependencies] diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..9e8ff9a --- /dev/null +++ b/src/main.rs @@ -0,0 +1,116 @@ +use std::{ + env, + io::{BufRead, BufReader, ErrorKind, Write}, + net::{TcpListener, TcpStream}, +}; + +fn main() { + // let listener = TcpListener::bind("0.0.0.0:8080").expect("Could not bind to address"); + + let listener = match TcpListener::bind("0.0.0.0:8080") { + Ok(listener) => listener, + Err(e) => { + //panic!("Failed to bind: {}", e) + eprintln!("Failed to bind: {}", e); + return; + } + }; + + for stream in listener.incoming() { + println!("Connection incoming"); + match stream { + Ok(stream) => handle_connection(stream), + Err(e) => eprintln!("Connection failed: {}", e), + } + println!("Waiting for next"); + } +} + +fn handle_connection(mut stream: TcpStream) { + // Handle the connection + println!("Handling Connection"); + + let req_buffer = BufReader::new(&stream); + + println!("Request received"); + + let req: Vec<_> = req_buffer + .lines() + .map(|line| match line { + Ok(line) => { + // println!("line read: {}", line); + line + } + Err(e) => { + eprintln!("Error reading line: {}", e); + String::new() + } + }) + .take_while(|line| !line.is_empty()) + .collect(); + + println!("Request: {:#?}", req); + + let mut file = String::new(); + + if req[0].starts_with("GET") { + if req[0].contains("/ ") { + file = String::from("index.html"); + } else { + file = req[0].split_whitespace().nth(1).unwrap().to_string(); + file.remove(0); + } + } + + println!("req: {}", file); + + let args: Vec<String> = env::args().collect(); + + let mut path = String::new(); + + if args.len() == 2 && args[1].ends_with("/") { + path.push_str(&args[1]); + } else { + path.push_str("app/"); + } + path.push_str(&file); + + // let status_line = "HTTP/1.1 200 OK"; + // println!("Serving file at path: {:?}", path); + // let contents = match std::fs::read_to_string(path) { + // Ok(contents) => contents, + // Err(e) => { + // eprintln!("Error reading file: {}", e.kind()); + // + // String::from("<h1>Internal Server Error</h1>") + // } + // }; + + let (contents, status_line) = match std::fs::read_to_string(path) { + Ok(contents) => (contents, "HTTP/1.1 200 OK"), + Err(e) => { + if e.kind() == ErrorKind::NotFound { + eprintln!("404 Error: file not found"); + ( + String::from("<h1>404 Error: file not found</h1>"), + "HTTP/1.1 404 Not Found", + ) + } else { + eprintln!("Error reading file: {}", e); + + ( + String::from("<h1>Internal Server Error</h1>"), + "HTTP 500 Internal Server Error", + ) + } + } + }; + + let length = contents.len(); + + let response = format!("{status_line}\r\nContent-Length: {length}\r\n\r\n{contents}"); + + stream.write_all(response.as_bytes()).unwrap(); + + println!("Response sent"); +} |
