diff options
Diffstat (limited to 'parrot_module/src/lib.rs')
-rw-r--r-- | parrot_module/src/lib.rs | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/parrot_module/src/lib.rs b/parrot_module/src/lib.rs new file mode 100644 index 0000000..148f41d --- /dev/null +++ b/parrot_module/src/lib.rs @@ -0,0 +1,57 @@ +use std::ffi::{self, CStr, CString}; + +#[repr(C)] +struct ModuleRequest<'req> { + headers_len: ffi::c_ulong, + headers: &'req [[*const ffi::c_char; 2]], + body_len: ffi::c_ulong, + body: *const u8, +} + +#[repr(C)] +struct ModuleResponse { + status: ffi::c_ushort, + headers_len: ffi::c_ulong, + headers: &'static [[*const ffi::c_char; 2]], + body_len: ffi::c_ulong, + body: *const u8, +} + +const HEADERS: &'static [[*const ffi::c_char; 2]] = + &[[c"Content-Type".as_ptr(), c"text/plain".as_ptr()]]; + +#[unsafe(no_mangle)] +extern "C" fn handle(req: *const ModuleRequest) -> *const ModuleResponse { + let mut ret = String::new(); + + // unwrap is bad here + let reqref = unsafe { req.as_ref() }.unwrap(); + + for idx in 0..reqref.headers_len { + 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(); + ret.push_str(&format!("{k}: {v}\n")); + } + + let body = CString::new(ret).unwrap(); + + let resp = ModuleResponse { + status: 200, + headers_len: 1, + headers: HEADERS, + body_len: body.as_bytes().len() as u64, + body: body.into_raw() as *const u8, + }; + + let boxed = Box::new(resp); + + Box::<ModuleResponse>::into_raw(boxed) +} + +#[unsafe(no_mangle)] +extern "C" fn free(req: *const ModuleResponse) { + // from_raw what we need to here so that these get dropped + let boxed = unsafe { Box::from_raw(req as *mut ModuleResponse) }; + let body = unsafe { CString::from_raw(boxed.body as *mut i8) }; +} |