/* 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 #include #include #include #include #include #include #include #include "proxy.h" #define IMG_SZ (256 * 1024*1024UL) #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) { int fd; bool ok; char clen[32]; char *buf; 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; (void)request; buf = malloc(IMG_SZ); fd = open("/var/tmp/img", O_RDONLY); if (fd == -1) { wasi_http_types_status_code_t sc; printf("E: %s (/var/tmp/img)\n", strerror(errno)); switch (errno) { case EACCES: case EFAULT: case EPERM: sc = 403; break; case EBADF: case ENAMETOOLONG: case ENODEV: case ENOENT: case ENOTDIR: sc = 404; break; default: sc = 500; } fields = wasi_http_types_constructor_fields(); resp = wasi_http_types_constructor_outgoing_response(fields); b_resp = wasi_http_types_borrow_outgoing_response(resp); wasi_http_types_method_outgoing_response_set_status_code(b_resp, sc); rerr.val.ok = resp; goto out_response; } read(fd, buf, IMG_SZ); close(fd); 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, "application/octet-stream"); ok = wasi_http_types_method_fields_append(b_fields, &key, &value, &hdr_err); if (!ok) ex("wasi_http_types_method_fields_append(Content-Type) failed\n"); proxy_string_set((proxy_string_t *)&key, "Content-Length"); sprintf(clen, "%zu", IMG_SZ); 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(Content-Length) 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 = IMG_SZ; stream_data.ptr = (uint8_t *)buf; 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"); out_response: wasi_http_types_static_response_outparam_set(response_out, &rerr); free(buf); }