use std::io::{Write, BufReader, BufRead}; use std::thread; use std::net::{TcpListener, TcpStream}; use std::fs; use std::string::{String}; use std::process::Command; fn process_cgi(filename: String) -> String { // This is gonna be the boggiest implementation of CGI that anyone // has ever seen in the history of the fucking world let query; let script; if filename.contains("?") { let vars = filename.to_string().find("?").unwrap(); let vars1 = vars + 1; query = &filename[vars1..]; script = &filename[..vars]; } else { query = ""; script = &filename; } let output = Command::new(script) .arg("GATEWAY_INTERFACE=\"CGI/1.1\"") .arg("SERVER_SOFTWARE=\"Herb/0.3.0\"") .arg("REQUEST_METHOD=\"GET\"") .arg(format!("QUERY_STRING=\"{}\"", query)) .arg(format!("SCRIPT_NAME=\"{}\"", script)) .output() .expect("failed to execute process"); let outputd = String::from_utf8_lossy(&output.stdout).to_string(); return outputd; } fn detect_media_type(filename: String) -> String { // The Lynx terminal browser made me do this. let path = filename.to_string(); let paths = check_if_path_exists(path); let path = filename.to_string(); let dir = check_if_dir(path); if paths == true && dir == false && filename.contains(".") == false { return "text/html".to_string(); } else { let ext_index = filename.to_string().find(".").unwrap(); let test = ext_index + 1; let ext = &filename[test..]; if filename[test..].contains("cgi") { return "text/html".to_string(); } match ext { "aac" => "audio/aac".to_string(), "avi" => "video/x-msvideo".to_string(), "bmp" => "image/bmp".to_string(), "bz2" => "application/x-bzip2".to_string(), "css" => "text/css".to_string(), "gz" => "application/gzip".to_string(), "gif" => "image/gif".to_string(), "png" => "image/png".to_string(), "pdf" => "application/pdf".to_string(), "jpeg" => "image/jpeg".to_string(), "jpg" => "image/jpeg".to_string(), "js" => "text/javascript".to_string(), "mid" => "audio/midi".to_string(), "midi" => "audio/midi".to_string(), "mp3" => "audio/mpeg".to_string(), "mp4" => "video/mp4".to_string(), "mpeg" => "video/mpeg".to_string(), "ogg" => "audio/ogg".to_string(), "oga" => "audio/ogg".to_string(), "ogv" => "video/ogg".to_string(), "opus" => "audio/opus".to_string(), "txt" => "text/plain".to_string(), "html" => "text/html".to_string(), "htm" => "text/html".to_string(), "cgi" => "text/html".to_string(), ".error_server_404" => "text/html".to_string(), ".error_server_503" => "text/html".to_string(), _ => "application/octet-stream".to_string(), } } } fn check_if_path_exists(path: String) -> bool { // This is probably not the best way of checking if a path // exists but I don't care :) let file = fs::metadata(path); match file { Ok(_) => true, Err(_) => false, } } fn check_if_dir(directory: String) -> bool { let path = directory + "/index.html"; let result = check_if_path_exists(path); return result; } fn generate_index(directory: String) -> String { let mut index = format!("
The resource you are trying to locate cannot be accessed!
"; return result.to_string(); } else if filename == ".error_server_503" { let result = "The request sent by your web browser cannot be handled by this server software.
"; return result.to_string(); } else if filename.contains(".cgi") { let result = process_cgi(filename); return result.to_string(); } else { let result = fs::read_to_string(filename); match result { Ok(i) => i.to_string(), Err(_e) => "The resource you are trying to access cannot be read by the server.
".to_string(), } } } fn grab_time() -> String{ let output = Command::new("date") .arg("+'%a, %d %b %Y %H:%m:%S %Z'") .output() .expect("failed to execute process"); return String::from_utf8_lossy(&output.stdout).to_string(); } fn process_request(request: Vec