diff options
author | Andrew Clayton <a.clayton@nginx.com> | 2023-08-02 17:03:48 +0100 |
---|---|---|
committer | Andrew Clayton <a.clayton@nginx.com> | 2023-08-21 23:24:12 +0100 |
commit | d6ed6a219b31a58526721f96195c80061d41ce54 (patch) | |
tree | 17a1fd6ecf72a327916ff0f8bc7aaf85b981ceff /examples/c/luw-echo-request.c | |
download | unit-wasm-c43c6b57d70ae3a2cb3a52f5f991cd68fd39b47d.tar.gz unit-wasm-c43c6b57d70ae3a2cb3a52f5f991cd68fd39b47d.tar.bz2 |
Initial commitv0.1.0
libunit-wasm and example C and Rust WebAssembly modules for NGINX Unit.
Co-developed-by: Timo Stark <t.stark@nginx.com>
Co-developed-by: Liam Crilly <liam@nginx.com>
Signed-off-by: Andrew Clayton <a.clayton@nginx.com>
Diffstat (limited to 'examples/c/luw-echo-request.c')
-rw-r--r-- | examples/c/luw-echo-request.c | 98 |
1 files changed, 98 insertions, 0 deletions
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; +} |