diff options
Diffstat (limited to 'examples/c')
-rw-r--r-- | examples/c/Makefile | 40 | ||||
-rw-r--r-- | examples/c/echo-request-raw.c | 187 | ||||
-rw-r--r-- | examples/c/luw-echo-request.c | 98 | ||||
-rw-r--r-- | examples/c/luw-upload-reflector.c | 101 | ||||
-rw-r--r-- | examples/c/unit-wasm-raw.c | 46 | ||||
-rw-r--r-- | examples/c/unit-wasm-raw.h | 87 | ||||
-rw-r--r-- | examples/c/upload-reflector-raw.c | 223 |
7 files changed, 782 insertions, 0 deletions
diff --git a/examples/c/Makefile b/examples/c/Makefile new file mode 100644 index 0000000..1b10269 --- /dev/null +++ b/examples/c/Makefile @@ -0,0 +1,40 @@ +include ../../shared.mk + +CFLAGS += -I../../src/c/include +LIBS = -L../../src/c -lunit-wasm + +SDIR = examples/c + +LUW_SRCDIR = ../../src/c + +luw_deps = $(LUW_SRCDIR)/libunit-wasm.a \ + $(LUW_SRCDIR)/include/unit/unit-wasm.h + +examples: examples-luw + +examples-luw: luw-echo-request.wasm luw-upload-reflector.wasm + +examples-raw: echo-request-raw.wasm upload-reflector-raw.wasm + +luw-echo-request.wasm: luw-echo-request.c $(luw_deps) + $(PP_CCLNK) $(SDIR)/$@ + $(v)$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) + +luw-upload-reflector.wasm: luw-upload-reflector.c $(luw_deps) + $(PP_CCLNK) $(SDIR)/$@ + $(v)$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) + +unit-wasm-raw.o: unit-wasm-raw.c unit-wasm-raw.h + $(PP_CC) $(SDIR)/$@ + $(v)$(CC) $(CFLAGS) -c $< + +echo-request-raw.wasm: echo-request-raw.c unit-wasm-raw.o + $(PP_CCLNK) $(SDIR)/$@ + $(v)$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< unit-wasm-raw.o + +upload-reflector-raw.wasm: upload-reflector-raw.c unit-wasm-raw.o + $(PP_CCLNK) $(SDIR)/$@ + $(v)$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< unit-wasm-raw.o + +clean: + rm -f *.wasm *.o *.gch diff --git a/examples/c/echo-request-raw.c b/examples/c/echo-request-raw.c new file mode 100644 index 0000000..2071597 --- /dev/null +++ b/examples/c/echo-request-raw.c @@ -0,0 +1,187 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +/* + * Copyright (C) Andrew Clayton + * Copyright (C) F5, Inc. + */ + +/* + * echo-request-raw.c - Raw example of writing a WASM module for use with Unit + * + * Download the wasi-sysroot tarball from https://github.com/WebAssembly/wasi-sdk/releases + */ + +#define _GNU_SOURCE + +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <string.h> + +#include "unit-wasm-raw.h" + +static u8 *request_buf; + +__attribute__((import_module("env"), import_name("nxt_wasm_get_init_mem_size"))) +u32 nxt_wasm_get_init_mem_size(void); +__attribute__((import_module("env"), import_name("nxt_wasm_response_end"))) +void nxt_wasm_response_end(void); +__attribute__((import_module("env"), import_name("nxt_wasm_send_response"))) +void nxt_wasm_send_response(u32 offset); + +__attribute__((export_name("wasm_module_end_handler"))) +void wasm_module_end_handler(void) +{ + free(request_buf); +} + +__attribute__((export_name("wasm_module_init_handler"))) +void wasm_module_init_handler(void) +{ + request_buf = malloc(nxt_wasm_get_init_mem_size()); +} + +__attribute__((export_name("wasm_free_handler"))) +void wasm_free_handler(u32 addr) +{ + free((void *)addr); +} + +__attribute__((export_name("wasm_malloc_handler"))) +u32 wasm_malloc_handler(size_t size) +{ + return (u32)malloc(size); +} + +static int echo_request(u8 *addr) +{ + u8 *p; + const char *method; + struct req *req; + struct resp *resp; + struct hdr_field *hf; + struct hdr_field *hf_end; + static const int resp_offs = 4096; + + printf("==[WASM RESP]== %s:\n", __func__); + + /* + * For convenience, we will return our headers at the start + * of the shared memory so leave a little space (resp_offs) + * before storing the main response. + * + * send_headers() will return the start of the shared memory, + * echo_request() will return the start of the shared memory + * plus resp_offs. + */ + resp = (struct resp *)(addr + resp_offs); + + req = (struct req *)request_buf; + +#define BUF_ADD(name, member) \ + do { \ + p = mempcpy(p, name, strlen(name)); \ + p = mempcpy(p, (u8 *)req + req->member##_offs, req->member##_len); \ + p = mempcpy(p, "\n", 1); \ + } while (0) + +#define BUF_ADD_HF() \ + do { \ + p = mempcpy(p, (u8 *)req + hf->name_offs, hf->name_len); \ + p = mempcpy(p, " = ", 3); \ + p = mempcpy(p, (u8 *)req + hf->value_offs, hf->value_len); \ + p = mempcpy(p, "\n", 1); \ + } while (0) + + p = resp->data; + + p = mempcpy(p, "Welcome to WebAssembly on Unit!\n\n", 33); + + p = mempcpy(p, "[Request Info]\n", 15); + BUF_ADD("REQUEST_PATH = ", path); + BUF_ADD("METHOD = ", method); + BUF_ADD("VERSION = ", version); + BUF_ADD("QUERY = ", query); + BUF_ADD("REMOTE = ", remote); + BUF_ADD("LOCAL_ADDR = ", local_addr); + BUF_ADD("LOCAL_PORT = ", local_port); + BUF_ADD("SERVER_NAME = ", server_name); + + p = mempcpy(p, "\n[Request Headers]\n", 19); + hf_end = req->fields + req->nr_fields; + for (hf = req->fields; hf < hf_end; hf++) + BUF_ADD_HF(); + + method = (char *)req + req->method_offs; + if (memcmp(method, "POST", req->method_len) == 0 || + memcmp(method, "PUT", req->method_len) == 0) { + p = mempcpy(p, "\n[", 2); + p = mempcpy(p, method, req->method_len); + p = mempcpy(p, " data]\n", 7); + p = mempcpy(p, (u8 *)req + req->content_offs, req->content_len); + p = mempcpy(p, "\n", 1); + } + + p = memcpy(p, "\0", 1); + + resp->size = p - resp->data; + + send_headers(addr, "text/plain", resp->size); + + nxt_wasm_send_response(resp_offs); + /* Tell Unit no more data to send */ + nxt_wasm_response_end(); + + return 0; +} + +__attribute__((export_name("wasm_request_handler"))) +int wasm_request_handler(u8 *addr) +{ + struct req *req = (struct req *)addr; + struct req *rb = (struct req *)request_buf; + + printf("==[WASM REQ]== %s:\n", __func__); + + /* + * This function _may_ be called multiple times during a single + * request if there is a large amount of data to transfer. + * + * In this simple demo, we are only expecting it to be called + * once per request. + * + * Some useful request meta data: + * + * req->content_len contains the overall size of the POST/PUT + * data. + * req->content_sent shows how much of the body content has been + * in _this_ request. + * req->total_content_sent shows how much of it has been sent in + * total. + * req->content_offs is the offset in the passed in memory where + * the body content starts. + * + * For new requests req->request_size shows the total size of + * _this_ request, incl the req structure itself. + * For continuation requests, req->request_size is just the amount + * of new content, i.e req->content_sent + * + * When req->content_len == req->total_content_sent, that's the end + * of that request. + */ + + printf("==[WASM REQ]== req->request_size : %u\n", req->request_size); + memcpy(request_buf, addr, req->request_size); + + rb = (struct req *)request_buf; + printf("==[WASM REQ]== rb@%p\n", rb); + printf("==[WASM REQ]== request_buf@%p\n", request_buf); + printf("==[WASM REQ]== rb->content_offs : %u\n", rb->content_offs); + printf("==[WASM REQ]== rb->content_len : %u\n", rb->content_len); + printf("==[WASM REQ]== rb->content_sent : %u\n", rb->content_sent); + printf("==[WASM REQ]== rb->request_size : %u\n", rb->request_size); + + echo_request(addr); + + return 0; +} diff --git a/examples/c/luw-echo-request.c b/examples/c/luw-echo-request.c new file mode 100644 index 0000000..5655c65 --- /dev/null +++ b/examples/c/luw-echo-request.c @@ -0,0 +1,98 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +/* + * examples/c/luw-echo-request.c - Example of writing a WASM module for use + * with Unit using libunit-wasm + * + * Copyright (C) Andrew Clayton + * Copyright (C) F5, Inc. + */ + +#define _XOPEN_SOURCE 500 + +#include <stdio.h> +#include <stdlib.h> +#include <stdbool.h> +#include <string.h> + +#include "unit/unit-wasm.h" + +static u8 *request_buf; + +__luw_export_name("luw_module_end_handler") +void luw_module_end_handler(void) +{ + free(request_buf); +} + +__luw_export_name("luw_module_init_handler") +void luw_module_init_handler(void) +{ + request_buf = malloc(luw_mem_get_init_size()); +} + +static bool hdr_iter_func(luw_ctx_t *ctx, const char *name, const char *value, + void *user_data __luw_unused) +{ + luw_mem_writep(ctx, "%s = %s\n", name, value); + + return true; +} + +__luw_export_name("luw_request_handler") +int luw_request_handler(u8 *addr) +{ + luw_ctx_t ctx; + char clen[32]; + const char *method; + + luw_init_ctx(&ctx, addr, 4096 /* Response offset */); + /* Take a copy of the request and use that */ + luw_set_req_buf(&ctx, &request_buf, LUW_SRB_NONE); + +#define BUF_ADD(fmt, member) \ + luw_mem_writep(&ctx, fmt, luw_get_http_##member(&ctx)); + + luw_mem_writep(&ctx, + " *** Welcome to WebAssembly on Unit! " + "[libunit-wasm (%d.%d.%d/%#0.8x)] ***\n\n", + LUW_VERSION_MAJOR, LUW_VERSION_MINOR, LUW_VERSION_PATCH, + LUW_VERSION_NUMBER); + + luw_mem_writep(&ctx, "[Request Info]\n"); + BUF_ADD("REQUEST_PATH = %s\n", path); + BUF_ADD("METHOD = %s\n", method); + BUF_ADD("VERSION = %s\n", version); + BUF_ADD("QUERY = %s\n", query); + BUF_ADD("REMOTE = %s\n", remote); + BUF_ADD("LOCAL_ADDR = %s\n", local_addr); + BUF_ADD("LOCAL_PORT = %s\n", local_port); + BUF_ADD("SERVER_NAME = %s\n", server_name); + + luw_mem_writep(&ctx, "\n[Request Headers]\n"); + + luw_http_hdr_iter(&ctx, hdr_iter_func, NULL); + + method = luw_get_http_method(&ctx); + if (memcmp(method, "POST", strlen(method)) == 0 || + memcmp(method, "PUT", strlen(method)) == 0) { + luw_mem_writep(&ctx, "\n[%s data]\n", method); + luw_mem_writep_data(&ctx, luw_get_http_content(&ctx), + luw_get_http_content_len(&ctx)); + luw_mem_writep(&ctx, "\n"); + } + + luw_http_init_headers(&ctx, 2, 0); + + snprintf(clen, sizeof(clen), "%lu", luw_get_response_data_size(&ctx)); + luw_http_add_header(&ctx, 0, "Content-Type", "text/plain"); + luw_http_add_header(&ctx, 1, "Content-Length", clen); + + luw_http_send_headers(&ctx); + + luw_http_send_response(&ctx); + /* Tell Unit no more data to send */ + luw_http_response_end(); + + return 0; +} diff --git a/examples/c/luw-upload-reflector.c b/examples/c/luw-upload-reflector.c new file mode 100644 index 0000000..95bc514 --- /dev/null +++ b/examples/c/luw-upload-reflector.c @@ -0,0 +1,101 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +/* + * examples/c/luw-upload-reflector.c - Example of writing a WASM module for + * use with Unit using libunit-wasm + * + * Copyright (C) Andrew Clayton + * Copyright (C) F5, Inc. + */ + +#define _XOPEN_SOURCE 500 + +#include <stdio.h> +#include <stdlib.h> + +#include "unit/unit-wasm.h" + +static luw_ctx_t ctx; + +static size_t total_response_sent; + +static u8 *request_buf; + +/* + * While these first two _handlers_ aren't technically required, they + * could be combined or the code could just go in upload_reflector(), + * they demonstrate their use in ensuring the module is in the right + * state for a new request. + */ +__luw_export_name("luw_response_end_handler") +void luw_response_end_handler(void) +{ + total_response_sent = 0; +} + +__luw_export_name("luw_request_end_handler") +void luw_request_end_handler(void) +{ + if (!request_buf) + return; + + free(request_buf); + request_buf = NULL; +} + +static int upload_reflector(luw_ctx_t *ctx) +{ + size_t write_bytes; + + /* Send headers */ + if (total_response_sent == 0) { + static const char *defct = "application/octet-stream"; + const char *ct = luw_http_hdr_get_value(ctx, "Content-Type"); + char clen[32]; + + snprintf(clen, sizeof(clen), "%lu", + luw_get_http_content_len(ctx)); + + luw_http_init_headers(ctx, 2, 0); + luw_http_add_header(ctx, 0, "Content-Type", ct ? ct : defct); + luw_http_add_header(ctx, 1, "Content-Length", clen); + luw_http_send_headers(ctx); + } + + write_bytes = luw_mem_fill_buf_from_req(ctx, total_response_sent); + total_response_sent += write_bytes; + + luw_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(); + } + + return 0; +} + +__luw_export_name("luw_request_handler") +int luw_request_handler(u8 *addr) +{ + if (!request_buf) { + 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, &request_buf, + LUW_SRB_APPEND|LUW_SRB_ALLOC|LUW_SRB_FULL_SIZE); + } else { + luw_req_buf_append(&ctx, addr); + } + + upload_reflector(&ctx); + + return 0; +} diff --git a/examples/c/unit-wasm-raw.c b/examples/c/unit-wasm-raw.c new file mode 100644 index 0000000..42ebcbf --- /dev/null +++ b/examples/c/unit-wasm-raw.c @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +/* + * Copyright (C) Andrew Clayton + * Copyright (C) F5, Inc. + */ + +#define _GNU_SOURCE + +#include <stdio.h> +#include <string.h> + +#include "unit-wasm-raw.h" + +__attribute__((import_module("env"), import_name("nxt_wasm_send_headers"))) +void nxt_wasm_send_headers(u32 offset); + +void send_headers(u8 *addr, const char *ct, size_t len) +{ + struct resp_hdr *rh; + char clen[32]; + u8 *p; + static const u32 hdr_offs = 0; + + rh = (struct resp_hdr *)addr; + +#define SET_HDR_FIELD(idx, name, val) \ + do { \ + rh->fields[idx].name_offs = p - addr; \ + rh->fields[idx].name_len = strlen(name); \ + p = mempcpy(p, name, rh->fields[idx].name_len); \ + rh->fields[idx].value_offs = p - addr; \ + rh->fields[idx].value_len = strlen(val); \ + p = mempcpy(p, val, rh->fields[idx].value_len); \ + } while (0) + + rh->nr_fields = 2; + p = addr + sizeof(struct resp_hdr) + + (rh->nr_fields * sizeof(struct hdr_field)); + + SET_HDR_FIELD(0, "Content-Type", ct); + snprintf(clen, sizeof(clen), "%lu", len); + SET_HDR_FIELD(1, "Content-Length", clen); + + nxt_wasm_send_headers(hdr_offs); +} diff --git a/examples/c/unit-wasm-raw.h b/examples/c/unit-wasm-raw.h new file mode 100644 index 0000000..6fd9d35 --- /dev/null +++ b/examples/c/unit-wasm-raw.h @@ -0,0 +1,87 @@ +#ifndef _UNIT_WASM_H_ +#define _UNIT_WASM_H_ + +#include <stddef.h> +#include <stdint.h> + +typedef uint64_t u64; +typedef int64_t s64; +typedef uint32_t u32; +typedef int32_t s32; +typedef uint16_t u16; +typedef int16_t s16; +typedef uint8_t u8; +typedef int8_t s8; + +#ifndef __unused +#define __unused __attribute__((unused)) +#endif +#ifndef __maybe_unused +#define __maybe_unused __unused +#endif +#ifndef __always_unused +#define __always_unused __unused +#endif + +struct hdr_field { + u32 name_offs; + u32 name_len; + u32 value_offs; + u32 value_len; +}; + +struct req { + u32 method_offs; + u32 method_len; + u32 version_offs; + u32 version_len; + u32 path_offs; + u32 path_len; + u32 query_offs; + u32 query_len; + u32 remote_offs; + u32 remote_len; + u32 local_addr_offs; + u32 local_addr_len; + u32 local_port_offs; + u32 local_port_len; + u32 server_name_offs; + u32 server_name_len; + + u32 content_offs; + u32 content_len; + u32 content_sent; + u32 total_content_sent; + + u32 request_size; + + u32 nr_fields; + + u32 tls; + + struct hdr_field fields[]; +}; + +struct resp { + u32 size; + + u8 data[]; +}; + +struct resp_hdr { + u32 nr_fields; + + struct hdr_field fields[]; +}; + +extern void wasm_module_end_handler(void); +extern void wasm_module_init_handler(void); +extern void wasm_response_end_handler(void); +extern void wasm_request_end_handler(void); +extern void wasm_free_handler(u32 addr); +extern u32 wasm_malloc_handler(size_t size); +extern int wasm_request_handler(u8 *addr); + +extern void send_headers(u8 *addr, const char *ct, size_t len); + +#endif /* _UNIT_WASM_H_ */ diff --git a/examples/c/upload-reflector-raw.c b/examples/c/upload-reflector-raw.c new file mode 100644 index 0000000..3da4f8d --- /dev/null +++ b/examples/c/upload-reflector-raw.c @@ -0,0 +1,223 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +/* + * Copyright (C) Andrew Clayton + * Copyright (C) F5, Inc. + */ + +/* + * upload-reflector-raw.c - Raw example of writing a WASM module for use with + * Unit + * + * Download the wasi-sysroot tarball from https://github.com/WebAssembly/wasi-sdk/releases + */ + +#define _GNU_SOURCE + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "unit-wasm-raw.h" + +static size_t total_response_sent; + +static u8 *request_buf; + +__attribute__((import_module("env"), import_name("nxt_wasm_get_init_mem_size"))) +u32 nxt_wasm_get_init_mem_size(void); +__attribute__((import_module("env"), import_name("nxt_wasm_response_end"))) +void nxt_wasm_response_end(void); +__attribute__((import_module("env"), import_name("nxt_wasm_send_response"))) +void nxt_wasm_send_response(u32 offset); + +__attribute__((export_name("wasm_response_end_handler"))) +void wasm_response_end_handler(void) +{ + total_response_sent = 0; +} + +__attribute__((export_name("wasm_request_end_handler"))) +void wasm_request_end_handler(void) +{ + if (!request_buf) + return; + + free(request_buf); + request_buf = NULL; +} + +__attribute__((export_name("wasm_free_handler"))) +void wasm_free_handler(u32 addr) +{ + free((void *)addr); +} + +__attribute__((export_name("wasm_malloc_handler"))) +u32 wasm_malloc_handler(size_t size) +{ + return (u32)malloc(size); +} + +static int upload_reflector(u8 *addr) +{ + size_t mem_size = nxt_wasm_get_init_mem_size(); + size_t rsize = sizeof(struct resp); + size_t write_bytes; + struct req *req; + struct resp *resp; + + printf("==[WASM RESP]== %s:\n", __func__); + + resp = (struct resp *)addr; + req = (struct req *)request_buf; + + printf("==[WASM RESP]== resp@%p\n", resp); + printf("==[WASM RESP]== req@%p\n", req); + printf("==[WASM RESP]== req->content_len : %u\n", req->content_len); + + resp = (struct resp *)addr; + + /* Send headers */ + if (total_response_sent == 0) { + const char *field; + struct hdr_field *f; + struct hdr_field *f_end; + char ct[256]; + + /* Try to set the Content-Type */ + f_end = req->fields + req->nr_fields; + for (f = req->fields; f < f_end; f++) { + field = (const char *)(u8 *)req + f->name_offs; + + if (strncasecmp(field, "Content-Type", 12) == 0) { + snprintf(ct, sizeof(ct), "%.*s", f->value_len, + (u8 *)req + f->value_offs); + break; + } + + field = NULL; + } + if (!field) + sprintf(ct, "application/octet-stream"); + + send_headers(addr, ct, req->content_len); + } + + write_bytes = req->content_sent; + if (write_bytes > mem_size - rsize) + write_bytes = mem_size - rsize; + + printf("==[WASM RESP]== write_bytes : %lu\n", write_bytes); + printf("==[WASM RESP]== req->content_len : %u\n", req->content_len); + printf("==[WASM RESP]== total_response_sent : %lu\n", + total_response_sent); + + printf("==[WASM RESP]== Copying (%lu) bytes of data from [%p+%lx] to " + "[%p]\n", write_bytes, req, + req->content_offs + total_response_sent, resp->data); + memcpy(resp->data, + (u8 *)req + req->content_offs + total_response_sent, + write_bytes); + + total_response_sent += write_bytes; + resp->size = write_bytes; + printf("==[WASM RESP]== resp->size : %u\n", resp->size); + + nxt_wasm_send_response(0); + + if (total_response_sent == req->content_len) { + printf("==[WASM RESP]== All data sent. Cleaning up...\n"); + total_response_sent = 0; + + free(request_buf); + request_buf = NULL; + + /* Tell Unit no more data to send */ + nxt_wasm_response_end(); + } + + return 0; +} + +__attribute__((export_name("wasm_request_handler"))) +int wasm_request_handler(u8 *addr) +{ + struct req *req = (struct req *)addr; + struct req *rb = (struct req *)request_buf; + + printf("==[WASM REQ]== %s:\n", __func__); + + /* + * This function _may_ be called multiple times during a single + * request if there is a large amount of data to transfer. + * + * Some useful request meta data: + * + * req->content_len contains the overall size of the POST/PUT + * data. + * req->content_sent shows how much of the body content has been + * in _this_ request. + * req->total_content_sent shows how much of it has been sent in + * total. + * req->content_offs is the offset in the passed in memory where + * the body content starts. + * + * For new requests req->request_size shows the total size of + * _this_ request, incl the req structure itself. + * For continuation requests, req->request_size is just the amount + * of new content, i.e req->content_sent + * + * When req->content_len == req->total_content_sent, that's the end + * of that request. + */ + + if (!request_buf) { + /* + * 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. + */ + printf("==[WASM REQ]== malloc(%u)\n", + req->content_offs + req->content_len); + request_buf = malloc(req->content_offs + req->content_len); + + /* + * Regardless of how much memory we allocated above, here + * we only want to copy the amount of data we actually + * received in this request. + */ + printf("==[WASM REQ]== req->request_size : %u\n", + req->request_size); + memcpy(request_buf, addr, req->request_size); + + rb = (struct req *)request_buf; + printf("==[WASM REQ]== rb@%p\n", rb); + printf("==[WASM REQ]== request_buf@%p\n", request_buf); + printf("==[WASM REQ]== rb->content_offs : %u\n", + rb->content_offs); + printf("==[WASM REQ]== rb->content_len : %u\n", + rb->content_len); + printf("==[WASM REQ]== rb->content_sent : %u\n", + rb->content_sent); + printf("==[WASM REQ]== rb->request_size : %u\n", + rb->request_size); + } else { + memcpy(request_buf + rb->request_size, addr + req->content_offs, + req->request_size); + + printf("==[WASM REQ +]== req->content_offs : %u\n", + req->content_offs); + printf("==[WASM REQ +]== req->content_sent : %u\n", + req->content_sent); + printf("==[WASM REQ +]== req->request_size : %u\n", + req->request_size); + + rb->content_sent = req->content_sent; + rb->total_content_sent = req->total_content_sent; + } + + upload_reflector(addr); + + return 0; +} |