diff options
author | gennyble <gen@nyble.dev> | 2025-04-04 00:39:07 -0500 |
---|---|---|
committer | gennyble <gen@nyble.dev> | 2025-04-04 00:39:07 -0500 |
commit | 31d650e75acfd447cf6c58d29ca4d6ad1010a65c (patch) | |
tree | dd1e3d2d2659f4932c9b7f8c6b2af6086a113749 | |
parent | ff02aba40dd599373380631a1d0e87ecbed3f8b5 (diff) | |
download | corgi-31d650e75acfd447cf6c58d29ca4d6ad1010a65c.tar.gz corgi-31d650e75acfd447cf6c58d29ca4d6ad1010a65c.zip |
halt module system work
-rw-r--r-- | corgi/src/main.rs | 29 | ||||
-rw-r--r-- | smalldog/src/lib.rs | 46 | ||||
-rw-r--r-- | stats_module/src/lib.rs | 6 |
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"); }; |