about summary refs log tree commit diff
diff options
context:
space:
mode:
authorgennyble <gen@nyble.dev>2025-04-02 06:15:57 -0500
committergennyble <gen@nyble.dev>2025-04-02 06:15:57 -0500
commit315f3268525dc05c587ab4b28772b73cb18e66ef (patch)
treefa17b45a4827fa3544fa134670590c79cdaea12c
parent23f494f065be5eaec37aab6ca6e72348c6a025e0 (diff)
downloadcorgi-315f3268525dc05c587ab4b28772b73cb18e66ef.tar.gz
corgi-315f3268525dc05c587ab4b28772b73cb18e66ef.zip
improve ffi
-rw-r--r--Cargo.lock1
-rw-r--r--corgi/Cargo.toml1
-rw-r--r--smalldog/src/lib.rs53
-rw-r--r--stats_module/src/lib.rs8
4 files changed, 37 insertions, 26 deletions
diff --git a/Cargo.lock b/Cargo.lock
index fe3f346..85f7e8b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -93,6 +93,7 @@ dependencies = [
  "regex-lite",
  "rusqlite",
  "sha2",
+ "smalldog",
  "tokio",
 ]
 
diff --git a/corgi/Cargo.toml b/corgi/Cargo.toml
index ea5fe74..0a492c6 100644
--- a/corgi/Cargo.toml
+++ b/corgi/Cargo.toml
@@ -10,6 +10,7 @@ version = "1.0.0"
 edition = "2024"
 
 [dependencies]
+smalldog = { path = "../smalldog" }
 base64 = "0.22.1"
 http-body-util = "0.1.3"
 hyper-util = { version = "0.1.10", features = ["tokio"] }
diff --git a/smalldog/src/lib.rs b/smalldog/src/lib.rs
index e139d30..27b0140 100644
--- a/smalldog/src/lib.rs
+++ b/smalldog/src/lib.rs
@@ -1,12 +1,28 @@
-use core::ffi;
 use std::{borrow::Cow, ffi::CStr, ptr, sync::Mutex};
 
-#[repr(C)]
-pub struct ModuleRequest<'req> {
-	pub headers_len: ffi::c_ulong,
-	pub headers: &'req [[*const ffi::c_char; 2]],
-	pub body_len: ffi::c_ulong,
-	pub body: *const u8,
+use ffi::{ModuleRequest, ModuleResponse};
+
+pub mod ffi {
+	use core::ffi;
+	use std::marker::PhantomData;
+
+	#[repr(C)]
+	pub struct ModuleRequest<'req> {
+		pub headers_len: ffi::c_ulong,
+		pub headers: *const [*const ffi::c_char; 2],
+		pub body_len: ffi::c_ulong,
+		pub body: *const u8,
+		pub _phantom: PhantomData<&'req u8>,
+	}
+
+	#[repr(C)]
+	pub struct ModuleResponse {
+		pub status: ffi::c_ushort,
+		pub headers_len: ffi::c_ulong,
+		pub headers: *const [*const ffi::c_char; 2],
+		pub body_len: ffi::c_ulong,
+		pub body: *const u8,
+	}
 }
 
 pub struct Request<'req> {
@@ -19,11 +35,13 @@ impl<'req> Request<'req> {
 		// SAFTEY: corgi will never give us a null pointer
 		let reqref = unsafe { request.as_ref() }.unwrap();
 
+		let headers_ffi =
+			unsafe { std::slice::from_raw_parts(reqref.headers, reqref.headers_len as usize) };
+
 		let mut headers = vec![];
-		for idx in 0..reqref.headers_len as usize {
-			let kvarr = reqref.headers[idx as usize];
-			let k = unsafe { CStr::from_ptr(kvarr[0]) }.to_string_lossy();
-			let v = unsafe { CStr::from_ptr(kvarr[1]) }.to_string_lossy();
+		for pair in headers_ffi {
+			let k = unsafe { CStr::from_ptr(pair[0]) }.to_string_lossy();
+			let v = unsafe { CStr::from_ptr(pair[1]) }.to_string_lossy();
 			headers.push((k, v));
 		}
 
@@ -55,17 +73,8 @@ impl<'req> Request<'req> {
 	}
 }
 
-#[repr(C)]
-pub struct ModuleResponse {
-	pub status: ffi::c_ushort,
-	pub headers_len: ffi::c_ulong,
-	pub headers: &'static [[*const ffi::c_char; 2]],
-	pub body_len: ffi::c_ulong,
-	pub body: *const u8,
-}
-
 const HEADERS_LEN: usize = 64;
-static mut HEADERS: [[*const ffi::c_char; 2]; HEADERS_LEN] = [[ptr::null(), ptr::null()]; 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 {
@@ -98,7 +107,7 @@ impl Response {
 		let boxed = Box::new(ModuleResponse {
 			status,
 			headers_len,
-			headers: unsafe { &HEADERS[..headers_len as usize] },
+			headers: unsafe { HEADERS[..headers_len as usize].as_ptr() },
 			body_len: this.body.len() as u64,
 			body: this.body.as_ptr(),
 		});
diff --git a/stats_module/src/lib.rs b/stats_module/src/lib.rs
index 2c1bce0..47a5e6f 100644
--- a/stats_module/src/lib.rs
+++ b/stats_module/src/lib.rs
@@ -1,9 +1,9 @@
 use rusqlite::{Connection, params};
-use smalldog::{ModuleRequest, ModuleResponse, Request, Response};
+use smalldog::{Request, Response, ffi};
 use time::{Duration, OffsetDateTime};
 
 #[unsafe(no_mangle)]
-extern "C" fn cgi_handle(req: *const ModuleRequest) -> *const ModuleResponse {
+extern "C" fn cgi_handle(req: *const ffi::ModuleRequest) -> *const ffi::ModuleResponse {
 	let mut response = Response::new();
 	let mut body = String::new();
 
@@ -67,7 +67,7 @@ extern "C" fn cgi_handle(req: *const ModuleRequest) -> *const ModuleResponse {
 	response.into_mod_response(200)
 }
 
-fn make_error<S: AsRef<str>>(code: u16, msg: S) -> *const ModuleResponse {
+fn make_error<S: AsRef<str>>(code: u16, msg: S) -> *const ffi::ModuleResponse {
 	let mut response = Response::new();
 	response.header(c"Content-Length", c"text/html");
 	response.body(msg.as_ref().as_bytes().to_vec());
@@ -76,6 +76,6 @@ fn make_error<S: AsRef<str>>(code: u16, msg: S) -> *const ModuleResponse {
 }
 
 #[unsafe(no_mangle)]
-extern "C" fn cgi_cleanup(response: *const ModuleResponse) {
+extern "C" fn cgi_cleanup(response: *const ffi::ModuleResponse) {
 	Response::cleanup(response);
 }