about summary refs log tree commit diff
diff options
context:
space:
mode:
authorgennyble <gen@nyble.dev>2025-04-04 00:39:07 -0500
committergennyble <gen@nyble.dev>2025-04-04 00:39:07 -0500
commit31d650e75acfd447cf6c58d29ca4d6ad1010a65c (patch)
treedd1e3d2d2659f4932c9b7f8c6b2af6086a113749
parentff02aba40dd599373380631a1d0e87ecbed3f8b5 (diff)
downloadcorgi-31d650e75acfd447cf6c58d29ca4d6ad1010a65c.tar.gz
corgi-31d650e75acfd447cf6c58d29ca4d6ad1010a65c.zip
halt module system work
-rw-r--r--corgi/src/main.rs29
-rw-r--r--smalldog/src/lib.rs46
-rw-r--r--stats_module/src/lib.rs6
3 files changed, 44 insertions, 37 deletions
diff --git a/corgi/src/main.rs b/corgi/src/main.rs
index 3923084..fb6b75a 100644
--- a/corgi/src/main.rs
+++ b/corgi/src/main.rs
@@ -3,6 +3,7 @@ use std::{
 	path::PathBuf,
 	pin::Pin,
 	sync::{Arc, Mutex},
+	thread::JoinHandle,
 	time::Instant,
 };
 
