2022-06-11 05:38:09 +02:00
|
|
|
use std::io::prelude::*;
|
2024-03-23 18:03:05 +01:00
|
|
|
use std::net::{TcpListener, TcpStream};
|
|
|
|
use std::{env, fs};
|
2022-06-04 19:22:41 +02:00
|
|
|
|
|
|
|
fn main() {
|
2022-06-05 20:45:19 +02:00
|
|
|
let args: Vec<String> = env::args().collect();
|
2022-06-04 19:22:41 +02:00
|
|
|
|
2022-06-05 20:45:19 +02:00
|
|
|
let host = if args.len() < 2 {
|
2022-06-11 05:38:09 +02:00
|
|
|
"127.0.0.1:55566"
|
2022-06-05 20:45:19 +02:00
|
|
|
} else {
|
|
|
|
&args[1]
|
|
|
|
};
|
|
|
|
println!("Starting server on {:?}...\n", &host);
|
|
|
|
|
|
|
|
let listener = TcpListener::bind(host).expect("Could not bind to address");
|
2022-06-04 19:22:41 +02:00
|
|
|
|
2022-06-05 20:45:19 +02:00
|
|
|
for stream in listener.incoming() {
|
2024-03-23 18:03:05 +01:00
|
|
|
match stream {
|
|
|
|
Ok(stream) => handle_connection(stream),
|
|
|
|
Err(err) => println!("Error with incoming stream: {}", err),
|
2022-06-05 20:45:19 +02:00
|
|
|
}
|
2022-06-04 19:22:41 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn handle_connection(mut stream: TcpStream) {
|
2022-06-11 05:38:09 +02:00
|
|
|
let mut buffer = vec![0; 2048];
|
2024-03-23 18:03:05 +01:00
|
|
|
let size = if let Ok(size) = stream.read(&mut buffer) {
|
|
|
|
size
|
|
|
|
} else {
|
|
|
|
return;
|
|
|
|
};
|
|
|
|
|
2022-06-11 05:38:09 +02:00
|
|
|
buffer.resize(size, 0);
|
2022-06-05 20:45:19 +02:00
|
|
|
|
2024-03-23 18:03:05 +01:00
|
|
|
let request = String::from_utf8_lossy(&buffer);
|
|
|
|
|
|
|
|
let peer_addr = stream.peer_addr().ok();
|
|
|
|
|
|
|
|
println!(
|
|
|
|
"Received {} bytes from {:?}\n\n[{}]",
|
|
|
|
size,
|
|
|
|
peer_addr,
|
|
|
|
request
|
|
|
|
.escape_debug()
|
|
|
|
.collect::<String>()
|
|
|
|
.replace("\\r\\n", "\n")
|
|
|
|
.replace("\\n", "\n")
|
2022-06-04 19:22:41 +02:00
|
|
|
);
|
2024-03-23 18:03:05 +01:00
|
|
|
|
|
|
|
let mut request = request.into_owned();
|
|
|
|
while request.contains("..") {
|
|
|
|
request = request.replace("..", "");
|
|
|
|
}
|
|
|
|
|
|
|
|
if request.starts_with("GET") {
|
|
|
|
if let Some(file) = request.split_whitespace().nth(1) {
|
|
|
|
let path = format!("./{}", file);
|
|
|
|
send_file(&mut stream, &path);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
let response = "HTTP/1.1 400 BAD REQUEST\r\n\r\n";
|
|
|
|
stream
|
|
|
|
.write_all(response.as_bytes())
|
|
|
|
.unwrap_or_else(|_| println!("failed to respond"));
|
|
|
|
stream
|
|
|
|
.flush()
|
|
|
|
.unwrap_or_else(|_| println!("failed to respond"));
|
2022-06-04 19:22:41 +02:00
|
|
|
}
|
2022-06-11 05:38:09 +02:00
|
|
|
|
|
|
|
fn send_file(stream: &mut TcpStream, path: &str) {
|
2024-03-23 18:03:05 +01:00
|
|
|
if let Ok(text) = fs::read_to_string(path) {
|
|
|
|
let contents = text + "\n\n";
|
|
|
|
let response = format!(
|
|
|
|
"HTTP/1.1 200 OK\r\nContent-Type: {}; charset=UTF-8\r\nContent-Length: {}\r\n\r\n{}",
|
|
|
|
if path.ends_with(".html") {
|
|
|
|
"text/html"
|
|
|
|
} else {
|
|
|
|
"text/plain"
|
|
|
|
},
|
|
|
|
contents.len(),
|
|
|
|
contents
|
|
|
|
);
|
|
|
|
stream
|
|
|
|
.write_all(response.as_bytes())
|
|
|
|
.unwrap_or_else(|_| println!("failed to respond"));
|
|
|
|
} else {
|
|
|
|
eprintln!("File does not exist: {}", path);
|
|
|
|
let response = format!("HTTP/1.1 404 NOT FOUND\r\nContent-Type: text/plain; charset=UTF-8\r\nContent-Length: {}\r\n\r\n{}", path.len(), path);
|
|
|
|
stream
|
|
|
|
.write_all(response.as_bytes())
|
|
|
|
.unwrap_or_else(|_| println!("failed to respond with 404"));
|
|
|
|
};
|
|
|
|
stream
|
|
|
|
.flush()
|
|
|
|
.unwrap_or_else(|_| println!("failed to respond"));
|
2022-06-11 05:38:09 +02:00
|
|
|
}
|