summaryrefslogtreecommitdiff
path: root/c/wasi-http
diff options
context:
space:
mode:
authorAndrew Clayton <a.clayton@nginx.com>2024-02-13 22:12:38 +0000
committerAndrew Clayton <a.clayton@nginx.com>2024-02-13 22:12:38 +0000
commit016ae29e0d69cc6b919b9011894802bb70ce5fad (patch)
tree177a81a2e95407b26d9de694f957117b87fd8556 /c/wasi-http
parentf5e85249d680e1501793cc46b7a3f0a177f3f383 (diff)
downloadproject_blackbird-016ae29e0d69cc6b919b9011894802bb70ce5fad.tar.gz
project_blackbird-016ae29e0d69cc6b919b9011894802bb70ce5fad.tar.bz2
Add a wasi-http 0.2.0 large-upload component in C
This makes use of the 'reactor' adaptor for filesystem access via the preopens method. Signed-off-by: Andrew Clayton <a.clayton@nginx.com>
Diffstat (limited to '')
-rw-r--r--c/wasi-http/0.2.0/large-upload/Makefile29
-rw-r--r--c/wasi-http/0.2.0/large-upload/component.c90
-rw-r--r--c/wasi-http/0.2.0/large-upload/wasi_snapshot_preview1.reactor.wasmbin0 -> 96758 bytes
3 files changed, 119 insertions, 0 deletions
diff --git a/c/wasi-http/0.2.0/large-upload/Makefile b/c/wasi-http/0.2.0/large-upload/Makefile
new file mode 100644
index 0000000..d84c222
--- /dev/null
+++ b/c/wasi-http/0.2.0/large-upload/Makefile
@@ -0,0 +1,29 @@
+# Look for wasi-sysroot in some common places, falling back
+# to provided WASI_SYSROOT
+ifneq ("$(wildcard /usr/wasm32-wasi)", "")
+ # Fedora
+ WASI_SYSROOT ?= /usr/wasm32-wasi
+endif
+
+export WASI_SYSROOT
+
+CC = clang
+CFLAGS = -Wall -Wextra -g --target=wasm32-wasi --sysroot=$(WASI_SYSROOT)
+LDFLAGS = -Wl,--no-entry,--export=__heap_base,--export=__data_end,--export=malloc,--export=free,--stack-first,-z,stack-size=$$((8*1024*1024)) -mexec-model=reactor --rtlib=compiler-rt
+
+all: component.wasm
+
+bindgen:
+ /home/andrew/src/c/wasm/git/wit-bindgen/target/release/wit-bindgen c /home/andrew/src/c/wasm/git/wasi-http/wit --autodrop-borrows yes --world wasi:http/proxy
+ /home/andrew/src/c/wasm/git/wit-bindgen/target/release/wit-bindgen markdown /home/andrew/src/c/wasm/git/wasi-http/wit --world wasi:http/proxy
+
+.PHONY:
+module.wasm: bindgen
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ proxy.c proxy_component_type.o component.c
+
+.PHONY:
+component.wasm: module.wasm
+ /home/andrew/src/c/wasm/git/wasm-tools/target/release/wasm-tools component new module.wasm --adapt wasi_snapshot_preview1.reactor.wasm -o component.wasm
+
+clean:
+ rm -f component.wasm module.wasm proxy*
diff --git a/c/wasi-http/0.2.0/large-upload/component.c b/c/wasi-http/0.2.0/large-upload/component.c
new file mode 100644
index 0000000..148100d
--- /dev/null
+++ b/c/wasi-http/0.2.0/large-upload/component.c
@@ -0,0 +1,90 @@
+/* SPDX-License-Identifier: Apache-2.0 */
+
+/*
+ * component.c - Example of writing a wasi-http Wasm component
+ *
+ * Copyright (C) Andrew Clayton
+ * Copyright (C) F5, Inc.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "proxy.h"
+
+#define ex(...) \
+ do { \
+ printf(__VA_ARGS__); \
+ return; \
+ } while (0)
+
+void exports_wasi_http_incoming_handler_handle(
+ exports_wasi_http_incoming_handler_own_incoming_request_t request,
+ exports_wasi_http_incoming_handler_own_response_outparam_t response_out)
+{
+ wasi_http_types_borrow_incoming_request_t b_req;
+ wasi_http_types_own_incoming_body_t r_body;
+ wasi_http_types_borrow_incoming_body_t b_r_body;
+ wasi_http_types_result_own_outgoing_response_error_code_t rerr = { };
+ wasi_http_types_own_fields_t hdrs;
+ wasi_http_types_borrow_fields_t b_hdrs;
+ wasi_http_types_own_fields_t fields;
+ wasi_http_types_own_input_stream_t in_stream;
+ wasi_io_streams_borrow_input_stream_t b_in_stream;
+ wasi_io_streams_stream_error_t in_stream_err;
+ proxy_list_u8_t data;
+ proxy_list_field_value_t f_clen;
+ unsigned long long total_bytes_wrote = 0;
+ unsigned long long content_len;
+ bool ok;
+ int fd;
+
+ fd = open("/var/tmp/wasm-wasi-component-upload.dat",
+ O_CREAT|O_TRUNC|O_WRONLY, 0666);
+
+ b_req = wasi_http_types_borrow_incoming_request(request);
+
+ hdrs = wasi_http_types_method_incoming_request_headers(b_req);
+ b_hdrs = wasi_http_types_borrow_fields(hdrs);
+
+ wasi_http_types_method_fields_get(
+ b_hdrs,
+ &(proxy_string_t){ .ptr = (uint8_t *)"content-length",
+ .len = strlen("content-length") },
+ &f_clen);
+
+ content_len = strtoull((const char *)f_clen.ptr[0].ptr, NULL, 10);
+
+ ok = wasi_http_types_method_incoming_request_consume(b_req, &r_body);
+ if (!ok)
+ ex("wasi_http_types_method_incoming_request_consume() failed\n");
+ b_r_body = wasi_http_types_borrow_incoming_body(r_body);
+ ok = wasi_http_types_method_incoming_body_stream(b_r_body, &in_stream);
+ if (!ok)
+ ex("wasi_http_types_method_incoming_body_stream() failed\n");
+ b_in_stream = wasi_io_streams_borrow_input_stream(in_stream);
+
+ do {
+ ok = wasi_io_streams_method_input_stream_blocking_read(
+ b_in_stream,
+ 8 * 1024*1024,
+ &data,
+ &in_stream_err);
+ if (!ok)
+ break;
+
+ write(fd, data.ptr, data.len);
+ total_bytes_wrote += data.len;
+ } while (total_bytes_wrote < content_len);
+
+ fields = wasi_http_types_constructor_fields();
+ wasi_http_types_constructor_outgoing_response(fields);
+ wasi_http_types_static_response_outparam_set(response_out, &rerr);
+
+ close(fd);
+}
diff --git a/c/wasi-http/0.2.0/large-upload/wasi_snapshot_preview1.reactor.wasm b/c/wasi-http/0.2.0/large-upload/wasi_snapshot_preview1.reactor.wasm
new file mode 100644
index 0000000..0717d98
--- /dev/null
+++ b/c/wasi-http/0.2.0/large-upload/wasi_snapshot_preview1.reactor.wasm
Binary files differ