summaryrefslogtreecommitdiffhomepage
path: root/examples
diff options
context:
space:
mode:
authorAndrew Clayton <a.clayton@nginx.com>2023-08-24 20:43:38 +0100
committerAndrew Clayton <a.clayton@nginx.com>2023-08-25 21:13:49 +0100
commitf9c01f4f721969c7dbe6152bbd38cc039acb27bf (patch)
treeec9bbdbaaf31ae51da5b0931ed7b58334a05ec25 /examples
parent55a41414b87301e37d9dc35937694d5aa13d9d99 (diff)
downloadunit-wasm-f9c01f4f721969c7dbe6152bbd38cc039acb27bf.tar.gz
unit-wasm-f9c01f4f721969c7dbe6152bbd38cc039acb27bf.tar.bz2
Rust: Port the Rust Wasm demos to the new 'rusty' wrappers
rusty is a thin wrapper over the generated libunit-wasm bindings to provide a more native rust like interface. This gets rid of all the casting and ugly string handling. It massively reduces the amount of unsafe {} blocks needed, though some still are... All in all this provides a nice code cleanup. Signed-off-by: Andrew Clayton <a.clayton@nginx.com>
Diffstat (limited to 'examples')
-rw-r--r--examples/rust/echo-request/src/lib.rs233
-rw-r--r--examples/rust/upload-reflector/src/lib.rs143
2 files changed, 137 insertions, 239 deletions
diff --git a/examples/rust/echo-request/src/lib.rs b/examples/rust/echo-request/src/lib.rs
index 4802cff..3fea8d5 100644
--- a/examples/rust/echo-request/src/lib.rs
+++ b/examples/rust/echo-request/src/lib.rs
@@ -6,30 +6,27 @@
* Copyright (C) F5, Inc.
*/
-// Include RAW FFI Bindings.
-// @todo: Replace this with the new native Rust API
-use unit_wasm::ffi::*;
+use unit_wasm::rusty::*;
use std::ffi::CStr;
use std::os::raw::c_char;
use std::os::raw::c_void;
-use std::ptr;
+use std::ptr::null_mut;
// Buffer of some size to store the copy of the request
-static mut REQUEST_BUF: *mut u8 = ptr::null_mut();
+static mut REQUEST_BUF: *mut u8 = null_mut();
#[no_mangle]
-pub extern "C" fn luw_module_end_handler() {
+pub extern "C" fn uwr_module_end_handler() {
unsafe {
- luw_free(REQUEST_BUF as *mut c_void);
+ uwr_free(REQUEST_BUF);
}
}
#[no_mangle]
-pub extern "C" fn luw_module_init_handler() {
+pub extern "C" fn uwr_module_init_handler() {
unsafe {
- REQUEST_BUF = luw_malloc(luw_mem_get_init_size().try_into().unwrap())
- as *mut u8;
+ REQUEST_BUF = uwr_malloc(uwr_mem_get_init_size());
}
}
@@ -39,162 +36,90 @@ pub extern "C" fn hdr_iter_func(
value: *const c_char,
_data: *mut c_void,
) -> bool {
- unsafe {
- luw_mem_writep(
- ctx,
- "%s = %s\n\0".as_ptr() as *const c_char,
- name,
- value,
- );
- }
+ uwr_write_str!(ctx, "{} = {}\n", C2S!(name), C2S!(value));
return true;
}
#[no_mangle]
-pub extern "C" fn luw_request_handler(addr: *mut u8) -> i32 {
- // Need a initalization
+pub extern "C" fn uwr_request_handler(addr: *mut u8) -> i32 {
+ // Declare a 0-initialised context structure
+ let ctx = &mut UWR_CTX_INITIALIZER();
+ // Initialise the context structure.
+ //
+ // addr is the address of the previously allocated memory shared
+ // between the module and unit.
//
- // It sucks that rust needs this, this is supposed to be
- // an opaque structure and the structure is 0-initialised
- // in luw_init_ctx();
- let mut ctx_: luw_ctx_t = luw_ctx_t {
- addr: ptr::null_mut(),
- mem: ptr::null_mut(),
- req: ptr::null_mut(),
- resp: ptr::null_mut(),
- resp_hdr: ptr::null_mut(),
- resp_offset: 0,
- req_buf: ptr::null_mut(),
- hdrp: ptr::null_mut(),
- reqp: ptr::null_mut(),
- };
- let ctx: *mut luw_ctx_t = &mut ctx_;
+ // The response data will be stored @ addr + offset (of 4096 bytes).
+ // This will leave some space for the response headers.
+ uwr_init_ctx(ctx, addr, 4096);
+ // Set where we will copy the request into
unsafe {
- // Initialise the context structure.
- //
- // addr is the address of the previously allocated memory shared
- // between the module and unit.
- //
- // The response data will be stored @ addr + offset (of 4096 bytes).
- // This will leave some space for the response headers.
- luw_init_ctx(ctx, addr, 4096);
-
- // Allocate memory to store the request and copy the request data.
- luw_set_req_buf(ctx, &mut REQUEST_BUF, luw_srb_flags_t_LUW_SRB_NONE);
-
- // Define the Response Body Text.
-
- luw_mem_writep(
- ctx,
- " * Welcome to WebAssembly in Rust on Unit! \
- [libunit-wasm (%d.%d.%d/%#0.8x)] \
- *\n\n\0"
- .as_ptr() as *const c_char,
- LUW_VERSION_MAJOR,
- LUW_VERSION_MINOR,
- LUW_VERSION_PATCH,
- LUW_VERSION_NUMBER,
- );
-
- luw_mem_writep(ctx, "[Request Info]\n\0".as_ptr() as *const c_char);
-
- luw_mem_writep(
- ctx,
- "REQUEST_PATH = %s\n\0".as_ptr() as *const c_char,
- luw_get_http_path(ctx) as *const c_char,
- );
- luw_mem_writep(
- ctx,
- "METHOD = %s\n\0".as_ptr() as *const c_char,
- luw_get_http_method(ctx) as *const c_char,
- );
- luw_mem_writep(
- ctx,
- "VERSION = %s\n\0".as_ptr() as *const c_char,
- luw_get_http_version(ctx) as *const c_char,
- );
- luw_mem_writep(
- ctx,
- "QUERY = %s\n\0".as_ptr() as *const c_char,
- luw_get_http_query(ctx) as *const c_char,
- );
- luw_mem_writep(
- ctx,
- "REMOTE = %s\n\0".as_ptr() as *const c_char,
- luw_get_http_remote(ctx) as *const c_char,
- );
- luw_mem_writep(
- ctx,
- "LOCAL_ADDR = %s\n\0".as_ptr() as *const c_char,
- luw_get_http_local_addr(ctx) as *const c_char,
- );
- luw_mem_writep(
- ctx,
- "LOCAL_PORT = %s\n\0".as_ptr() as *const c_char,
- luw_get_http_local_port(ctx) as *const c_char,
- );
- luw_mem_writep(
- ctx,
- "SERVER_NAME = %s\n\0".as_ptr() as *const c_char,
- luw_get_http_server_name(ctx) as *const c_char,
- );
-
- luw_mem_writep(
- ctx,
- "\n[Request Headers]\n\0".as_ptr() as *const c_char,
- );
+ uwr_set_req_buf(ctx, &mut REQUEST_BUF, LUW_SRB_NONE);
+ }
- luw_http_hdr_iter(ctx, Some(hdr_iter_func), ptr::null_mut());
-
- let method = CStr::from_ptr(luw_get_http_method(ctx)).to_str().unwrap();
- if method == "POST" || method == "PUT" {
- luw_mem_writep(
- ctx,
- "\n[%s data]\n\0".as_ptr() as *const c_char,
- luw_get_http_method(ctx) as *const c_char,
- );
- luw_mem_writep_data(
- ctx,
- luw_get_http_content(ctx),
- luw_get_http_content_len(ctx),
- );
- luw_mem_writep(ctx, "\n\0".as_ptr() as *const c_char);
- }
-
- let content_len = format!("{}\0", luw_get_response_data_size(ctx));
-
- // Init Response Headers
- //
- // Needs the context, number of headers about to add as well as
- // the offset where to store the headers. In this case we are
- // storing the response headers at the beginning of our shared
- // memory at offset 0.
-
- luw_http_init_headers(ctx, 2, 0);
- luw_http_add_header(
+ // Define the Response Body Text.
+
+ uwr_write_str!(
+ ctx,
+ " * Welcome to WebAssembly in Rust on Unit! \
+ [libunit-wasm ({}.{}.{}/{:#010x})] *\n\n",
+ LUW_VERSION_MAJOR,
+ LUW_VERSION_MINOR,
+ LUW_VERSION_PATCH,
+ LUW_VERSION_NUMBER,
+ );
+
+ uwr_write_str!(ctx, "[Request Info]\n");
+
+ uwr_write_str!(ctx, "REQUEST_PATH = {}\n", uwr_get_http_path(ctx));
+ uwr_write_str!(ctx, "METHOD = {}\n", uwr_get_http_method(ctx));
+ uwr_write_str!(ctx, "VERSION = {}\n", uwr_get_http_version(ctx));
+ uwr_write_str!(ctx, "QUERY = {}\n", uwr_get_http_query(ctx));
+ uwr_write_str!(ctx, "REMOTE = {}\n", uwr_get_http_remote(ctx));
+ uwr_write_str!(ctx, "LOCAL_ADDR = {}\n", uwr_get_http_local_addr(ctx));
+ uwr_write_str!(ctx, "LOCAL_PORT = {}\n", uwr_get_http_local_port(ctx));
+ uwr_write_str!(ctx, "SERVER_NAME = {}\n", uwr_get_http_server_name(ctx));
+
+ uwr_write_str!(ctx, "\n[Request Headers]\n");
+
+ uwr_http_hdr_iter(ctx, Some(hdr_iter_func), null_mut());
+
+ let method = uwr_get_http_method(ctx);
+ if method == "POST" || method == "PUT" {
+ uwr_write_str!(ctx, "\n[{} data]\n", method);
+ uwr_mem_write_buf(
ctx,
- 0,
- "Content-Type\0".as_ptr() as *const c_char,
- "text/plain\0".as_ptr() as *const c_char,
+ uwr_get_http_content(ctx),
+ uwr_get_http_content_len(ctx),
);
- luw_http_add_header(
- ctx,
- 1,
- "Content-Length\0".as_ptr() as *const c_char,
- content_len.as_ptr() as *const c_char,
- );
-
- // This calls nxt_wasm_send_headers() in Unit
- luw_http_send_headers(ctx);
-
- // This calls nxt_wasm_send_response() in Unit
- luw_http_send_response(ctx);
-
- // This calls nxt_wasm_response_end() in Unit
- luw_http_response_end();
+ uwr_write_str!(ctx, "\n");
}
+ // Init Response Headers
+ //
+ // Needs the context, number of headers about to add as well as
+ // the offset where to store the headers. In this case we are
+ // storing the response headers at the beginning of our shared
+ // memory at offset 0.
+ uwr_http_init_headers(ctx, 2, 0);
+ uwr_http_add_header(ctx, 0, "Content-Type", "text/plain");
+ uwr_http_add_header(
+ ctx,
+ 1,
+ "Content-Length",
+ &format!("{}", uwr_get_response_data_size(ctx)),
+ );
+
+ // This calls nxt_wasm_send_headers() in Unit
+ uwr_http_send_headers(ctx);
+
+ // This calls nxt_wasm_send_response() in Unit
+ uwr_http_send_response(ctx);
+
+ // This calls nxt_wasm_response_end() in Unit
+ uwr_http_response_end();
+
return 0;
}
diff --git a/examples/rust/upload-reflector/src/lib.rs b/examples/rust/upload-reflector/src/lib.rs
index 9893d5a..01138b0 100644
--- a/examples/rust/upload-reflector/src/lib.rs
+++ b/examples/rust/upload-reflector/src/lib.rs
@@ -6,126 +6,99 @@
* Copyright (C) F5, Inc.
*/
-// Include RAW FFI Bindings.
-// @todo: Replace this with the new native Rust API
-use unit_wasm::ffi::*;
-
-use std::os::raw::c_char;
-use std::os::raw::c_void;
-use std::ptr;
-
-static mut CTX: luw_ctx_t = luw_ctx_t {
- addr: ptr::null_mut(),
- mem: ptr::null_mut(),
- req: ptr::null_mut(),
- resp: ptr::null_mut(),
- resp_hdr: ptr::null_mut(),
- resp_offset: 0,
- req_buf: ptr::null_mut(),
- hdrp: ptr::null_mut(),
- reqp: ptr::null_mut(),
-};
+use unit_wasm::rusty::*;
+
+use std::ptr::null_mut;
+
+static mut CTX: luw_ctx_t = UWR_CTX_INITIALIZER();
static mut TOTAL_RESPONSE_SENT: usize = 0;
// Buffer of some size to store the copy of the request
-static mut REQUEST_BUF: *mut u8 = ptr::null_mut();
+static mut REQUEST_BUF: *mut u8 = null_mut();
#[no_mangle]
-pub extern "C" fn luw_response_end_handler() {
+pub extern "C" fn uwr_response_end_handler() {
unsafe {
TOTAL_RESPONSE_SENT = 0;
}
}
#[no_mangle]
-pub extern "C" fn luw_request_end_handler() {
+pub extern "C" fn uwr_request_end_handler() {
unsafe {
if REQUEST_BUF.is_null() {
return;
}
- luw_free(REQUEST_BUF as *mut c_void);
- REQUEST_BUF = ptr::null_mut();
+ uwr_free(REQUEST_BUF);
+ REQUEST_BUF = null_mut();
}
}
pub fn upload_reflector(ctx: *mut luw_ctx_t) -> i32 {
let write_bytes: usize;
- unsafe {
- // Send headers
- if TOTAL_RESPONSE_SENT == 0 {
- let content_len = format!("{}\0", luw_get_http_content_len(ctx));
- let defct = "application/octet-stream\0".as_ptr() as *const c_char;
- let mut ct = luw_http_hdr_get_value(
- ctx,
- "Content-Type\0".as_ptr() as *const c_char,
- );
-
- if ct == ptr::null_mut() {
- ct = defct;
- }
-
- luw_http_init_headers(ctx, 2, 0);
- luw_http_add_header(
- ctx,
- 0,
- "Content-Type\0".as_ptr() as *const c_char,
- ct,
- );
- luw_http_add_header(
- ctx,
- 1,
- "Content-Length\0".as_ptr() as *const c_char,
- content_len.as_ptr() as *const c_char,
- );
- luw_http_send_headers(ctx);
+ // Send headers
+ if unsafe { TOTAL_RESPONSE_SENT == 0 } {
+ let defct = "application/octet-stream";
+ let mut ct = uwr_http_hdr_get_value(ctx, "Content-Type");
+
+ if ct.is_empty() {
+ ct = defct;
}
- write_bytes = luw_mem_fill_buf_from_req(ctx, TOTAL_RESPONSE_SENT);
+ uwr_http_init_headers(ctx, 2, 0);
+ uwr_http_add_header(ctx, 0, "Content-Type", ct);
+ uwr_http_add_header(
+ ctx,
+ 1,
+ "Content-Length",
+ &format!("{}", uwr_get_http_content_len(ctx)),
+ );
+ uwr_http_send_headers(ctx);
+ }
+
+ unsafe {
+ write_bytes = uwr_mem_fill_buf_from_req(ctx, TOTAL_RESPONSE_SENT);
TOTAL_RESPONSE_SENT += write_bytes;
+ }
- luw_http_send_response(ctx);
+ uwr_http_send_response(ctx);
- if TOTAL_RESPONSE_SENT == luw_get_http_content_len(ctx) {
- // Tell Unit no more data to send
- luw_http_response_end();
- }
+ if unsafe { TOTAL_RESPONSE_SENT == uwr_get_http_content_len(ctx) } {
+ // Tell Unit no more data to send
+ uwr_http_response_end();
}
return 0;
}
#[no_mangle]
-pub extern "C" fn luw_request_handler(addr: *mut u8) -> i32 {
- unsafe {
- let ctx: *mut luw_ctx_t = &mut CTX;
-
- if REQUEST_BUF.is_null() {
- luw_init_ctx(ctx, addr, 0 /* Response offset */);
- /*
- * Take a copy of the request and use that, we do this
- * in APPEND mode so we can build up request_buf from
- * multiple requests.
- *
- * Just allocate memory for the total amount of data we
- * expect to get, this includes the request structure
- * itself as well as any body content.
- */
- luw_set_req_buf(
- ctx,
- &mut REQUEST_BUF,
- luw_srb_flags_t_LUW_SRB_APPEND
- | luw_srb_flags_t_LUW_SRB_ALLOC
- | luw_srb_flags_t_LUW_SRB_FULL_SIZE,
- );
- } else {
- luw_req_buf_append(ctx, addr);
- }
-
- upload_reflector(ctx);
+pub extern "C" fn uwr_request_handler(addr: *mut u8) -> i32 {
+ let ctx: *mut luw_ctx_t = unsafe { &mut CTX };
+
+ if unsafe { REQUEST_BUF.is_null() } {
+ uwr_init_ctx(ctx, addr, 0 /* Response offset */);
+ /*
+ * Take a copy of the request and use that, we do this
+ * in APPEND mode so we can build up request_buf from
+ * multiple requests.
+ *
+ * Just allocate memory for the total amount of data we
+ * expect to get, this includes the request structure
+ * itself as well as any body content.
+ */
+ uwr_set_req_buf(
+ ctx,
+ unsafe { &mut REQUEST_BUF },
+ LUW_SRB_APPEND | LUW_SRB_ALLOC | LUW_SRB_FULL_SIZE,
+ );
+ } else {
+ uwr_req_buf_append(ctx, addr);
}
+ upload_reflector(ctx);
+
return 0;
}