add support for sending data other than text
This commit is contained in:
parent
a0b37387eb
commit
245131ee27
1 changed files with 44 additions and 17 deletions
61
src/main.rs
61
src/main.rs
|
@ -1,18 +1,24 @@
|
||||||
use std::io::{Write, BufReader, BufRead};
|
use std::io::{Write, BufReader, BufRead, Read};
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::net::{TcpListener, TcpStream};
|
use std::net::{TcpListener, TcpStream};
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
use std::fs::File;
|
||||||
use std::string::{String};
|
use std::string::{String};
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
use packeteer::http1::*;
|
use packeteer::http1::*;
|
||||||
use packeteer::{generate_kvheader, unwrap_url_into_segments};
|
use packeteer::{generate_kvheader, unwrap_url_into_segments};
|
||||||
|
|
||||||
struct Resource {
|
struct Resource {
|
||||||
contents: String,
|
contents: Vec<u8>,
|
||||||
status_code: i32,
|
status_code: i32,
|
||||||
mime: String,
|
mime: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct GetPageResult {
|
||||||
|
is500: bool,
|
||||||
|
contents: Vec<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
fn process_cgi(filename: String) -> String {
|
fn process_cgi(filename: String) -> String {
|
||||||
// This is gonna be the boggiest implementation of CGI that anyone
|
// This is gonna be the boggiest implementation of CGI that anyone
|
||||||
// has ever seen in the history of the fucking world
|
// has ever seen in the history of the fucking world
|
||||||
|
@ -138,7 +144,7 @@ fn generate_index(directory: String) -> String {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_page(filename: String) -> String {
|
fn get_page(filename: String) -> GetPageResult {
|
||||||
|
|
||||||
// The loaded page should be left immutable as it does
|
// The loaded page should be left immutable as it does
|
||||||
// not need to be modified by the server.
|
// not need to be modified by the server.
|
||||||
|
@ -147,28 +153,44 @@ fn get_page(filename: String) -> String {
|
||||||
let checks = check_if_path_exists(path.clone());
|
let checks = check_if_path_exists(path.clone());
|
||||||
let index = check_if_dir(path.clone());
|
let index = check_if_dir(path.clone());
|
||||||
|
|
||||||
|
let mut resultstruct = GetPageResult { is500: false, contents: vec![] };
|
||||||
|
|
||||||
println!("{} {} {}", path, checks, index);
|
println!("{} {} {}", path, checks, index);
|
||||||
|
|
||||||
if checks == true && index == false {
|
if checks == true && index == false {
|
||||||
if path.contains(".") != true && path.contains(".cgi?") != true {
|
if path.contains(".") != true && path.contains(".cgi?") != true {
|
||||||
let result = generate_index(filename);
|
let result = generate_index(filename);
|
||||||
return result.to_string();
|
resultstruct.contents = result.to_string().into_bytes();
|
||||||
|
return resultstruct;
|
||||||
} else if path.contains(".cgi?") {
|
} else if path.contains(".cgi?") {
|
||||||
let result = process_cgi(filename);
|
let result = process_cgi(filename);
|
||||||
return result.to_string();
|
resultstruct.contents = result.to_string().into_bytes();
|
||||||
|
return resultstruct;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if filename.contains(".cgi") {
|
if filename.contains(".cgi") {
|
||||||
let result = process_cgi(filename);
|
let result = process_cgi(filename);
|
||||||
return result.to_string();
|
resultstruct.contents = result.to_string().into_bytes();
|
||||||
|
return resultstruct;
|
||||||
} else {
|
} else {
|
||||||
let result = fs::read_to_string(filename);
|
let f = File::open(filename);
|
||||||
match result {
|
if f.is_ok() {
|
||||||
Ok(i) => i.to_string(),
|
let mut buf: Vec<u8> = vec![];
|
||||||
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(),
|
let result = f.unwrap().read_to_end(&mut buf);
|
||||||
|
if result.is_ok() {
|
||||||
|
resultstruct.contents = buf;
|
||||||
|
return resultstruct;
|
||||||
|
} else {
|
||||||
|
resultstruct.contents = "<!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().into_bytes();
|
||||||
|
resultstruct.is500 = true;
|
||||||
|
return resultstruct;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
resultstruct.contents = "<!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().into_bytes();
|
||||||
|
resultstruct.is500 = true;
|
||||||
|
return resultstruct;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,7 +221,7 @@ fn process_request(request: Vec<u8>) -> Resource {
|
||||||
let exists = check_if_path_exists(path.clone());
|
let exists = check_if_path_exists(path.clone());
|
||||||
|
|
||||||
if exists == false && path.contains(".cgi?") == false {
|
if exists == false && path.contains(".cgi?") == false {
|
||||||
let resource = Resource { contents: "<!DOCTYPE HTML><html><body><h1>404 Not Found</h1><p>The resource you are trying to locate cannot be accessed!</p></body></html>".to_string(), status_code: 404, mime: "text/html".to_string() };
|
let resource = Resource { contents: "<!DOCTYPE HTML><html><body><h1>404 Not Found</h1><p>The resource you are trying to locate cannot be accessed!</p></body></html>".to_string().into_bytes(), status_code: 404, mime: "text/html".to_string() };
|
||||||
return resource;
|
return resource;
|
||||||
} else {
|
} else {
|
||||||
let dir = check_if_dir(path.clone());
|
let dir = check_if_dir(path.clone());
|
||||||
|
@ -215,14 +237,15 @@ fn process_request(request: Vec<u8>) -> Resource {
|
||||||
output = "index.html";
|
output = "index.html";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let resource = Resource { contents: "<!DOCTYPE HTML><html><body><h1>501 Not Implemented</h1><p>The request sent by your web browser cannot be handled by this server software.</p></body></html>".to_string(), status_code: 501, mime: "text/html".to_string() };
|
let resource = Resource { contents: "<!DOCTYPE HTML><html><body><h1>501 Not Implemented</h1><p>The request sent by your web browser cannot be handled by this server software.</p></body></html>".to_string().into_bytes(), status_code: 501, mime: "text/html".to_string() };
|
||||||
println!("Stream sent unhandlable request.");
|
println!("Stream sent unhandlable request.");
|
||||||
return resource;
|
return resource;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Did you want to see chars.as_str().to_string()?
|
// Did you want to see chars.as_str().to_string()?
|
||||||
let mut resource = Resource { contents: get_page(output.to_string()), status_code: 200, mime: detect_media_type(output.to_string()) };
|
let rescontents = get_page(output.to_string());
|
||||||
if resource.contents.contains("500 Internal Server Error") {
|
let mut resource = Resource { contents: rescontents.contents, status_code: 200, mime: detect_media_type(output.to_string()) };
|
||||||
|
if rescontents.is500 {
|
||||||
resource.status_code = 500;
|
resource.status_code = 500;
|
||||||
resource.mime = "text/html".to_string();
|
resource.mime = "text/html".to_string();
|
||||||
}
|
}
|
||||||
|
@ -241,7 +264,7 @@ fn serve(mut stream: TcpStream) {
|
||||||
|
|
||||||
let resource = process_request(request);
|
let resource = process_request(request);
|
||||||
|
|
||||||
let mut response_constructed = generate_response(resource.status_code, &resource.contents);
|
let mut response_constructed = generate_response(resource.status_code, "");
|
||||||
response_constructed.headers.push(generate_kvheader("Content-Type", &resource.mime));
|
response_constructed.headers.push(generate_kvheader("Content-Type", &resource.mime));
|
||||||
response_constructed.headers.push(generate_kvheader("Server", &format!("herb/{}", env!("CARGO_PKG_VERSION"))));
|
response_constructed.headers.push(generate_kvheader("Server", &format!("herb/{}", env!("CARGO_PKG_VERSION"))));
|
||||||
|
|
||||||
|
@ -249,7 +272,11 @@ fn serve(mut stream: TcpStream) {
|
||||||
response_constructed.headers.push(generate_kvheader("Date", &grab_time()))
|
response_constructed.headers.push(generate_kvheader("Date", &grab_time()))
|
||||||
}
|
}
|
||||||
|
|
||||||
stream.write(unpack_response(response_constructed).as_bytes()).unwrap();
|
let mut contents_clone = resource.contents.clone();
|
||||||
|
let mut unpacked_response = unpack_response(response_constructed).into_bytes();
|
||||||
|
unpacked_response.append(&mut contents_clone);
|
||||||
|
|
||||||
|
stream.write(unpacked_response.as_slice()).unwrap();
|
||||||
stream.flush().unwrap();
|
stream.flush().unwrap();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue