blob: a4eeba69104cee04fc39a7d5636848a258bfd6a7 (
plain) (
tree)
|
|
/* 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 <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#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);
}
|