Compare commits
5 commits
9f28bcdb84
...
ba06ad686a
Author | SHA1 | Date | |
---|---|---|---|
ba06ad686a | |||
66dfbd2291 | |||
2823990ec8 | |||
5e783bcbb6 | |||
60af42f3fa |
6 changed files with 60 additions and 69 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -4,4 +4,4 @@ version = 3
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "herb"
|
name = "herb"
|
||||||
version = "0.3.0"
|
version = "0.4.2"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "herb"
|
name = "herb"
|
||||||
version = "0.3.0"
|
version = "0.4.2"
|
||||||
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
Normal file
17
README
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
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
Normal file
16
README.html
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
<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
50
README.md
|
@ -1,50 +0,0 @@
|
||||||
# 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
|
|
42
src/main.rs
42
src/main.rs
|
@ -21,16 +21,27 @@ fn process_cgi(filename: String) -> String {
|
||||||
query = "";
|
query = "";
|
||||||
script = &filename;
|
script = &filename;
|
||||||
}
|
}
|
||||||
|
println!("{}", script);
|
||||||
|
|
||||||
|
let output;
|
||||||
let output = Command::new(script)
|
if query != "" {
|
||||||
.arg("GATEWAY_INTERFACE=\"CGI/1.1\"")
|
output = Command::new(format!("./{}", script))
|
||||||
.arg("SERVER_SOFTWARE=\"Herb/0.3.0\"")
|
.env("GATEWAY_INTERFACE", "CGI/1.1")
|
||||||
.arg("REQUEST_METHOD=\"GET\"")
|
.env("SERVER_SOFTWARE", "Herb/0.4.2")
|
||||||
.arg(format!("QUERY_STRING=\"{}\"", query))
|
.env("REQUEST_METHOD", "GET")
|
||||||
.arg(format!("SCRIPT_NAME=\"{}\"", script))
|
.env("QUERY_STRING", query)
|
||||||
.output()
|
.env("SCRIPT_NAME", script)
|
||||||
.expect("failed to execute process");
|
.output()
|
||||||
|
.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;
|
||||||
}
|
}
|
||||||
|
@ -110,14 +121,12 @@ 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>", directory);
|
let mut index = format!("<!DOCTYPE HTML><html><body><h1>Directory of {}</h1><hr/>", 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 index.to_string();
|
return format!("{}<hr/>Generated by herb 0.4.2", index).to_string();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,7 +166,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>403 Forbidden</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>500 Internal Server Error</h1><p>The resource you are trying to access cannot be read by the server.</p></body></html>".to_string(),
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -244,7 +253,6 @@ 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!
|
||||||
|
@ -258,7 +266,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.3.0\r\n";
|
let server = "Server: Herb/0.4.2\r\n";
|
||||||
let extra_fields;
|
let extra_fields;
|
||||||
|
|
||||||
if cfg!(unix) {
|
if cfg!(unix) {
|
||||||
|
|
Loading…
Reference in a new issue