@@ -30,17 +31,26 @@ pub struct Settings {
 	scripts: Vec<Script>,
 }
 
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug)]
 pub enum ScriptKind {
 	Executable,
-	Object,
+	Module { thread: Arc<Option<JoinHandle<()>>> },
+}
+
+impl ScriptKind {
+	pub fn is_executable(&self) -> bool {
+		if let ScriptKind::Executable = self {
+			true
+		} else {
+			false
+		}
+	}
 }
 
 #[derive(Clone, Debug)]
 pub struct Script {
 	name: String,
 	kind: ScriptKind,
-	module_lock: Arc<Mutex<()>>,
 	regex: Option<Regex>,
 	filename: String,
 	env: Vec<(String, String)>,
@@ -98,7 +108,9 @@ fn parse_script_conf(conf: &Value) -> Script {
 	let kind = match conf.get("Type") {
 		None => ScriptKind::Executable,
 		Some("executable") => ScriptKind::Executable,
-		Some("object") => ScriptKind::Object,
+		Some("object") => ScriptKind::Module {
+			thread: Arc::new(None),
+		},
 		Some(kind) => {
 			eprintln!("'{kind}' is not a valid script type");
 			std::process::exit(1)
@@ -108,7 +120,6 @@ fn parse_script_conf(conf: &Value) -> Script {
 	Script {
 		name,
 		kind,
-		module_lock: Arc::new(Mutex::new(())),
 		regex,
 		filename,
 		env: env.unwrap_or_default(),
@@ -240,14 +251,12 @@ impl Svc {
 			body: if content_length > 0 { Some(body) } else { None },
 		};
 
-		let start_cgi = Instant::now();
 		let cgi_response = match script.kind {
 			ScriptKind::Executable => {
 				caller::call_and_parse_cgi(script.clone(), http_request).await
 			}
 			ScriptKind::Object => caller::call_and_parse_module(script.clone(), http_request).await,
 		};
-		let cgi_time = start_cgi.elapsed();
 
 		let status = StatusCode::from_u16(cgi_response.status).unwrap();
 		let mut response = Response::builder().status(status);
@@ -264,10 +273,8 @@ impl Svc {
 		};
 
 		println!(
-			"served to [{client_addr}]\n\tscript: {}\n\tpath: {path}\n\tcgi took {}ms. total time {}ms\n\tUA: {uagent}",
-			&script.name,
-			cgi_time.as_millis(),
-			start.elapsed().as_millis()
+			"served to [{client_addr}]\n\tscript: {}\n\tpath: {path}\n\tUA: {uagent}",
+			&script.name
 		);
 
 		stats.log_request(db_req);
diff --git a/smalldog/src/lib.rs b/smalldog/src/lib.rs
index 1691588..1b1ddbb 100644
--- a/smalldog/src/lib.rs
+++ b/smalldog/src/lib.rs
@@ -1,4 +1,7 @@
-use std::{borrow::Cow, ffi::CStr, ptr, sync::Mutex};
+use std::{
+	borrow::Cow,
+	ffi::{CStr, c_void},
+};
 
 use ffi::{ModuleRequest, ModuleResponse};
 
@@ -22,6 +25,9 @@ pub mod ffi {
 		pub headers: *const [*const ffi::c_char; 2],
 		pub body_len: u64,
 		pub body: *const u8,
+		/// The etc field is not read by corgi and exists so you may
+		/// associate data with a request
+		pub etc: *const ffi::c_void,
 	}
 }
 
@@ -73,12 +79,9 @@ impl<'req> Request<'req> {
 	}
 }
 
-const HEADERS_LEN: usize = 64;
-static mut HEADERS: [[*const core::ffi::c_char; 2]; HEADERS_LEN] = [[ptr::null(), ptr::null()]; 64];
-static RESPONSE: Mutex<Option<Response>> = Mutex::new(None);
-
 pub struct Response {
 	headers: Vec<(Cow<'static, CStr>, Cow<'static, CStr>)>,
+	ffi_headers: Vec<[*const i8; 2]>,
 	body: Vec<u8>,
 }
 
@@ -86,30 +89,26 @@ impl Response {
 	pub fn new() -> Self {
 		Self {
 			headers: vec![],
+			ffi_headers: vec![],
 			body: vec![],
 		}
 	}
 
 	pub fn into_mod_response(self, status: u16) -> *const ModuleResponse {
-		let mut lock = RESPONSE.lock().unwrap();
-		*lock = Some(self);
-
-		let this = lock.as_mut().unwrap();
+		let mut boxed_self = Box::new(self);
 
-		for (idx, (key, value)) in this.headers.iter().enumerate().take(HEADERS_LEN) {
-			unsafe {
-				HEADERS[idx][0] = key.as_ptr();
-				HEADERS[idx][1] = value.as_ptr();
-			}
+		for (key, value) in boxed_self.headers.iter() {
+			let ffi_pair = [key.as_ptr(), value.as_ptr()];
+			boxed_self.ffi_headers.push(ffi_pair);
 		}
 
-		let headers_len = this.headers.len().min(HEADERS_LEN) as u64;
 		let boxed = Box::new(ModuleResponse {
 			status,
-			headers_len,
-			headers: unsafe { HEADERS[..headers_len as usize].as_ptr() },
-			body_len: this.body.len() as u64,
-			body: this.body.as_ptr(),
+			headers_len: boxed_self.ffi_headers.len() as u64,
+			headers: boxed_self.ffi_headers.as_ptr(),
+			body_len: boxed_self.body.len() as u64,
+			body: boxed_self.body.as_ptr(),
+			etc: Box::<Response>::into_raw(boxed_self) as *const c_void,
 		});
 
 		Box::<ModuleResponse>::into_raw(boxed)
@@ -130,13 +129,10 @@ impl Response {
 	}
 
 	pub fn cleanup(response: *const ModuleResponse) {
-		let mut lock = RESPONSE.lock().unwrap();
-		match lock.take() {
-			Some(response) => drop(response),
-			None => (),
-		}
-
 		let boxed = unsafe { Box::from_raw(response as *mut ModuleResponse) };
+		let etc = unsafe { Box::from_raw(boxed.etc as *mut Response) };
+
 		drop(boxed);
+		drop(etc);
 	}
 }
diff --git a/stats_module/src/lib.rs b/stats_module/src/lib.rs
index 18a7c2b..ba9d199 100644
--- a/stats_module/src/lib.rs
+++ b/stats_module/src/lib.rs
@@ -9,7 +9,11 @@ extern "C" fn cgi_handle(req: *const ffi::ModuleRequest) -> *const ffi::ModuleRe
 
 	let request = Request::from_mod_request(req);
 	let db = if let Some(path) = request.header("CORGI_STATS_DB") {
-		Connection::open(path).unwrap()
+		if let Ok(db) = Connection::open(path) {
+			db
+		} else {
+			return make_error(500, "failed to open database");
+		}
 	} else {
 		return make_error(500, "could not open stats database");
 	};