/* 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 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_own_outgoing_response_t resp; 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; fields = wasi_http_types_constructor_fields(); resp = wasi_http_types_constructor_outgoing_response(fields); rerr.val.ok = resp; fd = open("/var/tmp/wasm-wasi-component-upload.dat", O_CREAT|O_TRUNC|O_WRONLY, 0666); if (fd == -1) { wasi_http_types_status_code_t sc; wasi_http_types_borrow_outgoing_response_t b_resp; printf("E: %s (/var/tmp/wasm-wasi-component-upload.dat)\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; } 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; } 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); out_response: wasi_http_types_static_response_outparam_set(response_out, &rerr); close(fd); }