diff options
author | Andrew Clayton <a.clayton@nginx.com> | 2023-08-24 20:03:25 +0100 |
---|---|---|
committer | Andrew Clayton <a.clayton@nginx.com> | 2023-08-25 21:13:49 +0100 |
commit | 55a41414b87301e37d9dc35937694d5aa13d9d99 (patch) | |
tree | bd19eacf97c5b3888ea89f502c6105bd3b5712d3 | |
parent | 5f8623b45b1ff9c96f0db57fcc41eb5e1bbca90e (diff) | |
download | unit-wasm-55a41414b87301e37d9dc35937694d5aa13d9d99.tar.gz unit-wasm-55a41414b87301e37d9dc35937694d5aa13d9d99.tar.bz2 |
Rust: Add a nicer wrapper around the libunit-wasm bindings
This adds a nice wrapper (aka rusty) around the generated libunit-wasm
bindings.
This should provide a more native rust like experience with the
following benefits
- No casting. So no things like 'as *mut c_void'
- Native rust strings. So no things like '.as_ptr() as *const c_char'
- Better ctx initialisation. Filed initialisation is now hidden away
- Great reduction in the amount of unsafe {} blocks required
- Generally more compact
There are also some new macros
- C2S!() converts a CStr to a Str
- S2C!() converts a formatted Str to a Cstr using format!()
- uwr_write_str!() a wrapper around luw_mem_writep_data and format!()
This wrapper uses a uwr (Unit Wasm Rust) prefix under a 'rusty'
namespace.
The luw_http_hdr_iter() function proved tricky to wrap and the callback
function still takes C style arguments due to the fact that this
function is called from the libunit-wasm C library.
The provided wrapper simply means we can use this without having to use
an unsafe {} block around it in application code.
Similarly with other functions that technically didn't need to be
wrapped, wrapping them means that the unsafe {} blocks are hidden away.
Signed-off-by: Andrew Clayton <a.clayton@nginx.com>
-rw-r--r-- | src/rust/src/lib.rs | 1 | ||||
-rw-r--r-- | src/rust/src/rusty/mod.rs | 3 | ||||
-rw-r--r-- | src/rust/unit-wasm-sys/lib.rs | 2 | ||||
-rw-r--r-- | src/rust/unit-wasm-sys/macros.rs | 5 | ||||
-rw-r--r-- | src/rust/unit-wasm-sys/rusty.rs | 214 |
5 files changed, 225 insertions, 0 deletions
diff --git a/src/rust/src/lib.rs b/src/rust/src/lib.rs index dface32..2b17728 100644 --- a/src/rust/src/lib.rs +++ b/src/rust/src/lib.rs @@ -6,3 +6,4 @@ */ pub mod ffi; +pub mod rusty; diff --git a/src/rust/src/rusty/mod.rs b/src/rust/src/rusty/mod.rs new file mode 100644 index 0000000..087148a --- /dev/null +++ b/src/rust/src/rusty/mod.rs @@ -0,0 +1,3 @@ +// @todo: Check if this is valid?! +extern crate unit_wasm_sys; +pub use self::unit_wasm_sys::*; diff --git a/src/rust/unit-wasm-sys/lib.rs b/src/rust/unit-wasm-sys/lib.rs index 42d5981..81cd464 100644 --- a/src/rust/unit-wasm-sys/lib.rs +++ b/src/rust/unit-wasm-sys/lib.rs @@ -9,9 +9,11 @@ mod bindings { #![allow(non_upper_case_globals)] #![allow(non_camel_case_types)] + #![allow(non_snake_case)] include!(concat!(env!("OUT_DIR"), "/bindings.rs")); include!("macros.rs"); + include!("rusty.rs"); } #[doc(no_inline)] diff --git a/src/rust/unit-wasm-sys/macros.rs b/src/rust/unit-wasm-sys/macros.rs index d7fde22..059fef3 100644 --- a/src/rust/unit-wasm-sys/macros.rs +++ b/src/rust/unit-wasm-sys/macros.rs @@ -13,3 +13,8 @@ pub const LUW_VERSION_NUMBER: i32 = (LUW_VERSION_MAJOR << 24) | (LUW_VERSION_MINOR << 16) | (LUW_VERSION_PATCH << 8); + +pub const LUW_SRB_NONE: u32 = luw_srb_flags_t_LUW_SRB_NONE; +pub const LUW_SRB_APPEND: u32 = luw_srb_flags_t_LUW_SRB_APPEND; +pub const LUW_SRB_ALLOC: u32 = luw_srb_flags_t_LUW_SRB_ALLOC; +pub const LUW_SRB_FULL_SIZE: u32 = luw_srb_flags_t_LUW_SRB_FLAGS_ALL; diff --git a/src/rust/unit-wasm-sys/rusty.rs b/src/rust/unit-wasm-sys/rusty.rs new file mode 100644 index 0000000..79c38f3 --- /dev/null +++ b/src/rust/unit-wasm-sys/rusty.rs @@ -0,0 +1,214 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +/* + * Copyright (C) Andrew Clayton + * Copyright (C) F5, Inc. + */ + +use std::ffi::c_char; +use std::ffi::c_void; +use std::ffi::CStr; +use std::ptr::null_mut; + +#[macro_export] +macro_rules! C2S { + ($a:expr) => {{ + unsafe { CStr::from_ptr($a).to_str().unwrap() } + }}; +} + +#[macro_export] +macro_rules! S2C { + ($a:expr) => {{ + format!("{}\0", $a) + }}; +} + +#[macro_export] +macro_rules! uwr_write_str{ + ($a:expr, $($arg:tt)*) => { + { + uwr_mem_write_str($a, &format!($($arg)*)) + } +}} + +pub const fn UWR_CTX_INITIALIZER() -> luw_ctx_t { + luw_ctx_t { + addr: null_mut(), + mem: null_mut(), + req: null_mut(), + resp: null_mut(), + resp_hdr: null_mut(), + resp_offset: 0, + req_buf: null_mut(), + hdrp: null_mut(), + reqp: null_mut(), + } +} + +pub fn uwr_init_ctx(ctx: *mut luw_ctx_t, addr: *mut u8, offset: usize) { + unsafe { + luw_init_ctx(ctx, addr, offset); + } +} + +pub fn uwr_set_req_buf( + ctx: *mut luw_ctx_t, + buf: *mut *mut u8, + flags: u32, +) -> i32 { + unsafe { luw_set_req_buf(ctx, buf, flags) } +} + +pub fn uwr_get_http_path(ctx: *mut luw_ctx_t) -> &'static str { + C2S!(luw_get_http_path(ctx)) +} + +pub fn uwr_get_http_method(ctx: *mut luw_ctx_t) -> &'static str { + C2S!(luw_get_http_method(ctx)) +} + +pub fn uwr_get_http_version(ctx: *mut luw_ctx_t) -> &'static str { + C2S!(luw_get_http_version(ctx)) +} + +pub fn uwr_get_http_query(ctx: *mut luw_ctx_t) -> &'static str { + C2S!(luw_get_http_query(ctx)) +} + +pub fn uwr_get_http_remote(ctx: *mut luw_ctx_t) -> &'static str { + C2S!(luw_get_http_remote(ctx)) +} + +pub fn uwr_get_http_local_addr(ctx: *mut luw_ctx_t) -> &'static str { + C2S!(luw_get_http_local_addr(ctx)) +} + +pub fn uwr_get_http_local_port(ctx: *mut luw_ctx_t) -> &'static str { + C2S!(luw_get_http_local_port(ctx)) +} + +pub fn uwr_get_http_server_name(ctx: *mut luw_ctx_t) -> &'static str { + C2S!(luw_get_http_server_name(ctx)) +} + +pub fn uwr_get_http_content(ctx: *const luw_ctx_t) -> *const u8 { + unsafe { luw_get_http_content(ctx) } +} + +pub fn uwr_get_http_content_len(ctx: *const luw_ctx_t) -> usize { + unsafe { luw_get_http_content_len(ctx) } +} + +pub fn uwr_get_http_content_sent(ctx: *const luw_ctx_t) -> usize { + unsafe { luw_get_http_content_sent(ctx) } +} + +pub fn uwr_http_is_tls(ctx: *const luw_ctx_t) -> bool { + unsafe { luw_http_is_tls(ctx) } +} + +pub fn uwr_http_hdr_iter( + ctx: *mut luw_ctx_t, + luw_http_hdr_iter_func: ::std::option::Option< + unsafe extern "C" fn( + ctx: *mut luw_ctx_t, + name: *const c_char, + value: *const c_char, + data: *mut c_void, + ) -> bool, + >, + user_data: *mut c_void, +) { + unsafe { luw_http_hdr_iter(ctx, luw_http_hdr_iter_func, user_data) } +} + +pub fn uwr_http_hdr_get_value(ctx: *mut luw_ctx_t, hdr: &str) -> &'static str { + C2S!(luw_http_hdr_get_value(ctx, S2C!(hdr).as_ptr() as *const i8)) +} + +pub fn uwr_get_response_data_size(ctx: *const luw_ctx_t) -> usize { + unsafe { luw_get_response_data_size(ctx) } +} + +pub fn uwr_mem_write_str(ctx: *mut luw_ctx_t, src: &str) -> usize { + unsafe { luw_mem_writep_data(ctx, src.as_ptr(), src.len()) } +} + +pub fn uwr_mem_write_buf( + ctx: *mut luw_ctx_t, + src: *const u8, + size: usize, +) -> usize { + unsafe { luw_mem_writep_data(ctx, src, size) } +} + +pub fn uwr_req_buf_append(ctx: *mut luw_ctx_t, src: *const u8) { + unsafe { + luw_req_buf_append(ctx, src); + } +} + +pub fn uwr_mem_fill_buf_from_req(ctx: *mut luw_ctx_t, from: usize) -> usize { + unsafe { luw_mem_fill_buf_from_req(ctx, from) } +} + +pub fn uwr_luw_mem_reset(ctx: *mut luw_ctx_t) { + unsafe { + luw_mem_reset(ctx); + } +} + +pub fn uwr_http_send_response(ctx: *const luw_ctx_t) { + unsafe { + luw_http_send_response(ctx); + } +} + +pub fn uwr_http_init_headers(ctx: *mut luw_ctx_t, nr: usize, offset: usize) { + unsafe { + luw_http_init_headers(ctx, nr, offset); + } +} + +pub fn uwr_http_add_header( + ctx: *mut luw_ctx_t, + idx: u16, + name: &str, + value: &str, +) { + unsafe { + luw_http_add_header( + ctx, + idx, + S2C!(name).as_ptr() as *const i8, + S2C!(value).as_ptr() as *const i8, + ); + } +} + +pub fn uwr_http_send_headers(ctx: *const luw_ctx_t) { + unsafe { + luw_http_send_headers(ctx); + } +} + +pub fn uwr_http_response_end() { + unsafe { + luw_http_response_end(); + } +} + +pub fn uwr_mem_get_init_size() -> u32 { + unsafe { luw_mem_get_init_size() } +} + +pub fn uwr_malloc(size: u32) -> *mut u8 { + unsafe { luw_malloc(size as usize) as *mut u8 } +} + +pub fn uwr_free(ptr: *mut u8) { + unsafe { + luw_free(ptr as *mut c_void); + } +} |