diff options
author | gennyble <gen@nyble.dev> | 2025-04-02 06:15:57 -0500 |
---|---|---|
committer | gennyble <gen@nyble.dev> | 2025-04-02 06:15:57 -0500 |
commit | 315f3268525dc05c587ab4b28772b73cb18e66ef (patch) | |
tree | fa17b45a4827fa3544fa134670590c79cdaea12c | |
parent | 23f494f065be5eaec37aab6ca6e72348c6a025e0 (diff) | |
download | corgi-315f3268525dc05c587ab4b28772b73cb18e66ef.tar.gz corgi-315f3268525dc05c587ab4b28772b73cb18e66ef.zip |
improve ffi
-rw-r--r-- | Cargo.lock | 1 | ||||
-rw-r--r-- | corgi/Cargo.toml | 1 | ||||
-rw-r--r-- | smalldog/src/lib.rs | 53 | ||||
-rw-r--r-- | stats_module/src/lib.rs | 8 |
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); } |