/* 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 "proxy.h"
#define ex(...) \
do { \
printf(__VA_ARGS__); \
exit(EXIT_FAILURE); \
} 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)
{
bool ok;
FILE *out;
size_t size;
char *out_ptr;
char clen[32];
wasi_http_types_own_outgoing_response_t resp;
wasi_http_types_borrow_outgoing_response_t b_resp;
wasi_http_types_own_fields_t fields;
wasi_http_types_borrow_fields_t b_fields;
wasi_http_types_result_own_outgoing_response_error_code_t rerr = { };
wasi_http_types_own_outgoing_body_t body;
wasi_http_types_borrow_outgoing_body_t b_body;
wasi_io_streams_own_output_stream_t out_stream;
wasi_io_streams_borrow_output_stream_t b_out_stream;
proxy_list_u8_t stream_data;
wasi_io_streams_stream_error_t stream_err;
wasi_http_types_header_error_t hdr_err;
wasi_http_types_field_key_t key;
wasi_http_types_field_value_t value;
proxy_list_tuple2_string_string_t env;
(void)request;
out = open_memstream(&out_ptr, &size);
#define BUF_ADD(fmt, ...) \
fprintf(out, fmt, ##__VA_ARGS__);
BUF_ADD("*** Environment Variables ***\n\n");
wasi_cli_environment_get_environment(&env);
for (size_t i = 0; i < env.len; i++)
BUF_ADD("%.*s=%.*s\n",
(int)env.ptr[i].f0.len, env.ptr[i].f0.ptr,
(int)env.ptr[i].f1.len, env.ptr[i].f1.ptr);
fclose(out);
fields = wasi_http_types_constructor_fields();
b_fields = wasi_http_types_borrow_fields(fields);
proxy_string_set((proxy_string_t *)&key, "Content-Type");
proxy_string_set((proxy_string_t *)&value, "text/plain");
proxy_string_set((proxy_string_t *)&key, "Content-Length");
sprintf(clen, "%zu", size);
proxy_string_set((proxy_string_t *)&value, clen);
ok = wasi_http_types_method_fields_append(b_fields, &key, &value,
&hdr_err);
if (!ok)
ex("wasi_http_types_method_fields_append() failed\n");
resp = wasi_http_types_constructor_outgoing_response(fields);
rerr.val.ok = resp;
b_resp = wasi_http_types_borrow_outgoing_response(resp);
ok = wasi_http_types_method_outgoing_response_body(b_resp, &body);
if (!ok)
ex("wasi_http_types_method_outgoing_response_body() failed\n");
b_body = wasi_http_types_borrow_outgoing_body(body);
ok = wasi_http_types_method_outgoing_body_write(b_body, &out_stream);
if (!ok)
ex("wasi_http_types_method_outgoing_body_write() failed\n");
b_out_stream = wasi_io_streams_borrow_output_stream(out_stream);
stream_data.len = size;
stream_data.ptr = (uint8_t *)out_ptr;
ok = wasi_io_streams_method_output_stream_write(b_out_stream,
&stream_data,
&stream_err);
if (!ok)
ex("wasi_io_streams_method_output_stream_blocking_write_and_flush() failed\n");
wasi_http_types_static_response_outparam_set(response_out, &rerr);
free(out_ptr);
}