do some prelim cgi stuff and prelim vers

This commit is contained in:
abbie 2024-01-23 20:02:36 +00:00
parent 8da3844f4b
commit 6411f84c5c
Signed by: threeoh6000
GPG key ID: 801FE4AD456E922C
4 changed files with 78 additions and 18 deletions

2
Cargo.lock generated
View file

@ -10,7 +10,7 @@ checksum = "17cbf58e19f2bda088d8c4c95a46b41895375e15a2d63dd686a4273f8c43d46b"
[[package]]
name = "herb"
version = "0.8.2"
version = "0.9.0-develop"
dependencies = [
"frostwalker",
"packeteer",

View file

@ -1,6 +1,6 @@
[package]
name = "herb"
version = "0.8.2"
version = "0.9.0-develop"
edition = "2018"
[dependencies]

View file

@ -5,7 +5,7 @@ herb is able to send all types of data to clients, including text, video, audio,
## Features
* Dynamic websites through CGI
* Only one external dependency (packeteer)
* Only two external dependencies ([packeteer](https://git.colean.cc/threeoh6000/packeteer), [frostwalker](https://git.colean.cc/threeoh6000/frostwalker))
* Directory index generation
* Primitive media type detection
* Supports text and raw data, including PNGs and MP3s

View file

@ -4,7 +4,7 @@ use std::net::{TcpListener, TcpStream};
use std::fs;
use std::fs::File;
use std::string::{String};
use std::process::Command;
use std::process::{Command, Stdio};
use packeteer::http1::*;
use frostwalker;
use packeteer::{generate_kvheader, unwrap_url_into_segments};
@ -30,15 +30,17 @@ struct Settings {
index_generation: bool,
address: String,
logging: bool,
server_header: bool,
time_header: bool,
}
impl Settings {
fn new() -> Settings {
return Settings { cgi: true, index_generation: true, address: "0.0.0.0:8080".to_string(), logging: false};
return Settings { cgi: true, index_generation: true, address: "0.0.0.0:8080".to_string(), logging: false, server_header: true, time_header: false};
}
}
fn process_cgi(filename: String) -> Option<Vec<u8>> {
fn process_cgi(filename: String, post_data: Option<String>) -> Option<Vec<u8>> {
// This is gonna be the bodgiest implementation of CGI that anyone
// has ever seen in the history of the fucking world
@ -56,7 +58,35 @@ fn process_cgi(filename: String) -> Option<Vec<u8>> {
}
let output;
if query != "" {
if query != "".to_string() && post_data.is_some() {
let mut child = Command::new(format!("./{}", script))
.env("GATEWAY_INTERFACE", "CGI/1.1")
.env("SERVER_SOFTWARE", format!("herb/{}", env!("CARGO_PKG_VERSION")))
.env("REQUEST_METHOD", "POST")
.env("QUERY_STRING", query)
.env("SCRIPT_NAME", script)
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()
.unwrap();
let mut stdin = child.stdin.take().unwrap();
stdin.write_all(post_data.unwrap().as_bytes()).unwrap();
output = child.wait_with_output();
} else if query == "".to_string() && post_data.is_some() {
let mut child = Command::new(format!("./{}", script))
.env("GATEWAY_INTERFACE", "CGI/1.1")
.env("SERVER_SOFTWARE", format!("herb/{}", env!("CARGO_PKG_VERSION")))
.env("REQUEST_METHOD", "POST")
.env("SCRIPT_NAME", script)
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()
.unwrap();
let mut stdin = child.stdin.take().unwrap();
stdin.write_all(post_data.unwrap().as_bytes()).unwrap();
output = child.wait_with_output();
}
else if query != "" {
output = Command::new(format!("./{}", script))
.env("GATEWAY_INTERFACE", "CGI/1.1")
.env("SERVER_SOFTWARE", format!("herb/{}", env!("CARGO_PKG_VERSION")))
@ -79,7 +109,7 @@ fn process_cgi(filename: String) -> Option<Vec<u8>> {
}
}
fn process_cgi_with_path(filename: String, segments: Vec<String>, location: i32) -> Option<Vec<u8>> {
fn process_cgi_with_path(filename: String, segments: Vec<String>, location: i32, post_data: Option<String>) -> Option<Vec<u8>> {
let mut query: String = "".to_string();
let script = filename;
@ -104,22 +134,52 @@ fn process_cgi_with_path(filename: String, segments: Vec<String>, location: i32)
path = format!("{}/", path);
let output;
if query != "".to_string() {
output = Command::new(format!("./{}", script))
if query != "".to_string() && post_data.is_some() {
let mut child = Command::new(format!("./{}", script.clone()))
.env("GATEWAY_INTERFACE", "CGI/1.1")
.env("SERVER_SOFTWARE", format!("herb/{}", env!("CARGO_PKG_VERSION")))
.env("REQUEST_METHOD", "POST")
.env("QUERY_STRING", query)
.env("PATH_INFO", path.clone())
.env("SCRIPT_NAME", script.clone())
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()
.unwrap();
let mut stdin = child.stdin.take().unwrap();
stdin.write_all(post_data.unwrap().as_bytes()).unwrap();
output = child.wait_with_output();
} else if query == "".to_string() && post_data.is_some() {
let mut child = Command::new(format!("./{}", script.clone()))
.env("GATEWAY_INTERFACE", "CGI/1.1")
.env("SERVER_SOFTWARE", format!("herb/{}", env!("CARGO_PKG_VERSION")))
.env("REQUEST_METHOD", "POST")
.env("PATH_INFO", path.clone())
.env("SCRIPT_NAME", script.clone())
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()
.unwrap();
let mut stdin = child.stdin.take().unwrap();
stdin.write_all(post_data.unwrap().as_bytes()).unwrap();
output = child.wait_with_output();
}
else if query != "".to_string() && post_data.is_none() {
output = Command::new(format!("./{}", script.clone()))
.env("GATEWAY_INTERFACE", "CGI/1.1")
.env("SERVER_SOFTWARE", format!("herb/{}", env!("CARGO_PKG_VERSION")))
.env("REQUEST_METHOD", "GET")
.env("QUERY_STRING", query)
.env("PATH_INFO", path)
.env("SCRIPT_NAME", script)
.env("PATH_INFO", path.clone())
.env("SCRIPT_NAME", script.clone())
.output();
} else {
output = Command::new(format!("./{}", script))
output = Command::new(format!("./{}", script.clone()))
.env("GATEWAY_INTERFACE", "CGI/1.1")
.env("SERVER_SOFTWARE", format!("herb/{}", env!("CARGO_PKG_VERSION")))
.env("REQUEST_METHOD", "GET")
.env("PATH_INFO", path)
.env("SCRIPT_NAME", script)
.env("PATH_INFO", path.clone())
.env("SCRIPT_NAME", script.clone())
.output();
}
if output.is_ok() {
@ -242,7 +302,7 @@ fn get_page(filename: String, settings: Settings) -> GetPageResult {
return resultstruct;
}
let result = process_cgi(filename);
let result = process_cgi(filename, None);
if result.is_some() {
resultstruct.contents = result.unwrap();
resultstruct.iscgi = true;
@ -263,7 +323,7 @@ fn get_page(filename: String, settings: Settings) -> GetPageResult {
return resultstruct;
}
let result = process_cgi(filename);
let result = process_cgi(filename, None);
if result.is_some() {
resultstruct.contents = result.unwrap();
resultstruct.iscgi = true;
@ -370,7 +430,7 @@ fn process_request(request: Vec<u8>, settings: Settings) -> Resource {
return resource;
}
let contents = process_cgi_with_path(cgipathraw, segclone, cgiscript);
let contents = process_cgi_with_path(cgipathraw, segclone, cgiscript, None);
if contents.is_some() {
let resource = Resource { contents: contents.unwrap(), status_code: 200, mime: "text/html".to_string(), iscgi: true };
return resource;