summaryrefslogblamecommitdiff
path: root/c/wasi-http/0.2.0/large-upload/component.c
blob: 148100dc61138f40f3667fece65cfde6ce136195 (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 "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_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;

	fd = open("/var/tmp/wasm-wasi-component-upload.dat",
		  O_CREAT|O_TRUNC|O_WRONLY, 0666);

	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);

	fields = wasi_http_types_constructor_fields();
	wasi_http_types_constructor_outgoing_response(fields);
	wasi_http_types_static_response_outparam_set(response_out, &rerr);

	close(fd);
}