summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Cargo.lock7
-rw-r--r--Cargo.toml6
-rw-r--r--src/main.rs116
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");
+}