Add media type detection and server fields.
This commit is contained in:
parent
a6f5fba33b
commit
00b3e628ae
4 changed files with 59 additions and 6 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -1,7 +1,5 @@
|
||||||
# This file is automatically @generated by Cargo.
|
# This file is automatically @generated by Cargo.
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "herb"
|
name = "herb"
|
||||||
version = "0.1.2"
|
version = "0.1.2"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "herb"
|
name = "herb"
|
||||||
version = "0.1.2"
|
version = "0.1.3"
|
||||||
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
|
||||||
|
|
2
src/index.html
Normal file
2
src/index.html
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
<h1>FAT RIP</h1>
|
||||||
|
hohoho
|
59
src/main.rs
59
src/main.rs
|
@ -3,6 +3,44 @@ use std::net::{TcpListener, TcpStream};
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::string::{String};
|
use std::string::{String};
|
||||||
|
|
||||||
|
fn detect_media_type(filename: String) -> String {
|
||||||
|
|
||||||
|
// The Lynx terminal browser made me do this.
|
||||||
|
|
||||||
|
let ext_index = filename.to_string().find(".").unwrap();
|
||||||
|
let test = ext_index + 1;
|
||||||
|
let ext = &filename[test..];
|
||||||
|
|
||||||
|
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(),
|
||||||
|
_ => "application/octet-stream".to_string(),
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
fn check_if_path_exists(path: String) -> bool {
|
fn check_if_path_exists(path: String) -> bool {
|
||||||
|
|
||||||
// This is probably not the best way of checking if a path
|
// This is probably not the best way of checking if a path
|
||||||
|
@ -76,13 +114,21 @@ fn get_page(filename: String) -> String {
|
||||||
fn process_request(request: Vec<u8>) -> String {
|
fn process_request(request: Vec<u8>) -> String {
|
||||||
let mut input = String::from_utf8_lossy(&request).to_string();
|
let mut input = String::from_utf8_lossy(&request).to_string();
|
||||||
|
|
||||||
|
let debug = false;
|
||||||
|
|
||||||
let mut index = String::new();
|
let mut index = String::new();
|
||||||
let output;
|
let output;
|
||||||
if input.contains("GET") {
|
if input.contains("GET") {
|
||||||
// To-do: find a less atrocious way to do this.
|
// To-do: find a less atrocious way to do this.
|
||||||
println!("Stream sent GET request.");
|
println!("Stream sent GET request.");
|
||||||
|
|
||||||
|
if debug { println!("{}", input); }
|
||||||
input = input.replace("GET ", "");
|
input = input.replace("GET ", "");
|
||||||
input = input.replace(" HTTP/1.1\r\n", "");
|
input = input.replace(" HTTP/1.1\r\n", "");
|
||||||
|
|
||||||
|
// Lynx also made me do this
|
||||||
|
input = input.replace(" HTTP/1.0\r\n", "");
|
||||||
|
|
||||||
// Theoretically by this point, the request
|
// Theoretically by this point, the request
|
||||||
// will have been cut down to just the
|
// will have been cut down to just the
|
||||||
// requested resource, but in my experience
|
// requested resource, but in my experience
|
||||||
|
@ -134,9 +180,16 @@ fn serve(mut stream: TcpStream) {
|
||||||
|
|
||||||
|
|
||||||
let resource = process_request(request);
|
let resource = process_request(request);
|
||||||
|
|
||||||
|
// Haha, bodged my way around Rust's ownership paradigm!
|
||||||
|
let mime = detect_media_type(resource.to_string());
|
||||||
|
|
||||||
let contents = get_page(resource);
|
let contents = get_page(resource);
|
||||||
let header = "HTTP/1.1 200 OK\r\n\r\n";
|
let header = "HTTP/1.1 200 OK\r\n";
|
||||||
let response = format!("{}{}", header, contents);
|
let content_type = format!("Content-Type: {}\r\n", mime);
|
||||||
|
let server = "Server: Herb/0.1.3\r\n";
|
||||||
|
let extra_fields = format!("{}\r\n", server);
|
||||||
|
let response = format!("{}{}{}{}", header, content_type, extra_fields, contents);
|
||||||
|
|
||||||
stream.write(response.as_bytes()).unwrap();
|
stream.write(response.as_bytes()).unwrap();
|
||||||
stream.flush().unwrap();
|
stream.flush().unwrap();
|
||||||
|
@ -145,7 +198,7 @@ fn serve(mut stream: TcpStream) {
|
||||||
|
|
||||||
|
|
||||||
fn main() -> std::io::Result<()> {
|
fn main() -> std::io::Result<()> {
|
||||||
let listen = TcpListener::bind("0.0.0.0:8080")?;
|
let listen = TcpListener::bind("0.0.0.0:80")?;
|
||||||
|
|
||||||
for stream in listen.incoming() {
|
for stream in listen.incoming() {
|
||||||
println!("Serving incoming stream.");
|
println!("Serving incoming stream.");
|
||||||
|
|
Loading…
Reference in a new issue