Check for mime-type and JS fun
This commit is contained in:
23
Cargo.lock
generated
23
Cargo.lock
generated
@ -6,6 +6,7 @@ version = 4
|
||||
name = "http_server"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"mime_guess",
|
||||
"signal-hook",
|
||||
]
|
||||
|
||||
@ -15,6 +16,22 @@ version = "0.2.171"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"
|
||||
|
||||
[[package]]
|
||||
name = "mime"
|
||||
version = "0.3.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
|
||||
|
||||
[[package]]
|
||||
name = "mime_guess"
|
||||
version = "2.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e"
|
||||
dependencies = [
|
||||
"mime",
|
||||
"unicase",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook"
|
||||
version = "0.3.17"
|
||||
@ -33,3 +50,9 @@ checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicase"
|
||||
version = "2.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539"
|
||||
|
@ -5,3 +5,4 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
signal-hook = "0.3.17"
|
||||
mime_guess = "2.0.5"
|
||||
|
168
src/main.rs
168
src/main.rs
@ -10,7 +10,7 @@ use std::{
|
||||
thread,
|
||||
};
|
||||
|
||||
#[derive(PartialEq, Eq, Debug)]
|
||||
#[derive(PartialEq, Eq, Debug, Copy, Clone)]
|
||||
enum RequestMethods {
|
||||
NULL = -1, // This is only to initialise the struct
|
||||
GET,
|
||||
@ -40,11 +40,7 @@ impl RequestLine {
|
||||
}
|
||||
|
||||
// Only GET and HEAD are required, the rest is optional
|
||||
if ["GET", "HEAD"].contains(&method.trim()) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
["GET", "HEAD"].contains(&method.trim())
|
||||
}
|
||||
|
||||
// TODO: make the checks less shit and actually correct
|
||||
@ -350,6 +346,86 @@ fn response_builder(
|
||||
return response;
|
||||
}
|
||||
|
||||
fn act_upon_request(start_line: &RequestLine) -> Result<Vec<u8>, Box<dyn Error>> {
|
||||
let mut response_field_lines: HashMap<String, String> = HashMap::new();
|
||||
let mut response_body: Vec<u8> = vec![];
|
||||
let response: Vec<u8>;
|
||||
|
||||
if start_line.target == "/" {
|
||||
let file = match fs::read("./www/index.html") {
|
||||
Ok(val) => val,
|
||||
Err(_) => {
|
||||
b"The is no index.html, only you and me."
|
||||
.iter()
|
||||
.for_each(|byte| response_body.push(*byte));
|
||||
|
||||
response_field_lines.insert(
|
||||
String::from("Content-Length"),
|
||||
response_body.len().to_string(),
|
||||
);
|
||||
response_field_lines
|
||||
.insert(String::from("Content-Type"), String::from("text/plain"));
|
||||
|
||||
response = response_builder(
|
||||
start_line.method,
|
||||
"HTTP/1.1 200 OK",
|
||||
response_field_lines,
|
||||
Some(response_body),
|
||||
);
|
||||
|
||||
return Ok(response);
|
||||
}
|
||||
};
|
||||
|
||||
file.iter().for_each(|byte| response_body.push(*byte));
|
||||
|
||||
response_field_lines.insert(String::from("Content-Length"), file.len().to_string());
|
||||
response_field_lines.insert(String::from("Content-Type"), String::from("text/html"));
|
||||
|
||||
response = response_builder(
|
||||
start_line.method,
|
||||
"HTTP/1.1 200 OK",
|
||||
response_field_lines,
|
||||
Some(response_body),
|
||||
);
|
||||
} else {
|
||||
let path: PathBuf = PathBuf::from(format!("./www{}", start_line.target));
|
||||
|
||||
match fs::read(&path) {
|
||||
Ok(val) => {
|
||||
val.iter().for_each(|byte| response_body.push(*byte));
|
||||
|
||||
response_field_lines.insert(
|
||||
String::from("Content-Length"),
|
||||
response_body.len().to_string(),
|
||||
);
|
||||
// TODO: get mime-type of file and use that here
|
||||
let mime_type = mime_guess::from_path(&path)
|
||||
.first_raw()
|
||||
.expect("Could not guess mime-type from path");
|
||||
response_field_lines.insert(String::from("Content-Type"), mime_type.to_string());
|
||||
|
||||
response = response_builder(
|
||||
start_line.method,
|
||||
"HTTP/1.1 200 OK",
|
||||
response_field_lines,
|
||||
Some(response_body),
|
||||
);
|
||||
}
|
||||
Err(_) => {
|
||||
response = response_builder(
|
||||
start_line.method,
|
||||
"HTTP/1.1 404 Not Found",
|
||||
response_field_lines,
|
||||
None,
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Ok(response)
|
||||
}
|
||||
|
||||
fn handle_request(mut stream: TcpStream) -> Result<(), Box<dyn Error>> {
|
||||
let mut line = String::new();
|
||||
let mut reader = BufReader::new(&mut stream);
|
||||
@ -384,85 +460,9 @@ fn handle_request(mut stream: TcpStream) -> Result<(), Box<dyn Error>> {
|
||||
// reader.read_to_end(&mut body)?;
|
||||
// dbg!(&body);
|
||||
|
||||
let mut response_field_lines: HashMap<String, String> = HashMap::new();
|
||||
let mut response_body: Vec<u8> = vec![];
|
||||
|
||||
// TODO: Act upon the request
|
||||
if start_line.target == "/" {
|
||||
let file = match fs::read("./www/index.html") {
|
||||
Ok(val) => val,
|
||||
Err(_) => {
|
||||
b"The is no index.html, only you and me."
|
||||
.iter()
|
||||
.for_each(|byte| response_body.push(*byte));
|
||||
|
||||
response_field_lines.insert(
|
||||
String::from("Content-Length"),
|
||||
response_body.len().to_string(),
|
||||
);
|
||||
response_field_lines
|
||||
.insert(String::from("Content-Type"), String::from("text/plain"));
|
||||
|
||||
let response = response_builder(
|
||||
start_line.method,
|
||||
"HTTP/1.1 200 OK",
|
||||
response_field_lines,
|
||||
Some(response_body),
|
||||
);
|
||||
|
||||
stream.write_all(&response)?;
|
||||
return Ok(());
|
||||
}
|
||||
};
|
||||
|
||||
file.iter().for_each(|byte| response_body.push(*byte));
|
||||
|
||||
response_field_lines.insert(String::from("Content-Length"), file.len().to_string());
|
||||
response_field_lines.insert(String::from("Content-Type"), String::from("text/html"));
|
||||
|
||||
let response = response_builder(
|
||||
start_line.method,
|
||||
"HTTP/1.1 200 OK",
|
||||
response_field_lines,
|
||||
Some(response_body),
|
||||
);
|
||||
|
||||
stream.write_all(&response)?;
|
||||
} else {
|
||||
let path: PathBuf = PathBuf::from(format!("./www{}", start_line.target));
|
||||
|
||||
match fs::read(path) {
|
||||
Ok(val) => {
|
||||
val.iter().for_each(|byte| response_body.push(*byte));
|
||||
|
||||
response_field_lines.insert(
|
||||
String::from("Content-Length"),
|
||||
response_body.len().to_string(),
|
||||
);
|
||||
// TODO: get mime-type of file and use that here
|
||||
response_field_lines.insert(String::from("Content-Type"), String::from("*/*"));
|
||||
|
||||
let response = response_builder(
|
||||
start_line.method,
|
||||
"HTTP/1.1 200 OK",
|
||||
response_field_lines,
|
||||
Some(response_body),
|
||||
);
|
||||
|
||||
stream.write_all(&response)?;
|
||||
}
|
||||
Err(_) => {
|
||||
let response = response_builder(
|
||||
start_line.method,
|
||||
"HTTP/1.1 404 Not Found",
|
||||
response_field_lines,
|
||||
None,
|
||||
);
|
||||
|
||||
stream.write_all(&response)?;
|
||||
}
|
||||
};
|
||||
}
|
||||
let response = act_upon_request(&start_line)?;
|
||||
stream.write_all(&response)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -3,8 +3,12 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>http-server</title>
|
||||
<script src="main.js" async></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello, World!</h1>
|
||||
|
||||
<button type="button" id="click-me">Click Me!</button>
|
||||
<div id="output"></div>
|
||||
</body>
|
||||
</html>
|
||||
|
9
www/main.js
Normal file
9
www/main.js
Normal file
@ -0,0 +1,9 @@
|
||||
document.getElementById("click-me").addEventListener("click", function() {
|
||||
let output = document.getElementById("output");
|
||||
|
||||
if (output.innerHTML != "") {
|
||||
output.innerHTML = ""
|
||||
} else {
|
||||
document.getElementById("output").innerHTML = "Wow! This actually works.";
|
||||
}
|
||||
});
|
Reference in New Issue
Block a user