Compare commits
No commits in common. "ba06ad686a68992575147e5492472f3a514211d3" and "9f28bcdb84a9a95add8ac9203d4dfc8fa6d3f60c" have entirely different histories.
ba06ad686a
...
9f28bcdb84
6 changed files with 69 additions and 60 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -4,4 +4,4 @@ version = 3
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "herb"
|
name = "herb"
|
||||||
version = "0.4.2"
|
version = "0.3.0"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "herb"
|
name = "herb"
|
||||||
version = "0.4.2"
|
version = "0.3.0"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
17
README
17
README
|
@ -1,17 +0,0 @@
|
||||||
herb
|
|
||||||
---------
|
|
||||||
T(h)e hackabl(e) web se(r)ver (b)inary (Formerly the web server yer mom uses.)
|
|
||||||
|
|
||||||
In all seriousness!
|
|
||||||
------------------------
|
|
||||||
This was a little fun experiment for me to mess around with Rust but at this point it has turned into a hobby server that I whittle away at.
|
|
||||||
|
|
||||||
At this point, if it's put behind a reverse proxy like HAProxy or nginx, it could actually be used as a small web server.
|
|
||||||
|
|
||||||
To-do list
|
|
||||||
---------------
|
|
||||||
Custom error pages
|
|
||||||
Make it user configurable
|
|
||||||
Properly generate headers
|
|
||||||
Image thumbnailing/compression
|
|
||||||
Compressing big files
|
|
16
README.html
16
README.html
|
@ -1,16 +0,0 @@
|
||||||
<h2>herb</h2>
|
|
||||||
<p>T(h)e hackabl(e) web se(r)ver (b)inary (Formerly the web server yer mom uses.)</p>
|
|
||||||
|
|
||||||
<h2>In all seriousness!</h2>
|
|
||||||
<p>This was a little fun experiment for me to mess around with Rust but at this point it has turned into a hobby server that I whittle away at.</p>
|
|
||||||
|
|
||||||
<p>At this point, if it's put behind a reverse proxy like HAProxy or nginx, it could actually be used as a small web server.</p>
|
|
||||||
|
|
||||||
<h2>To-do list</h2>
|
|
||||||
<ul>
|
|
||||||
<li>Custom error pages</li>
|
|
||||||
<li>Make it user configurable</li>
|
|
||||||
<li>Properly generate headers</li>
|
|
||||||
<li>Image thumbnailing/compression</li>
|
|
||||||
<li>Compressing big files</li>
|
|
||||||
</ul>
|
|
50
README.md
Normal file
50
README.md
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
# herb
|
||||||
|
The web server yer mom uses.
|
||||||
|
|
||||||
|
## In all seriousness!
|
||||||
|
This is a little fun experiment for me to mess around with Rust
|
||||||
|
|
||||||
|
## Chonklist
|
||||||
|
I need this stuff to actually have a functioning but basic web server.
|
||||||
|
|
||||||
|
[x] Open a socket
|
||||||
|
|
||||||
|
[x] Recieve HTTP requests
|
||||||
|
|
||||||
|
[x] Process said requests
|
||||||
|
|
||||||
|
[x] Send back HTTP requests
|
||||||
|
|
||||||
|
[x] Read index page from filesystem
|
||||||
|
|
||||||
|
### Next Chonklist
|
||||||
|
The stuff I need to make it usable.
|
||||||
|
|
||||||
|
[x] Read the stream
|
||||||
|
|
||||||
|
[x] Detect which resource the client wants to access
|
||||||
|
|
||||||
|
[x] Detect missing files and return a 404 page
|
||||||
|
|
||||||
|
[ ] Custom error pages
|
||||||
|
|
||||||
|
[ ] Make it user configurable
|
||||||
|
|
||||||
|
[ ] Properly generate headers
|
||||||
|
|
||||||
|
[x] Read and serve other pages from filesystem
|
||||||
|
|
||||||
|
### SUPAR Chonklist
|
||||||
|
Whatever is on here, just to make it extra spicy.
|
||||||
|
|
||||||
|
[ ] HTTPS support
|
||||||
|
|
||||||
|
[ ] HTTP/2 support
|
||||||
|
|
||||||
|
[ ] Dynamic pages via CGI?
|
||||||
|
|
||||||
|
[ ] Image thumbnailing/compression
|
||||||
|
|
||||||
|
[ ] Compressing big files
|
||||||
|
|
||||||
|
[x] Directory index generation
|
38
src/main.rs
38
src/main.rs
|
@ -21,27 +21,16 @@ fn process_cgi(filename: String) -> String {
|
||||||
query = "";
|
query = "";
|
||||||
script = &filename;
|
script = &filename;
|
||||||
}
|
}
|
||||||
println!("{}", script);
|
|
||||||
|
|
||||||
let output;
|
|
||||||
if query != "" {
|
let output = Command::new(script)
|
||||||
output = Command::new(format!("./{}", script))
|
.arg("GATEWAY_INTERFACE=\"CGI/1.1\"")
|
||||||
.env("GATEWAY_INTERFACE", "CGI/1.1")
|
.arg("SERVER_SOFTWARE=\"Herb/0.3.0\"")
|
||||||
.env("SERVER_SOFTWARE", "Herb/0.4.2")
|
.arg("REQUEST_METHOD=\"GET\"")
|
||||||
.env("REQUEST_METHOD", "GET")
|
.arg(format!("QUERY_STRING=\"{}\"", query))
|
||||||
.env("QUERY_STRING", query)
|
.arg(format!("SCRIPT_NAME=\"{}\"", script))
|
||||||
.env("SCRIPT_NAME", script)
|
|
||||||
.output()
|
.output()
|
||||||
.expect("failed to execute process");
|
.expect("failed to execute process");
|
||||||
} else {
|
|
||||||
output = Command::new(format!("./{}", script))
|
|
||||||
.env("GATEWAY_INTERFACE", "CGI/1.1")
|
|
||||||
.env("SERVER_SOFTWARE", "Herb/0.4.2")
|
|
||||||
.env("REQUEST_METHOD", "GET")
|
|
||||||
.env("SCRIPT_NAME", script)
|
|
||||||
.output()
|
|
||||||
.expect("failed to execute process");
|
|
||||||
}
|
|
||||||
let outputd = String::from_utf8_lossy(&output.stdout).to_string();
|
let outputd = String::from_utf8_lossy(&output.stdout).to_string();
|
||||||
return outputd;
|
return outputd;
|
||||||
}
|
}
|
||||||
|
@ -121,12 +110,14 @@ fn check_if_dir(directory: String) -> bool {
|
||||||
|
|
||||||
fn generate_index(directory: String) -> String {
|
fn generate_index(directory: String) -> String {
|
||||||
|
|
||||||
let mut index = format!("<!DOCTYPE HTML><html><body><h1>Directory of {}</h1><hr/>", directory);
|
let mut index = format!("<!DOCTYPE HTML><html><body><h1>Directory of {}</h1>", directory);
|
||||||
for file in fs::read_dir(directory).unwrap() {
|
for file in fs::read_dir(directory).unwrap() {
|
||||||
index = format!("{}<br/><a href={}>{:#?}</a>", index, format!("\"./{}\"", file.as_ref().unwrap().path().display().to_string()), file.unwrap().file_name());
|
|
||||||
|
index = format!("{}<br/><a href={}>{:#?}</a>", index, file.as_ref().unwrap().path().display(), file.unwrap().file_name());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return format!("{}<hr/>Generated by herb 0.4.2", index).to_string();
|
return index.to_string();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,7 +157,7 @@ fn get_page(filename: String) -> String {
|
||||||
let result = fs::read_to_string(filename);
|
let result = fs::read_to_string(filename);
|
||||||
match result {
|
match result {
|
||||||
Ok(i) => i.to_string(),
|
Ok(i) => i.to_string(),
|
||||||
Err(_e) => "<!DOCTYPE HTML><html><body><h1>500 Internal Server Error</h1><p>The resource you are trying to access cannot be read by the server.</p></body></html>".to_string(),
|
Err(_e) => "<!DOCTYPE HTML><html><body><h1>403 Forbidden</h1><p>The resource you are trying to access cannot be read by the server.</p></body></html>".to_string(),
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -253,6 +244,7 @@ fn serve(mut stream: TcpStream) {
|
||||||
.read_until(b'\n', &mut request)
|
.read_until(b'\n', &mut request)
|
||||||
.expect("Failed to read from stream!");
|
.expect("Failed to read from stream!");
|
||||||
|
|
||||||
|
|
||||||
let resource = process_request(request);
|
let resource = process_request(request);
|
||||||
|
|
||||||
// Haha, bodged my way around Rust's ownership paradigm!
|
// Haha, bodged my way around Rust's ownership paradigm!
|
||||||
|
@ -266,7 +258,7 @@ fn serve(mut stream: TcpStream) {
|
||||||
let contents = get_page(resource);
|
let contents = get_page(resource);
|
||||||
let header = "HTTP/1.1 200 OK\r\n";
|
let header = "HTTP/1.1 200 OK\r\n";
|
||||||
let content_type = format!("Content-Type: {}\r\n", mime);
|
let content_type = format!("Content-Type: {}\r\n", mime);
|
||||||
let server = "Server: Herb/0.4.2\r\n";
|
let server = "Server: Herb/0.3.0\r\n";
|
||||||
let extra_fields;
|
let extra_fields;
|
||||||
|
|
||||||
if cfg!(unix) {
|
if cfg!(unix) {
|
||||||
|
|
Loading…
Reference in a new issue