Compare commits

..

No commits in common. "ba06ad686a68992575147e5492472f3a514211d3" and "9f28bcdb84a9a95add8ac9203d4dfc8fa6d3f60c" have entirely different histories.

6 changed files with 69 additions and 60 deletions

2
Cargo.lock generated
View file

@ -4,4 +4,4 @@ version = 3
[[package]]
name = "herb"
version = "0.4.2"
version = "0.3.0"

View file

@ -1,6 +1,6 @@
[package]
name = "herb"
version = "0.4.2"
version = "0.3.0"
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

17
README
View file

@ -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

View file

@ -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
View 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

View file

@ -21,27 +21,16 @@ fn process_cgi(filename: String) -> String {
query = "";
script = &filename;
}
println!("{}", script);
let output;
if query != "" {
output = Command::new(format!("./{}", script))
.env("GATEWAY_INTERFACE", "CGI/1.1")
.env("SERVER_SOFTWARE", "Herb/0.4.2")
.env("REQUEST_METHOD", "GET")
.env("QUERY_STRING", query)
.env("SCRIPT_NAME", script)
.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 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;
}
@ -121,12 +110,14 @@ fn check_if_dir(directory: String) -> bool {
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() {
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);
match result {
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)
.expect("Failed to read from stream!");
let resource = process_request(request);
// Haha, bodged my way around Rust's ownership paradigm!
@ -266,7 +258,7 @@ fn serve(mut stream: TcpStream) {
let contents = get_page(resource);
let header = "HTTP/1.1 200 OK\r\n";
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;
if cfg!(unix) {